changeset 6874:94bda6abc224

[project @ 2007-09-06 21:34:24 by jwe]
author jwe
date Thu, 06 Sep 2007 21:34:24 +0000
parents e03d52dc3d12
children 1f843c5601b3
files src/ChangeLog src/Makefile.in src/genprops.awk src/graphics.cc src/graphics.h src/graphics.h.in
diffstat 6 files changed, 2465 insertions(+), 2099 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Thu Sep 06 21:20:30 2007 +0000
+++ b/src/ChangeLog	Thu Sep 06 21:34:24 2007 +0000
@@ -1,3 +1,32 @@
+2007-08-31  John W. Eaton  <jwe@octave.org>
+
+	* Makefile.in (INCLUDES): Remove graphics.h from the list.
+	(DISTFILES): Include graphics.h.in in the list.
+	(genprops.awk): New file.
+	(graphics.h): New rule.
+	(distclean): Remove graphics.h.
+	* graphics.h.in: New file, from graphics.h.
+	(graphics_handle): Now a class instead of typedef.  Adapt all uses.
+	(OCTAVE_GRAPHICS_PROPERTY_INTERNAL, OCTAVE_GRAPHICS_PROPERTY,
+	OCTAVE_GRAPHICS_MUTABLE_PROPERTY): Delete macros.
+	(class root_figure, class figure, class axes, class line, class
+	text, class image, class patch, class surface): Use genprops.awk
+	to generate property declarations and set/get functions.
+	* graphics.h: Delete.
+	* graphics.cc (nan_to_empty, empty_to_nan): Delete.
+	(root_figure::properties::set, figure::properties::set,
+	axes::properties::set, line::properties::set,
+	text::properties::set, image::properties::set,
+	patch::properties::set, surface::properties::set): Call
+	type-specific set functions to set properties.
+	(root_figure::properties::set_currentfigure,
+	figure::properties::set_currentaxes, figure::properties::set_visible,
+	axes::properties::get_title, axes::properties::get_xlabel,
+	axes::properties::get_ylabel,  axes::properties::get_zlabel,
+	axes::properties::set_title, axes::properties::set_xlabel,
+	axes::properties::set_ylabel,  axes::properties::set_zlabel):
+	Define custom versions.
+
 2007-09-06  David Bateman  <dbateman@free.fr>
 
         * DLD-FUNCTIONS/bsxfun.cc: New function.
--- a/src/Makefile.in	Thu Sep 06 21:20:30 2007 +0000
+++ b/src/Makefile.in	Thu Sep 06 21:34:24 2007 +0000
@@ -101,7 +101,7 @@
 
 INCLUDES := Cell.h base-list.h c-file-ptr-stream.h comment-list.h \
 	defun-dld.h defun-int.h defun.h dirfns.h dynamic-ld.h \
-	error.h file-io.h graphics.h gripes.h help.h input.h \
+	error.h file-io.h gripes.h help.h input.h \
 	lex.h load-path.h load-save.h ls-hdf5.h ls-mat-ascii.h ls-mat4.h \
 	ls-mat5.h ls-oct-ascii.h ls-oct-binary.h ls-utils.h \
 	mex.h mexproto.h \
@@ -187,7 +187,7 @@
 
 SOURCES := $(DIST_SRC) $(OP_SRC) $(TI_SRC)
 
-BUILT_EXTRAS := mxarray.h
+BUILT_EXTRAS := graphics.h mxarray.h
 
 EXTRAS := ov-base-int.cc ov-base-mat.cc ov-base-scalar.cc
 
@@ -263,7 +263,8 @@
 
 DISTFILES = Makefile.in ChangeLog mkdefs mkops mkgendoc \
 	mkbuiltins mk-errno-list mk-pkg-add \
-	defaults.h.in mxarray.h.in oct-conf.h.in oct-errno.cc.in octave.gperf \
+	defaults.h.in graphics.h.in mxarray.h.in oct-conf.h.in \
+	oct-errno.cc.in octave.gperf \
 	$(INCLUDES) $(DIST_SRC) $(EXTRAS)
 
 all: octave$(EXEEXT) $(OCT_FILES) PKG_ADD DOCSTRINGS
@@ -353,6 +354,11 @@
 	@$(srcdir)/mkbuiltins def-files > $@-t
 	@$(simple-move-if-change-rule)
 
+graphics.h: graphics.h.in genprops.awk
+	@echo making $@
+	@awk -f $(srcdir)/genprops.awk $< > $@-t
+	@$(simple-move-if-change-rule)
+
 PKG_ADD: $(DLD_DEF_FILES)
 	$(srcdir)/mk-pkg-add $(DLD_DEF_FILES) > $@-t
 	@$(simple-move-if-change-rule)
@@ -509,7 +515,7 @@
 distclean: clean
 	rm -f Makefile octave$(EXEEXT) .fname so_locations oct-errno.cc
 	rm -f stamp-prereq stamp-liboctave-prereq
-	rm -f doc-files gendoc.cc mxarray.h DOCSTRINGS
+	rm -f doc-files gendoc.cc graphics.h mxarray.h DOCSTRINGS
 .PHONY: distclean
 
 maintainer-clean: distclean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/genprops.awk	Thu Sep 06 21:34:24 2007 +0000
@@ -0,0 +1,205 @@
+## This script is used to generate the graphics.h file from graphics.h.in.
+##
+## Lines between the BEGIN_PROPERTIES and END_PROPERTIES markers have
+## one of the following formats:
+##
+##   TYPE NAME
+##   TYPE NAME QUALIFIERS
+##   mutable TYPE NAME
+##   mutable TYPE NAME QUALIFIERS
+##
+## For each property, we generate a declaration for the property.
+##
+## If QUALIFIERS is omitted, we generate the following functions directly
+## in the class declaration:
+##
+##   TYPE get_NAME (void) const { return NAME; }
+##   void set_NAME (const TYPE& val) { NAME = val; }
+##   void set_NAME (const octave_value& val) { set_NAME (TYPE (val)); }
+##
+## If present, the QUALIFIERS string may include any of the characters
+## g, G, m, s, S, o, O, which have the following meanings:
+##
+##   g:  There is a custom inline definition for the get function,
+##       so we don't emit one.
+##
+##   G:  There is a custom extern definition for the get function,
+##       so we emit only the declaration.
+##
+##   s:  There is a custom inline definition for the type-specific set
+##       function, so we don't emit one.
+##
+##   S:  There is a custom extern definition for the type-specific set
+##       function, so we emit only the declaration.
+##
+##   o:  There is a custom inline definition for the octave_value version
+##       of the set function, so we don't emit one.
+##
+##   O:  There is a custom extern definition for the octave_value version
+##       of the set function, so we emit only the declaration.
+##
+##   m:  Add the line
+##
+##         set_NAMEmode ("manual");
+##
+##       to the type-specific set function.
+##
+## The 'o' and 'O' qualifiers are only useful when the the property type
+## is something other than octave_value.
+
+function emit_decls ()
+{
+  if (idx > 0)
+      print "private:\n";
+
+  for (i = 1; i <= idx; i++)
+      printf ("  %s%s %s;\n", mutable[i] ? "mutable " : "", type[i], name[i]);
+
+  if (idx > 0)
+      print "\npublic:\n";
+
+  for (i = 1; i <= idx; i++)
+  {
+      if (emit_get[i])
+      {
+	  printf ("  %s get_%s (void) const", type[i], name[i]);
+
+	  if (emit_get[i] == "defn")
+	      printf (" { return %s; }\n", name[i]);
+	  else
+	      printf (";\n");
+      }
+  }
+
+  if (idx > 0)
+      printf ("\n");
+
+  for (i = 1; i <= idx; i++)
+  {
+      if (emit_set[i])
+      {
+	  printf ("  void set_%s (const %s& val)", name[i], type[i]);
+
+	  if (emit_set[i] == "defn")
+	  {
+	      printf ("\n  {\n    if (! error_state)\n      {\n        %s = val;\n",
+		      name[i]);
+	      if (mode[i])
+		  printf ("        set_%smode (\"manual\");\n", name[i]);
+	      printf ("        mark_modified ();\n      }\n  }\n\n");
+	  }
+	  else
+	      printf (";\n");
+      }
+
+      if (emit_ov_set[i])
+      {
+	  printf ("  void set_%s (const octave_value& val)", name[i]);
+
+	  if (emit_ov_set[i] == "defn")
+	      printf (" { set_%s (%s (val)); }\n\n", name[i], type[i]);
+	  else
+	      printf (";\n");
+      }
+  }
+
+  if (idx > 0)
+      print "\nprivate:";
+}
+
+BEGIN {
+    printf ("// DO NOT EDIT!  Generated automatically by genprops.awk.\n\n");
+}
+
+/BEGIN_PROPERTIES/ {
+    gather = 1;
+    idx = 0;
+    next;
+}
+
+/END_PROPERTIES/ {
+    emit_decls();
+    gather = 0;
+    next;
+}
+
+{
+  if (gather)
+    {
+      if (NF < 2 || NF > 4)
+	next;
+
+      idx++;
+
+      field = 1;
+
+      if ($field == "mutable")
+      {
+	  mutable[idx] = 1;
+	  field++;
+      }
+      else
+	  mutable[idx] = 0;
+
+      type[idx] = $(field++);
+      name[idx] = $(field++);
+
+      mode[idx] = 0;
+      emit_get[idx] = "defn";
+      emit_set[idx] = "defn";
+      if (type[idx] == "octave_value")
+	  emit_ov_set[idx] = "";
+      else
+	  emit_ov_set[idx] = "defn";
+
+      if (NF == field)
+        {
+	    quals = $field;
+
+	    if (index (quals, "m"))
+		mode[idx] = 1;
+
+	    ## There is a custom inline definition for the get function,
+	    ## so we don't emit anything.
+	    if (index (quals, "g"))
+		emit_get[idx] = "";
+
+	    ## There is a custom extern definition for the get function,
+	    ## but we still emit the declaration.
+	    if (index (quals, "G"))
+		emit_get[idx] = "decl";
+
+	    ## There is a custom inline definition for the set function,
+	    ## so we don't emit anything.
+	    if (index (quals, "s"))
+		emit_set[idx] = "";
+
+	    ## There is a custom extern definition for the set function,
+	    ## but we still emit the declaration.
+	    if (index (quals, "S"))
+		emit_set[idx] = "decl";
+
+	    if (type[idx] != "octave_value")
+	    {
+		## The 'o' and 'O' qualifiers are only useful when the
+		## the property type is something other than an
+		## octave_value.
+
+		## There is a custom inline definition for the
+		## octave_value version of the set function, so we
+		## don't emit anything.
+		if (index (quals, "o"))
+		    emit_ov_set[idx] = "";
+
+		## There is a custom extern definition for the
+		## octave_value version of the set function, but we
+		## still emit the declaration.
+		if (index (quals, "O"))
+		    emit_ov_set[idx] = "decl";
+	    }
+        }
+
+    }
+  else
+      print $0;
+}
\ No newline at end of file
--- a/src/graphics.cc	Thu Sep 06 21:20:30 2007 +0000
+++ b/src/graphics.cc	Thu Sep 06 21:34:24 2007 +0000
@@ -48,18 +48,6 @@
   error ("set: invalid value for %s property", pname.c_str ());
 }
 
-static octave_value
-nan_to_empty (double val)
-{
-  return xisnan (val) ? octave_value (Matrix ()) : octave_value (val);
-}
-
-static octave_value
-empty_to_nan (const octave_value& val)
-{
-  return val.is_empty () ? octave_value (octave_NaN) : val;
-}
-
 // ---------------------------------------------------------------------
 
 radio_values::radio_values (const std::string& opt_string)
@@ -380,6 +368,22 @@
   return m;    
 }
 
+graphics_handle::graphics_handle (const octave_value& a)
+  : val (octave_NaN)
+{
+  if (a.is_empty ())
+    /* do nothing */;
+  else
+    {
+      double tval = a.double_value ();
+
+      if (! error_state)
+	val = tval;
+      else
+	error ("invalid graphics handle");
+    }
+}
+
 void
 graphics_object::set (const octave_value_list& args)
 {
@@ -454,25 +458,27 @@
 void
 gh_manager::do_free (const graphics_handle& h)
 {
-  if (h != 0)
+  if (h)
     {
-      iterator p = handle_map.find (h);
-
-      if (p != handle_map.end ())
+      if (h.value () != 0)
 	{
-	  handle_map.erase (p);
-
-	  if (h < 0)
-	    handle_free_list.insert (h);
+	  iterator p = handle_map.find (h);
+
+	  if (p != handle_map.end ())
+	    {
+	      handle_map.erase (p);
+
+	      if (h.value () < 0)
+		handle_free_list.insert (h);
+	    }
+	  else
+	    error ("graphics_handle::free: invalid object %g", h.value ());
 	}
       else
-	error ("graphics_handle::free: invalid object %g", h);
+	error ("graphics_handle::free: can't delete root figure");
     }
-  else
-    error ("graphics_handle::free: can't delete root figure");
 }
 
-
 gh_manager *gh_manager::instance = 0;
 
 static void
@@ -514,7 +520,7 @@
     {
       h = gh_manager::lookup (val);
 
-      if (! xisnan (h))
+      if (h)
 	{
 	  graphics_object obj = gh_manager::get_object (h);
 	  
@@ -525,7 +531,7 @@
 	  parent_obj.remove_child (h);
 
 	  if (adopt)
-	    obj.set ("parent", new_parent);
+	    obj.set ("parent", new_parent.value ());
 	  else
 	    obj.reparent (new_parent);
 	}
@@ -569,7 +575,9 @@
 static bool
 is_handle (double val)
 {
-  return ! xisnan (gh_manager::lookup (val));
+  graphics_handle h = gh_manager::lookup (val);
+
+  return h.ok ();
 }
 
 static bool
@@ -667,7 +675,7 @@
   octave_idx_type n = children.numel ();
   for (octave_idx_type i = 0; i < n; i++)
     {
-      if (h == children(i))
+      if (h.value () == children(i))
 	{
 	  k = i;
 	  break;
@@ -698,7 +706,7 @@
     {
       new_parent = gh_manager::lookup (tmp);
 
-      if (! xisnan (new_parent))
+      if (new_parent)
 	{
 	  graphics_object parent_obj = gh_manager::get_object (parent);
 
@@ -740,26 +748,31 @@
 }
 
 void
+root_figure::properties::set_currentfigure (const graphics_handle& val)
+{
+  if (error_state)
+    return;
+
+  if (is_handle (val))
+    {
+      currentfigure = val;
+
+      gh_manager::push_figure (currentfigure);
+    }
+  else
+    gripe_set_invalid ("currentfigure");
+}
+
+void
 root_figure::properties::set (const property_name& name,
 			      const octave_value& val)
 {
   if (name.compare ("currentfigure"))
-    {
-      octave_value tval = empty_to_nan (val);
-
-      if (is_handle (tval))
-	{
-	  currentfigure = tval.double_value ();
-
-	  gh_manager::push_figure (currentfigure);
-	}
-      else
-	gripe_set_invalid ("currentfigure");
-    }
+    set_currentfigure (val);
   else if (name.compare ("children"))
     children = maybe_set_children (children, val);
   else if (name.compare ("visible"))
-    visible = val;
+    set_visible (val);
   else
     warning ("set: invalid property `%s'", name.c_str ());
 }
@@ -769,7 +782,7 @@
   Octave_map m;
 
   m.assign ("type", type);
-  m.assign ("currentfigure", nan_to_empty (currentfigure));
+  m.assign ("currentfigure", currentfigure.as_octave_value ());
   m.assign ("children", children);
   m.assign ("visible", visible);
 
@@ -784,7 +797,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("currentfigure"))
-    retval = nan_to_empty (currentfigure);
+    retval = currentfigure.as_octave_value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("visible"))
@@ -815,8 +828,33 @@
 { }
 
 void
-figure::properties::set (const property_name& name,
-			 const octave_value& val)
+figure::properties::set_currentaxes (const graphics_handle& val)
+{
+  if (error_state)
+    return;
+
+  if (is_handle (val))
+    currentaxes = val;
+  else
+    gripe_set_invalid ("currentaxes");
+}
+
+void
+figure::properties::set_visible (const octave_value& val)
+{
+  std::string s = val.string_value ();
+
+  if (! error_state)
+    {
+      if (s == "on")
+	xset (0, "currentfigure", __myhandle__.value ());
+
+      visible = val;
+    }
+}
+
+void
+figure::properties::set (const property_name& name, const octave_value& val)
 {
   bool modified = true;
 
@@ -828,36 +866,19 @@
       modified = false;
     }
   else if (name.compare ("__plot_stream__"))
-    __plot_stream__ = val;
+    set___plot_stream__ (val);
   else if (name.compare ("nextplot"))
-    nextplot = val;
+    set_nextplot (val);
   else if (name.compare ("closerequestfcn"))
-    closerequestfcn = val;
+    set_closerequestfcn (val);
   else if (name.compare ("currentaxes"))
-    {
-      octave_value tval = empty_to_nan (val);
-
-      if (is_handle (tval))
-	currentaxes = tval.double_value ();
-      else
-	gripe_set_invalid ("currentaxes");
-    }
+    set_currentaxes (val);
   else if (name.compare ("colormap"))
-    colormap = colormap_property (val);
+    set_colormap (val);
   else if (name.compare ("visible"))
-    {
-      std::string s = val.string_value ();
-
-      if (! error_state)
-	{
-	  if (s == "on")
-	    xset (0, "currentfigure", __myhandle__);
-
-	  visible = val;
-	}
-    }
+    set_visible (val);
   else if (name.compare ("paperorientation"))
-    paperorientation = val;
+    set_paperorientation (val);
   else
     {
       modified = false;
@@ -874,13 +895,13 @@
   Octave_map m;
 
   m.assign ("type", type);
-  m.assign ("parent", parent);
+  m.assign ("parent", parent.as_octave_value ());
   m.assign ("children", children);
   m.assign ("__modified__", __modified__);
   m.assign ("__plot_stream__", __plot_stream__);
   m.assign ("nextplot", nextplot);
   m.assign ("closerequestfcn", closerequestfcn);
-  m.assign ("currentaxes", nan_to_empty (currentaxes));
+  m.assign ("currentaxes", currentaxes.as_octave_value ());
   m.assign ("colormap", colormap);
   m.assign ("visible", visible);
   m.assign ("paperorientation", paperorientation);
@@ -896,7 +917,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("parent"))
-    retval = parent;
+    retval = parent.as_octave_value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("__modified__"))
@@ -908,7 +929,7 @@
   else if (name.compare ("closerequestfcn"))
     retval = closerequestfcn;
   else if (name.compare ("currentaxes"))
-    retval = nan_to_empty (currentaxes);
+    retval = currentaxes.as_octave_value ();
   else if (name.compare ("colormap"))
     retval = colormap;
   else if (name.compare ("visible"))
@@ -937,7 +958,9 @@
 
   gh_manager::pop_figure (__myhandle__);
 
-  xset (0, "currentfigure", gh_manager::current_figure ());
+  graphics_handle cf = gh_manager::current_figure ();
+
+  xset (0, "currentfigure", cf.value ());
 }
 
 property_list::pval_map_type
@@ -1047,6 +1070,70 @@
 }
 
 void
+axes::properties::set_title (const graphics_handle& val)
+{
+  if (! error_state)
+    {
+      gh_manager::free (title);
+      title = val;
+    }
+}
+
+void
+axes::properties::set_title (const octave_value& val)
+{
+  set_title (::reparent (val, "set", "title", __myhandle__, false));
+}
+
+void
+axes::properties::set_xlabel (const graphics_handle& val)
+{
+  if (! error_state)
+    {
+      gh_manager::free (xlabel);
+      xlabel = val;
+    }
+}
+
+void
+axes::properties::set_xlabel (const octave_value& val)
+{
+  set_xlabel (::reparent (val, "set", "xlabel", __myhandle__, false));
+}
+
+void
+axes::properties::set_ylabel (const graphics_handle& val)
+{
+  if (! error_state)
+    {
+      gh_manager::free (ylabel);
+      ylabel = val;
+    }
+}
+
+void
+axes::properties::set_ylabel (const octave_value& val)
+{
+  set_ylabel (::reparent (val, "set", "ylabel", __myhandle__, false));
+}
+
+void
+axes::properties::set_zlabel (const graphics_handle& val)
+{
+  if (! error_state)
+    {
+      gh_manager::free (zlabel);
+      zlabel = val;
+    }
+}
+
+void
+axes::properties::set_zlabel (const octave_value& val)
+{
+  set_zlabel (::reparent (val, "set", "zlabel", __myhandle__, false));
+}
+
+void
 axes::properties::set (const property_name& name, const octave_value& val)
 {
   bool modified = true;
@@ -1061,176 +1148,103 @@
       modified = false;
     }
   else if (name.compare ("position"))
-    position = val;
+    set_position (val);
   else if (name.compare ("title"))
-    {
-      graphics_handle h = ::reparent (val, "set", "title",
-				      __myhandle__, false);
-      if (! error_state)
-	{
-	  if (! xisnan (title))
-	    gh_manager::free (title);
-
-	  title = h;
-	}
-    }
+    set_title (val);
   else if (name.compare ("box"))
-    box = val;
+    set_box (val);
   else if (name.compare ("key"))
-    key = val;
+    set_key (val);
   else if (name.compare ("keybox"))
-    keybox = val;
+    set_keybox (val);
   else if (name.compare ("keypos"))
-    keypos = val;
+    set_keypos (val);
   else if (name.compare ("dataaspectratio"))
-    {
-      dataaspectratio = val;
-      dataaspectratiomode = "manual";
-    }
+    set_dataaspectratio (val);
   else if (name.compare ("dataaspectratiomode"))
-    dataaspectratiomode = val;
+    set_dataaspectratiomode (val);
   else if (name.compare ("xlim"))
-    {
-      xlim = val;
-      xlimmode = "manual";
-    }
+    set_xlim (val);
   else if (name.compare ("ylim"))
-    {
-      ylim = val;
-      ylimmode = "manual";
-    }
+    set_ylim (val);
   else if (name.compare ("zlim"))
-    {
-      zlim = val;
-      zlimmode = "manual";
-    }
+    set_zlim (val);
   else if (name.compare ("clim"))
-    {
-      clim = val;
-      climmode = "manual";
-    }
+    set_clim (val);
   else if (name.compare ("xlimmode"))
-    xlimmode = val;
+    set_xlimmode (val);
   else if (name.compare ("ylimmode"))
-    ylimmode = val;
+    set_ylimmode (val);
   else if (name.compare ("zlimmode"))
-    zlimmode = val;
+    set_zlimmode (val);
   else if (name.compare ("climmode"))
-    climmode = val;
+    set_climmode (val);
   else if (name.compare ("xlabel"))
-    {
-      graphics_handle h = ::reparent (val, "set", "xlabel",
-				      __myhandle__, false);
-      if (! error_state)
-	{
-	  if (! xisnan (xlabel))
-	    gh_manager::free (xlabel);
-
-	  xlabel = h;
-	}
-    }
+    set_xlabel (val);
   else if (name.compare ("ylabel"))
-    {
-      graphics_handle h = ::reparent (val, "set", "ylabel",
-				      __myhandle__, false);
-      if (! error_state)
-	{
-	  if (! xisnan (ylabel))
-	    gh_manager::free (ylabel);
-
-	  ylabel = h;
-	}
-    }
+    set_ylabel (val);
   else if (name.compare ("zlabel"))
-    {
-      graphics_handle h = ::reparent (val, "set", "zlabel",
-				      __myhandle__, false);
-      if (! error_state)
-	{
-	  if (! xisnan (zlabel))
-	    gh_manager::free (zlabel);
-
-	  zlabel = h;
-	}
-    }
+    set_zlabel (val);
   else if (name.compare ("xgrid"))
-    xgrid = val;
+    set_xgrid (val);
   else if (name.compare ("ygrid"))
-    ygrid = val;
+    set_ygrid (val);
   else if (name.compare ("zgrid"))
-    zgrid = val;
+    set_zgrid (val);
   else if (name.compare ("xminorgrid"))
-    xminorgrid = val;
+    set_xminorgrid (val);
   else if (name.compare ("yminorgrid"))
-    yminorgrid = val;
+    set_yminorgrid (val);
   else if (name.compare ("zminorgrid"))
-    zminorgrid = val;
+    set_zminorgrid (val);
   else if (name.compare ("xtick"))
-    {
-      xtick = val;
-      xtickmode = "manual";
-    }
+    set_xtick (val);
   else if (name.compare ("ytick"))
-    {
-      ytick = val;
-      ytickmode = "manual";
-    }
+    set_xtick (val);
   else if (name.compare ("ztick"))
-    {
-      ztick = val;
-      ztickmode = "manual";
-    }
+    set_ztick (val);
   else if (name.compare ("xtickmode"))
-    xtickmode = val;
+    set_xtickmode (val);
   else if (name.compare ("ytickmode"))
-    ytickmode = val;
+    set_ytickmode (val);
   else if (name.compare ("ztickmode"))
-    ztickmode = val;
+    set_ztickmode (val);
   else if (name.compare ("xticklabel"))
-    {
-      xticklabel = val;
-      xticklabelmode = "manual";
-    }
+    set_xticklabel (val);
   else if (name.compare ("yticklabel"))
-    {
-      yticklabel = val;
-      yticklabelmode = "manual";
-    }
+    set_yticklabel (val);
   else if (name.compare ("zticklabel"))
-    {
-      zticklabel = val;
-      zticklabelmode = "manual";
-    }
+    set_zticklabel (val);
   else if (name.compare ("xticklabelmode"))
-    xticklabelmode = val;
+    set_xticklabelmode (val);
   else if (name.compare ("yticklabelmode"))
-    yticklabelmode = val;
+    set_yticklabelmode (val);
   else if (name.compare ("zticklabelmode"))
-    zticklabelmode = val;
+    set_zticklabelmode (val);
   else if (name.compare ("xscale"))
-    xscale = val;
+    set_xscale (val);
   else if (name.compare ("yscale"))
-    yscale = val;
+    set_yscale (val);
   else if (name.compare ("zscale"))
-    zscale = val;
+    set_zscale (val);
   else if (name.compare ("xdir"))
-    xdir = val;
+    set_xdir (val);
   else if (name.compare ("ydir"))
-    ydir = val;
+    set_ydir (val);
   else if (name.compare ("zdir"))
-    zdir = val;
+    set_zdir (val);
   else if (name.compare ("xaxislocation"))
-    xaxislocation = val;
+    set_xaxislocation (val);
   else if (name.compare ("yaxislocation"))
-    yaxislocation = val;
+    set_yaxislocation (val);
   else if (name.compare ("view"))
-    view = val;
+    set_view (val);
   else if (name.compare ("visible"))
-    visible = val;
+    set_visible (val);
   else if (name.compare ("nextplot"))
-    nextplot = val;
+    set_nextplot (val);
   else if (name.compare ("outerposition"))
-    outerposition = val;
+    set_outerposition (val);
   else
     {
       modified = false;
@@ -1323,29 +1337,53 @@
   override_defaults (obj);
 }
 
+graphics_handle
+axes::properties::get_title (void) const
+{
+  if (! title)
+    title = gh_manager::make_graphics_handle ("text", __myhandle__);
+
+  return title;
+}
+
+graphics_handle
+axes::properties::get_xlabel (void) const
+{
+  if (! xlabel)
+    xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
+
+  return xlabel;
+}
+
+graphics_handle
+axes::properties::get_ylabel (void) const
+{
+  if (! ylabel)
+    ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
+
+  return ylabel;
+}
+
+graphics_handle
+axes::properties::get_zlabel (void) const
+{
+  if (! zlabel)
+    zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
+
+  return zlabel;
+}
+
 octave_value
 axes::properties::get (void) const
 {
   Octave_map m;
 
-  if (xisnan (title))
-    title = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-  if (xisnan (xlabel))
-    xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-  if (xisnan (ylabel))
-    ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-  if (xisnan (zlabel))
-    zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
   m.assign ("type", type);
-  m.assign ("parent", parent);
+  m.assign ("parent", parent.as_octave_value ());
   m.assign ("children", children);
   m.assign ("__modified__", __modified__);
   m.assign ("position", position);
-  m.assign ("title", title);
+  m.assign ("title", get_title().as_octave_value ());
   m.assign ("box", box);
   m.assign ("key", key);
   m.assign ("keybox", keybox);
@@ -1360,9 +1398,9 @@
   m.assign ("ylimmode", ylimmode);
   m.assign ("zlimmode", zlimmode);
   m.assign ("climmode", climmode);
-  m.assign ("xlabel", xlabel);
-  m.assign ("ylabel", ylabel);
-  m.assign ("zlabel", zlabel);
+  m.assign ("xlabel", get_xlabel().as_octave_value ());
+  m.assign ("ylabel", get_ylabel().as_octave_value ());
+  m.assign ("zlabel", get_zlabel().as_octave_value ());
   m.assign ("xgrid", xgrid);
   m.assign ("ygrid", ygrid);
   m.assign ("zgrid", zgrid);
@@ -1405,7 +1443,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("parent"))
-    retval = parent;
+    retval = parent.value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("__modified__"))
@@ -1413,12 +1451,7 @@
   else if (name.compare ("position"))
     retval = position;
   else if (name.compare ("title"))
-    {
-      if (xisnan (title))
-	title = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-      retval = title;
-    }
+    retval = get_title().as_octave_value ();
   else if (name.compare ("box"))
     retval = box;
   else if (name.compare ("key"))
@@ -1448,26 +1481,11 @@
   else if (name.compare ("climmode"))
     retval = climmode;
   else if (name.compare ("xlabel"))
-    {
-      if (xisnan (xlabel))
-	xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-      retval = xlabel;
-    }
+    retval = get_xlabel().as_octave_value ();
   else if (name.compare ("ylabel"))
-    {
-      if (xisnan (ylabel))
-	ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-      retval = ylabel;
-    }
+    retval = get_ylabel().as_octave_value ();
   else if (name.compare ("zlabel"))
-    {
-      if (xisnan (zlabel))
-	zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-      retval = zlabel;
-    }
+    retval = get_zlabel().as_octave_value ();
   else if (name.compare ("xgrid"))
     retval = xgrid;
   else if (name.compare ("ygrid"))
@@ -1537,13 +1555,13 @@
 void
 axes::properties::remove_child (const graphics_handle& h)
 {
-  if (! xisnan (title) && h == title)
+  if (title && h == title)
     title = gh_manager::make_graphics_handle ("text", __myhandle__);
-  else if (! xisnan (xlabel) && h == xlabel)
+  else if (xlabel && h == xlabel)
     xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-  else if (! xisnan (ylabel) && h == ylabel)
+  else if (ylabel && h == ylabel)
     ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-  else if (! xisnan (zlabel) && h == zlabel)
+  else if (zlabel && h == zlabel)
     zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
   else
     base_properties::remove_child (h);
@@ -1554,17 +1572,10 @@
 {
   base_properties::delete_children ();
 
-  if (! xisnan (title))
-    gh_manager::free (title);
-
-  if (! xisnan (xlabel))
-    gh_manager::free (xlabel);
-
-  if (! xisnan (ylabel))
-    gh_manager::free (ylabel);
-
-  if (! xisnan (zlabel))
-    gh_manager::free (zlabel);
+  gh_manager::free (title);
+  gh_manager::free (xlabel);
+  gh_manager::free (ylabel);
+  gh_manager::free (zlabel);
 }
 
 property_list::pval_map_type
@@ -1710,35 +1721,35 @@
       modified = false;
     }
   else if (name.compare ("xdata"))
-    xdata = val;
+    set_xdata (val);
   else if (name.compare ("ydata"))
-    ydata = val;
+    set_ydata (val);
   else if (name.compare ("zdata"))
-    zdata = val;
+    set_zdata (val);
   else if (name.compare ("ldata"))
-    ldata = val;
+    set_ldata (val);
   else if (name.compare ("udata"))
-    udata = val;
+    set_udata (val);
   else if (name.compare ("xldata"))
-    xldata = val;
+    set_xldata (val);
   else if (name.compare ("xudata"))
-    xudata = val;
+    set_xudata (val);
   else if (name.compare ("color"))
-    color = val;
+    set_color (val);
   else if (name.compare ("linestyle"))
-    linestyle = val;
+    set_linestyle (val);
   else if (name.compare ("linewidth"))
-    linewidth = val;
+    set_linewidth (val);
   else if (name.compare ("marker"))
-    marker = val;
+    set_marker (val);
   else if (name.compare ("markeredgecolor"))
-    markeredgecolor = val;
+    set_markeredgecolor (val);
   else if (name.compare ("markerfacecolor"))
-    markerfacecolor = val;
+    set_markerfacecolor (val);
   else if (name.compare ("markersize"))
-    markersize = val;
+    set_markersize (val);
   else if (name.compare ("keylabel"))
-    keylabel = val;
+    set_keylabel (val);
   else
     {
       modified = false;
@@ -1755,7 +1766,7 @@
   Octave_map m;
 
   m.assign ("type", type);
-  m.assign ("parent", parent);
+  m.assign ("parent", parent.as_octave_value ());
   m.assign ("children", children);
   m.assign ("__modified__", __modified__);
   m.assign ("xdata", xdata);
@@ -1785,7 +1796,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("parent"))
-    retval = parent;
+    retval = parent.as_octave_value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("__modified__"))
@@ -1880,17 +1891,17 @@
       modified = false;
     }
   else if (name.compare ("string"))
-    string = val;
+    set_string (val);
   else if (name.compare ("units"))
-    units = val;
+    set_units (val);
   else if (name.compare ("position"))
-    position = val;
+    set_position (val);
   else if (name.compare ("rotation"))
-    rotation = val;
+    set_rotation (val);
   else if (name.compare ("horizontalalignment"))
-    horizontalalignment = val;
+    set_horizontalalignment (val);
   else if (name.compare ("color"))
-    color = val;
+    set_color (val);
   else
     {
       modified = false;
@@ -1907,7 +1918,7 @@
   Octave_map m;
 
   m.assign ("type", type);
-  m.assign ("parent", parent);
+  m.assign ("parent", parent.as_octave_value ());
   m.assign ("children", children);
   m.assign ("__modified__", __modified__);
   m.assign ("string", string);
@@ -1928,7 +1939,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("parent"))
-    retval = parent;
+    retval = parent.as_octave_value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("__modified__"))
@@ -1994,11 +2005,11 @@
       modified = false;
     }
   else if (name.compare ("cdata"))
-    cdata = val;
+    set_cdata (val);
   else if (name.compare ("xdata"))
-    xdata = val;
+    set_xdata (val);
   else if (name.compare ("ydata"))
-    ydata = val;
+    set_ydata (val);
   else
     {
       modified = false;
@@ -2015,7 +2026,7 @@
   Octave_map m;
 
   m.assign ("type", type);
-  m.assign ("parent", parent);
+  m.assign ("parent", parent.as_octave_value ());
   m.assign ("children", children);
   m.assign ("__modified__", __modified__);
   m.assign ("cdata", cdata);
@@ -2033,7 +2044,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("parent"))
-    retval = parent;
+    retval = parent.as_octave_value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("__modified__"))
@@ -2100,32 +2111,31 @@
       modified = false;
     }
   else if (name.compare ("cdata"))
-    cdata = val;
+    set_cdata (val);
   else if (name.compare ("xdata"))
-    xdata = val;
+    set_xdata (val);
   else if (name.compare ("ydata"))
-    ydata = val;
+    set_ydata (val);
   else if (name.compare ("zdata"))
-    zdata = val;
+    set_zdata (val);
   else if (name.compare ("facecolor"))
-    facecolor = val;
+    set_facecolor (val);
   else if (name.compare ("facealpha"))
-    facealpha = val;
+    set_facealpha (val);
   else if (name.compare ("edgecolor"))
-    edgecolor = val;
+    set_edgecolor (val);
   else if (name.compare ("linestyle"))
-    linestyle = val;
+    set_linestyle (val);
   else if (name.compare ("linewidth"))
-    linewidth = val;
+    set_linewidth (val);
   else if (name.compare ("marker"))
-    marker = val;
+    set_marker (val);
   else if (name.compare ("markeredgecolor"))
-    markeredgecolor = val;
+    set_markeredgecolor (val);
   else if (name.compare ("markerfacecolor"))
-    markerfacecolor = val;
+    set_markerfacecolor (val);
   else if (name.compare ("markersize"))
-    markersize = val;
-
+    set_markersize (val);
   else
     {
       modified = false;
@@ -2142,7 +2152,7 @@
   Octave_map m;
 
   m.assign ("type", type);
-  m.assign ("parent", parent);
+  m.assign ("parent", parent.as_octave_value ());
   m.assign ("children", children);
   m.assign ("__modified__", __modified__);
   m.assign ("cdata", cdata);
@@ -2170,7 +2180,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("parent"))
-    retval = parent;
+    retval = parent.as_octave_value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("__modified__"))
@@ -2259,13 +2269,13 @@
       modified = false;
     }
   else if (name.compare ("xdata"))
-    xdata = val;
+    set_xdata (val);
   else if (name.compare ("ydata"))
-    ydata = val;
+    set_ydata (val);
   else if (name.compare ("zdata"))
-    zdata = val;
+    set_zdata (val);
   else if (name.compare ("keylabel"))
-    keylabel = val;
+    set_keylabel (val);
   else
     {
       modified = false;
@@ -2282,7 +2292,7 @@
   Octave_map m;
 
   m.assign ("type", type);
-  m.assign ("parent", parent);
+  m.assign ("parent", parent.as_octave_value ());
   m.assign ("children", children);
   m.assign ("__modified__", __modified__);
   m.assign ("xdata", xdata);
@@ -2301,7 +2311,7 @@
   if (name.compare ("type"))
     retval = type;
   else if (name.compare ("parent"))
-    retval = parent;
+    retval = parent.as_octave_value ();
   else if (name.compare ("children"))
     retval = children;
   else if (name.compare ("__modified__"))
@@ -2579,7 +2589,7 @@
 
 static octave_value
 make_graphics_object (const std::string& go_name,
-          const octave_value_list& args)
+		      const octave_value_list& args)
 {
   octave_value retval;
 
@@ -2589,7 +2599,7 @@
     {
       graphics_handle parent = gh_manager::lookup (val);
 
-      if (! xisnan (parent))
+      if (parent)
 	{
 	  graphics_handle h
 	    = gh_manager::make_graphics_handle (go_name, parent);
@@ -2600,7 +2610,7 @@
 
 	      xset (h, args.splice (0, 1));
 
-	      retval = h;
+	      retval = h.value ();
 	    }
 	  else
 	    error ("__go%s__: unable to create graphics handle",
@@ -2635,7 +2645,7 @@
 
 	      xset (h, args.splice (0, 1));
 
-	      retval = h;
+	      retval = h.value ();
 	    }
 	  else
 	    {
@@ -2648,13 +2658,13 @@
 	      else
 		error ("__go_figure__: invalid figure number");
 
-	      if (! (error_state || xisnan (h)))
+	      if (! error_state && h)
 		{
 		  adopt (0, h);
 
 		  xset (h, args.splice (0, 1));
 
-		  retval = h;
+		  retval = h.value ();
 		}
 	      else
 		error ("__go_figure__: failed to create figure handle");
@@ -2750,7 +2760,7 @@
 	{
 	  h = gh_manager::lookup (val);
 
-	  if (! xisnan (h))
+	  if (h)
 	    {
 	      graphics_object obj = gh_manager::get_object (h);
 
@@ -2804,7 +2814,7 @@
 	{
 	  h = gh_manager::lookup (val);
 
-	  if (! xisnan (h))
+	  if (h)
 	    {
 	      graphics_object obj = gh_manager::get_object (h);
 
--- a/src/graphics.h	Thu Sep 06 21:20:30 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1781 +0,0 @@
-/*
-
-Copyright (C) 2007 John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, write to the Free
-Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
-
-*/
-
-#if !defined (graphics_h)
-#define graphics_h 1
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cctype>
-
-#include <algorithm>
-#include <list>
-#include <map>
-#include <set>
-#include <string>
-
-#include "oct-map.h"
-#include "ov.h"
-
-#define OCTAVE_GRAPHICS_PROPERTY_INTERNAL(TAG, TYPE, NAME) \
-  private: \
-    TAG TYPE NAME; \
-  public: \
-    const TYPE& get_ ## NAME () const { return NAME; } \
-  private:
-
-#define OCTAVE_GRAPHICS_PROPERTY(TYPE, NAME) \
-  OCTAVE_GRAPHICS_PROPERTY_INTERNAL ( , TYPE, NAME)
-
-#define OCTAVE_GRAPHICS_MUTABLE_PROPERTY(TYPE, NAME) \
-  OCTAVE_GRAPHICS_PROPERTY_INTERNAL (mutable, TYPE, NAME)
-
-class
-radio_values
-{
-public:
-  radio_values (const std::string& opt_string = std::string ());
-  radio_values (const radio_values& a)
-    : default_val (a.default_val), possible_vals (a.possible_vals) { }
-
-  radio_values& operator = (const radio_values& a)
-  {
-    if (&a != this)
-      {
-	default_val = a.default_val;
-	possible_vals = a.possible_vals;
-      }
-
-    return *this;
-  }
-
-  std::string default_value (void) const { return default_val; }
-
-  std::set<std::string> possible_values (void) const { return possible_vals; }
-
-  bool validate (const std::string& val)
-  {
-    bool retval = true;
-
-    if (possible_vals.find (val) == possible_vals.end ())
-      {
-	error ("invalid value = %s", val.c_str ());
-	retval = false;
-      }
-
-    return retval;
-  }
-
-private:
-  // Might also want to cache
-  std::string default_val;
-  std::set<std::string> possible_vals;
-};
-
-class
-radio_property
-{
-public:
-  radio_property (const radio_values& v)
-    : vals (v), current_val (v.default_value ()) { }
-
-  radio_property (const radio_values& v, const std::string& initial_value)
-    : vals (v), current_val (initial_value) { }
-
-  radio_property (const radio_property& a)
-    : vals (a.vals), current_val (a.current_val) { }
-
-  radio_property& operator = (const radio_property& a)
-  {
-    if (&a != this)
-      {
-	vals = a.vals;
-	current_val = a.current_val;
-      }
-
-    return *this;
-  }
-
-  radio_property& operator = (const std::string& newval)
-  {
-    if (vals.validate (newval))
-      current_val = newval;
-
-    return *this;
-  }
-
-  const std::string& current_value (void) const { return current_val; }
-
-private:
-  radio_values vals;
-  std::string current_val;
-};
-
-class
-color_values
-{
-public:
-  color_values (double r = 0, double g = 0, double b = 1)
-  {
-    xrgb[0] = r;
-    xrgb[1] = g;
-    xrgb[2] = b;
-
-    validate ();
-  }
-
-  color_values (std::string str)
-  {
-    if (! str2rgb (str))
-      error ("invalid color specification");
-  }
-
-  color_values (const color_values& c)
-  {
-    xrgb[0] = c.xrgb[0];
-    xrgb[1] = c.xrgb[1];
-    xrgb[2] = c.xrgb[2];
-  }
-
-  color_values& operator = (const color_values& c)
-  {
-    if (&c != this)
-      {
-	xrgb[0] = c.xrgb[0];
-	xrgb[1] = c.xrgb[1];
-	xrgb[2] = c.xrgb[2];
-
-      }
-
-    return *this;
-  }
-
-  const double* rgb (void) const { return xrgb; }
-
-  void validate (void) const
-  {
-    for (int i = 0; i < 3; i++)
-      {
-	if (xrgb[i] < 0 ||  xrgb[i] > 1)
-	  {
-	    error ("invalid RGB color specification");
-	    break;
-	  }
-      }
-  }
-
-private:
-  double xrgb[3];
-
-  bool str2rgb (std::string str);
-};
-
-
-class 
-color_property
-{
-public:
-  color_property (const color_values& c = color_values (),
-		  const radio_values& v = radio_values ())
-    : current_type (color_t), color_val (c), radio_val (v),
-      current_val (v.default_value ())
-  { }
-
-  color_property (const radio_values& v)
-    : current_type (radio_t), color_val (color_values ()), radio_val (v),
-      current_val (v.default_value ())
-  { }
-
-  color_property (const radio_values& v, const std::string& initial_value)
-    : current_type (radio_t), color_val (color_values ()), radio_val (v),
-      current_val (initial_value)
-  { }
-
-  color_property (const octave_value& val);
-
-  operator octave_value (void) const
-  {
-    if (current_type == color_t)
-      {
-	Matrix retval (1, 3);
-	const double *xrgb = color_val.rgb ();
-
-	for (int i = 0; i < 3 ; i++)
-	  retval(i) = xrgb[i];
-
-	return retval;
-      }
-
-    return current_val;
-  }
-
-  color_property& operator = (const color_property& a)
-  {
-    if (&a != this)
-      {
-	current_type = a.current_type;
-	color_val = a.color_val;
-	radio_val = a.radio_val;
-	current_val = a.current_val;
-      }
-
-    return *this;
-  }
-
-  color_property& operator = (const std::string& newval)
-  {
-    if (radio_val.validate (newval))
-      {
-	current_val = newval;
-	current_type = radio_t;
-      }
-
-    return *this;
-  }
-
-  color_property& operator = (const color_values& newval)
-  {
-    color_val = newval;
-    current_type = color_t;
-
-    return *this;
-  }
-
-  color_property& operator = (const octave_value& newval);
-
-  bool is_rgb (void) const { return (current_type == color_t); }
-
-  bool is_radio (void) const { return (current_type == radio_t); }
-
-  const double* rgb (void) const
-  {
-    if (current_type != color_t)
-      error ("color has no rgb value");
-
-    return color_val.rgb ();
-  }
-
-  const std::string& current_value (void) const
-  {
-    if (current_type != radio_t)
-      error ("color has no radio value");
-
-    return current_val;
-  }
-
-private:
-  enum current_enum { color_t, radio_t } current_type;
-  color_values color_val;
-  radio_values radio_val;
-  std::string current_val;
-};
-
-class 
-colormap_property
-{
-public:
-  colormap_property (const Matrix& m = Matrix ())
-    : cmap (m)
-  {
-    if (cmap.is_empty ())
-      {
-	cmap = Matrix (64, 3);
-
-	for (octave_idx_type i = 0; i < 64; i++)
-	  cmap(i,0) = cmap(i,1) = cmap(i,2) = i / 64.0;
-      }
-
-    validate ();
-  }
-
-  colormap_property (const octave_value& val)
-  {
-    cmap = val.matrix_value ();
-
-    validate ();
-  }
-
-  void validate (void) const
-  {
-    if (error_state || cmap.columns () != 3)
-      error ("invalid colormap specification");
-  }
-
-  operator octave_value (void) const { return cmap; }
-
-private:
-  Matrix cmap;
-};
-
-// ---------------------------------------------------------------------
-
-class property_name : public std::string
-{
-public:
-  typedef std::string::iterator iterator;
-  typedef std::string::const_iterator const_iterator;
-
-  property_name (void) : std::string () { }
-  property_name (const std::string& s) : std::string (s) { }
-  property_name (const char *s) : std::string (s) { }
-
-  property_name (const property_name& name) : std::string (name) { }
-
-  property_name& operator = (const property_name& pname)
-  {
-    std::string::operator = (pname);
-    return *this;
-  }
-
-  operator std::string (void) const { return *this; }
-
-  // Case-insensitive comparison.
-  bool compare (const std::string& s, size_t limit = NPOS) const
-  {
-    const_iterator p1 = begin ();
-    const_iterator p2 = s.begin ();
-
-    size_t k = 0;
-
-    while (p1 != end () && p2 != s.end () && k++ < limit)
-      {
-	if (std::tolower (*p1) != std::tolower (*p2))
-	  return false;
-
-	*p1++;
-	*p2++;
-      }
-
-    return (limit == NPOS) ? size () == s.size () : k == limit;
-  }
-};
-
-// ---------------------------------------------------------------------
-
-class property_list
-{
-public:
-  typedef std::map<std::string, octave_value> pval_map_type;
-  typedef std::map<std::string, pval_map_type> plist_map_type;
-  
-  typedef pval_map_type::iterator pval_map_iterator;
-  typedef pval_map_type::const_iterator pval_map_const_iterator;
-
-  typedef plist_map_type::iterator plist_map_iterator;
-  typedef plist_map_type::const_iterator plist_map_const_iterator;
-
-  property_list (const plist_map_type& m = plist_map_type ())
-    : plist_map (m) { }
-
-  ~property_list (void) { }
-
-  void set (const property_name& name, const octave_value& val);
-
-  octave_value lookup (const property_name& name) const;
-
-  plist_map_iterator begin (void) { return plist_map.begin (); }
-  plist_map_const_iterator begin (void) const { return plist_map.begin (); }
-
-  plist_map_iterator end (void) { return plist_map.end (); }
-  plist_map_const_iterator end (void) const { return plist_map.end (); }
-
-  plist_map_iterator find (const std::string& go_name)
-  {
-    return plist_map.find (go_name);
-  }
-
-  plist_map_const_iterator find (const std::string& go_name) const
-  {
-    return plist_map.find (go_name);
-  }
-
-  Octave_map as_struct (const std::string& prefix_arg) const;
-
-private:
-  plist_map_type plist_map;
-};
-
-// ---------------------------------------------------------------------
-
-typedef double graphics_handle;
-
-// ---------------------------------------------------------------------
-
-class base_graphics_object;
-
-class base_properties
-{
-public:
-  base_properties (const std::string& t = "unknown",
-		   const graphics_handle& mh = octave_NaN,
-		   const graphics_handle& p = octave_NaN)
-    : type (t), __modified__ (true), __myhandle__ (mh), parent (p),
-      children () { }
-
-  virtual ~base_properties (void) { }
-
-  virtual std::string graphics_object_name (void) const { return "unknonwn"; }
-
-  void mark_modified (void);
-
-  void override_defaults (base_graphics_object& obj);
-
-  // Look through DEFAULTS for properties with given CLASS_NAME, and
-  // apply them to the current object with set (virtual method).
-
-  void set_from_list (base_graphics_object& obj, property_list& defaults);
-
-  virtual void set (const property_name&, const octave_value&) { }
-
-  graphics_handle get_parent (void) const { return parent; }
-
-  void remove_child (const graphics_handle& h);
-
-  void adopt (const graphics_handle& h)
-  {
-    octave_idx_type n = children.numel ();
-    children.resize (1, n+1);
-    children(n) = h;
-  }
-
-  void set_parent (const octave_value& val);
-
-  void reparent (const graphics_handle& new_parent) { parent = new_parent; }
-
-  virtual void delete_children (void);
-
-protected:
-  std::string type;
-  bool __modified__;
-  graphics_handle __myhandle__;
-  graphics_handle parent;
-  Matrix children;
-};
-
-class base_graphics_object
-{
-public:
-  friend class graphics_object;
-
-  base_graphics_object (void) : count (1) { }
-
-  base_graphics_object (const base_graphics_object&) { }
-
-  virtual ~base_graphics_object (void) { }
-
-  virtual void mark_modified (void)
-  {
-    error ("base_graphics_object::mark_modified: invalid graphics object");
-  }
-
-  virtual void override_defaults (base_graphics_object&)
-  {
-    error ("base_graphics_object::override_defaults: invalid graphics object");
-  }
-
-  virtual void set_from_list (property_list&)
-  {
-    error ("base_graphics_object::set_from_list: invalid graphics object");
-  }
-
-  virtual void set (const property_name&, const octave_value&)
-  {
-    error ("base_graphics_object::set: invalid graphics object");
-  }
-
-  virtual void set_defaults (const std::string&)
-  {
-    error ("base_graphics_object::set_defaults: invalid graphics object");
-  }
-
-  virtual octave_value get (void) const
-  {
-    error ("base_graphics_object::get: invalid graphics object");
-    return octave_value ();
-  }
-
-  virtual octave_value get (const property_name&) const
-  {
-    error ("base_graphics_object::get: invalid graphics object");
-    return octave_value ();
-  }
-
-  virtual octave_value get_default (const property_name&) const;
-
-  virtual octave_value get_factory_default (const property_name&) const;
-
-  virtual octave_value get_defaults (void) const
-  {
-    error ("base_graphics_object::get_defaults: invalid graphics object");
-    return octave_value ();
-  }
-
-  virtual octave_value get_factory_defaults (void) const
-  {
-    error ("base_graphics_object::get_factory_defaults: invalid graphics object");
-    return octave_value ();
-  }
-
-  virtual graphics_handle get_parent (void) const
-  {
-    error ("base_graphics_object::get_parent: invalid graphics object");
-    return octave_NaN;
-  }
-
-  virtual void remove_child (const graphics_handle&)
-  {
-    error ("base_graphics_object::remove_child: invalid graphics object");
-  }
-
-  virtual void adopt (const graphics_handle&)
-  {
-    error ("base_graphics_object::adopt: invalid graphics object");
-  }
-
-  virtual void reparent (const graphics_handle&)
-  {
-    error ("base_graphics_object::reparent: invalid graphics object");
-  }
-
-  virtual void defaults (void) const
-  {
-    error ("base_graphics_object::default: invalid graphics object");
-  }
-
-  virtual base_properties& get_properties (void)
-  {
-    static base_properties properties;
-    error ("base_graphics_object::get_properties: invalid graphics object");
-    return properties;
-  }
-
-  virtual bool valid_object (void) const { return false; }
-
-  virtual std::string type (void) const { return "unknown"; }
-
-  bool isa (const std::string& go_name) const
-  {
-    return type () == go_name;
-  }
-
-protected:
-  // A reference count.
-  int count;
-};
-
-class graphics_object
-{
-public:
-  graphics_object (void) : rep (new base_graphics_object ()) { }
-
-  graphics_object (base_graphics_object *new_rep)
-    : rep (new_rep) { }
-
-  graphics_object (const graphics_object& obj)
-  {
-    rep = obj.rep;
-    rep->count++;
-  }
-
-  graphics_object& operator = (const graphics_object& obj)
-  {
-    if (rep != obj.rep)
-      {
-	if (--rep->count == 0)
-	  delete rep;
-
-	rep = obj.rep;
-	rep->count++;
-      }
-
-    return *this;
-  }
-
-  ~graphics_object (void)
-  {
-    if (--rep->count == 0)
-      delete rep;
-  }
-
-  void mark_modified (void) { rep->mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    rep->override_defaults (obj);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    rep->set_from_list (plist);
-  }
-
-  void set (const property_name& name, const octave_value& val)
-  {
-    rep->set (name, val);
-  }
-
-  void set (const octave_value_list& args);
-
-  void set_defaults (const std::string& mode)
-  {
-    rep->set_defaults (mode);
-  }
-
-  octave_value get (void) const
-  {
-    return rep->get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    return name.compare ("default")
-      ? get_defaults ()
-      : (name.compare ("factory")
-	 ? get_factory_defaults () : rep->get (name));
-  }
-
-  octave_value get_default (const property_name& name) const
-  {
-    return rep->get_default (name);
-  }
-
-  octave_value get_factory_default (const property_name& name) const
-  {
-    return rep->get_factory_default (name);
-  }
-
-  octave_value get_defaults (void) const { return rep->get_defaults (); }
-
-  octave_value get_factory_defaults (void) const
-  {
-    return rep->get_factory_defaults ();
-  }
-
-  graphics_handle get_parent (void) const { return rep->get_parent (); }
-
-  void remove_child (const graphics_handle& h) { return rep->remove_child (h); }
-
-  void adopt (const graphics_handle& h) { return rep->adopt (h); }
-
-  void reparent (const graphics_handle& h) { return rep->reparent (h); }
-
-  void defaults (void) const { rep->defaults (); }
-
-  bool isa (const std::string& go_name) const { return rep->isa (go_name); }
-
-  base_properties& get_properties (void) { return rep->get_properties (); }
-
-  bool valid_object (void) const { return rep->valid_object (); }
-
-  operator bool (void) const { return rep->valid_object (); }
-
-private:
-  base_graphics_object *rep;
-};
-
-// ---------------------------------------------------------------------
-
-class root_figure : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (void)
-      : base_properties ("root figure", 0, octave_NaN),
-	currentfigure (octave_NaN),
-	visible ("on")
-    { }
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-  private:
-    OCTAVE_GRAPHICS_PROPERTY (graphics_handle, currentfigure);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, visible);
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-
-  root_figure (void) : xproperties (), default_properties () { }
-
-  ~root_figure (void) { xproperties.delete_children (); }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Now override with our defaults.  If the default_properties
-    // list includes the properties for all defaults (line,
-    // surface, etc.) then we don't have to know the type of OBJ
-    // here, we just call its set function and let it decide which
-    // properties from the list to use.
-    obj.set_from_list (default_properties);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& value)
-  {
-    if (name.compare ("default", 7))
-      // strip "default", pass rest to function that will
-      // parse the remainder and add the element to the
-      // default_properties map.
-      default_properties.set (name.substr (7), value);
-    else
-      xproperties.set (name, value);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    octave_value retval;
-
-    if (name.compare ("default", 7))
-      return get_default (name.substr (7));
-    else if (name.compare ("factory", 7))
-      return get_factory_default (name.substr (7));
-    else
-      retval = xproperties.get (name);
-
-    return retval;
-  }
-
-  octave_value get_default (const property_name& name) const
-  {
-    octave_value retval = default_properties.lookup (name);
-
-    if (retval.is_undefined ())
-      error ("get: invalid default property `%s'", name.c_str ());
-
-    return retval;
-  }
-
-  octave_value get_factory_default (const property_name& name) const
-  {
-    octave_value retval = factory_properties.lookup (name);
-
-    if (retval.is_undefined ())
-      error ("get: invalid factory default property `%s'", name.c_str ());
-
-    return retval;
-  }
-
-  octave_value get_defaults (void) const
-  {
-    return default_properties.as_struct ("default");
-  }
-
-  octave_value get_factory_defaults (void) const
-  {
-    return factory_properties.as_struct ("factory");
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& np) { xproperties.reparent (np); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-
-private:
-  property_list default_properties;
-
-  static property_list factory_properties;
-
-  static property_list::plist_map_type init_factory_properties (void);
-};
-
-// ---------------------------------------------------------------------
-
-class figure : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (const graphics_handle& mh, const graphics_handle& p);
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    void close (void);
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-    static property_list::pval_map_type factory_defaults (void);
-
-  private:
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, __plot_stream__);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, nextplot);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, closerequestfcn);
-    OCTAVE_GRAPHICS_PROPERTY (graphics_handle, currentaxes);
-    OCTAVE_GRAPHICS_PROPERTY (colormap_property, colormap);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, visible);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, paperorientation);
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-  figure (const graphics_handle& mh, const graphics_handle& p)
-    : base_graphics_object (), xproperties (mh, p), default_properties ()
-  {
-    xproperties.override_defaults (*this);
-  }
-
-  ~figure (void)
-  {
-    xproperties.delete_children ();
-    xproperties.close ();
-  }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { xproperties.mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Allow parent (root figure) to override first (properties knows how
-    // to find the parent object).
-    xproperties.override_defaults (obj);
-
-    // Now override with our defaults.  If the default_properties
-    // list includes the properties for all defaults (line,
-    // surface, etc.) then we don't have to know the type of OBJ
-    // here, we just call its set function and let it decide which
-    // properties from the list to use.
-    obj.set_from_list (default_properties);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& value)
-  {
-    if (name.compare ("default", 7))
-      // strip "default", pass rest to function that will
-      // parse the remainder and add the element to the
-      // default_properties map.
-      default_properties.set (name.substr (7), value);
-    else
-      xproperties.set (name, value);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    octave_value retval;
-
-    if (name.compare ("default", 7))
-      retval = get_default (name.substr (7));
-    else
-      retval = xproperties.get (name);
-
-    return retval;
-  }
-
-  octave_value get_default (const property_name& name) const;
-
-  octave_value get_defaults (void) const
-  {
-    return default_properties.as_struct ("default");
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& np) { xproperties.reparent (np); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-
-private:
-  property_list default_properties;
-};
-
-// ---------------------------------------------------------------------
-
-class axes : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (const graphics_handle& mh, const graphics_handle& p);
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    void set_defaults (base_graphics_object& obj, const std::string& mode);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    void remove_child (const graphics_handle& h);
-
-    void delete_children (void);
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-    static property_list::pval_map_type factory_defaults (void);
-
-  private:
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, position);
-    OCTAVE_GRAPHICS_MUTABLE_PROPERTY (graphics_handle, title);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, box);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, key);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, keybox);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, keypos);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, dataaspectratio);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, dataaspectratiomode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xlim);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ylim);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zlim);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, clim);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xlimmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ylimmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zlimmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, climmode);
-    OCTAVE_GRAPHICS_MUTABLE_PROPERTY (graphics_handle, xlabel);
-    OCTAVE_GRAPHICS_MUTABLE_PROPERTY (graphics_handle, ylabel);
-    OCTAVE_GRAPHICS_MUTABLE_PROPERTY (graphics_handle, zlabel);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xgrid);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ygrid);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zgrid);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xminorgrid);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, yminorgrid);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zminorgrid);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xtick);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ytick);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ztick);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xtickmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ytickmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ztickmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xticklabel);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, yticklabel);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zticklabel);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xticklabelmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, yticklabelmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zticklabelmode);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xscale);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, yscale);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zscale);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xdir);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ydir);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zdir);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xaxislocation);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, yaxislocation);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, view);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, visible);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, nextplot);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, outerposition);
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-  axes (const graphics_handle& mh, const graphics_handle& p)
-    : base_graphics_object (), xproperties (mh, p), default_properties ()
-  {
-    xproperties.override_defaults (*this);
-  }
-
-  ~axes (void) { xproperties.delete_children (); }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { xproperties.mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Allow parent (figure) to override first (properties knows how
-    // to find the parent object).
-    xproperties.override_defaults (obj);
-
-    // Now override with our defaults.  If the default_properties
-    // list includes the properties for all defaults (line,
-    // surface, etc.) then we don't have to know the type of OBJ
-    // here, we just call its set function and let it decide which
-    // properties from the list to use.
-    obj.set_from_list (default_properties);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& value)
-  {
-    if (name.compare ("default", 7))
-      // strip "default", pass rest to function that will
-      // parse the remainder and add the element to the
-      // default_properties map.
-      default_properties.set (name.substr (7), value);
-    else
-      xproperties.set (name, value);
-  }
-
-  void set_defaults (const std::string& mode)
-  {
-    xproperties.set_defaults (*this, mode);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    octave_value retval;
-
-    // FIXME -- finish this.
-    if (name.compare ("default", 7))
-      retval = get_default (name.substr (7));
-    else
-      retval = xproperties.get (name);
-
-    return retval;
-  }
-
-  octave_value get_default (const property_name& name) const;
-
-  octave_value get_defaults (void) const
-  {
-    return default_properties.as_struct ("default");
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& np) { xproperties.reparent (np); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-
-private:
-  property_list default_properties;
-};
-
-// ---------------------------------------------------------------------
-
-class line : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (const graphics_handle& mh, const graphics_handle& p);
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-    static property_list::pval_map_type factory_defaults (void);
-
-  private:
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ydata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ldata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, udata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xldata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xudata);
-    OCTAVE_GRAPHICS_PROPERTY (color_property, color);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, linestyle);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, linewidth);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, marker);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, markeredgecolor);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, markerfacecolor);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, markersize);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, keylabel);
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-  line (const graphics_handle& mh, const graphics_handle& p)
-    : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
-
-  ~line (void) { xproperties.delete_children (); }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { xproperties.mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Allow parent (figure) to override first (properties knows how
-    // to find the parent object).
-    xproperties.override_defaults (obj);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& val)
-  {
-    xproperties.set (name, val);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    return xproperties.get (name);
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-};
-
-// ---------------------------------------------------------------------
-
-class text : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (const graphics_handle& mh, const graphics_handle& p);
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-    static property_list::pval_map_type factory_defaults (void);
-
-  private:
-    octave_value string;
-    octave_value units;
-    octave_value position;
-    octave_value rotation;
-    octave_value horizontalalignment;
-    octave_value color;
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-  text (const graphics_handle& mh, const graphics_handle& p)
-    : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
-
-  ~text (void) { xproperties.delete_children (); }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { xproperties.mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Allow parent (figure) to override first (properties knows how
-    // to find the parent object).
-    xproperties.override_defaults (obj);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& val)
-  {
-    xproperties.set (name, val);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    return xproperties.get (name);
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-};
-
-// ---------------------------------------------------------------------
-
-class image : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (const graphics_handle& mh, const graphics_handle& p);
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-    static property_list::pval_map_type factory_defaults (void);
-
-  private:
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, cdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ydata);
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-  image (const graphics_handle& mh, const graphics_handle& p)
-    : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
-
-  ~image (void) { xproperties.delete_children (); }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { xproperties.mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Allow parent (figure) to override first (properties knows how
-    // to find the parent object).
-    xproperties.override_defaults (obj);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& val)
-  {
-    xproperties.set (name, val);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    return xproperties.get (name);
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-};
-
-// ---------------------------------------------------------------------
-
-class patch : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (const graphics_handle& mh, const graphics_handle& p);
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-    static property_list::pval_map_type factory_defaults (void);
-
-  private:
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, cdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ydata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zdata);
-    OCTAVE_GRAPHICS_PROPERTY (color_property, facecolor);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, facealpha);
-    OCTAVE_GRAPHICS_PROPERTY (color_property, edgecolor);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, linestyle);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, linewidth);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, marker);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, markeredgecolor);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, markerfacecolor);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, markersize);
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-  patch (const graphics_handle& mh, const graphics_handle& p)
-    : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
-
-  ~patch (void) { xproperties.delete_children (); }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { xproperties.mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Allow parent (figure) to override first (properties knows how
-    // to find the parent object).
-    xproperties.override_defaults (obj);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& val)
-  {
-    xproperties.set (name, val);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    return xproperties.get (name);
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-};
-
-// ---------------------------------------------------------------------
-
-class surface : public base_graphics_object
-{
-public:
-  class properties : public base_properties
-  {
-  public:
-    properties (const graphics_handle& mh, const graphics_handle& p);
-
-    ~properties (void) { }
-
-    void set (const property_name& name, const octave_value& val);
-
-    octave_value get (void) const;
-
-    octave_value get (const property_name& name) const;
-
-    std::string graphics_object_name (void) const { return go_name; }
-
-    static property_list::pval_map_type factory_defaults (void);
-
-  private:
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, xdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, ydata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, zdata);
-    OCTAVE_GRAPHICS_PROPERTY (octave_value, keylabel);
-
-    static std::string go_name;
-  };
-
-private:
-  properties xproperties;
-
-public:
-  surface (const graphics_handle& mh, const graphics_handle& p)
-    : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
-
-  ~surface (void) { xproperties.delete_children (); }
-
-  std::string type (void) const { return xproperties.graphics_object_name (); }
-
-  void mark_modified (void) { xproperties.mark_modified (); }
-
-  void override_defaults (base_graphics_object& obj)
-  {
-    // Allow parent (figure) to override first (properties knows how
-    // to find the parent object).
-    xproperties.override_defaults (obj);
-  }
-
-  void set_from_list (property_list& plist)
-  {
-    xproperties.set_from_list (*this, plist);
-  }
-
-  void set (const property_name& name, const octave_value& val)
-  {
-    xproperties.set (name, val);
-  }
-
-  octave_value get (void) const
-  {
-    return xproperties.get ();
-  }
-
-  octave_value get (const property_name& name) const
-  {
-    return xproperties.get (name);
-  }
-
-  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
-
-  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
-
-  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
-
-  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
-
-  base_properties& get_properties (void) { return xproperties; }
-
-  bool valid_object (void) const { return true; }
-};
-
-octave_value
-get_property_from_handle (double handle, const std::string &property,
-			  const std::string &func);
-bool
-set_property_in_handle (double handle, const std::string &property,
-			const octave_value &arg, const std::string &func);
-
-
-#undef OCTAVE_GRAPHICS_PROPERTY_INTERNAL
-#undef OCTAVE_GRAPHICS_PROPERTY
-#undef OCTAVE_GRAPHICS_MUTABLE_PROPERTY
-
-// ---------------------------------------------------------------------
-
-class gh_manager
-{
-protected:
-
-  gh_manager (void);
-
-public:
-
-  static bool instance_ok (void)
-  {
-    bool retval = true;
-
-    if (! instance)
-      instance = new gh_manager ();
-
-    if (! instance)
-      {
-	::error ("unable to create gh_manager!");
-
-	retval = false;
-      }
-
-    return retval;
-  }
-
-  static void free (const graphics_handle& h)
-  {
-    if (instance_ok ())
-      instance->do_free (h);
-  }
-
-  static graphics_handle lookup (double val)
-  {
-    return instance_ok () ? instance->do_lookup (val) : graphics_handle ();
-  }
-
-  static graphics_object get_object (const graphics_handle& h)
-  {
-    return instance_ok () ? instance->do_get_object (h) : graphics_object ();
-  }
-
-  static graphics_handle
-  make_graphics_handle (const std::string& go_name,
-			const graphics_handle& parent)
-  {
-    return instance_ok ()
-      ? instance->do_make_graphics_handle (go_name, parent) : octave_NaN;
-  }
-
-  static graphics_handle make_figure_handle (double val)
-  {
-    return instance_ok ()
-      ? instance->do_make_figure_handle (val) : octave_NaN;
-  }
-
-  static void push_figure (const graphics_handle& h)
-  {
-    if (instance_ok ())
-      instance->do_push_figure (h);
-  }
-
-  static void pop_figure (const graphics_handle& h)
-  {
-    if (instance_ok ())
-      instance->do_pop_figure (h);
-  }
-
-  static graphics_handle current_figure (void)
-  {
-    return instance_ok () ? instance->do_current_figure () : octave_NaN;
-  }
-
-  static Matrix handle_list (void)
-  {
-    return instance_ok () ? instance->do_handle_list () : Matrix ();
-  }
-
-  static Matrix figure_handle_list (void)
-  {
-    return instance_ok () ? instance->do_figure_handle_list () : Matrix ();
-  }
-
-private:
-
-  static gh_manager *instance;
-
-  typedef std::map<graphics_handle, graphics_object>::iterator iterator;
-  typedef std::map<graphics_handle, graphics_object>::const_iterator const_iterator;
-
-  typedef std::set<graphics_handle>::iterator free_list_iterator;
-  typedef std::set<graphics_handle>::const_iterator const_free_list_iterator;
-
-  typedef std::list<graphics_handle>::iterator figure_list_iterator;
-  typedef std::list<graphics_handle>::const_iterator const_figure_list_iterator;
-
-  // A map of handles to graphics objects.
-  std::map<graphics_handle, graphics_object> handle_map;
-
-  // The available graphics handles.
-  std::set<graphics_handle> handle_free_list;
-
-  // The next handle available if handle_free_list is empty.
-  graphics_handle next_handle;
-
-  // The allocated figure handles.  Top of the stack is most recently
-  // created.
-  std::list<graphics_handle> figure_list;
-
-  graphics_handle get_handle (const std::string& go_name);
-
-  void do_free (const graphics_handle& h);
-
-  graphics_handle do_lookup (double val)
-  {
-    iterator p = handle_map.find (val);
-
-    return (p != handle_map.end ()) ? p->first : octave_NaN;
-  }
-
-  graphics_object do_get_object (const graphics_handle& h)
-  {
-    iterator p = handle_map.find (h);
-
-    return (p != handle_map.end ()) ? p->second : graphics_object ();
-  }
-
-  graphics_handle do_make_graphics_handle (const std::string& go_name,
-					   const graphics_handle& p);
-
-  graphics_handle do_make_figure_handle (double val);
-
-  Matrix do_handle_list (void)
-  {
-    Matrix retval (1, handle_map.size ());
-    octave_idx_type i = 0;
-    for (const_iterator p = handle_map.begin (); p != handle_map.end (); p++)
-      retval(i++) = p->first;
-    return retval;
-  }
-
-  Matrix do_figure_handle_list (void)
-  {
-    Matrix retval (1, figure_list.size ());
-    octave_idx_type i = 0;
-    for (const_figure_list_iterator p = figure_list.begin ();
-	 p != figure_list.end ();
-	 p++)
-      retval(i++) = *p;
-    return retval;
-  }
-
-  void do_push_figure (const graphics_handle& h);
-
-  void do_pop_figure (const graphics_handle& h);
-
-  graphics_handle do_current_figure (void) const
-  {
-    return figure_list.empty () ? octave_NaN : figure_list.front ();
-  }
-};
-
-
-// This function is NOT equivalent to the scripting language function gcf.
-graphics_handle gcf (void);
-
-// This function is NOT equivalent to the scripting language function gca.
-graphics_handle gca (void);
-
-#endif
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/graphics.h.in	Thu Sep 06 21:34:24 2007 +0000
@@ -0,0 +1,1897 @@
+/*
+
+Copyright (C) 2007 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+*/
+
+#if !defined (graphics_h)
+#define graphics_h 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cctype>
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+
+#include "oct-map.h"
+#include "ov.h"
+
+class
+radio_values
+{
+public:
+  radio_values (const std::string& opt_string = std::string ());
+  radio_values (const radio_values& a)
+    : default_val (a.default_val), possible_vals (a.possible_vals) { }
+
+  radio_values& operator = (const radio_values& a)
+  {
+    if (&a != this)
+      {
+	default_val = a.default_val;
+	possible_vals = a.possible_vals;
+      }
+
+    return *this;
+  }
+
+  std::string default_value (void) const { return default_val; }
+
+  std::set<std::string> possible_values (void) const { return possible_vals; }
+
+  bool validate (const std::string& val)
+  {
+    bool retval = true;
+
+    if (possible_vals.find (val) == possible_vals.end ())
+      {
+	error ("invalid value = %s", val.c_str ());
+	retval = false;
+      }
+
+    return retval;
+  }
+
+private:
+  // Might also want to cache
+  std::string default_val;
+  std::set<std::string> possible_vals;
+};
+
+class
+radio_property
+{
+public:
+  radio_property (const radio_values& v)
+    : vals (v), current_val (v.default_value ()) { }
+
+  radio_property (const radio_values& v, const std::string& initial_value)
+    : vals (v), current_val (initial_value) { }
+
+  radio_property (const radio_property& a)
+    : vals (a.vals), current_val (a.current_val) { }
+
+  radio_property& operator = (const radio_property& a)
+  {
+    if (&a != this)
+      {
+	vals = a.vals;
+	current_val = a.current_val;
+      }
+
+    return *this;
+  }
+
+  radio_property& operator = (const std::string& newval)
+  {
+    if (vals.validate (newval))
+      current_val = newval;
+
+    return *this;
+  }
+
+  const std::string& current_value (void) const { return current_val; }
+
+private:
+  radio_values vals;
+  std::string current_val;
+};
+
+class
+color_values
+{
+public:
+  color_values (double r = 0, double g = 0, double b = 1)
+  {
+    xrgb[0] = r;
+    xrgb[1] = g;
+    xrgb[2] = b;
+
+    validate ();
+  }
+
+  color_values (std::string str)
+  {
+    if (! str2rgb (str))
+      error ("invalid color specification");
+  }
+
+  color_values (const color_values& c)
+  {
+    xrgb[0] = c.xrgb[0];
+    xrgb[1] = c.xrgb[1];
+    xrgb[2] = c.xrgb[2];
+  }
+
+  color_values& operator = (const color_values& c)
+  {
+    if (&c != this)
+      {
+	xrgb[0] = c.xrgb[0];
+	xrgb[1] = c.xrgb[1];
+	xrgb[2] = c.xrgb[2];
+
+      }
+
+    return *this;
+  }
+
+  const double* rgb (void) const { return xrgb; }
+
+  void validate (void) const
+  {
+    for (int i = 0; i < 3; i++)
+      {
+	if (xrgb[i] < 0 ||  xrgb[i] > 1)
+	  {
+	    error ("invalid RGB color specification");
+	    break;
+	  }
+      }
+  }
+
+private:
+  double xrgb[3];
+
+  bool str2rgb (std::string str);
+};
+
+
+class 
+color_property
+{
+public:
+  color_property (const color_values& c = color_values (),
+		  const radio_values& v = radio_values ())
+    : current_type (color_t), color_val (c), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const radio_values& v)
+    : current_type (radio_t), color_val (color_values ()), radio_val (v),
+      current_val (v.default_value ())
+  { }
+
+  color_property (const radio_values& v, const std::string& initial_value)
+    : current_type (radio_t), color_val (color_values ()), radio_val (v),
+      current_val (initial_value)
+  { }
+
+  color_property (const octave_value& val);
+
+  operator octave_value (void) const
+  {
+    if (current_type == color_t)
+      {
+	Matrix retval (1, 3);
+	const double *xrgb = color_val.rgb ();
+
+	for (int i = 0; i < 3 ; i++)
+	  retval(i) = xrgb[i];
+
+	return retval;
+      }
+
+    return current_val;
+  }
+
+  color_property& operator = (const color_property& a)
+  {
+    if (&a != this)
+      {
+	current_type = a.current_type;
+	color_val = a.color_val;
+	radio_val = a.radio_val;
+	current_val = a.current_val;
+      }
+
+    return *this;
+  }
+
+  color_property& operator = (const std::string& newval)
+  {
+    if (radio_val.validate (newval))
+      {
+	current_val = newval;
+	current_type = radio_t;
+      }
+
+    return *this;
+  }
+
+  color_property& operator = (const color_values& newval)
+  {
+    color_val = newval;
+    current_type = color_t;
+
+    return *this;
+  }
+
+  color_property& operator = (const octave_value& newval);
+
+  bool is_rgb (void) const { return (current_type == color_t); }
+
+  bool is_radio (void) const { return (current_type == radio_t); }
+
+  const double* rgb (void) const
+  {
+    if (current_type != color_t)
+      error ("color has no rgb value");
+
+    return color_val.rgb ();
+  }
+
+  const std::string& current_value (void) const
+  {
+    if (current_type != radio_t)
+      error ("color has no radio value");
+
+    return current_val;
+  }
+
+private:
+  enum current_enum { color_t, radio_t } current_type;
+  color_values color_val;
+  radio_values radio_val;
+  std::string current_val;
+};
+
+class 
+colormap_property
+{
+public:
+  colormap_property (const Matrix& m = Matrix ())
+    : cmap (m)
+  {
+    if (cmap.is_empty ())
+      {
+	cmap = Matrix (64, 3);
+
+	for (octave_idx_type i = 0; i < 64; i++)
+	  cmap(i,0) = cmap(i,1) = cmap(i,2) = i / 64.0;
+      }
+
+    validate ();
+  }
+
+  colormap_property (const octave_value& val)
+  {
+    cmap = val.matrix_value ();
+
+    validate ();
+  }
+
+  void validate (void) const
+  {
+    if (error_state || cmap.columns () != 3)
+      error ("invalid colormap specification");
+  }
+
+  operator octave_value (void) const { return cmap; }
+
+private:
+  Matrix cmap;
+};
+
+// ---------------------------------------------------------------------
+
+class property_name : public std::string
+{
+public:
+  typedef std::string::iterator iterator;
+  typedef std::string::const_iterator const_iterator;
+
+  property_name (void) : std::string () { }
+  property_name (const std::string& s) : std::string (s) { }
+  property_name (const char *s) : std::string (s) { }
+
+  property_name (const property_name& name) : std::string (name) { }
+
+  property_name& operator = (const property_name& pname)
+  {
+    std::string::operator = (pname);
+    return *this;
+  }
+
+  operator std::string (void) const { return *this; }
+
+  // Case-insensitive comparison.
+  bool compare (const std::string& s, size_t limit = NPOS) const
+  {
+    const_iterator p1 = begin ();
+    const_iterator p2 = s.begin ();
+
+    size_t k = 0;
+
+    while (p1 != end () && p2 != s.end () && k++ < limit)
+      {
+	if (std::tolower (*p1) != std::tolower (*p2))
+	  return false;
+
+	*p1++;
+	*p2++;
+      }
+
+    return (limit == NPOS) ? size () == s.size () : k == limit;
+  }
+};
+
+// ---------------------------------------------------------------------
+
+class property_list
+{
+public:
+  typedef std::map<std::string, octave_value> pval_map_type;
+  typedef std::map<std::string, pval_map_type> plist_map_type;
+  
+  typedef pval_map_type::iterator pval_map_iterator;
+  typedef pval_map_type::const_iterator pval_map_const_iterator;
+
+  typedef plist_map_type::iterator plist_map_iterator;
+  typedef plist_map_type::const_iterator plist_map_const_iterator;
+
+  property_list (const plist_map_type& m = plist_map_type ())
+    : plist_map (m) { }
+
+  ~property_list (void) { }
+
+  void set (const property_name& name, const octave_value& val);
+
+  octave_value lookup (const property_name& name) const;
+
+  plist_map_iterator begin (void) { return plist_map.begin (); }
+  plist_map_const_iterator begin (void) const { return plist_map.begin (); }
+
+  plist_map_iterator end (void) { return plist_map.end (); }
+  plist_map_const_iterator end (void) const { return plist_map.end (); }
+
+  plist_map_iterator find (const std::string& go_name)
+  {
+    return plist_map.find (go_name);
+  }
+
+  plist_map_const_iterator find (const std::string& go_name) const
+  {
+    return plist_map.find (go_name);
+  }
+
+  Octave_map as_struct (const std::string& prefix_arg) const;
+
+private:
+  plist_map_type plist_map;
+};
+
+// ---------------------------------------------------------------------
+
+class graphics_handle
+{
+public:
+  graphics_handle (void) : val (octave_NaN) { }
+
+  graphics_handle (const octave_value& a);
+
+  graphics_handle (int a) : val (a) { }
+
+  graphics_handle (double a) : val (a) { }
+
+  graphics_handle (const graphics_handle& a) : val (a.val) { }
+
+  graphics_handle& operator = (const graphics_handle& a)
+  {
+    if (&a != this)
+      val = a.val;
+
+    return *this;
+  }
+
+  ~graphics_handle (void) { }
+
+  operator double (void) const { return val; }
+
+  double value (void) const { return val; }
+
+  octave_value as_octave_value (void) const
+  {
+    return ok () ? octave_value (val) : octave_value (Matrix ());
+  }
+
+  graphics_handle operator ++ (void)
+  {
+    ++val;
+    return *this;
+  }
+
+  graphics_handle operator ++ (int)
+  {
+    graphics_handle h = *this;
+    ++val;
+    return h;
+  }
+
+  graphics_handle operator -- (void)
+  {
+    --val;
+    return *this;
+  }
+
+  graphics_handle operator -- (int)
+  {
+    graphics_handle h = *this;
+    --val;
+    return h;
+  }
+
+  bool ok (void) const { return ! xisnan (val); }
+
+  operator bool () const { return ok (); }
+
+private:
+  double val;
+};
+
+inline bool
+operator == (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () == b.value ();
+}
+
+inline bool
+operator != (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () != b.value ();
+}
+
+inline bool
+operator < (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () < b.value ();
+}
+
+inline bool
+operator <= (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () <= b.value ();
+}
+
+inline bool
+operator >= (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () >= b.value ();
+}
+
+inline bool
+operator > (const graphics_handle& a, const graphics_handle& b)
+{
+  return a.value () > b.value ();
+}
+
+// ---------------------------------------------------------------------
+
+class base_graphics_object;
+
+class base_properties
+{
+public:
+  base_properties (const std::string& t = "unknown",
+		   const graphics_handle& mh = graphics_handle (),
+		   const graphics_handle& p = graphics_handle ())
+    : type (t), __modified__ (true), __myhandle__ (mh), parent (p),
+      children () { }
+
+  virtual ~base_properties (void) { }
+
+  virtual std::string graphics_object_name (void) const { return "unknonwn"; }
+
+  void mark_modified (void);
+
+  void override_defaults (base_graphics_object& obj);
+
+  // Look through DEFAULTS for properties with given CLASS_NAME, and
+  // apply them to the current object with set (virtual method).
+
+  void set_from_list (base_graphics_object& obj, property_list& defaults);
+
+  virtual void set (const property_name&, const octave_value&) { }
+
+  graphics_handle get_parent (void) const { return parent; }
+
+  void remove_child (const graphics_handle& h);
+
+  void adopt (const graphics_handle& h)
+  {
+    octave_idx_type n = children.numel ();
+    children.resize (1, n+1);
+    children(n) = h;
+  }
+
+  void set_parent (const octave_value& val);
+
+  void reparent (const graphics_handle& new_parent) { parent = new_parent; }
+
+  virtual void delete_children (void);
+
+protected:
+  std::string type;
+  bool __modified__;
+  graphics_handle __myhandle__;
+  graphics_handle parent;
+  Matrix children;
+};
+
+class base_graphics_object
+{
+public:
+  friend class graphics_object;
+
+  base_graphics_object (void) : count (1) { }
+
+  base_graphics_object (const base_graphics_object&) { }
+
+  virtual ~base_graphics_object (void) { }
+
+  virtual void mark_modified (void)
+  {
+    error ("base_graphics_object::mark_modified: invalid graphics object");
+  }
+
+  virtual void override_defaults (base_graphics_object&)
+  {
+    error ("base_graphics_object::override_defaults: invalid graphics object");
+  }
+
+  virtual void set_from_list (property_list&)
+  {
+    error ("base_graphics_object::set_from_list: invalid graphics object");
+  }
+
+  virtual void set (const property_name&, const octave_value&)
+  {
+    error ("base_graphics_object::set: invalid graphics object");
+  }
+
+  virtual void set_defaults (const std::string&)
+  {
+    error ("base_graphics_object::set_defaults: invalid graphics object");
+  }
+
+  virtual octave_value get (void) const
+  {
+    error ("base_graphics_object::get: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual octave_value get (const property_name&) const
+  {
+    error ("base_graphics_object::get: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual octave_value get_default (const property_name&) const;
+
+  virtual octave_value get_factory_default (const property_name&) const;
+
+  virtual octave_value get_defaults (void) const
+  {
+    error ("base_graphics_object::get_defaults: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual octave_value get_factory_defaults (void) const
+  {
+    error ("base_graphics_object::get_factory_defaults: invalid graphics object");
+    return octave_value ();
+  }
+
+  virtual graphics_handle get_parent (void) const
+  {
+    error ("base_graphics_object::get_parent: invalid graphics object");
+    return graphics_handle ();
+  }
+
+  virtual void remove_child (const graphics_handle&)
+  {
+    error ("base_graphics_object::remove_child: invalid graphics object");
+  }
+
+  virtual void adopt (const graphics_handle&)
+  {
+    error ("base_graphics_object::adopt: invalid graphics object");
+  }
+
+  virtual void reparent (const graphics_handle&)
+  {
+    error ("base_graphics_object::reparent: invalid graphics object");
+  }
+
+  virtual void defaults (void) const
+  {
+    error ("base_graphics_object::default: invalid graphics object");
+  }
+
+  virtual base_properties& get_properties (void)
+  {
+    static base_properties properties;
+    error ("base_graphics_object::get_properties: invalid graphics object");
+    return properties;
+  }
+
+  virtual bool valid_object (void) const { return false; }
+
+  virtual std::string type (void) const { return "unknown"; }
+
+  bool isa (const std::string& go_name) const
+  {
+    return type () == go_name;
+  }
+
+protected:
+  // A reference count.
+  int count;
+};
+
+class graphics_object
+{
+public:
+  graphics_object (void) : rep (new base_graphics_object ()) { }
+
+  graphics_object (base_graphics_object *new_rep)
+    : rep (new_rep) { }
+
+  graphics_object (const graphics_object& obj)
+  {
+    rep = obj.rep;
+    rep->count++;
+  }
+
+  graphics_object& operator = (const graphics_object& obj)
+  {
+    if (rep != obj.rep)
+      {
+	if (--rep->count == 0)
+	  delete rep;
+
+	rep = obj.rep;
+	rep->count++;
+      }
+
+    return *this;
+  }
+
+  ~graphics_object (void)
+  {
+    if (--rep->count == 0)
+      delete rep;
+  }
+
+  void mark_modified (void) { rep->mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    rep->override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    rep->set_from_list (plist);
+  }
+
+  void set (const property_name& name, const octave_value& val)
+  {
+    rep->set (name, val);
+  }
+
+  void set (const octave_value_list& args);
+
+  void set_defaults (const std::string& mode)
+  {
+    rep->set_defaults (mode);
+  }
+
+  octave_value get (void) const
+  {
+    return rep->get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    return name.compare ("default")
+      ? get_defaults ()
+      : (name.compare ("factory")
+	 ? get_factory_defaults () : rep->get (name));
+  }
+
+  octave_value get_default (const property_name& name) const
+  {
+    return rep->get_default (name);
+  }
+
+  octave_value get_factory_default (const property_name& name) const
+  {
+    return rep->get_factory_default (name);
+  }
+
+  octave_value get_defaults (void) const { return rep->get_defaults (); }
+
+  octave_value get_factory_defaults (void) const
+  {
+    return rep->get_factory_defaults ();
+  }
+
+  graphics_handle get_parent (void) const { return rep->get_parent (); }
+
+  void remove_child (const graphics_handle& h) { return rep->remove_child (h); }
+
+  void adopt (const graphics_handle& h) { return rep->adopt (h); }
+
+  void reparent (const graphics_handle& h) { return rep->reparent (h); }
+
+  void defaults (void) const { rep->defaults (); }
+
+  bool isa (const std::string& go_name) const { return rep->isa (go_name); }
+
+  base_properties& get_properties (void) { return rep->get_properties (); }
+
+  bool valid_object (void) const { return rep->valid_object (); }
+
+  operator bool (void) const { return rep->valid_object (); }
+
+private:
+  base_graphics_object *rep;
+};
+
+// ---------------------------------------------------------------------
+
+class root_figure : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (void)
+      : base_properties ("root figure", 0, graphics_handle ()),
+	currentfigure (),
+	visible ("on")
+    { }
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      graphics_handle currentfigure S
+      octave_value visible
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+
+  root_figure (void) : xproperties (), default_properties () { }
+
+  ~root_figure (void) { xproperties.delete_children (); }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    octave_value retval;
+
+    if (name.compare ("default", 7))
+      return get_default (name.substr (7));
+    else if (name.compare ("factory", 7))
+      return get_factory_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const property_name& name) const
+  {
+    octave_value retval = default_properties.lookup (name);
+
+    if (retval.is_undefined ())
+      error ("get: invalid default property `%s'", name.c_str ());
+
+    return retval;
+  }
+
+  octave_value get_factory_default (const property_name& name) const
+  {
+    octave_value retval = factory_properties.lookup (name);
+
+    if (retval.is_undefined ())
+      error ("get: invalid factory default property `%s'", name.c_str ());
+
+    return retval;
+  }
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  octave_value get_factory_defaults (void) const
+  {
+    return factory_properties.as_struct ("factory");
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& np) { xproperties.reparent (np); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+
+  static property_list factory_properties;
+
+  static property_list::plist_map_type init_factory_properties (void);
+};
+
+// ---------------------------------------------------------------------
+
+class figure : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (const graphics_handle& mh, const graphics_handle& p);
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    void close (void);
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    static property_list::pval_map_type factory_defaults (void);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      octave_value __plot_stream__
+      octave_value nextplot
+      octave_value closerequestfcn
+      graphics_handle currentaxes S
+      colormap_property colormap
+      octave_value visible S
+      octave_value paperorientation
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  figure (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p), default_properties ()
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~figure (void)
+  {
+    xproperties.delete_children ();
+    xproperties.close ();
+  }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { xproperties.mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (root figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    octave_value retval;
+
+    if (name.compare ("default", 7))
+      retval = get_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const property_name& name) const;
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& np) { xproperties.reparent (np); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+};
+
+// ---------------------------------------------------------------------
+
+class axes : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (const graphics_handle& mh, const graphics_handle& p);
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    void set_defaults (base_graphics_object& obj, const std::string& mode);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    void remove_child (const graphics_handle& h);
+
+    void delete_children (void);
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    static property_list::pval_map_type factory_defaults (void);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      octave_value position
+      mutable graphics_handle title GSO
+      octave_value box
+      octave_value key
+      octave_value keybox
+      octave_value keypos
+      octave_value dataaspectratio m
+      octave_value dataaspectratiomode
+      octave_value xlim m
+      octave_value ylim m
+      octave_value zlim m
+      octave_value clim m
+      octave_value xlimmode
+      octave_value ylimmode
+      octave_value zlimmode
+      octave_value climmode
+      mutable graphics_handle xlabel GSO
+      mutable graphics_handle ylabel GSO
+      mutable graphics_handle zlabel GSO
+      octave_value xgrid
+      octave_value ygrid
+      octave_value zgrid
+      octave_value xminorgrid
+      octave_value yminorgrid
+      octave_value zminorgrid
+      octave_value xtick m
+      octave_value ytick m
+      octave_value ztick m
+      octave_value xtickmode
+      octave_value ytickmode
+      octave_value ztickmode
+      octave_value xticklabel m
+      octave_value yticklabel m
+      octave_value zticklabel m
+      octave_value xticklabelmode
+      octave_value yticklabelmode
+      octave_value zticklabelmode
+      octave_value xscale
+      octave_value yscale
+      octave_value zscale
+      octave_value xdir
+      octave_value ydir
+      octave_value zdir
+      octave_value xaxislocation
+      octave_value yaxislocation
+      octave_value view
+      octave_value visible
+      octave_value nextplot
+      octave_value outerposition
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  axes (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p), default_properties ()
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~axes (void) { xproperties.delete_children (); }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { xproperties.mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+
+    // Now override with our defaults.  If the default_properties
+    // list includes the properties for all defaults (line,
+    // surface, etc.) then we don't have to know the type of OBJ
+    // here, we just call its set function and let it decide which
+    // properties from the list to use.
+    obj.set_from_list (default_properties);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& value)
+  {
+    if (name.compare ("default", 7))
+      // strip "default", pass rest to function that will
+      // parse the remainder and add the element to the
+      // default_properties map.
+      default_properties.set (name.substr (7), value);
+    else
+      xproperties.set (name, value);
+  }
+
+  void set_defaults (const std::string& mode)
+  {
+    xproperties.set_defaults (*this, mode);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    octave_value retval;
+
+    // FIXME -- finish this.
+    if (name.compare ("default", 7))
+      retval = get_default (name.substr (7));
+    else
+      retval = xproperties.get (name);
+
+    return retval;
+  }
+
+  octave_value get_default (const property_name& name) const;
+
+  octave_value get_defaults (void) const
+  {
+    return default_properties.as_struct ("default");
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& np) { xproperties.reparent (np); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+
+private:
+  property_list default_properties;
+};
+
+// ---------------------------------------------------------------------
+
+class line : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (const graphics_handle& mh, const graphics_handle& p);
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    static property_list::pval_map_type factory_defaults (void);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      octave_value xdata
+      octave_value ydata
+      octave_value zdata
+      octave_value ldata
+      octave_value udata
+      octave_value xldata
+      octave_value xudata
+      color_property color
+      octave_value linestyle
+      octave_value linewidth
+      octave_value marker
+      octave_value markeredgecolor
+      octave_value markerfacecolor
+      octave_value markersize
+      octave_value keylabel
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  line (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~line (void) { xproperties.delete_children (); }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { xproperties.mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& val)
+  {
+    xproperties.set (name, val);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    return xproperties.get (name);
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class text : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (const graphics_handle& mh, const graphics_handle& p);
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    static property_list::pval_map_type factory_defaults (void);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      octave_value string
+      octave_value units
+      octave_value position
+      octave_value rotation
+      octave_value horizontalalignment
+      octave_value color
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  text (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~text (void) { xproperties.delete_children (); }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { xproperties.mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& val)
+  {
+    xproperties.set (name, val);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    return xproperties.get (name);
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class image : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (const graphics_handle& mh, const graphics_handle& p);
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    static property_list::pval_map_type factory_defaults (void);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      octave_value cdata
+      octave_value xdata
+      octave_value ydata
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  image (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~image (void) { xproperties.delete_children (); }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { xproperties.mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& val)
+  {
+    xproperties.set (name, val);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    return xproperties.get (name);
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class patch : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (const graphics_handle& mh, const graphics_handle& p);
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    static property_list::pval_map_type factory_defaults (void);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      octave_value cdata
+      octave_value xdata
+      octave_value ydata
+      octave_value zdata
+      color_property facecolor
+      octave_value facealpha
+      color_property edgecolor
+      octave_value linestyle
+      octave_value linewidth
+      octave_value marker
+      octave_value markeredgecolor
+      octave_value markerfacecolor
+      octave_value markersize
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  patch (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~patch (void) { xproperties.delete_children (); }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { xproperties.mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& val)
+  {
+    xproperties.set (name, val);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    return xproperties.get (name);
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class surface : public base_graphics_object
+{
+public:
+  class properties : public base_properties
+  {
+  public:
+    properties (const graphics_handle& mh, const graphics_handle& p);
+
+    ~properties (void) { }
+
+    void set (const property_name& name, const octave_value& val);
+
+    octave_value get (void) const;
+
+    octave_value get (const property_name& name) const;
+
+    std::string graphics_object_name (void) const { return go_name; }
+
+    static property_list::pval_map_type factory_defaults (void);
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES
+      octave_value xdata
+      octave_value ydata
+      octave_value zdata
+      octave_value keylabel
+    END_PROPERTIES
+
+    static std::string go_name;
+  };
+
+private:
+  properties xproperties;
+
+public:
+  surface (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~surface (void) { xproperties.delete_children (); }
+
+  std::string type (void) const { return xproperties.graphics_object_name (); }
+
+  void mark_modified (void) { xproperties.mark_modified (); }
+
+  void override_defaults (base_graphics_object& obj)
+  {
+    // Allow parent (figure) to override first (properties knows how
+    // to find the parent object).
+    xproperties.override_defaults (obj);
+  }
+
+  void set_from_list (property_list& plist)
+  {
+    xproperties.set_from_list (*this, plist);
+  }
+
+  void set (const property_name& name, const octave_value& val)
+  {
+    xproperties.set (name, val);
+  }
+
+  octave_value get (void) const
+  {
+    return xproperties.get ();
+  }
+
+  octave_value get (const property_name& name) const
+  {
+    return xproperties.get (name);
+  }
+
+  graphics_handle get_parent (void) const { return xproperties.get_parent (); }
+
+  void remove_child (const graphics_handle& h) { xproperties.remove_child (h); }
+
+  void adopt (const graphics_handle& h) { xproperties.adopt (h); }
+
+  void reparent (const graphics_handle& h) { xproperties.reparent (h); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+octave_value
+get_property_from_handle (double handle, const std::string &property,
+			  const std::string &func);
+bool
+set_property_in_handle (double handle, const std::string &property,
+			const octave_value &arg, const std::string &func);
+
+// ---------------------------------------------------------------------
+
+class gh_manager
+{
+protected:
+
+  gh_manager (void);
+
+public:
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new gh_manager ();
+
+    if (! instance)
+      {
+	::error ("unable to create gh_manager!");
+
+	retval = false;
+      }
+
+    return retval;
+  }
+
+  static void free (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_free (h);
+  }
+
+  static graphics_handle lookup (double val)
+  {
+    return instance_ok () ? instance->do_lookup (val) : graphics_handle ();
+  }
+
+  static graphics_object get_object (const graphics_handle& h)
+  {
+    return instance_ok () ? instance->do_get_object (h) : graphics_object ();
+  }
+
+  static graphics_handle
+  make_graphics_handle (const std::string& go_name,
+			const graphics_handle& parent)
+  {
+    return instance_ok ()
+      ? instance->do_make_graphics_handle (go_name, parent)
+      : graphics_handle ();
+  }
+
+  static graphics_handle make_figure_handle (double val)
+  {
+    return instance_ok ()
+      ? instance->do_make_figure_handle (val) : graphics_handle ();
+  }
+
+  static void push_figure (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_push_figure (h);
+  }
+
+  static void pop_figure (const graphics_handle& h)
+  {
+    if (instance_ok ())
+      instance->do_pop_figure (h);
+  }
+
+  static graphics_handle current_figure (void)
+  {
+    return instance_ok ()
+      ? instance->do_current_figure () : graphics_handle ();
+  }
+
+  static Matrix handle_list (void)
+  {
+    return instance_ok () ? instance->do_handle_list () : Matrix ();
+  }
+
+  static Matrix figure_handle_list (void)
+  {
+    return instance_ok () ? instance->do_figure_handle_list () : Matrix ();
+  }
+
+private:
+
+  static gh_manager *instance;
+
+  typedef std::map<graphics_handle, graphics_object>::iterator iterator;
+  typedef std::map<graphics_handle, graphics_object>::const_iterator const_iterator;
+
+  typedef std::set<graphics_handle>::iterator free_list_iterator;
+  typedef std::set<graphics_handle>::const_iterator const_free_list_iterator;
+
+  typedef std::list<graphics_handle>::iterator figure_list_iterator;
+  typedef std::list<graphics_handle>::const_iterator const_figure_list_iterator;
+
+  // A map of handles to graphics objects.
+  std::map<graphics_handle, graphics_object> handle_map;
+
+  // The available graphics handles.
+  std::set<graphics_handle> handle_free_list;
+
+  // The next handle available if handle_free_list is empty.
+  graphics_handle next_handle;
+
+  // The allocated figure handles.  Top of the stack is most recently
+  // created.
+  std::list<graphics_handle> figure_list;
+
+  graphics_handle get_handle (const std::string& go_name);
+
+  void do_free (const graphics_handle& h);
+
+  graphics_handle do_lookup (double val)
+  {
+    iterator p = handle_map.find (val);
+
+    return (p != handle_map.end ()) ? p->first : graphics_handle ();
+  }
+
+  graphics_object do_get_object (const graphics_handle& h)
+  {
+    iterator p = handle_map.find (h);
+
+    return (p != handle_map.end ()) ? p->second : graphics_object ();
+  }
+
+  graphics_handle do_make_graphics_handle (const std::string& go_name,
+					   const graphics_handle& p);
+
+  graphics_handle do_make_figure_handle (double val);
+
+  Matrix do_handle_list (void)
+  {
+    Matrix retval (1, handle_map.size ());
+    octave_idx_type i = 0;
+    for (const_iterator p = handle_map.begin (); p != handle_map.end (); p++)
+      retval(i++) = p->first;
+    return retval;
+  }
+
+  Matrix do_figure_handle_list (void)
+  {
+    Matrix retval (1, figure_list.size ());
+    octave_idx_type i = 0;
+    for (const_figure_list_iterator p = figure_list.begin ();
+	 p != figure_list.end ();
+	 p++)
+      retval(i++) = *p;
+    return retval;
+  }
+
+  void do_push_figure (const graphics_handle& h);
+
+  void do_pop_figure (const graphics_handle& h);
+
+  graphics_handle do_current_figure (void) const
+  {
+    return figure_list.empty () ? graphics_handle () : figure_list.front ();
+  }
+};
+
+
+// This function is NOT equivalent to the scripting language function gcf.
+graphics_handle gcf (void);
+
+// This function is NOT equivalent to the scripting language function gca.
+graphics_handle gca (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/