Index: /trunk/Ohana/Makefile.in
===================================================================
--- /trunk/Ohana/Makefile.in	(revision 13478)
+++ /trunk/Ohana/Makefile.in	(revision 13479)
@@ -37,6 +37,5 @@
 imclean     \
 imregister  \
-kapa        \
-kii         \
+kapa2       \
 misc        \
 mosastro    \
@@ -96,12 +95,10 @@
 mana:
 	make libs
-	make kii.install
-	make kapa.install
+	make kapa2.install
 	cd src/opihi; make mana.install && exit
 
 dvoshell:
 	make libs
-	make kii.install
-	make kapa.install
+	make kapa2.install
 	cd src/opihi; make dvo.install && exit
 
Index: /trunk/Ohana/src/addstar/src/SEDops.c
===================================================================
--- /trunk/Ohana/src/addstar/src/SEDops.c	(revision 13478)
+++ /trunk/Ohana/src/addstar/src/SEDops.c	(revision 13479)
@@ -111,5 +111,5 @@
   graphdata.style = 2;
   graphdata.ptype = 2;
-  KapaClear (Xgraph, TRUE);
+  KapaClearSections (Xgraph);
   magSection.name = strcreate ("mag");
   magSection.x  = 0;
@@ -141,5 +141,5 @@
 
   int j, minRow, Nfilter;
-  double X, Y;
+  double X, Y, Z, RA, DEC;
   char line[1024], key[20];
 
@@ -156,5 +156,5 @@
   SWAP (graphdata.ymin, graphdata.ymax);
 
-  KapaClear (Xgraph, TRUE);
+  KapaClearSections (Xgraph);
   KapaSetSection (Xgraph, &magSection);
   KapaSetLimits (Xgraph, &graphdata);
@@ -164,6 +164,6 @@
   graphdata.ptype = 7;
   KapaPrepPlot (Xgraph, Nfilter, &graphdata);
-  KapaPlotVector (Xgraph, Nfilter, table[0].wavecode);
-  KapaPlotVector (Xgraph, Nfilter, fitmags);
+  KapaPlotVector (Xgraph, Nfilter, table[0].wavecode, "x");
+  KapaPlotVector (Xgraph, Nfilter, fitmags, "y");
 
   graphdata.color = KapaColorByName ("red");
@@ -178,8 +178,8 @@
   }
   KapaPrepPlot (Xgraph, Nfilter, &graphdata);
-  KapaPlotVector (Xgraph, Nfilter, table[0].wavecode);
-  KapaPlotVector (Xgraph, Nfilter, fitmags);
-  KapaPlotVector (Xgraph, Nfilter, fiterrs);
-  KapaPlotVector (Xgraph, Nfilter, fiterrs);
+  KapaPlotVector (Xgraph, Nfilter, table[0].wavecode, "x");
+  KapaPlotVector (Xgraph, Nfilter, fitmags, "x");
+  KapaPlotVector (Xgraph, Nfilter, fiterrs, "dym");
+  KapaPlotVector (Xgraph, Nfilter, fiterrs, "dyp");
   KapaSendLabel (Xgraph, "model,fit (mags)", 1);
 
@@ -208,13 +208,13 @@
   }
   KapaPrepPlot (Xgraph, Nfilter, &graphdata);
-  KapaPlotVector (Xgraph, Nfilter, table[0].wavecode);
-  KapaPlotVector (Xgraph, Nfilter, fitmags);
-  KapaPlotVector (Xgraph, Nfilter, fiterrs);
-  KapaPlotVector (Xgraph, Nfilter, fiterrs);
+  KapaPlotVector (Xgraph, Nfilter, table[0].wavecode, "x");
+  KapaPlotVector (Xgraph, Nfilter, fitmags, "y");
+  KapaPlotVector (Xgraph, Nfilter, fiterrs, "dym");
+  KapaPlotVector (Xgraph, Nfilter, fiterrs, "dyp");
   KapaSendLabel (Xgraph, "wavelength (nm)", 0);
   KapaSendLabel (Xgraph, "resid (mags)", 1);
 
   KiiCursorOn (Xgraph);
-  while (KiiCursorRead (Xgraph, &X, &Y, key)) {
+  while (KiiCursorRead (Xgraph, &X, &Y, &Z, &RA, &DEC, key)) {
     // fprintf (stderr, "window: %f %f (%s)\n", X, Y, key);
     if (!strcasecmp (key, "Q")) {
Index: /trunk/Ohana/src/gastro/Makefile
===================================================================
--- /trunk/Ohana/src/gastro/Makefile	(revision 13478)
+++ /trunk/Ohana/src/gastro/Makefile	(revision 13479)
@@ -15,5 +15,5 @@
 FULL_CFLAGS   = $(BASE_CFLAGS)
 FULL_CPPFLAGS = $(BASE_CPPFLAGS)
-FULL_LDFLAGS  = -ldvo -lFITS -lohana $(BASE_LDFLAGS)
+FULL_LDFLAGS  = -lkapa -ldvo -lFITS -lohana $(BASE_LDFLAGS)
 
 gastro: $(BIN)/gastro.$(ARCH)
Index: /trunk/Ohana/src/gastro/src/plotstuff.c
===================================================================
--- /trunk/Ohana/src/gastro/src/plotstuff.c	(revision 13478)
+++ /trunk/Ohana/src/gastro/src/plotstuff.c	(revision 13479)
@@ -13,100 +13,33 @@
 int open_graph (int N) {
 
-# ifdef ANSI
-#   define F_SETFL      4   
-#   define O_NONBLOCK 0200000  
-#   define       AF_UNIX         1          
-#   define       SOCK_STREAM     1          
-#define ENOENT          2       /* No such file or directory    */
-# endif /* ANSI */
-
-  int InitSocket, status;
-  socklen_t addreslen;
-  struct sockaddr_un Address;
-  char temp[100];
-  char socket_name[100];
+  char name[100];
   
   active = N;
-  sprintf (socket_name, "/tmp/kapa%d", N);
-  sprintf (temp, "rm -f %s", socket_name);
-  system (temp);
-    
-  strcpy (Address.sun_path, socket_name); 
-  Address.sun_family = AF_UNIX; 
-  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
-  status = bind (InitSocket, (struct sockaddr *) &Address, sizeof (Address));
-  status = listen (InitSocket, 1);
-  
-  sprintf (temp, "kapa %s &", socket_name);
-# ifndef DEBUG
-  system (temp);
-# else  
-  fprintf (stderr, "start kapa, press return: %s\n", temp);
-  fscanf (stdin, "%d", &i);
-# endif
-  
-  addreslen =  sizeof (Address);
-  Xgraph[N] = accept (InitSocket, (struct sockaddr *) &Address, &addreslen);
+
+  sprintf (name, "gastro [%d]", N);
+  Xgraph[N] = KapaOpen ("kapa", name);
+
   if (Xgraph[N] < 0) {
     fprintf (stderr, "error starting kapa\n");
     return (FALSE);
   }
-  else {
-    return (TRUE);
-  }
-  
+  return (TRUE);
 }
 
 void DonePlotting (Graphdata *graphmode, int N) {
-  char buffer[65], buffer2[65];
 
-  write (Xgraph[N], "DBOX", 4);
-  sprintf (buffer, "%f %f %f %f ", graphmode[0].xmin, graphmode[0].xmax, graphmode[0].ymin, graphmode[0].ymax);
-  sprintf (buffer2, "NBYTES: %6d ", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-
-  sprintf (buffer, "%s %s %s", "2222", "2222", "2222");
-  sprintf (buffer2, "NBYTES: %6d ", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
+  if (Xgraph[N] == 0) return;
+  KapaBox (Xgraph[N], graphmode);
+  return;
 }
 
 void PrepPlotting (int Npts, Graphdata *graphmode, int N) {
 
-  int i, status;
-  char buffer[128], buffer2[128];
+  if (Xgraph[N] == 0) return;
 
   active = N;
   if (Npts < 1) return;
 
-  /* test Xgraph[N], flush junk from pipe */
-  signal (SIGPIPE, XDead);
-  fcntl (Xgraph[N], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Xgraph[N], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Xgraph[N], F_SETFL, !O_NONBLOCK); 
-  
-  if (Xgraph[N] < 1) if (!open_graph(N)) return;
-  
-  /* tell kapa to look for the incoming image */
-  status = write (Xgraph[N], "PLOT", 4); 
-
-  /* send Xgraph[N] the plot details */
-  sprintf (buffer, "%8d %8d %d %d %d %d %f %f ", 
-	   Npts, graphmode[0].style, 
-	   graphmode[0].ptype, graphmode[0].ltype, 
-	   graphmode[0].etype, graphmode[0].color, 
-	   graphmode[0].lweight, graphmode[0].size);
-  sprintf (buffer2, "NBYTES: %6d ", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-  
-  sprintf (buffer, "%f %f %f %f ", 
-	   graphmode[0].xmin, graphmode[0].xmax, 
-	   graphmode[0].ymin, graphmode[0].ymax);
-  sprintf (buffer2, "NBYTES: %6d ", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-
+  KapaPrepPlot (Xgraph[N], Npts, graphmode);
 }
 
@@ -116,9 +49,6 @@
 
   if (Npts < 1) return;
-
   active = N;
-  Nbytes = Npts * sizeof (float);
-  write (Xgraph[N], vect, Nbytes);
-
+  KapaPlotVector (Xgraph[N], Npts, vect);
 }
 
@@ -135,8 +65,7 @@
   
   if (Xgraph[N] < 1) if (!open_graph(N)) return;
-  
-  write (Xgraph[N], "ERAS", 4);
+  KapaClearSections (Xgraph[N]);
+}
 
-}
 /* include these lines to plot a pair of vectors: 
 
Index: /trunk/Ohana/src/gastro2/Makefile
===================================================================
--- /trunk/Ohana/src/gastro2/Makefile	(revision 13478)
+++ /trunk/Ohana/src/gastro2/Makefile	(revision 13479)
@@ -15,5 +15,5 @@
 FULL_CFLAGS   = $(BASE_CFLAGS)
 FULL_CPPFLAGS = $(BASE_CPPFLAGS)
-FULL_LDFLAGS  = -ldvo -lFITS -lohana $(BASE_LDFLAGS)
+FULL_LDFLAGS  = -lkapa -ldvo -lFITS -lohana $(BASE_LDFLAGS)
 
 gastro2: $(BIN)/gastro2.$(ARCH)
Index: /trunk/Ohana/src/gastro2/src/plotstuff.c
===================================================================
--- /trunk/Ohana/src/gastro2/src/plotstuff.c	(revision 13478)
+++ /trunk/Ohana/src/gastro2/src/plotstuff.c	(revision 13479)
@@ -13,100 +13,33 @@
 int open_graph (int N) {
 
-# ifdef ANSI
-#   define F_SETFL      4   
-#   define O_NONBLOCK 0200000  
-#   define       AF_UNIX         1          
-#   define       SOCK_STREAM     1          
-#define ENOENT          2       /* No such file or directory    */
-# endif /* ANSI */
-
-  int InitSocket, status;
-  socklen_t addreslen;
-  struct sockaddr_un Address;
-  char temp[100];
-  char socket_name[100];
+  char name[100];
   
   active = N;
-  sprintf (socket_name, "/tmp/kapa%d", N);
-  sprintf (temp, "rm -f %s", socket_name);
-  system (temp);
-    
-  strcpy (Address.sun_path, socket_name); 
-  Address.sun_family = AF_UNIX; 
-  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
-  status = bind (InitSocket, (struct sockaddr *) &Address, sizeof (Address));
-  status = listen (InitSocket, 1);
-  
-  sprintf (temp, "kapa %s -name %d &", socket_name, N);
-# ifndef DEBUG
-  system (temp);
-# else  
-  fprintf (stderr, "start kapa, press return: %s\n", temp);
-  fscanf (stdin, "%d", &i);
-# endif
-  
-  addreslen =  sizeof (Address);
-  Xgraph[N] = accept (InitSocket, (struct sockaddr *) &Address, &addreslen);
+
+  sprintf (name, "gastro [%d]", N);
+  Xgraph[N] = KapaOpen ("kapa", name);
+
   if (Xgraph[N] < 0) {
     fprintf (stderr, "error starting kapa\n");
     return (FALSE);
   }
-  else {
-    return (TRUE);
-  }
-  
+  return (TRUE);
 }
 
 void DonePlotting (Graphdata *graphmode, int N) {
-  char buffer[65], buffer2[65];
 
-  write (Xgraph[N], "DBOX", 4);
-  sprintf (buffer, "%f %f %f %f", graphmode[0].xmin, graphmode[0].xmax, graphmode[0].ymin, graphmode[0].ymax);
-  sprintf (buffer2, "NBYTES: %6d", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-
-  sprintf (buffer, "%s %s %s", "2222", "2222", "2222");
-  sprintf (buffer2, "NBYTES: %6d", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
+  if (Xgraph[N] == 0) return;
+  KapaBox (Xgraph[N], graphmode);
+  return;
 }
 
 void PrepPlotting (int Npts, Graphdata *graphmode, int N) {
 
-  int i, status;
-  char buffer[128], buffer2[128];
+  if (Xgraph[N] == 0) return;
 
   active = N;
   if (Npts < 1) return;
 
-  /* test Xgraph[N], flush junk from pipe */
-  signal (SIGPIPE, XDead);
-  fcntl (Xgraph[N], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Xgraph[N], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Xgraph[N], F_SETFL, !O_NONBLOCK); 
-  
-  if (Xgraph[N] < 1) if (!open_graph(N)) return;
-  
-  /* tell kapa to look for the incoming image */
-  status = write (Xgraph[N], "PLOT", 4); 
-
-  /* send Xgraph[N] the plot details */
-  sprintf (buffer, "%8d %8d %d %d %d %d %d %f %f", 
-	   Npts, graphmode[0].style, 
-	   graphmode[0].ptype, graphmode[0].ltype, 
-	   graphmode[0].etype, graphmode[0].ebar, graphmode[0].color, 
-	   graphmode[0].lweight, graphmode[0].size);
-  sprintf (buffer2, "NBYTES: %6d", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-  
-  sprintf (buffer, "%f %f %f %f", 
-	   graphmode[0].xmin, graphmode[0].xmax, 
-	   graphmode[0].ymin, graphmode[0].ymax);
-  sprintf (buffer2, "NBYTES: %6d", (unsigned int) strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-
+  KapaPrepPlot (Xgraph[N], Npts, graphmode);
 }
 
@@ -116,9 +49,6 @@
 
   if (Npts < 1) return;
-
   active = N;
-  Nbytes = Npts * sizeof (float);
-  write (Xgraph[N], vect, Nbytes);
-
+  KapaPlotVector (Xgraph[N], Npts, vect);
 }
 
@@ -135,8 +65,7 @@
   
   if (Xgraph[N] < 1) if (!open_graph(N)) return;
-  
-  write (Xgraph[N], "ERAS", 4);
+  KapaClearSections (Xgraph[N]);
+}
 
-}
 /* include these lines to plot a pair of vectors: 
 
Index: /trunk/Ohana/src/kapa2/Makefile
===================================================================
--- /trunk/Ohana/src/kapa2/Makefile	(revision 13478)
+++ /trunk/Ohana/src/kapa2/Makefile	(revision 13479)
@@ -1,3 +1,3 @@
-default: kapa2
+default: kapa
 help:
 	@echo "make options: kapa (default)"
@@ -20,6 +20,6 @@
 INDEPS  = $(DESTINC)/kapa.h $(DESTINC)/dvo.h $(DESTINC)/gfitsio.h $(DESTINC)/ohana.h
 
-kapa2: $(BIN)/kapa2.$(ARCH)
-install: $(DESTBIN)/kapa2
+kapa2: $(BIN)/kapa.$(ARCH)
+install: $(DESTBIN)/kapa
 
 KAPA = \
@@ -49,4 +49,5 @@
 $(SRC)/Graphs.$(ARCH).o                   $(SRC)/SetGraphSize.$(ARCH).o       \
 $(SRC)/Resize.$(ARCH).o                   $(SRC)/ErasePlots.$(ARCH).o         \
+$(SRC)/EraseImage.$(ARCH).o         	  $(SRC)/SetToolbox.$(ARCH).o         \
 $(SRC)/EraseCurrentPlot.$(ARCH).o         $(SRC)/EraseSections.$(ARCH).o      \
 $(SRC)/SetSection.$(ARCH).o		  $(SRC)/DefineSection.$(ARCH).o      \
@@ -64,7 +65,7 @@
 $(SRC)/CreatePicture.$(ARCH).o            $(SRC)/CreateColorbar.$(ARCH).o     \
 $(SRC)/MakeColormap.$(ARCH).o		  $(SRC)/SetColormap.$(ARCH).o        \
-$(SRC)/PaintOverlay.$(ARCH).o		  $(SRC)/PaintTickmarks.$(ARCH).o     \
+$(SRC)/PaintOverlay.$(ARCH).o		  $(SRC)/SetGraphData.$(ARCH).o       \
 $(SRC)/LoadOverlay.$(ARCH).o		  $(SRC)/EraseOverlay.$(ARCH).o       \
-$(SRC)/LoadTickmarks.$(ARCH).o		  $(SRC)/SaveOverlay.$(ARCH).o        \
+$(SRC)/SaveOverlay.$(ARCH).o              $(SRC)/SetImageData.$(ARCH).o       \
 $(SRC)/CSaveOverlay.$(ARCH).o		  $(SRC)/EraseOverlay.$(ARCH).o       \
 $(SRC)/CheckVisual.$(ARCH).o              $(SRC)/CursorOps.$(ARCH).o          \
@@ -88,3 +89,3 @@
 $(OBJ): $(INDEPS) $(LDDEPS)
 
-$(BIN)/kapa2.$(ARCH): $(OBJ)
+$(BIN)/kapa.$(ARCH): $(OBJ)
Index: /trunk/Ohana/src/kapa2/include/constants.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/constants.h	(revision 13478)
+++ /trunk/Ohana/src/kapa2/include/constants.h	(revision 13479)
@@ -10,11 +10,11 @@
  | PointerMotionMask)
 
-# define PAD1  5
-# define PAD2  3
+# define PAD1  3
+# define PAD2  5
 # define TEXTPAD 25
 # define COLORPAD 10
 # define TEXT_Y 15
-# define ZOOM_X 170
-# define ZOOM_Y 170
+# define ZOOM_X 152
+# define ZOOM_Y 152
 # define NOVERLAYS 4
 # define BUTTON_WIDTH 28
Index: /trunk/Ohana/src/kapa2/include/globals.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/globals.h	(revision 13478)
+++ /trunk/Ohana/src/kapa2/include/globals.h	(revision 13479)
@@ -15,5 +15,5 @@
 
 /* file descriptor for socket connection to mana */
-int sock; 
+// int sock; 
 
 /* each layout / section defines one of the active portions of the graphics window
Index: /trunk/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 13478)
+++ /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 13479)
@@ -39,5 +39,5 @@
 
 /* EventLoop */
-int           PScommand           PROTO(());
+int           PScommand           PROTO((int sock));
 int           CheckPipe           PROTO(());
 int           Reconfig            PROTO((XEvent *event));
@@ -45,21 +45,28 @@
 
 /* CheckPipe */
-int           PNGit               PROTO(());
-int           PPMit               PROTO(());
-int           LoadFrame           PROTO(());
-int           LoadObject          PROTO(());
-int           LoadLabels          PROTO(());
-int           LoadTextlines       PROTO(());
-int           LoadVectorData      PROTO(());
-int           Resize              PROTO(());
-int           GetLimits           PROTO(());
-int           SetLimits           PROTO(());
-int           SetSection          PROTO(());
-int           ListSection         PROTO(());
-int           DefineSection       PROTO(());
-int           SetFont             PROTO(());
-int           EraseCurrentPlot    PROTO(());
-int           ErasePlots          PROTO(());
-int           EraseSections       PROTO(());
+int           PNGit               PROTO((int sock));
+int           PPMit               PROTO((int sock));
+int           LoadFrame           PROTO((int sock));
+int           LoadObject          PROTO((int sock));
+int           LoadLabels          PROTO((int sock));
+int           LoadTextlines       PROTO((int sock));
+int           Resize              PROTO((int sock));
+int           GetLimits           PROTO((int sock));
+int           SetLimits           PROTO((int sock));
+int           SetSection          PROTO((int sock));
+int           ListSection         PROTO((int sock));
+int           MoveSection         PROTO((int sock));
+int           DefineSection       PROTO((int sock));
+int           SetFont             PROTO((int sock));
+int           EraseCurrentPlot    PROTO((void));
+int           ErasePlots          PROTO((void));
+int           EraseSections       PROTO((void));
+int           EraseImage          PROTO((void));
+int           SetGraphData        PROTO((int sock));
+int           GetGraphData        PROTO((int sock));
+int           SetImageData        PROTO((int sock));
+int           GetImageData        PROTO((int sock));
+
+int           LoadVectorData      PROTO((int sock, KapaGraphWidget *graph, int N, char *type));
 
 /* Section Utilities */
@@ -74,9 +81,10 @@
 Section      *GetActiveSection	  PROTO(());
 int           SetActiveSectionByNumber PROTO((int N));
-int           ListSection         PROTO(());
+int           ListSection         PROTO((int sock));
 
 KapaGraphWidget *InitGraph        PROTO(());
 void          DrawGraph           PROTO((KapaGraphWidget *graph));
 void          SetGraphSize        PROTO((Section *section));
+void          FreeGraph           PROTO((KapaGraphWidget *graph));
 
 void          InitLayout          PROTO((int argc, char **argv));
@@ -124,4 +132,5 @@
 void          QuitX               PROTO((Display *display, char *message));
 Graphic      *GetGraphic          PROTO(());
+int           GetPixelCount       PROTO((int sock));
 
 int           Center              PROTO(());
@@ -131,8 +140,10 @@
 void          Remap24             PROTO((Graphic *graphic, KapaImageWidget *image, Matrix *matrix));
 void          Remap32             PROTO((Graphic *graphic, KapaImageWidget *image, Matrix *matrix));
-int           LoadPicture         PROTO(());
+int           LoadPicture         PROTO((int sock));
+
 KapaImageWidget *InitImage        PROTO(());
+void          FreeImage           PROTO((KapaImageWidget *image));
 void          SetImageSize        PROTO((Section *section));
-int           GetPixelCount       PROTO(());
+
 void          InitButtonSize      PROTO((Button *button, int width, int height, char *bitmap));
 void          InitButtonFunc      PROTO((Button *button, int (*function)()));
Index: /trunk/Ohana/src/kapa2/include/structures.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/structures.h	(revision 13478)
+++ /trunk/Ohana/src/kapa2/include/structures.h	(revision 13479)
@@ -95,5 +95,5 @@
   int Nobjects;
   unsigned long color;
-  Object *objects;
+  KiiOverlay *objects;
 } Overlay;
   
@@ -116,4 +116,5 @@
   Axis      axis[4];    /* coordinate axes */
   Label     label[8];   /* fixed axis labels */
+  Graphdata data;       /* current graph data */
 
   Gobjects *objects;    /* graphic objects */    
@@ -138,9 +139,10 @@
   Button   grey_button;
   Button   rainbow_button;
-  Button   puns_button;
+  Button    puns_button;
   Button   overlay_button[NOVERLAYS];
 
   // location of the status box
   int      text_x, text_y;
+  int      text_dx, text_dy;
   int      location;	      // position of the zoom/status widgets (0 = none, 1-4 = bottom,left,top,right)
   int      MovePointer;
@@ -159,5 +161,5 @@
   Coords   coords;
   char     file[1024];     /* name of file */
-  char     buffer_name[1024];  /* name of buffer */
+  char     name[1024];  /* name of buffer */
 } KapaImageWidget;
 
Index: /trunk/Ohana/src/kapa2/src/CSaveOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CSaveOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CSaveOverlay.c	(revision 13479)
@@ -1,7 +1,7 @@
 # include "Ximage.h"
 
-int CSaveOverlay () {
+int CSaveOverlay (int sock) {
 
-  char filename[256];
+  char filename[256], *type;
   int i, N;
   double ra, dec, ra1, dec1, x1, y1, dra, ddec;
@@ -10,9 +10,10 @@
   KapaImageWidget *image;
 
+  KiiScanMessage (sock, "%*s %d %s", &N, filename);
+  
   section = GetActiveSection();
   image   = section->image;
+  if (image == NULL) return (TRUE);
 
-  KiiScanMessage (sock, "%*s %d %s", &N, filename);
-  
   f = fopen (filename, "w");
   if (f == NULL) {
@@ -22,5 +23,5 @@
 
   for (i = 0; i < image[0].overlay[N].Nobjects; i++) {
-    if (!strcmp (image[0].overlay[N].objects[i].type, "LINE")) {
+    if (image[0].overlay[N].objects[i].type == KII_OVERLAY_LINE) {
       XY_to_RD (&ra, &dec, image[0].overlay[N].objects[i].x, image[0].overlay[N].objects[i].y, &image[0].coords);
       x1 = image[0].overlay[N].objects[i].x + image[0].overlay[N].objects[i].dx;
@@ -40,5 +41,7 @@
       dra = cos (dec*RAD_DEG) * fabs (ra1 - ra);
     }
-    fprintf (f, "%s %lf %lf %lf %lf\n", image[0].overlay[N].objects[i].type, ra, dec, dra, ddec);
+    type = KiiOverlayTypeByNumber (image[0].overlay[N].objects[i].type);
+    if (type == NULL) continue;
+    fprintf (f, "%s %lf %lf %lf %lf\n", type, ra, dec, dra, ddec);
    }
   fclose (f);
Index: /trunk/Ohana/src/kapa2/src/Center.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Center.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Center.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int Center () {
+int Center (int sock) {
 
   int zoom;
@@ -9,9 +9,10 @@
   KapaImageWidget *image;
 
+  KiiScanMessage (sock, "%lf %lf %d", &X,  &Y, &zoom);
+
   graphic = GetGraphic();
   section = GetActiveSection();
   image = section->image;
-
-  KiiScanMessage (sock, "%lf %lf %d", &X,  &Y, &zoom);
+  if (image == NULL) return (TRUE);
 
   image[0].X = 0.5*image[0].matrix.Naxis[0] - X;
Index: /trunk/Ohana/src/kapa2/src/CheckPipe.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CheckPipe.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CheckPipe.c	(revision 13479)
@@ -2,12 +2,37 @@
 # define STRCONST(A) ((int)(0x1000000*A[0] + 0x10000*A[1] + 0x100*A[2] + 0x1*A[3]))
 
+static KapaSockAddress Address;
+static int InitSocket = -1;
+static int sock = -1;
+
+// we can supply a port here, with only small changes
+void InitPipe () {
+  InitSocket = KapaServerInit (&Address);
+  return;
+}
+
+int GetActiveSocket () {
+  return (sock);
+}
+
+// after we have processed the command, we unblock the socket
+# define FINISHED(A) { fcntl (sock, F_SETFL, O_NONBLOCK); return (A); }
+
 int CheckPipe () {
 
   int status;
-  char buffer[32];
+  char word[5];
+
+  // check if we have a valid connection. if not, see if we can get one
+  if (sock == -1) {
+    sock = KapaServerWait (InitSocket, &Address);
+    if (sock == -1) return (TRUE);
+    close (InitSocket); /* stop listening for new connections */
+    fcntl (sock, F_SETFL, O_NONBLOCK);  
+  }
 
   /***** read (4 byte) message word from socket ****/
-  status = read (sock, buffer, 4);
-  buffer[4] = 0;
+  status = read (sock, word, 4);
+  word[4] = 0;
   switch (status) {
   case -1:                          /* no input from pipe: continue */
@@ -29,163 +54,227 @@
   }
   
+  /* once we get a command, we block to ensure we get complete messages */
+  fcntl (sock, F_SETFL, !O_NONBLOCK);  
+
   /***** handle different messages ****/
   if (ACTIVE_CURSOR) {
-    if (strcmp (buffer, "NCUR")) {
-      fprintf (stderr, "wrong end message %s\n", buffer);
-      return (TRUE);
+    if (strcmp (word, "NCUR")) {
+      fprintf (stderr, "wrong end message %s\n", word);
+      KiiSendCommand (sock, 4, "DONE");
+      FINISHED (TRUE);
     }
     ACTIVE_CURSOR = FALSE;
-    return (TRUE);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
   } 
 
-  if (!strcmp (buffer, "QUIT")) return (FALSE);
-  
-  if (!strcmp (buffer, "CURS")) {
+  if (!strcmp (word, "QUIT")) FINISHED (FALSE);
+  
+  if (!strcmp (word, "CURS")) {
     ACTIVE_CURSOR = TRUE;
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "PSIT")) {
-    status = PScommand ();
-    write (sock, "DONE", 4);
-    return (status);
-  }
-  
-  if (!strcmp (buffer, "PNGF")) {
-    status = PNGit ();
-    write (sock, "DONE", 4);
-    return (status);
-  }
-  
-  if (!strcmp (buffer, "PPMF")) {
-    status = PPMit ();
-    write (sock, "DONE", 4);
-    return (status);
-  }
-  
-  if (!strcmp (buffer, "DBOX")) {
-    status = LoadFrame ();
-    return (status);
-  }
-  
-  if (!strcmp (buffer, "PLOT")) {
-    status = LoadObject ();
-    return (status);
-  }
-  
-  if (!strcmp (buffer, "LABL")) {
-    status = LoadLabels ();
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "PTXT")) {
-    status = LoadTextlines ();
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "RSIZ")) {
-    status = Resize ();
-    return (status);
-  }
-
-  if (!strcmp (buffer, "LIMS")) {
-    GetLimits ();
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "SLIM")) {
-    status = SetLimits ();
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "SSEC")) {
-    status = SetSection ();
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "LSEC")) {
-    status = ListSection ();
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "DSEC")) {
-    status = DefineSection ();
-    return (TRUE);
-  }
-  
-  if (!strcmp (buffer, "FONT")) {
-    status = SetFont ();
-    return (TRUE);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "PSIT")) {
+    status = PScommand (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+  
+  if (!strcmp (word, "PNGF")) {
+    status = PNGit (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+  
+  if (!strcmp (word, "PPMF")) {
+    status = PPMit (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+  
+  if (!strcmp (word, "DBOX")) {
+    status = LoadFrame (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+  
+  if (!strcmp (word, "PLOT")) {
+    status = LoadObject (sock);
+    // LoadObject sends its own handshake
+    // KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+  
+  if (!strcmp (word, "LABL")) {
+    status = LoadLabels (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "PTXT")) {
+    status = LoadTextlines (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "RSIZ")) {
+    status = Resize (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "GLIM")) {
+    GetLimits (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "SLIM")) {
+    status = SetLimits (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "GSTY")) {
+    GetGraphData (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "SSTY")) {
+    status = SetGraphData (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "GIMD")) {
+    GetImageData (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "SIMD")) {
+    status = SetImageData (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "TOOL")) {
+    status = SetToolbox (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "SSEC")) {
+    status = SetSection (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "LSEC")) {
+    status = ListSection (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "DSEC")) {
+    status = DefineSection (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "MSEC")) {
+    status = MoveSection (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
+  if (!strcmp (word, "FONT")) {
+    status = SetFont (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
   }
   
   /* Erase Section */
-  if (!strcmp (buffer, "ERSC")) {
-    status = EraseCurrentPlot (TRUE);
-    return (status);
-  }
-  
-  /* Erase Section */
-  if (!strcmp (buffer, "ERAS")) {
-    status = ErasePlots (TRUE);
-    return (status);
-  }
-  
-  /* Don't Erase Section */
-  if (!strcmp (buffer, "ERSS")) {
-    status = EraseSections (FALSE);
-    return (status);
-  }
-  
-
-  if (!strcmp (buffer, "READ")) {
-    status = LoadPicture ();
-    return (status);
-  }
-
-  // XXX duplicate Command word
-  if (!strcmp (buffer, "ERAS")) {
-    status = EraseOverlay ();
-    return (status);
-  }
-
-  if (!strcmp (buffer, "LOAD")) {
-    status = LoadOverlay ();
-    return (status);
-  }
-
-  if (!strcmp (buffer, "TICK")) {
-    status = LoadTickmarks ();
-    return (status);
-  }
-
-  if (!strcmp (buffer, "SAVE")) {
-    status = SaveOverlay ();
-    return (status);
-  }
-
-  if (!strcmp (buffer, "CSVE")) {
-    status = CSaveOverlay ();
-    return (status);
-  }
-
-  if (!strcmp (buffer, "JPEG")) {
-    status = JPEGit24 ();
-    write (sock, "DONE", 4);
-    return (status);
-  }
-
-  if (!strcmp (buffer, "CENT")) {
-    status = Center ();
-    return (status);
-  }
-
-  if (!strcmp (buffer, "NPIX")) {
-    GetPixelCount ();
-    return (TRUE);
-  }
-
-  fprintf (stderr, "unknown signal %s\n", buffer);
-
-  return (TRUE);
-
+  if (!strcmp (word, "ERSC")) {
+    status = EraseCurrentPlot ();
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+  
+  /* Erase Plots */
+  if (!strcmp (word, "ERSP")) {
+    status = ErasePlots ();
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+  
+  /* Erase Sections */
+  if (!strcmp (word, "ERSS")) {
+    status = EraseSections ();
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  /* Erase Image */
+  if (!strcmp (word, "ERSI")) {
+    status = EraseImage ();
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  /* Erase Overlay for this section */
+  if (!strcmp (word, "ERSO")) {
+    status = EraseOverlay (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "READ")) {
+    status = LoadPicture (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "LOAD")) {
+    status = LoadOverlay (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "SAVE")) {
+    status = SaveOverlay (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "CSVE")) {
+    status = CSaveOverlay (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "JPEG")) {
+    status = JPEGit24 (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "CENT")) {
+    status = Center (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (status);
+  }
+
+  if (!strcmp (word, "NPIX")) {
+    GetPixelCount (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+
+  fprintf (stderr, "unknown signal %s\n", word);
+  KiiSendCommand (sock, 4, "DONE");
+  FINISHED (TRUE);
 }
Index: /trunk/Ohana/src/kapa2/src/CheckVisual.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CheckVisual.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CheckVisual.c	(revision 13479)
@@ -158,5 +158,5 @@
     /* make private colormap  */
     if (graphic[0].Npixels < 16) {
-      fprintf (stderr, "can't allocate enough cells, using private colormap\n");
+      // fprintf (stderr, "can't allocate enough cells, using private colormap\n");
       graphic[0].colormap = XCreateColormap (graphic[0].display, RootWindow (graphic[0].display, graphic[0].screen), graphic[0].visual, AllocNone);
       for (graphic[0].Npixels = NPIXELS;
@@ -178,7 +178,7 @@
   if (!dyn) {
     graphic[0].Npixels = 256;
-    fprintf (stderr, "can't use dynamic colors, color scrollbar inactive\n");
-    fprintf (stderr, " this can be avoided by using a dynamic visual class\n");
-    fprintf (stderr, " (see Kii help page for details)\n");
+    // fprintf (stderr, "can't use dynamic colors, color scrollbar inactive\n");
+    // fprintf (stderr, " this can be avoided by using a dynamic visual class\n");
+    // fprintf (stderr, " (see Kii help page for details)\n");
   }
 
Index: /trunk/Ohana/src/kapa2/src/CreatePicture.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CreatePicture.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CreatePicture.c	(revision 13479)
@@ -56,5 +56,4 @@
   case 32:
     REALLOCATE (image[0].picture.data, char, (4*image[0].picture.dx*image[0].picture.dy + 32));
-    fprintf (stderr, "allocating %d for picture data\n", (4*image[0].picture.dx*image[0].picture.dy + 32));
     memset (image[0].picture.data, 0xbd, 4*image[0].picture.dx*image[0].picture.dy + 30);
     l = (unsigned int *) image[0].picture.data;
Index: /trunk/Ohana/src/kapa2/src/CreateZoom16.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CreateZoom16.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CreateZoom16.c	(revision 13479)
@@ -1,6 +1,15 @@
 # include "Ximage.h"
-# define XPIX(x,Rx,S) (x*S + Rx)
-# define ZPIX(value,Rz1,Rz2) (value*Rz1 - Rz2)
 # define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void CreateZoom16 (KapaImageWidget *image, Graphic *graphic, double x, double y) {
@@ -9,9 +18,9 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, zoomscale, Rx, Ry;
   int expand_in, expand_out;
   unsigned char *out_pix, *out_pix2, *data;
-  unsigned char *in_pix,  *in_pix2;
+  float *imdata, *in_pix,  *in_pix2;
   unsigned char pixel1[256], pixel2[256];
   unsigned char pixvalue1, pixvalue2;
@@ -37,4 +46,13 @@
   back1 = 0x0000ff & back;
   back2 = 0x0000ff & (back >> 8);
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
 
   zoomscale = MAX (5, image[0].expand + 5);
@@ -56,5 +74,6 @@
 
   data = out_pix = (unsigned char *) image[0].zoom.data;
-  in_pix  = (unsigned char *) (image[0].matrix.buffer) + DX*(int)MAX(Ry,0) + (int)MAX(Rx,0);
+  imdata  = (float *) image[0].matrix.buffer;
+  in_pix  = &imdata[DX*(int)MAX(Ry,0) + (int)MAX(Rx,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -91,12 +110,13 @@
     if (expand_out == 1) {
       for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix+=2) {
-	out_pix[0] = pixel1[*in_pix2];
-	out_pix[1] = pixel2[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	out_pix[0] = pixel1[pixelN];
+	out_pix[1] = pixel2[pixelN];
       }
-    }
-    else {
+    } else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= 2*expand_out) { 
-	pixvalue1 = pixel1[*in_pix2];
-	pixvalue2 = pixel2[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	pixvalue1 = pixel1[pixelN];
+	pixvalue2 = pixel2[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=2*(dx-expand_out)) {
@@ -129,6 +149,6 @@
   }
 
-  image[0].zoom.pix = XCreateImage (graphic[0].display, graphic[0].visual, 16, ZPixmap, 0, 
-					image[0].zoom.data, image[0].zoom.dx, image[0].zoom.dy, 32, 0);
+  image[0].zoom.pix = XCreateImage (graphic[0].display, graphic[0].visual, graphic[0].depth, ZPixmap, 0, 
+					image[0].zoom.data, image[0].zoom.dx, image[0].zoom.dy, 16, 0);
   
 }
Index: /trunk/Ohana/src/kapa2/src/CreateZoom24.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CreateZoom24.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CreateZoom24.c	(revision 13479)
@@ -1,6 +1,15 @@
 # include "Ximage.h"
-# define XPIX(x,Rx,S) (x*S + Rx)
-# define ZPIX(value,Rz1,Rz2) (value*Rz1 - Rz2)
 # define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void CreateZoom24 (KapaImageWidget *image, Graphic *graphic, double x, double y) {
@@ -9,9 +18,9 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, zoomscale, Rx, Ry;
   int expand_in, expand_out;
   unsigned char *out_pix, *out_pix2, *data;
-  unsigned char *in_pix,  *in_pix2;
+  float *imdata, *in_pix, *in_pix2;
   unsigned char pixel1[256], pixel2[256], pixel3[256];
   unsigned char pixvalue1, pixvalue2, pixvalue3;
@@ -41,4 +50,14 @@
   back3 = 0x0000ff & (back >> 16);
 
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
+
   zoomscale = MAX (5, image[0].expand + 5);
   expand = 1 / zoomscale;
@@ -59,5 +78,6 @@
 
   data = out_pix = (unsigned char *) image[0].zoom.data;
-  in_pix  = (unsigned char *) (image[0].matrix.buffer) + DX*(int)MAX(Ry,0) + (int)MAX(Rx,0);
+  imdata  = (float *) image[0].matrix.buffer;
+  in_pix  = &imdata[DX*(int)MAX(Ry,0) + (int)MAX(Rx,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -97,14 +117,15 @@
     if (expand_out == 1) {
       for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix+=3) {
-	out_pix[0] = pixel1[*in_pix2];
-	out_pix[1] = pixel2[*in_pix2];
-	out_pix[2] = pixel3[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	out_pix[0] = pixel1[pixelN];
+	out_pix[1] = pixel2[pixelN];
+	out_pix[2] = pixel3[pixelN];
       }
-    }
-    else {
+    } else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= 3*expand_out) { 
-	pixvalue1 = pixel1[*in_pix2];
-	pixvalue2 = pixel2[*in_pix2];
-	pixvalue3 = pixel3[*in_pix2];
+	pixelN   = PixelLookup(*in_pix2);
+	pixvalue1 = pixel1[pixelN];
+	pixvalue2 = pixel2[pixelN];
+	pixvalue3 = pixel3[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=3*(dx-expand_out)+extra) {
Index: /trunk/Ohana/src/kapa2/src/CreateZoom32.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CreateZoom32.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CreateZoom32.c	(revision 13479)
@@ -1,6 +1,15 @@
 # include "Ximage.h"
-# define XPIX(x,Rx,S) (x*S + Rx)
-# define ZPIX(value,Rz1,Rz2) (value*Rz1 - Rz2)
 # define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void CreateZoom32 (KapaImageWidget *image, Graphic *graphic, double x, double y) {
@@ -9,9 +18,9 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, zoomscale, Rx, Ry;
   int expand_in, expand_out;
-  unsigned int *out_pix, *out_pix2, *data;
-  unsigned char  *in_pix,  *in_pix2;
+  unsigned int *out_pix, *out_pix2;
+  float *imdata, *in_pix, *in_pix2;
   unsigned long pixel[256], pixvalue;
   unsigned long back;
@@ -28,4 +37,14 @@
   }
   back = graphic[0].back;
+
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
 
   zoomscale = MAX (5, image[0].expand + 5);
@@ -49,6 +68,6 @@
 
   out_pix = (unsigned int *) image[0].zoom.data;
-  data = (unsigned int *) image[0].zoom.data;
-  in_pix  = (unsigned char *) (image[0].matrix.buffer) + DX*(int)MAX(Ry,0) + (int)MAX(Rx,0);
+  imdata  = (float *) image[0].matrix.buffer;
+  in_pix  = &imdata[DX*(int)MAX(Ry,0) + (int)MAX(Rx,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -81,10 +100,12 @@
     if (expand_out == 1) {
       for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix++) {
-	out_pix[0] = pixel[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	out_pix[0] = pixel[pixelN];
       }
     }
     else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= expand_out) { 
-	pixvalue = *(pixel + *in_pix2);
+	pixelN   = PixelLookup(*in_pix2);
+	pixvalue = pixel[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=(dx-expand_out)) {
Index: /trunk/Ohana/src/kapa2/src/CreateZoom8.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CreateZoom8.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/CreateZoom8.c	(revision 13479)
@@ -1,6 +1,15 @@
 # include "Ximage.h"
-# define XPIX(x,Rx,S) (x*S + Rx)
-# define ZPIX(value,Rz1,Rz2) (value*Rz1 - Rz2)
 # define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void CreateZoom8 (KapaImageWidget *image, Graphic *graphic, double x, double y) {
@@ -9,9 +18,9 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, zoomscale, Rx, Ry;
   int expand_in, expand_out;
-  char  *out_pix, *out_pix2;
-  char  *in_pix,  *in_pix2;
+  unsigned char *out_pix, *out_pix2;
+  float *imdata, *in_pix, *in_pix2;
   unsigned long pixel[256], pixvalue;
   unsigned long back;
@@ -30,30 +39,18 @@
   back = graphic[0].back;
 
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
+
   zoomscale = MAX (5, image[0].expand + 5);
   expand = 1 / zoomscale;
   expand_out = (int) zoomscale;
   expand_in  = 1;
-
-  /*
-  dx = image[0].zoom.dx;
-  dy = image[0].zoom.dy;
-  DX = image[0].matrix.Naxis[0];
-  DY = image[0].matrix.Naxis[1];
-  Rx = 0.5*(DX - (dx - 1)*expand) - x;
-  Ry = 0.5*(DY - (dy - 1)*expand) - y;
-  data coords of 0,0 point in pic array 
-  X = 0.5*image[0].matrix.Naxis[0] - expand*((int)(0.5*image[0].zoom.dx + 0.5) - 0.0) - image[0].X;
-  Y = 0.5*image[0].matrix.Naxis[1] - expand*((int)(0.5*image[0].zoom.dy + 0.5) - 0.0) - image[0].Y;  
-  i_start = MIN (MAX (-Rx / expand, 0), dx - expand_out + 1);
-  j_start = MIN (MAX (-Ry / expand, 0), dy - expand_out + 1);
-  i_end   = MAX (MIN ((DX-Rx) / expand, dx - expand_out + 1), 0);
-  j_end   = MAX (MIN ((DY-Ry) / expand, dy - expand_out + 1), 0);
-  dropback = expand_out - (i_end - i_start) % expand_out;
-  if ((i_end - i_start) % expand_out == 0) dropback = 0;
-
-  out_pix = image[0].zoom.data;
-  in_pix  = (char *) (image[0].matrix.buffer) + DX*(int)MAX(Y,0) + (int)MAX(X,0);
-
-  */
 
   dx = image[0].zoom.dx;
@@ -72,5 +69,6 @@
 
   out_pix = (char *) image[0].zoom.data;
-  in_pix  = (char *) (image[0].matrix.buffer) + DX*(int)MAX(Ry,0) + (int)MAX(Rx,0);
+  imdata  = (float *) image[0].matrix.buffer;
+  in_pix  = &imdata[DX*(int)MAX(Ry,0) + (int)MAX(Rx,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -100,10 +98,12 @@
     in_pix2 = in_pix;
     if (expand_out == 1) {
-      for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix++)
-	*out_pix = *(pixel + *in_pix2); 
-    }
-    else {
+      for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix++) {
+	pixelN = PixelLookup(*in_pix2);
+	*out_pix = pixel[pixelN];
+      }
+    } else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= expand_out) { 
-	pixvalue = *(pixel + *in_pix2);
+	pixelN   = PixelLookup(*in_pix2);
+	pixvalue = pixel[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=(dx-expand_out)) {
@@ -131,5 +131,5 @@
   
   /**** fill in top area ****/
-  for (j = 0; (j < dx*(dy - j_end)) && (out_pix - image[0].zoom.data < dx*dy); j++, out_pix++) { 
+  for (j = 0; (j < dx*(dy - j_end)) && (out_pix - (unsigned char *) image[0].zoom.data < dx*dy); j++, out_pix++) { 
     *out_pix = back;
   }
Index: /trunk/Ohana/src/kapa2/src/DefineSection.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/DefineSection.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/DefineSection.c	(revision 13479)
@@ -1,5 +1,6 @@
 # include "Ximage.h"
 
-int DefineSection () {
+// define the section, but do not create a graph or image 
+int DefineSection (int sock) {
   
   int i, N, MoveSection;
@@ -15,5 +16,4 @@
   if (N < 0) {
     section = AddSection (name, x, y, dx, dy);
-    section->graph = InitGraph ();
     MoveSection = TRUE;
   } else {
@@ -33,5 +33,5 @@
 
   if (MoveSection) {
-    SetGraphSize (section);
+    SetSectionSizes (section);
     Refresh (1);
   }
Index: /trunk/Ohana/src/kapa2/src/EraseCurrentPlot.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/EraseCurrentPlot.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/EraseCurrentPlot.c	(revision 13479)
@@ -11,4 +11,5 @@
   section = GetActiveSection();
   if (section->graph == NULL) return (TRUE);
+
   EraseGraph (section->graph);
   
Index: /trunk/Ohana/src/kapa2/src/EraseImage.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/EraseImage.c	(revision 13479)
+++ /trunk/Ohana/src/kapa2/src/EraseImage.c	(revision 13479)
@@ -0,0 +1,21 @@
+# include "Ximage.h"
+
+int EraseImage () {
+
+  char buffer[256];
+  int i, status, N;
+  Graphic *graphic;
+  Section *section;
+  KapaImageWidget *image;
+
+  graphic = GetGraphic();
+  section = GetActiveSection();
+  image = section->image;
+  if (image == NULL) return (TRUE);
+
+  FreeImage (image);
+  section->image = NULL;
+
+  if (USE_XWINDOW) Refresh ();
+  return (TRUE);
+}
Index: /trunk/Ohana/src/kapa2/src/EraseOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/EraseOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/EraseOverlay.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int EraseOverlay () {
+int EraseOverlay (int sock) {
 
   char buffer[256];
@@ -12,17 +12,18 @@
   section = GetActiveSection();
   image = section->image;
+  if (image == NULL) return (TRUE);
 
   KiiScanCommand (sock, 16, "%*s %d", &N);
 
   if (N > NOVERLAYS) {
-    REALLOCATE (image[0].tickmarks.objects, Object, 1);
+    REALLOCATE (image[0].tickmarks.objects, KiiOverlay, 1);
     image[0].tickmarks.Nobjects = 0;
   } else {
     for (i = 0; i < image[0].overlay[N].Nobjects; i++) {
-      if (!strcmp (image[0].overlay[N].objects[i].type, "TEXT")) {
+      if (image[0].overlay[N].objects[i].type == KII_OVERLAY_TEXT) {
 	free (image[0].overlay[N].objects[i].text);
       }
     }
-    REALLOCATE (image[0].overlay[N].objects, Object, 1);
+    REALLOCATE (image[0].overlay[N].objects, KiiOverlay, 1);
     image[0].overlay[N].Nobjects = 0;
     image[0].overlay[N].active = FALSE;
Index: /trunk/Ohana/src/kapa2/src/GetPixelCount.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/GetPixelCount.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/GetPixelCount.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int GetPixelCount () {
+int GetPixelCount (int sock) {
   
   int i;
Index: /trunk/Ohana/src/kapa2/src/Graphs.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Graphs.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Graphs.c	(revision 13479)
@@ -20,4 +20,9 @@
     strcpy (graph[0].label[i].text, "");
   }
+
+  graph[0].data.xmin = 0.0;
+  graph[0].data.xmax = 1.0;
+  graph[0].data.ymin = 0.0;
+  graph[0].data.ymax = 1.0;
 
   graph[0].Nobjects = 0;
@@ -100,4 +105,5 @@
   FREE (graph[0].objects);
   FREE (graph[0].textline);
+  free (graph);
   return;
 }
Index: /trunk/Ohana/src/kapa2/src/Image.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Image.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Image.c	(revision 13479)
@@ -21,9 +21,10 @@
   image[0].start = 0;
   image[0].slope = 1;
+  image[0].location = 4;
 
   image[0].coords.Npolyterms = 0;
   for (i = 0; i < NOVERLAYS; i++) {
     image[0].overlay[i].Nobjects = 0;
-    ALLOCATE (image[0].overlay[i].objects, Object, 1);  /* allocate so later free will not crash! */
+    ALLOCATE (image[0].overlay[i].objects, KiiOverlay, 1);  /* allocate so later free will not crash! */
     image[0].overlay[i].active = FALSE;
     image[0].overlay[i].color = graphic[0].overlay_color[i];
@@ -96,8 +97,8 @@
   graphic = GetGraphic ();
 
-  XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
-  XDrawRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, 
-		  image[0].picture.x, image[0].picture.y, 
-		  image[0].picture.dx + 1, image[0].picture.dy + 1);
+  XSetForeground (graphic[0].display,  graphic[0].gc, graphic[0].fore);
+  XDrawRectangle (graphic[0].display,  graphic[0].window, graphic[0].gc, 
+		  image[0].picture.x,  image[0].picture.y, 
+		  image[0].picture.dx+1, image[0].picture.dy+1);
   
   XPutImage (graphic[0].display, graphic[0].window, graphic[0].gc,
@@ -106,11 +107,4 @@
 	     image[0].picture.dx, image[0].picture.dy);
 
-  XPutImage (graphic[0].display, graphic[0].window, graphic[0].gc,
-	     image[0].cmapbar.pix, 0, 0, 
-	     image[0].cmapbar.x, image[0].cmapbar.y, 
-	     image[0].cmapbar.dx, image[0].cmapbar.dy);
-
-  CrossHairs (graphic, image);
-
   for (i = 0; i < NOVERLAYS; i++) {
     if (image[0].overlay[i].active) {
@@ -118,15 +112,19 @@
     }
   }
-# if (0)
-  PaintTickmarks (graphic, image);
-# endif
 
-  // XXX make this optional?a
-  if (1) {
+  if (image[0].location) {
+    XPutImage (graphic[0].display, graphic[0].window, graphic[0].gc,
+	       image[0].cmapbar.pix, 0, 0, 
+	       image[0].cmapbar.x, image[0].cmapbar.y, 
+	       image[0].cmapbar.dx, image[0].cmapbar.dy);
+
+    CrossHairs (graphic, image);
+  
     /* erase everything below zoom box, then draw */
+    /*
     XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].back);
     XFillRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, 
-		    image[0].text_x, image[0].text_x, image[0].zoom.dx, graphic[0].dy); 
-    
+		    image[0].text_x, image[0].text_x, image[0].text_dx, image[0].text_dy); 
+    */    
     DrawButton (graphic, &image[0].PS_button);
     DrawButton (graphic, &image[0].recenter_button);
@@ -139,8 +137,24 @@
       DrawButton (graphic, &image[0].overlay_button[i]);
     }
+    StatusBox (graphic, image);
   }
-
-  StatusBox (graphic, image);
 
   FlushDisplay (graphic[0].display);
 }
+
+void FreeImage (KapaImageWidget *image) {
+
+  int i;
+
+  if (image == NULL) return;
+
+  for (i = 0; i < NOVERLAYS; i++) {
+    free (image[0].overlay[i].objects);
+  }
+  free (image[0].matrix.buffer);
+  free (image[0].picture.data);
+  free (image[0].cmapbar.data);
+  free (image[0].zoom.data);
+
+  free (image);
+}
Index: /trunk/Ohana/src/kapa2/src/InterpretKeys.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/InterpretKeys.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/InterpretKeys.c	(revision 13479)
@@ -3,6 +3,7 @@
 int InterpretKeys (Graphic *graphic, XKeyEvent *event) {
 
-  double 	   X, Y, offset;
-  int    	   modstate;
+  float           *imdata;
+  double 	   X, Y, Z, R, D, offset;
+  int    	   sock, DX, DY, modstate;
   char   	  *name, string[16], line[40];
   KeySym           keysym;
@@ -23,4 +24,8 @@
   // XXX allow user to choose graph or image coords
   if (ACTIVE_CURSOR) {
+
+    sock = GetActiveSocket ();
+    if (sock == -1) goto skip_cursor;
+
     name = XKeysymToString (keysym);
 
@@ -43,7 +48,10 @@
     if (!strcmp (name, "(null)")) goto skip_cursor;
 
+    Z = -1;
+
     if (graph) {
       X = (event[0].x - graph[0].axis[0].fx)*(graph[0].axis[0].max - graph[0].axis[0].min)/graph[0].axis[0].dfx + graph[0].axis[0].min;
       Y = (event[0].y - graph[0].axis[1].fy)*(graph[0].axis[1].max - graph[0].axis[1].min)/graph[0].axis[1].dfy + graph[0].axis[1].min;
+      XY_to_RD (&R, &D, X, Y, &graph[0].data.coords);
     } 
     if (image && !graph) {
@@ -53,10 +61,23 @@
       if (event[0].y > image[0].picture.y + image[0].picture.dy) goto skip_cursor;
       Screen_to_Image (&X, &Y, (double)event[0].x, (double)event[0].y, image);
+      XY_to_RD (&R, &D, X, Y, &image[0].coords);
+
+      DX = image[0].matrix.Naxis[0];
+      DY = image[0].matrix.Naxis[1];
+
+      if (X < 0) goto off_image;
+      if (Y < 0) goto off_image;
+      if (X >= DX) goto off_image;
+      if (Y >= DY) goto off_image;
+      imdata = (float *) image[0].matrix.buffer;
+      Z      = imdata[DX*(int)(Y) + (int)(X)];
     }
-    snprintf (line, 40, "%12s %12.6f %12.6f ", name, X, Y);
-    write (sock, line, 40);
+  off_image:
+    KiiSendMessage (sock, "%12s %12.6f %12.6f %12.6f %12.6f %12.6f", name, X, Y, Z, R, D);
   }
 
 skip_cursor:
+  if (image == NULL) return (TRUE);
+
   // offset is in image pixels: 
   // 0.5 image pixels is 1 screen pixel for expand == +2
Index: /trunk/Ohana/src/kapa2/src/InterpretPresses.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/InterpretPresses.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/InterpretPresses.c	(revision 13479)
@@ -3,7 +3,8 @@
 int InterpretPresses (Graphic *graphic, XButtonEvent *event) {
 
-  int              status, done, this_button, old_cursor;
+  int              sock, DX, DY, status, done, this_button, old_cursor;
   char             name[16], line[40];
-  double           X, Y;
+  double           X, Y, Z, R, D;
+  float           *imdata;
   KeySym           keysym;
   Button          *button;
@@ -20,8 +21,12 @@
   // XXX allow user to choose graph or image coords
   if (ACTIVE_CURSOR) {
+    sock = GetActiveSocket ();
+    if (sock == -1) goto skip_cursor;
+
     sprintf (name, "Button%d", event[0].button);
     if (graph) {
       X = (event[0].x - graph[0].axis[0].fx)*(graph[0].axis[0].max - graph[0].axis[0].min)/graph[0].axis[0].dfx + graph[0].axis[0].min;
       Y = (event[0].y - graph[0].axis[1].fy)*(graph[0].axis[1].max - graph[0].axis[1].min)/graph[0].axis[1].dfy + graph[0].axis[1].min;
+      XY_to_RD (&R, &D, X, Y, &graph[0].data.coords);
     } 
     if (image && !graph) {
@@ -30,9 +35,20 @@
       if (event[0].x > image[0].picture.x + image[0].picture.dx) goto skip_cursor;
       if (event[0].y > image[0].picture.y + image[0].picture.dy) goto skip_cursor;
-	
       Screen_to_Image (&X, &Y, (double)event[0].x, (double)event[0].y, image);
+
+      XY_to_RD (&R, &D, X, Y, &image[0].coords);
+
+      DX = image[0].matrix.Naxis[0];
+      DY = image[0].matrix.Naxis[1];
+
+      if (X < 0) goto off_image;
+      if (Y < 0) goto off_image;
+      if (X >= DX) goto off_image;
+      if (Y >= DY) goto off_image;
+      imdata = (float *) image[0].matrix.buffer;
+      Z      = imdata[DX*(int)(Y) + (int)(X)];
     }
-    snprintf (line, 40, "%12s %12.6f %12.6f ", name, X, Y);
-    write (sock, line, 40);
+  off_image:
+    KiiSendMessage (sock, "%12s %12.6f %12.6f %12.6f %12.6f %12.6f", name, X, Y, Z, R, D);
   }
 
@@ -40,4 +56,7 @@
   status = TRUE;
   this_button = event[0].button;
+
+  // XXX add graph buttons here
+  if (image == NULL) return (TRUE);
   
   if ((event[0].type == ButtonPress) && InPicture (event, &image[0].picture)) {
Index: /trunk/Ohana/src/kapa2/src/JPEGit24.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/JPEGit24.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/JPEGit24.c	(revision 13479)
@@ -6,6 +6,17 @@
 # define WHITE_B 255
 
-// XXX this currently writes out the jpeg for the active image
-int JPEGit24 () {
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
+
+// XXX this currently writes out the jpeg for just the active image
+int JPEGit24 (int sock) {
 
   struct jpeg_compress_struct cinfo;
@@ -21,19 +32,21 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   int status, Nbytes, quality;
   int expand_in, expand_out;
   double expand, Rx, Ry, X, Y;
-  unsigned char *out_pix, *in_pix, *in_pix_ref;
+  unsigned char *out_pix;
+  float *imdata, *in_pix, *in_pix_ref;
   unsigned char pixel1[256], pixel2[256], pixel3[256];
   char filename[1024];
   FILE *f;
 
+  /* expect a line telling the number of bytes and a filename */
+  KiiScanMessage (sock, "%s", filename);
+
   graphic = GetGraphic();
   section = GetActiveSection();
   image   = section->image;
-
-  /* expect a line telling the number of bytes and a filename */
-  KiiScanMessage (sock, "%s", filename);
+  if (image == NULL) return (TRUE);
 
   /***** JPEG init calls */
@@ -69,4 +82,14 @@
   }
 
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
+
   expand = expand_in = expand_out = 1.0;
   if (image[0].expand == 0) /* set up expansions */
@@ -122,5 +145,6 @@
   ALLOCATE (line_buffer, JSAMPLE, 3*dx);
 
-  in_pix_ref  = (unsigned char *) (image[0].matrix.buffer) + DX*(int)MAX(Y,0) + (int)MAX(X,0);
+  imdata = (float *) image[0].matrix.buffer;
+  in_pix_ref = &imdata[DX*(int)MAX(Y,0) + (int)MAX(X,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -153,8 +177,9 @@
     /*** fill in the picture region ***/
     for (i = i_start; i < i_end; i+=expand_out, in_pix+=expand_in) {
+      pixelN = PixelLookup(*in_pix);
       for (ii = 0; ii < expand_out; ii++, out_pix+=3) {
-	out_pix[0] = pixel1[*in_pix];
-	out_pix[1] = pixel2[*in_pix];
-	out_pix[2] = pixel3[*in_pix];
+	out_pix[0] = pixel1[pixelN];
+	out_pix[1] = pixel2[pixelN];
+	out_pix[2] = pixel3[pixelN];
       }
     }
Index: /trunk/Ohana/src/kapa2/src/Layout.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Layout.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Layout.c	(revision 13479)
@@ -4,21 +4,8 @@
 void InitLayout (int argc, char **argv) {
 
-  int N, UseGraph;
+  int N;
   Section *section;
 
-  UseGraph = FALSE;
-  if ((N = get_argument (argc, argv, "-image"))) {
-    remove_argument(N, &argc, argv);
-    UseGraph = FALSE;
-  }
-
-  /** initiate connection with server **/
-  if (!FOREGROUND) {	
-    if (argc < 2) {
-      fprintf (stderr, "socket path not specified\n");
-      exit (0);
-    }
-    sock = KiiWait (argv[1]);
-  }
+  InitPipe();
 
   ACTIVE_CURSOR = FALSE;
@@ -37,14 +24,13 @@
   }
 
+  /* move this out of here... */
+  if (argc != 1) {
+    fprintf (stderr, "USAGE: kapa\n");
+    exit (0);
+  }
+
   InitRotFonts ();
 
-  /* create basic section */
+  /* create basic section, empty of image or graph */
   section = AddSection ("default", 0.0, 0.0, 1.0, 1.0);
-  if (UseGraph) {
-    section->graph = InitGraph ();
-    SetGraphSize (section);
-  } else {
-    section->image = InitImage ();
-    SetImageSize (section);
-  }
 }
Index: /trunk/Ohana/src/kapa2/src/LoadFrame.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadFrame.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/LoadFrame.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int LoadFrame () {
+int LoadFrame (int sock) {
   
   int i, status;
@@ -9,8 +9,10 @@
 
   section = GetActiveSection();
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
   graph = section->graph;
 
-  // XXX what to do if graph is NULL?
-  
   KiiScanMessage (sock, "%lf %lf %lf %lf", 
 		  &graph[0].axis[0].min, &graph[0].axis[0].max, 
@@ -60,4 +62,5 @@
   }
 
+  SetSectionSizes (section);
   if (USE_XWINDOW) DrawFrame (graph);
   FlushDisplay ();
Index: /trunk/Ohana/src/kapa2/src/LoadLabels.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadLabels.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/LoadLabels.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int LoadLabels () {
+int LoadLabels (int sock) {
   
   char *c, *label;
@@ -9,7 +9,9 @@
 
   section = GetActiveSection();
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
   graph = section->graph;
-  
-  fcntl (sock, F_SETFL, !O_NONBLOCK);  
   
   KiiScanMessage (sock, "%d", &mode);
@@ -21,6 +23,4 @@
   strncpy (graph[0].label[mode].text, label, Nbytes);
   label[Nbytes] = 0;
-
-  fcntl (sock, F_SETFL, O_NONBLOCK);  
   
   c = GetRotFont (&size);
Index: /trunk/Ohana/src/kapa2/src/LoadObject.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 13479)
@@ -1,6 +1,7 @@
 # include "Ximage.h"
 # include <errno.h>
-
-int LoadObject () {
+# define DEBUG 0
+
+int LoadObject (int sock) {
   
   int N;
@@ -9,7 +10,9 @@
 
   section = GetActiveSection();
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
   graph = section->graph;
-  
-  fcntl (sock, F_SETFL, !O_NONBLOCK);  
   
   N = graph[0].Nobjects;
@@ -41,8 +44,13 @@
 		  &graph[0].objects[N].x0, &graph[0].objects[N].x1, 
 		  &graph[0].objects[N].y0, &graph[0].objects[N].y1);
-  
-  fcntl (sock, F_SETFL, O_NONBLOCK);  
-  
-  if (!LoadVectorData (graph, N, "x")) {
+
+  // acknowledge receipt of the metadata
+  KiiSendCommand (sock, 4, "DONE"); 
+  
+  // XXX Currently, I require these in a special order.  The data includes a message defining the
+  // object type.  This could be made more flexible by using the information (though we still need
+  // to know how many items will be sent)
+
+  if (!LoadVectorData (sock, graph, N, "x")) {
     FreeObjectData (&graph[0].objects[N]);
     graph[0].Nobjects --;
@@ -50,5 +58,5 @@
   }
     
-  if (!LoadVectorData (graph, N, "y")) {
+  if (!LoadVectorData (sock, graph, N, "y")) {
     FreeObjectData (&graph[0].objects[N]);
     graph[0].Nobjects --;
@@ -56,5 +64,5 @@
   }
   if (graph[0].objects[N].size < 0.0) {
-    if (!LoadVectorData (graph, N, "z")) {
+    if (!LoadVectorData (sock, graph, N, "z")) {
       FreeObjectData (&graph[0].objects[N]);
       graph[0].Nobjects --;
@@ -63,10 +71,10 @@
   }
   if (graph[0].objects[N].etype & 0x01) {
-    if (!LoadVectorData (graph, N, "dym")) {
-      FreeObjectData (&graph[0].objects[N]);
-      graph[0].Nobjects --;
-      REALLOCATE (graph[0].objects, Gobjects, MAX (1, graph[0].Nobjects));
-    }
-    if (!LoadVectorData (graph, N, "dyp")) {
+    if (!LoadVectorData (sock, graph, N, "dym")) {
+      FreeObjectData (&graph[0].objects[N]);
+      graph[0].Nobjects --;
+      REALLOCATE (graph[0].objects, Gobjects, MAX (1, graph[0].Nobjects));
+    }
+    if (!LoadVectorData (sock, graph, N, "dyp")) {
       FreeObjectData (&graph[0].objects[N]);
       graph[0].Nobjects --;
@@ -75,10 +83,10 @@
   }
   if (graph[0].objects[N].etype & 0x02) {
-    if (!LoadVectorData (graph, N, "dxm")) {
-      FreeObjectData (&graph[0].objects[N]);
-      graph[0].Nobjects --;
-      REALLOCATE (graph[0].objects, Gobjects, MAX (1, graph[0].Nobjects));
-    }
-    if (!LoadVectorData (graph, N, "dxp")) {
+    if (!LoadVectorData (sock, graph, N, "dxm")) {
+      FreeObjectData (&graph[0].objects[N]);
+      graph[0].Nobjects --;
+      REALLOCATE (graph[0].objects, Gobjects, MAX (1, graph[0].Nobjects));
+    }
+    if (!LoadVectorData (sock, graph, N, "dxp")) {
       FreeObjectData (&graph[0].objects[N]);
       graph[0].Nobjects --;
@@ -96,50 +104,67 @@
 }
 
-/* load data for the named component */
-int LoadVectorData (KapaGraphWidget *graph, int N, char *type) {
-  
-  int Npts, Ninpts, status, Ntry;
+int LoadVectorData (int sock, KapaGraphWidget *graph, int N, char *type) {
+  
+  int i, Npts, Ninpts, status, Ntry;
   int bytes_left;
-  char *buff;
-
-  buff = NULL;
+  char *byte, *buffer, type_send[16], tmp;
+  int Npts_send, Nbytes_send, swap_client, swap_host;
+
+  buffer = NULL;
   Npts = graph[0].objects[N].Npts;
+
+  KiiWaitAnswer (sock, "PLOB");
+  KiiScanMessage (sock, "%s %d %d %d", type_send, &Npts_send, &Nbytes_send, &swap_client);
+  if (strcmp (type, type_send)) {
+    fprintf (stderr, "Kapa Communication error: unexpected data type %s vs %s\n", type_send, type);
+  }
+  if (Npts_send != Npts) {
+    fprintf (stderr, "Kapa Communication error: unexpected number of points %d vs %d\n", Npts_send, Npts);
+  }
+  if (Nbytes_send != Npts_send*sizeof(float)) {
+    fprintf (stderr, "Kapa Communication error: unexpected data size %d vs %d\n", Nbytes_send, Npts_send*sizeof(float));
+  }
+
   status = 1;
   if (!strcmp (type, "x")) {
     ALLOCATE (graph[0].objects[N].x, float, MAX (1, Npts));
-    buff = (char *) graph[0].objects[N].x;
+    buffer = (char *) graph[0].objects[N].x;
   }
   if (!strcmp (type, "y")) {
     ALLOCATE (graph[0].objects[N].y, float, MAX (1, Npts));
-    buff = (char *) graph[0].objects[N].y;
+    buffer = (char *) graph[0].objects[N].y;
   }
   if (!strcmp (type, "z")) {
     ALLOCATE (graph[0].objects[N].z, float, MAX (1, Npts));
-    buff = (char *) graph[0].objects[N].z;
+    buffer = (char *) graph[0].objects[N].z;
   }
   if (!strcmp (type, "dxm")) {
     ALLOCATE (graph[0].objects[N].dxm, float, MAX (1, Npts));
-    buff = (char *) graph[0].objects[N].dxm;
+    buffer = (char *) graph[0].objects[N].dxm;
   }
   if (!strcmp (type, "dxp")) {
     ALLOCATE (graph[0].objects[N].dxp, float, MAX (1, Npts));
-    buff = (char *) graph[0].objects[N].dxp;
+    buffer = (char *) graph[0].objects[N].dxp;
   }
   if (!strcmp (type, "dym")) {
     ALLOCATE (graph[0].objects[N].dym, float, MAX (1, Npts));
-    buff = (char *) graph[0].objects[N].dym;
+    buffer = (char *) graph[0].objects[N].dym;
   }
   if (!strcmp (type, "dyp")) {
     ALLOCATE (graph[0].objects[N].dyp, float, MAX (1, Npts));
-    buff = (char *) graph[0].objects[N].dyp;
+    buffer = (char *) graph[0].objects[N].dyp;
   }
 
   bytes_left = Npts*sizeof (float);
 
+  fcntl (sock, F_SETFL, O_NONBLOCK);  
+
+  // read the vector data as raw binary in client machine byte order (floats)
   Ntry = 0;
   if (DEBUG) fprintf (stderr, "starting vector load\n");
   Ninpts = 0;
+  byte = buffer;
   while (bytes_left > 0) {
-    status = read (sock, buff, bytes_left);
+    status = read (sock, byte, bytes_left);
     if (DEBUG) fprintf (stderr, "status: %d, %d\n", status, bytes_left);
     if (status == 0) {  /* No more pipe */
@@ -150,5 +175,5 @@
       Ninpts += status;
       bytes_left -= status;
-      buff = (char *)(buff + status);
+      byte = (char *)(byte + status);
       Ntry = 0;
       continue;
@@ -165,4 +190,24 @@
     perror ("kapa load");
   }
+
+  fcntl (sock, F_SETFL, !O_NONBLOCK);  
+  KiiSendCommand (sock, 4, "DONE"); 
+
+# ifdef BYTE_SWAP
+  swap_host = 1;
+# else 
+  swap_host = 0;
+# endif  
+
+  // if host and client have opposite swap parities, word swap the incoming data
+  // SWAP_WORD is strangely defined... it takes the number of the start byte in a
+  // buffer called 'byte'
+  if ((swap_host && !swap_client) || (!swap_host && swap_client)) {
+    byte = buffer;
+    for (i = 0; i < Nbytes_send; i+=4) {
+      SWAP_WORD (i);
+    }
+  }
+
   if (Ninpts != Npts*sizeof(float)) {  
     fprintf (stderr, "error: expected %d bytes, but got only %d\n", Ninpts, (unsigned int)(Npts*sizeof(float)));
@@ -185,3 +230,2 @@
   if (object[0].dyp != (float *) NULL) free (object[0].dyp);
 }
-
Index: /trunk/Ohana/src/kapa2/src/LoadOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/LoadOverlay.c	(revision 13479)
@@ -1,89 +1,118 @@
 # include "Ximage.h"
 
-// XXX this is a very inefficient method to send the data: binary would be better
-int LoadOverlay () {
+int LoadOverlay (int sock) {
   
-  char word[17], type[16], string[128];
-  char *buffer, *buff;
-  double x, y, dx, dy;
-  int Nin, bytes, status;
-  int i, N, NOBJECTS, Nobjects, Nstart;
+  int i, j, Ntotal, Nbytes, Nread, Nfound, Ntext, Nobjects, overnum;
+  int Noverlay, NOVERLAY, Ntextdata;
+  char *textdata, *buffer, *p, *q;
   Section *section;
   KapaImageWidget *image;
   Graphic *graphic;
+  KiiOverlayBase *overlay;
 
   graphic = GetGraphic ();
   section = GetActiveSection();
-  image   = section->image;
+  if (section->image == NULL) {
+    section->image = InitImage ();
+    SetSectionSizes (section);
+  }
+  image = section->image;
 
-  ALLOCATE (buffer, char, 65536);  /* space for 512 lines of 128 bytes */
-  bzero (buffer, 65536);
+  KiiScanMessage (sock, "%d %d %d %d", &overnum, &Noverlay, &Ntext, &Ntextdata);
 
-  KiiScanCommand (sock, 16, "%*s %d", &N);
-  Nstart = image[0].overlay[N].Nobjects;
+  // XXX need to validate overnum 
+  if ((overnum < 0) || (overnum >= NOVERLAYS)) overnum = 0;
 
-  while (1) {
-    KiiScanCommand (sock, 16, "%s %d", word, &Nin);
-    if (!strcmp (word, "DONE")) break;
-    if (strcmp (word, "NLINES")) abort();
+  // read the overlay data as binary 
+  Ntotal = 0;
+  Nbytes = Noverlay*sizeof(KiiOverlayBase);
+  fcntl (sock, F_SETFL, O_NONBLOCK);  
+  ALLOCATE (overlay, KiiOverlayBase, Noverlay);
+  buffer = (char *) overlay;
+  while (Nbytes > 0) { 
+    Nread = read (sock, &buffer[Ntotal], Nbytes);
+    // fprintf (stderr, "read: %d of %d remaining, %d so far, %d expected\n", Nread, Nbytes, Ntotal, Noverlay*sizeof(KiiOverlayBase));
+    if (Nread == 0) {  /* No more pipe */
+      fprintf (stderr, "error: pipe closed\n");
+      free (overlay);
+      fcntl (sock, F_SETFL, !O_NONBLOCK);  
+      return (FALSE);
+    }
+    if (Nread != -1) { /* pipe has data */
+      Nbytes -= Nread;
+      Ntotal += Nread;
+    }
+  }
+  fcntl (sock, F_SETFL, !O_NONBLOCK);  
+  KiiSendCommand (sock,  4, "DONE");
 
-    buff = buffer;
-    bytes = 128*Nin;
+  // read the textdata as binary
+  Ntotal = 0;
+  Nbytes = Ntextdata;
+  fcntl (sock, F_SETFL, O_NONBLOCK);  
+  ALLOCATE (textdata, char, Ntextdata);
+  while (Nbytes > 0) { 
+    Nread = read (sock, &textdata[Ntotal], Nbytes);
+    if (Nread == 0) {  /* No more pipe */
+      fprintf (stderr, "error: pipe closed\n");
+      free (textdata);
+      free (overlay);
+      fcntl (sock, F_SETFL, !O_NONBLOCK);  
+      return (FALSE);
+    }
+    if (Nread != -1) { /* pipe has data */
+      Nbytes -= Nread;
+      Ntotal += Nread;
+    }
+  }
+  fcntl (sock, F_SETFL, !O_NONBLOCK);  
+  KiiSendCommand (sock,  4, "DONE");
 
-    /* accept data from the socket until we have all of the bytes */
-    fcntl (sock, F_SETFL, O_NONBLOCK);  
-    while (bytes > 0) { 
-      status = read (sock, buff, bytes);
-      if (status == 0) {  /* No more pipe */
-	fprintf (stderr, "error: pipe closed\n");
-	free (buffer);
-	fcntl (sock, F_SETFL, O_NONBLOCK);  
-	return (FALSE);
-      }
-      if (status != -1) { /* pipe has data */
-	bytes -= status;
-	buff = (char *)(buff + status);
-      }
-    }
-    fcntl (sock, F_SETFL, !O_NONBLOCK);  
+  // add new overlay objects to existing data
+  Nobjects = image[0].overlay[overnum].Nobjects + Noverlay;
+  REALLOCATE (image[0].overlay[overnum].objects, KiiOverlay, Nobjects);
 
-    /* parse buffer data */
-    NOBJECTS = image[0].overlay[N].Nobjects + Nin;
-    Nobjects = image[0].overlay[N].Nobjects;
-    REALLOCATE (image[0].overlay[N].objects, Object, NOBJECTS);
-    for (i = 0; i < Nin; i++) {
-      sscanf (&buffer[i*128], "%s %lf %lf %lf %lf\n", type, &x, &y, &dx, &dy);
-
-      if (strcasecmp (type, "TEXT") && strcasecmp (type, "LINE") && strcasecmp (type, "BOX") && strcasecmp (type, "CIRCLE")) {  /* skip */
-	fprintf (stderr, "don't know %s, skipping\n", type);
-	continue;
-      }
-
-      if (!strcasecmp (type, "TEXT")) { /* end of objects */
-	sscanf (&buffer[i*128], "%s %lf %lf %s\n", type, &x, &y, string);
-      }
-	
-      strcpy (image[0].overlay[N].objects[Nobjects].type, type);
-      image[0].overlay[N].objects[Nobjects].x = x;
-      image[0].overlay[N].objects[Nobjects].y = y;
-      if (!strcmp (type, "TEXT")) {
-	image[0].overlay[N].objects[Nobjects].dx = 0;
-	image[0].overlay[N].objects[Nobjects].dy = 0;
-	image[0].overlay[N].objects[Nobjects].text = strcreate (string);
-      } else {
-	image[0].overlay[N].objects[Nobjects].dx = dx;
-	image[0].overlay[N].objects[Nobjects].dy = dy;
-      }
-      Nobjects++;
-    }
-    REALLOCATE (image[0].overlay[N].objects, Object, MAX(Nobjects, 1));
-    image[0].overlay[N].Nobjects = Nobjects;
+  j = image[0].overlay[overnum].Nobjects;
+  for (i = 0; i < Noverlay; i++, j++) {
+    image[0].overlay[overnum].objects[j].x = overlay[i].x;
+    image[0].overlay[overnum].objects[j].y = overlay[i].y;
+    image[0].overlay[overnum].objects[j].dx = overlay[i].dx;
+    image[0].overlay[overnum].objects[j].dy = overlay[i].dy;
+    image[0].overlay[overnum].objects[j].type = overlay[i].type;
+    image[0].overlay[overnum].objects[j].text = NULL;
   }
 
-  /* cleanup */
-  free (buffer);
-  REALLOCATE (image[0].overlay[N].objects, Object, MAX (1, image[0].overlay[N].Nobjects));
-  image[0].overlay[N].active = TRUE;
-  fcntl (sock, F_SETFL, O_NONBLOCK);  
+  // parse the text data : text lines are separated by '\n', one per text entry
+  p = textdata;
+  Nfound = 0;
+  for (i = 0; i < Noverlay; i++) {
+    if (overlay[i].type != KII_OVERLAY_TEXT) continue;
+    if (Nfound >= Ntext) {
+      fprintf (stderr, "inconsistent number of text lines\n");
+      break;
+    }
+    if (! *p) {
+      fprintf (stderr, "inconsistent number of text lines\n");
+      break;
+    }
+    q = strchr (p, '\n');
+    if (q == NULL) {
+      fprintf (stderr, "inconsistent text line\n");
+      break;
+    }
+    j = image[0].overlay[overnum].Nobjects + i;
+    image[0].overlay[overnum].objects[j].text = strncreate (p, q-p);
+    p = q + 1;
+    Nfound ++;
+  }
+  if (Nfound != Ntext) {
+    fprintf (stderr, "read %d text lines, expected %d\n", Nfound, Ntext);
+  }
+
+  free (textdata);
+  free (overlay);
+
+  image[0].overlay[overnum].Nobjects = Nobjects;
+  image[0].overlay[overnum].active = TRUE;
 
   if (USE_XWINDOW) {
@@ -93,5 +122,4 @@
       }
     }
-    PaintTickmarks (graphic, image);
     XFlush (graphic[0].display);
   }
Index: /trunk/Ohana/src/kapa2/src/LoadPicture.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadPicture.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/LoadPicture.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int LoadPicture () {
+int LoadPicture (int sock) {
 
   Header header;
@@ -12,20 +12,20 @@
   graphic = GetGraphic ();
   section = GetActiveSection();
-  image   = section->image;
+  if (section->image == NULL) {
+    section->image = InitImage ();
+    SetSectionSizes (section);
+  }
+  image = section->image;
   
   KiiSendMessage (sock, "%d", graphic->Npixels);
 
-  fcntl (sock, F_SETFL, !O_NONBLOCK);  
-
   header.Naxes = 2;
-
   KiiScanMessage (sock, "%d %d %d %d %lf %lf", &header.Naxis[0], &header.Naxis[1]);
   KiiScanMessage (sock, "%d %d %d %d %lf %lf", &header.bitpix, &header.unsign, &header.bzero, &header.bscale);
-  KiiScanMessage (sock, "%lf %lf",  &image[0].zero, &image[0].range);
+  KiiScanMessage (sock, "%lf %lf %s",  &image[0].zero, &image[0].range, image[0].name, image[0].file);
   KiiScanMessage (sock, "%lf %lf %d", &image[0].min,  &image[0].max, &header.size);
   KiiScanMessage (sock, "%lf %f %f %f %f", &image[0].coords.crval1, &image[0].coords.crpix1, &image[0].coords.cdelt1, &image[0].coords.pc1_1, &image[0].coords.pc1_2);
   KiiScanMessage (sock, "%lf %f %f %f %f", &image[0].coords.crval2, &image[0].coords.crpix2, &image[0].coords.cdelt2, &image[0].coords.pc2_1, &image[0].coords.pc2_2);
-	  
-  KiiScanMessage (sock, "%s %s %s", image[0].coords.ctype, image[0].file, image[0].buffer_name);
+  KiiScanMessage (sock, "%s", image[0].coords.ctype);
 
   gfits_free_matrix (&image[0].matrix);
@@ -51,4 +51,6 @@
   }
 
+  fcntl (sock, F_SETFL, !O_NONBLOCK);  
+
   if (DEBUG) fprintf (stderr, "read %d bytes\n", image[0].matrix.size);
   /* it it not obvious this condition should kill kii, but ... */
Index: /trunk/Ohana/src/kapa2/src/LoadTextlines.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadTextlines.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/LoadTextlines.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int LoadTextlines () {
+int LoadTextlines (int sock) {
   
   char *string;
@@ -11,7 +11,9 @@
   section = GetActiveSection();
   graph = section->graph;
-  
-  fcntl (sock, F_SETFL, !O_NONBLOCK);  
-  
+    if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
+
   graph[0].Ntextline = MAX (graph[0].Ntextline, 0);
   N = graph[0].Ntextline;
@@ -34,6 +36,4 @@
   strcpy (graph[0].textline[N].text, string);
   free (string);
-
-  fcntl (sock, F_SETFL, O_NONBLOCK);  
   
   string = GetRotFont (&size);
Index: /trunk/Ohana/src/kapa2/src/LoadTickmarks.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadTickmarks.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/LoadTickmarks.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int LoadTickmarks () {
+int LoadTickmarks (int sock) {
   
   char line[129], type[16];
@@ -10,10 +10,13 @@
 
   section = GetActiveSection();
+  if (section->image == NULL) {
+    section->image = InitImage ();
+    SetSectionSizes (section);
+  }
   image   = section->image;
-  fcntl (sock, F_SETFL, !O_NONBLOCK);  
 
   Nobjects = image[0].tickmarks.Nobjects;
   NOBJECTS = Nobjects + 100;
-  REALLOCATE (image[0].tickmarks.objects, Object, NOBJECTS);
+  REALLOCATE (image[0].tickmarks.objects, KiiOverlay, NOBJECTS);
   
   done = FALSE;
@@ -51,16 +54,13 @@
     if (Nobjects >= NOBJECTS) {
       NOBJECTS = Nobjects + 100;
-      REALLOCATE (image[0].tickmarks.objects, Object, NOBJECTS);
+      REALLOCATE (image[0].tickmarks.objects, KiiOverlay, NOBJECTS);
     }
 
   }
 
-  REALLOCATE (image[0].tickmarks.objects, Object, MAX(Nobjects, 1));
+  REALLOCATE (image[0].tickmarks.objects, KiiOverlay, MAX(Nobjects, 1));
   image[0].tickmarks.Nobjects = Nobjects;
 
   if (USE_XWINDOW) Refresh ();
-
-  fcntl (sock, F_SETFL, O_NONBLOCK);  
   return (TRUE);
-  
 }
Index: /trunk/Ohana/src/kapa2/src/PNGit.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PNGit.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/PNGit.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int PNGit () {
+int PNGit (int sock) {
 
   FILE *f;
Index: /trunk/Ohana/src/kapa2/src/PPMit.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PPMit.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/PPMit.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int PPMit () {
+int PPMit (int sock) {
 
   FILE *f;
Index: /trunk/Ohana/src/kapa2/src/PSOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PSOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/PSOverlay.c	(revision 13479)
@@ -31,38 +31,37 @@
     dY = (image[0].overlay[N].objects[i].dy)/expand;
     
-    if (!strcmp (image[0].overlay[N].objects[i].type, "LINE")) {
-      if (((X < Xmin) && (X + dX < Xmin)) || ((X > Xmax) && (X + dX > Xmax)) ||
-	  ((Y < Ymin) && (Y + dY < Ymin)) || ((Y > Ymax) && (Y + dY > Ymax))) {
-	continue;
-      }
-      fprintf (f, " %6.1f %6.1f %6.1f %6.1f L\n", X + extra, Y + extra, (X+dX + extra), (Y-dY + extra));
-      continue;
+    switch (image[0].overlay[N].objects[i].type) {
+      case KII_OVERLAY_LINE:
+	if (((X < Xmin) && (X + dX < Xmin)) || ((X > Xmax) && (X + dX > Xmax)) ||
+	    ((Y < Ymin) && (Y + dY < Ymin)) || ((Y > Ymax) && (Y + dY > Ymax))) {
+	  break;
+	}
+	fprintf (f, " %6.1f %6.1f %6.1f %6.1f L\n", X + extra, Y + extra, (X+dX + extra), (Y-dY + extra));
+	break;
+      case KII_OVERLAY_TEXT:
+	if (((X < Xmin) && (X + dX < Xmin)) || ((X > Xmax) && (X + dX > Xmax)) ||
+	    ((Y < Ymin) && (Y + dY < Ymin)) || ((Y > Ymax) && (Y + dY > Ymax))) {
+	  break;
+	}
+	fprintf (f, "(%s) %6.1f %6.1f T\n", image[0].overlay[N].objects[i].text, X + extra, Y + extra); 
+	break;
+      case KII_OVERLAY_BOX:
+	if (((X - 0.5*dX < Xmin) && (X + 0.5*dX < Xmin)) || ((X - 0.5*dX > Xmax) && (X + 0.5*dX > Xmax)) ||
+	    ((Y - 0.5*dY < Ymin) && (Y + 0.5*dY < Ymin)) || ((Y - 0.5*dY > Ymax) && (Y + 0.5*dY > Ymax))) {
+	  break;
+	}
+	fprintf (f, " %6.1f %6.1f %6.1f %6.1f B\n", (dX + 2*extra), (dY + 2*extra), (X - 0.5*dX - extra), (Y - 0.5*dY - extra));
+	break;
+      case KII_OVERLAY_CIRCLE:
+	if (((X - dX < Xmin) && (X + dX < Xmin)) || ((X - dX > Xmax) && (X + dX > Xmax)) ||
+	    ((Y - dY < Ymin) && (Y + dY < Ymin)) || ((Y - dY > Ymax) && (Y + dY > Ymax))) {
+	  break;
+	}
+	fprintf (f, " %6.1f %6.1f %6.1f C\n", X, Y, fabs(dX + extra));
+	break;
+      default:
+	fprintf (stderr, "skipping unknown object\n");
+	break;
     }
-    if (!strcmp (image[0].overlay[N].objects[i].type, "TEXT")) {
-      if (((X < Xmin) && (X + dX < Xmin)) || ((X > Xmax) && (X + dX > Xmax)) ||
-	  ((Y < Ymin) && (Y + dY < Ymin)) || ((Y > Ymax) && (Y + dY > Ymax))) {
-	continue;
-      }
-      fprintf (f, "(%s) %6.1f %6.1f T\n", image[0].overlay[N].objects[i].text, X + extra, Y + extra); 
-      continue;
-    }
-    if (!strcmp (image[0].overlay[N].objects[i].type, "BOX")) {
-      if (((X - 0.5*dX < Xmin) && (X + 0.5*dX < Xmin)) || ((X - 0.5*dX > Xmax) && (X + 0.5*dX > Xmax)) ||
-	  ((Y - 0.5*dY < Ymin) && (Y + 0.5*dY < Ymin)) || ((Y - 0.5*dY > Ymax) && (Y + 0.5*dY > Ymax))) {
-	continue;
-      }
-      fprintf (f, " %6.1f %6.1f %6.1f %6.1f B\n", (dX + 2*extra), (dY + 2*extra), (X - 0.5*dX - extra), (Y - 0.5*dY - extra));
-      continue;
-    }
-    if (!strcmp (image[0].overlay[N].objects[i].type, "CIRCLE")) {
-      if (((X - dX < Xmin) && (X + dX < Xmin)) || ((X - dX > Xmax) && (X + dX > Xmax)) ||
-	  ((Y - dY < Ymin) && (Y + dY < Ymin)) || ((Y - dY > Ymax) && (Y + dY > Ymax))) {
-	continue;
-      }
-      fprintf (f, " %6.1f %6.1f %6.1f C\n", X, Y, fabs(dX + extra));
-      continue;
-    }
-    fprintf (stderr, "don't know %s, skipping\n", image[0].overlay[N].objects[i].type);
   }
-  
 }
Index: /trunk/Ohana/src/kapa2/src/PSit.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PSit.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/PSit.c	(revision 13479)
@@ -6,5 +6,5 @@
 static Graphic *graphic;
 
-int PScommand () {
+int PScommand (int sock) {
 
   int status, scaleMode, pageMode;
Index: /trunk/Ohana/src/kapa2/src/PaintOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PaintOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/PaintOverlay.c	(revision 13479)
@@ -41,25 +41,25 @@
        for a BOX (x, y) is the center, (dx, dy) is the width */
 
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "LINE")) {
-      XDrawLine (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, (X+dX), (Y+dY));
-      continue;
+    switch (image[0].overlay[N].objects[i].type) {
+      case KII_OVERLAY_LINE:
+	XDrawLine (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, (X+dX), (Y+dY));
+	break;
+      case KII_OVERLAY_TEXT:
+	XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, image[0].overlay[N].objects[i].text, strlen(image[0].overlay[N].objects[i].text));
+	break;
+      case KII_OVERLAY_BOX:
+	dx = MAX (abs(dX),2) / 2;
+	dy = MAX (abs(dY),2) / 2;
+	XDrawRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, (X - dx), (Y - dy), 2*dx, 2*dy);
+	break;
+      case KII_OVERLAY_CIRCLE:
+	dx = MAX (abs(dX),2);
+	dy = MAX (abs(dY),2);
+	XDrawArc (graphic[0].display, graphic[0].window, graphic[0].gc, (X - dx), (Y - dy), 2*dx, 2*dy, 0, 23040);
+	break;
+      default:
+	fprintf (stderr, "skipping unknown object\n");
+	break;
     }
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "TEXT")) {
-      XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, image[0].overlay[N].objects[i].text, strlen(image[0].overlay[N].objects[i].text));
-      continue;
-    }
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "BOX")) {
-      dx = MAX (abs(dX),2) / 2;
-      dy = MAX (abs(dY),2) / 2;
-      XDrawRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, (X - dx), (Y - dy), 2*dx, 2*dy);
-       continue;
-    }
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "CIRCLE")) {
-      dx = MAX (abs(dX),2);
-      dy = MAX (abs(dY),2);
-      XDrawArc (graphic[0].display, graphic[0].window, graphic[0].gc, (X - dx), (Y - dy), 2*dx, 2*dy, 0, 23040);
-      continue;
-    }
-    fprintf (stderr, "don't know %s, skipping (PO)\n", image[0].overlay[N].objects[i].type);
   }
   
Index: /trunk/Ohana/src/kapa2/src/PaintTickmarks.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PaintTickmarks.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/PaintTickmarks.c	(revision 13479)
@@ -22,35 +22,33 @@
     dY = image[0].tickmarks.objects[i].dy * Yrange;
 
-    if (!strcmp (image[0].tickmarks.objects[i].type, "LINE")) {
-      XDrawLine (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, (X+dX), (Y+dY));
-      continue;
+    switch (image[0].overlay[0].objects[i].type) {
+      case KII_OVERLAY_LINE:
+	XDrawLine (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, (X+dX), (Y+dY));
+	break;
+      case KII_OVERLAY_TEXT:
+	if (image[0].tickmarks.objects[i].dy == 0) {
+	    XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].back);
+	    XFillRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y-11, 6*strlen(image[0].tickmarks.objects[i].text), 11); 
+	    XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
+	    XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, image[0].tickmarks.objects[i].text, strlen(image[0].tickmarks.objects[i].text));
+	}
+	if (image[0].tickmarks.objects[i].dy == 90) {
+	    XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].back);
+	    XFillRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y-6*strlen(image[0].tickmarks.objects[i].text), 11, 6*strlen(image[0].tickmarks.objects[i].text)); 
+	    XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
+	    /* XDrawRotString (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, image[0].tickmarks.objects[i].text, strlen(image[0].tickmarks.objects[i].text)); */
+	}
+	break;
+      case KII_OVERLAY_BOX:
+	XDrawRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, (int)(X - 0.5*dX), (int)(Y - 0.5*dY), abs(dX), abs(dY));
+	break;
+      case KII_OVERLAY_CIRCLE:
+	XDrawArc (graphic[0].display, graphic[0].window, graphic[0].gc, X - dX, Y - dY, abs(2*dX), abs(2*dY), 0, 23040);
+	break;
+      default:
+	fprintf (stderr, "skipping unknown object\n");
+	break;
     }
-    if (!strcmp (image[0].tickmarks.objects[i].type, "TEXT")) {
-      if (image[0].tickmarks.objects[i].dy == 0) {
-	XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].back);
-	XFillRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y-11, 6*strlen(image[0].tickmarks.objects[i].text), 11); 
-	XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
-	XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, image[0].tickmarks.objects[i].text, strlen(image[0].tickmarks.objects[i].text));
-      }
-      if (image[0].tickmarks.objects[i].dy == 90) {
-	XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].back);
-	XFillRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y-6*strlen(image[0].tickmarks.objects[i].text), 11, 6*strlen(image[0].tickmarks.objects[i].text)); 
-	XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
-	/* XDrawRotString (graphic[0].display, graphic[0].window, graphic[0].gc, X, Y, image[0].tickmarks.objects[i].text, strlen(image[0].tickmarks.objects[i].text)); */
-      }
-      continue;
-    }
-    if (!strcmp (image[0].tickmarks.objects[i].type, "BOX")) {
-      XDrawRectangle (graphic[0].display, graphic[0].window, graphic[0].gc, (int)(X - 0.5*dX), (int)(Y - 0.5*dY), abs(dX), abs(dY));
-       continue;
-    }
-    if (!strcmp (image[0].tickmarks.objects[i].type, "CIRCLE")) {
-      XDrawArc (graphic[0].display, graphic[0].window, graphic[0].gc, X - dX, Y - dY, abs(2*dX), abs(2*dY), 0, 23040);
-      continue;
-    }
-    fprintf (stderr, "don't know %s, skipping (PO)\n", image[0].tickmarks.objects[i].type);
   }
-  
   XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
-
 }
Index: /trunk/Ohana/src/kapa2/src/Reconfig.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Reconfig.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Reconfig.c	(revision 13479)
@@ -25,6 +25,5 @@
   for (i = 0; i < Nsection; i++) {
       section = GetSectionByNumber (i);
-      SetGraphSize (section);
-      SetImageSize (section);
+      SetSectionSizes (section);
   }
 
Index: /trunk/Ohana/src/kapa2/src/Refresh.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Refresh.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Refresh.c	(revision 13479)
@@ -21,6 +21,6 @@
   for (i = 0; i < Nsection; i++) {
       section = GetSectionByNumber (i);
+      DrawImage (section->image);
       DrawGraph (section->graph);
-      DrawImage (section->image);
   }
 
Index: /trunk/Ohana/src/kapa2/src/Remap16.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Remap16.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Remap16.c	(revision 13479)
@@ -1,4 +1,14 @@
 # include "Ximage.h"
-# define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void Remap16 (Graphic *graphic, KapaImageWidget *image, Matrix *matrix) {
@@ -7,18 +17,18 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, Rx, Ry, X, Y;
   int expand_in, expand_out;
   unsigned char *out_pix, *out_pix2, *data;
-  unsigned char *in_pix,  *in_pix2;
-  unsigned char pixel1[256], pixel2[256], pixel3[256];
+  float *imdata, *in_pix, *in_pix2;
+  unsigned char pixel1[256], pixel2[256];
   unsigned char pixvalue1, pixvalue2;
   unsigned long back;
   unsigned char back1, back2;
 
+  // local array for pixel values (is this working??)
   for (i = 0; i < 256; i++) { /* set up pixel array */
-    pixel1[i] = 0x0000ff &  graphic[0].cmap[i].pixel;
-    pixel2[i] = 0x0000ff & (graphic[0].cmap[i].pixel >> 8);
-    pixel3[i] = 0x0000ff & (graphic[0].cmap[i].pixel >> 16);
+    pixel1[i] = 0x00ff &  graphic[0].cmap[i].pixel;
+    pixel2[i] = 0x00ff & (graphic[0].cmap[i].pixel >> 8);
   }
   back = graphic[0].back;
@@ -26,4 +36,15 @@
   back2 = 0x00ff & (back >> 8);
 
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
+
+  // set up expansions
   expand = expand_in = expand_out = 1.0;
   if (image[0].expand == 0) /* set up expansions */
@@ -40,4 +61,5 @@
   }
 
+  // define the image boundaries
   dx = image[0].picture.dx;
   dy = image[0].picture.dy;
@@ -76,5 +98,6 @@
 
   data = out_pix = (unsigned char *) image[0].picture.data;
-  in_pix  = (unsigned char *) (matrix[0].buffer) + DX*(int)MAX(Y,0) + (int)MAX(X,0);
+  imdata  = (float *) matrix[0].buffer;
+  in_pix  = &imdata[DX*(int)MAX(Y,0) + (int)MAX(X,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -105,12 +128,14 @@
     if (expand_out == 1) {
       for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix+=2) {
-	out_pix[0] = pixel1[*in_pix2];
-	out_pix[1] = pixel2[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	out_pix[0] = pixel1[pixelN];
+	out_pix[1] = pixel2[pixelN];
       }
     }
     else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= 2*expand_out) { 
-	pixvalue1 = pixel1[*in_pix2];
-	pixvalue2 = pixel2[*in_pix2];
+	pixelN    = PixelLookup(*in_pix2);
+	pixvalue1 = pixel1[pixelN];
+	pixvalue2 = pixel2[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=2*(dx-expand_out)) {
Index: /trunk/Ohana/src/kapa2/src/Remap24.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Remap24.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Remap24.c	(revision 13479)
@@ -1,4 +1,14 @@
 # include "Ximage.h"
-# define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void Remap24 (Graphic *graphic, KapaImageWidget *image, Matrix *matrix) {
@@ -7,9 +17,9 @@
   int i_start, i_end, j_start, j_end;
   int dropback, extra;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, Rx, Ry, X, Y;
   int expand_in, expand_out;
   unsigned char *out_pix, *out_pix2, *data;
-  unsigned char *in_pix,  *in_pix2;
+  float *imdata, *in_pix, *in_pix2;
   unsigned char pixel1[256], pixel2[256], pixel3[256];
   unsigned char pixvalue1, pixvalue2, pixvalue3;
@@ -17,4 +27,5 @@
   unsigned char back1, back2, back3;
 
+  // local arrays for pixel values
   for (i = 0; i < 256; i++) { /* set up pixel array */
     pixel1[i] = 0x0000ff &  graphic[0].cmap[i].pixel;
@@ -27,4 +38,15 @@
   back3 = 0x0000ff & (back >> 16);
 
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
+
+  // set up expansions
   expand = expand_in = expand_out = 1.0;
   if (image[0].expand == 0) /* set up expansions */
@@ -78,5 +100,6 @@
 
   data = out_pix = (unsigned char *) image[0].picture.data;
-  in_pix  = (unsigned char *) (matrix[0].buffer) + DX*(int)MAX(Y,0) + (int)MAX(X,0);
+  imdata  = (float *) matrix[0].buffer;
+  in_pix  = &imdata[DX*(int)MAX(Y,0) + (int)MAX(X,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -110,14 +133,15 @@
     if (expand_out == 1) {
       for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix+=3) {
-	out_pix[0] = pixel1[*in_pix2];
-	out_pix[1] = pixel2[*in_pix2];
-	out_pix[2] = pixel3[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	out_pix[0] = pixel1[pixelN];
+	out_pix[1] = pixel2[pixelN];
+	out_pix[2] = pixel3[pixelN];
       }
-    }
-    else {
+    } else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= 3*expand_out) { 
-	pixvalue1 = pixel1[*in_pix2];
-	pixvalue2 = pixel2[*in_pix2];
-	pixvalue3 = pixel3[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	pixvalue1 = pixel1[pixelN];
+	pixvalue2 = pixel2[pixelN];
+	pixvalue3 = pixel3[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=3*(dx-expand_out)+extra) {
Index: /trunk/Ohana/src/kapa2/src/Remap32.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Remap32.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Remap32.c	(revision 13479)
@@ -1,4 +1,14 @@
 # include "Ximage.h"
-# define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void Remap32 (Graphic *graphic, KapaImageWidget *image, Matrix *matrix) {
@@ -7,19 +17,31 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, Rx, Ry, X, Y;
   int expand_in, expand_out;
   unsigned int *out_pix, *out_pix2;
-  unsigned char *in_pix,  *in_pix2;
+  float *imdata, *in_pix, *in_pix2;
   unsigned long pixel[256], pixvalue;
   unsigned long back;
 
-  for (i = 0; i < 256; i++) { /* set up pixel array */
+  // local array for pixel values
+  for (i = 0; i < 256; i++) { 
     pixel[i] = graphic[0].cmap[i].pixel;
   }
   back = graphic[0].back;
 
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
+
+  // set up expansions
   expand = expand_in = expand_out = 1.0;
-  if (image[0].expand == 0) /* set up expansions */
+  if (image[0].expand == 0) 
     image[0].expand = 1;
   if (image[0].expand > 0) {
@@ -34,4 +56,5 @@
   }
 
+  // define the image boundaries
   dx = image[0].picture.dx;
   dy = image[0].picture.dy;
@@ -69,5 +92,6 @@
 
   out_pix = (unsigned int *) image[0].picture.data;
-  in_pix  = (unsigned char *) (matrix[0].buffer) + DX*(int)MAX(Y,0) + (int)MAX(X,0);
+  imdata  = (float *) matrix[0].buffer;
+  in_pix  = &imdata[DX*(int)MAX(Y,0) + (int)MAX(X,0)];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -92,11 +116,12 @@
     if (expand_out == 1) {
       for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix++) {
-	*out_pix = pixel[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	*out_pix = pixel[pixelN];
       }
-      /* *out_pix = *(pixel + *in_pix2);  */
     }
     else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= expand_out) { 
-	pixvalue = pixel[*in_pix2];
+	pixelN   = PixelLookup(*in_pix2);
+	pixvalue = pixel[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=(dx-expand_out)) {
Index: /trunk/Ohana/src/kapa2/src/Remap8.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Remap8.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Remap8.c	(revision 13479)
@@ -1,4 +1,14 @@
 # include "Ximage.h"
-# define FRAC(a) ((a) - (int)(a))
+
+static float slope = 1.0;
+static float start = 0.0;
+static int MaxValue = 255;
+
+// XXX inline this if needed
+static int PixelLookup(float value) {
+  int out;
+  out = MIN (MAX (slope * value - start, 0), MaxValue);
+  return (out);
+}
 
 void Remap8 (Graphic *graphic, KapaImageWidget *image, Matrix *matrix) {
@@ -7,17 +17,29 @@
   int i_start, i_end, j_start, j_end;
   int dropback;  /* this is a bit of a kludge... */
-  int dx, dy, DX, DY;
+  int dx, dy, DX, DY, pixelN;
   double expand, Rx, Ry, X, Y;
   int expand_in, expand_out;
   unsigned char *out_pix, *out_pix2;
-  unsigned char *in_pix,  *in_pix2;
+  float *imdata, *in_pix,  *in_pix2;
   unsigned long pixel[256], pixvalue;
   unsigned long back;
 
-  for (i = 0; i < 256; i++) { /* set up pixel array */
+  // local array for pixel values
+  for (i = 0; i < 256; i++) {
     pixel[i] = graphic[0].cmap[i].pixel;
   }
   back = graphic[0].back;
 
+  // define the color transform parameters
+  MaxValue = graphic[0].Npixels - 1;
+  if (image[0].range != 0.0) {
+    slope = graphic[0].Npixels / image[0].range;
+    start = graphic[0].Npixels * image[0].zero / image[0].range;
+  } else {
+    slope = 1.0;
+    start = image[0].zero;
+  }
+
+  // set up expansions
   expand = expand_in = expand_out = 1.0;
   if (image[0].expand == 0) /* set up expansions */
@@ -34,8 +56,10 @@
   }
 
+  // define the image boundaries
   dx = image[0].picture.dx;
   dy = image[0].picture.dy;
   DX = matrix[0].Naxis[0];
   DY = matrix[0].Naxis[1];
+
   /* X,Y are the image coordinates of the first image pixel */
   X = MAX(0.5*(DX - dx*expand) - image[0].X, 0);
@@ -69,5 +93,6 @@
 
   out_pix = (unsigned char *) image[0].picture.data;
-  in_pix  = (unsigned char *) matrix[0].buffer + DX*(int)MAX(Y,0) + (int)MAX(X,0);
+  imdata  = (float *) matrix[0].buffer;
+  in_pix  = &imdata[(int)(DX*(int)MAX(Y,0) + (int)MAX(X,0))];
 
   /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
@@ -92,11 +117,11 @@
     if (expand_out == 1) {
       for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix++) {
-	*out_pix = pixel[*in_pix2];
+	pixelN = PixelLookup(*in_pix2);
+	*out_pix = pixel[pixelN];
       }
-      /* *out_pix = *(pixel + *in_pix2);  */
-    }
-    else {
+    } else {
       for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= expand_out) { 
-	pixvalue = pixel[*in_pix2];
+	pixelN   = PixelLookup(*in_pix2);
+	pixvalue = pixel[pixelN];
 	out_pix2 = out_pix;
 	for (jj = 0; jj < expand_out; jj++, out_pix2+=(dx-expand_out)) {
Index: /trunk/Ohana/src/kapa2/src/Resize.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Resize.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Resize.c	(revision 13479)
@@ -2,5 +2,5 @@
 
 // XXX Should there be a base command + KiiMessage command?
-int Resize () {
+int Resize (int sock) {
  
   int i, Nsection;
@@ -30,6 +30,5 @@
   for (i = 0; i < Nsection; i++) {
       section = GetSectionByNumber (i);
-      SetGraphSize (section);
-      SetImageSize (section);
+      SetSectionSizes (section);
   }
 
Index: /trunk/Ohana/src/kapa2/src/SaveOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SaveOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/SaveOverlay.c	(revision 13479)
@@ -1,8 +1,8 @@
 # include "Ximage.h"
 
-int SaveOverlay () {
+int SaveOverlay (int sock) {
 
   int i, N;
-  char filename[256];
+  char filename[256], *type;
   FILE *f;
   Section *section;
@@ -11,4 +11,5 @@
   section = GetActiveSection();
   image   = section->image;
+  if (image == NULL) return (TRUE);
 
   KiiScanMessage (sock, "%*s %d %s", &N, filename);
@@ -21,6 +22,8 @@
 
   for (i = 0; i < image[0].overlay[N].Nobjects; i++) {
+    type = KiiOverlayTypeByNumber (image[0].overlay[N].objects[i].type);
+    if (type == NULL) continue;
     fprintf (f, "%s %lf %lf %lf %lf\n", 
-	     image[0].overlay[N].objects[i].type,
+	     type,
 	     image[0].overlay[N].objects[i].x,
 	     image[0].overlay[N].objects[i].y,
@@ -31,2 +34,6 @@
   return (TRUE);
 }
+
+/* this is asymmetric with LoadOverlay.c.  In that case, the client reads the file and sends
+ * the overlay objects to kapa.  In this case, kapa writes the file directly... 
+ */
Index: /trunk/Ohana/src/kapa2/src/Sections.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Sections.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/Sections.c	(revision 13479)
@@ -24,7 +24,7 @@
 
   if (section == NULL) return;
-  if (section[0].graph != NULL) FreeGraph (section[0].graph);
-  // if (section[0].image != NULL) FreeImage (section[0].image);
-  if (section[0].name  != NULL) free (section[0].name);
+  FreeGraph (section[0].graph);
+  FreeImage (section[0].image);
+  FREE (section[0].name);
   free (section);
 }
@@ -42,6 +42,4 @@
 }
 
-// XXX how to set the section type?
-// XXX set active section on Add?
 Section *AddSection (char *name, float x, float y, float dx, float dy) {
 
@@ -116,5 +114,5 @@
 }
 
-int ListSection () {
+int ListSection (int sock) {
   
   int i, ThisSection;
@@ -149,2 +147,72 @@
   return (TRUE);
 }
+
+void SetSectionSizes (Section *section) {
+
+    SetGraphSize (section);
+    SetImageSize (section);
+    return;
+}
+
+// return TRUE even for nonsense cases to avoid quitting kapa
+int MoveSection (int sock) {
+
+  int i, N;
+  char name[128];
+  char direction[16];
+  Section *tmpSection = NULL;
+
+  KiiScanMessage (sock, "%s %s", name, direction);
+  
+  N = GetSectionByName (name);
+  if (N < 0) {
+    fprintf (stderr, "section %s not found\n", name);
+    return (TRUE);
+  }
+
+  if (!strcasecmp (direction, "up")) {
+      if (N < 0) return (TRUE);
+      if (N > Nsections - 2) return (TRUE);
+      tmpSection = sections[N];
+      sections[N] = sections[N+1];
+      sections[N+1] = tmpSection;
+      Refresh (1);
+      return (TRUE);
+  }
+
+  if (!strcasecmp (direction, "down")) {
+      if (N < 1) return (TRUE);
+      if (N > Nsections - 1) return (TRUE);
+      tmpSection = sections[N];
+      sections[N] = sections[N-1];
+      sections[N-1] = tmpSection;
+      Refresh (1);
+      return (TRUE);
+  }
+
+  if (!strcasecmp (direction, "top")) {
+      if (N < 0) return (TRUE);
+      if (N > Nsections - 2) return (TRUE);
+      tmpSection = sections[N];
+      for (i = N; i < Nsections - 1; i++) {
+	sections[i] = sections[i+1];
+      }
+      sections[i] = tmpSection;
+      Refresh (1);
+      return (TRUE);
+  }
+
+  if (!strcasecmp (direction, "bottom")) {
+      if (N < 1) return (TRUE);
+      if (N > Nsections - 1) return (TRUE);
+      tmpSection = sections[N];
+      for (i = N; i >= 1; i--) {
+	sections[i] = sections[i-1];
+      }
+      sections[i] = tmpSection;
+      Refresh (1);
+      return (TRUE);
+  }
+  fprintf (stderr, "unknown direction %s for MoveSection\n", direction);
+  return (TRUE);
+}
Index: /trunk/Ohana/src/kapa2/src/SetFont.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetFont.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/SetFont.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int SetFont () {
+int SetFont (int sock) {
   
   char name[64];
Index: /trunk/Ohana/src/kapa2/src/SetGraphData.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetGraphData.c	(revision 13479)
+++ /trunk/Ohana/src/kapa2/src/SetGraphData.c	(revision 13479)
@@ -0,0 +1,119 @@
+# include "Ximage.h"
+
+int SetGraphData (int sock) {
+  
+  int i;
+  double xmin, xmax, ymin, ymax;
+  Graphic *graphic;
+  Section *section;
+  KapaGraphWidget *graph;
+
+  graphic = GetGraphic();
+
+  section = GetActiveSection();
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
+  graph = section->graph;
+  
+  // get graph data from client 
+  KiiScanMessage (sock, "%d %d %d %d %d %d %lf %lf", 
+		  &graph[0].data.style, 
+		  &graph[0].data.ptype, 
+		  &graph[0].data.ltype, 
+		  &graph[0].data.etype, 
+		  &graph[0].data.ebar, 
+		  &graph[0].data.color, 
+		  &graph[0].data.lweight, 
+		  &graph[0].data.size);
+
+  KiiScanMessage (sock, "%lf %lf %lf %lf", 
+		  &graph[0].data.xmin, 
+		  &graph[0].data.xmax, 
+		  &graph[0].data.ymin, 
+		  &graph[0].data.ymax);
+
+  KiiScanMessage (sock, "%f %f %f %f", 
+		  &graph[0].data.coords.pc1_1, &graph[0].data.coords.pc2_2,
+		  &graph[0].data.coords.pc1_2, &graph[0].data.coords.pc2_1);
+
+  KiiScanMessage (sock, "%d %d %s", 
+		  &graph[0].data.flipeast, &graph[0].data.flipnorth,
+		  graph[0].data.coords.ctype);
+
+  KiiScanMessage (sock, "%lf %lf %f %f %f %f", 
+		  &graph[0].data.coords.crval1,
+		  &graph[0].data.coords.crval2,
+		  &graph[0].data.coords.crpix1,
+		  &graph[0].data.coords.crpix2,
+		  &graph[0].data.coords.cdelt1,
+		  &graph[0].data.coords.cdelt2);
+
+
+
+  xmin = graph[0].data.xmin;
+  xmax = graph[0].data.xmax;
+  ymin = graph[0].data.ymin;
+  ymax = graph[0].data.ymax;
+
+  // XXX there are now two things which track the graph limits
+  // make sure these are kept in sync (or drop one!)
+  graph[0].axis[2].min = graph[0].axis[0].min = xmin;
+  graph[0].axis[2].max = graph[0].axis[0].max = xmax;
+  graph[0].axis[3].min = graph[0].axis[1].min = ymin; 
+  graph[0].axis[3].max = graph[0].axis[1].max = ymax;
+  
+  for (i = 0; i < graph[0].Nobjects; i++) {
+    graph[0].objects[i].x0 = xmin;
+    graph[0].objects[i].x1 = xmax;
+    graph[0].objects[i].y0 = ymin;
+    graph[0].objects[i].y1 = ymax;
+  }
+
+  if (USE_XWINDOW) XClearWindow (graphic->display, graphic->window);
+  Refresh (1);
+
+  return (TRUE);  
+}
+
+int GetGraphData (int sock) {
+  
+  Section *section;
+  KapaGraphWidget *graph;
+
+  section = GetActiveSection();
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
+  graph = section->graph;
+
+  KiiSendMessage (sock, "%8d %d %d %d %d %d %f %f", 
+		  graph[0].data.style, 
+		  graph[0].data.ptype, graph[0].data.ltype, 
+		  graph[0].data.etype, graph[0].data.ebar, graph[0].data.color, 
+		  graph[0].data.lweight, graph[0].data.size);
+
+  KiiSendMessage (sock, "%g %g %g %g", 
+		  graph[0].data.xmin, graph[0].data.xmax, 
+		  graph[0].data.ymin, graph[0].data.ymax);
+
+  KiiSendMessage (sock, "%g %g %g %g", 
+		  graph[0].data.coords.pc1_1, graph[0].data.coords.pc2_2,
+		  graph[0].data.coords.pc1_2, graph[0].data.coords.pc2_1);
+
+  KiiSendMessage (sock, "%d %d %s", 
+		  graph[0].data.flipeast, graph[0].data.flipnorth,
+		  graph[0].data.coords.ctype);
+
+  KiiSendMessage (sock, "%g %g %g %g %g %g", 
+		  graph[0].data.coords.crval1,
+		  graph[0].data.coords.crval2,
+		  graph[0].data.coords.crpix1,
+		  graph[0].data.coords.crpix2,
+		  graph[0].data.coords.cdelt1,
+		  graph[0].data.coords.cdelt2);
+
+  return (TRUE);
+}
Index: /trunk/Ohana/src/kapa2/src/SetGraphSize.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetGraphSize.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/SetGraphSize.c	(revision 13479)
@@ -7,4 +7,5 @@
 
   int fontsize, bump, Nc;
+  int textpad, textdY, WdY; 
   double PADx, PADy, Dx, Dy;
   double PXm, PXp, PYm, PYp;
@@ -32,9 +33,33 @@
   PYp = (graph[0].axis[2].islabel) ? 4*fontsize : 0;
  
-  /* size of the graph in Xwindow coordinates */
+  /* basic size of the graph in Xwindow coordinates */
   X0 = PADx + PXm + (Dx * section[0].x);
   Y0 = PADy + PYm + (Dy * section[0].y);
   dX = (Dx * section[0].dx) - PXp - PXm;
   dY = (Dy * section[0].dy) - PYp - PYm;
+
+  // if we are tied to an image, make mods as needed
+  if (section->image) {
+    textpad = graphic[0].font[0].ascent;
+    textdY = 6*textpad + 7*PAD1;
+    WdY = MAX (ZOOM_Y, textdY + 2*BUTTON_HEIGHT + PAD1);
+
+    switch (section->image->location) {
+      case 1:
+	Y0 = graphic[0].dy * section[0].y + 2*PAD1 + WdY + 2; // tied to image in Y
+	dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD + 1;
+	break;
+      case 3:
+	dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD - PADy - PYm;
+	break;
+      case 2:
+	X0 = graphic[0].dx * section[0].x  + 2*PAD1 + ZOOM_X;
+	dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X;
+	break;
+      case 4:
+	dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X - PADx - PXm;
+	break;
+    }
+  }
 
   /* define locations of coordinate axes */
Index: /trunk/Ohana/src/kapa2/src/SetGraphStyle.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetGraphStyle.c	(revision 13479)
+++ /trunk/Ohana/src/kapa2/src/SetGraphStyle.c	(revision 13479)
@@ -0,0 +1,84 @@
+# include "Ximage.h"
+
+int SetGraphStyle (int sock) {
+  
+  int i;
+  double xmin, xmax, ymin, ymax;
+  Graphic *graphic;
+  Section *section;
+  KapaGraphWidget *graph;
+
+  graphic = GetGraphic();
+
+  section = GetActiveSection();
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
+  graph = section->graph;
+  
+  // get graph style from client 
+  KiiScanMessage (sock, "%d %d %d %d %d %d %lf %lf", 
+		  &graph[0].style.style, 
+		  &graph[0].style.ptype, 
+		  &graph[0].style.ltype, 
+		  &graph[0].style.etype, 
+		  &graph[0].style.ebar, 
+		  &graph[0].style.color, 
+		  &graph[0].style.lweight, 
+		  &graph[0].style.size);
+
+  KiiScanMessage (sock, "%lf %lf %lf %lf", 
+		  &graph[0].style.xmin, 
+		  &graph[0].style.xmax, 
+		  &graph[0].style.ymin, 
+		  &graph[0].style.ymax);
+
+  xmin = graph[0].style.xmin;
+  xmax = graph[0].style.xmax;
+  ymin = graph[0].style.ymin;
+  ymax = graph[0].style.ymax;
+
+  // XXX there are now two things which track the graph limits
+  // make sure these are kept in sync (or drop one!)
+  graph[0].axis[2].min = graph[0].axis[0].min = xmin;
+  graph[0].axis[2].max = graph[0].axis[0].max = xmax;
+  graph[0].axis[3].min = graph[0].axis[1].min = ymin; 
+  graph[0].axis[3].max = graph[0].axis[1].max = ymax;
+  
+  for (i = 0; i < graph[0].Nobjects; i++) {
+    graph[0].objects[i].x0 = xmin;
+    graph[0].objects[i].x1 = xmax;
+    graph[0].objects[i].y0 = ymin;
+    graph[0].objects[i].y1 = ymax;
+  }
+
+  if (USE_XWINDOW) XClearWindow (graphic->display, graphic->window);
+  Refresh (1);
+
+  return (TRUE);  
+}
+
+int GetGraphStyle (int sock) {
+  
+  Section *section;
+  KapaGraphWidget *graph;
+
+  section = GetActiveSection();
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
+  graph = section->graph;
+
+  KiiSendMessage (sock, "%8d %d %d %d %d %d %f %f", 
+		  graph[0].style.style, 
+		  graph[0].style.ptype, graph[0].style.ltype, 
+		  graph[0].style.etype, graph[0].style.ebar, graph[0].style.color, 
+		  graph[0].style.lweight, graph[0].style.size);
+  KiiSendMessage (sock, "%g %g %g %g", 
+		  graph[0].style.xmin, graph[0].style.xmax, 
+		  graph[0].style.ymin, graph[0].style.ymax);
+
+  return (TRUE);
+}
Index: /trunk/Ohana/src/kapa2/src/SetImageData.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetImageData.c	(revision 13479)
+++ /trunk/Ohana/src/kapa2/src/SetImageData.c	(revision 13479)
@@ -0,0 +1,53 @@
+# include "Ximage.h"
+
+int SetImageData (int sock) {
+  
+  int i;
+  double xmin, xmax, ymin, ymax;
+  Graphic *graphic;
+  Section *section;
+  KapaImageWidget *image;
+
+  graphic = GetGraphic();
+
+  section = GetActiveSection();
+  if (section->image == NULL) {
+    section->image = InitImage ();
+    SetSectionSizes (section);
+  }
+  image = section->image;
+  
+  // get image data from client 
+  KiiScanMessage (sock, "%lf %lf %s", 
+		  &image[0].zero, 
+		  &image[0].range, 
+		  image[0].name, 
+		  image[0].file);
+
+  // XXX when we go to 32bit, this should remap the image
+  // if (USE_XWINDOW) XClearWindow (graphic->display, graphic->window);
+  // Refresh (1);
+
+  return (TRUE);  
+}
+
+int GetImageData (int sock) {
+  
+  Section *section;
+  KapaImageWidget *image;
+
+  section = GetActiveSection();
+  if (section->image == NULL) {
+    section->image = InitImage ();
+    SetSectionSizes (section);
+  }
+  image = section->image;
+
+  KiiSendMessage (sock, "%g %g %s %s", 
+		  image[0].zero,
+		  image[0].range,
+		  image[0].name,
+		  image[0].file);
+
+  return (TRUE);
+}
Index: /trunk/Ohana/src/kapa2/src/SetImageSize.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetImageSize.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/SetImageSize.c	(revision 13479)
@@ -7,5 +7,8 @@
 void SetImageSize (Section *section) {
 
+  int Xs, Ys, Xe, Ye, dX, dY;
+  int textpad, textdY, WdY; 
   KapaImageWidget *image;
+  KapaGraphWidget *graph;
   Graphic *graphic;
 
@@ -13,57 +16,299 @@
   image = section->image;
   if (image == NULL) return;
+  graph = section->graph;
 
   graphic = GetGraphic ();
 
-  image[0].cmapbar.dx = graphic[0].dx - 2*PAD1; 
-  image[0].cmapbar.dy = COLORPAD;
-  image[0].cmapbar.x = PAD1;
-  image[0].cmapbar.y = PAD1;
-
-  image[0].zoom.dx = ZOOM_X; 
-  image[0].zoom.dy = ZOOM_Y;
-  image[0].zoom.x = graphic[0].dx - PAD1 - ZOOM_X;
-  image[0].zoom.y = image[0].cmapbar.y + image[0].cmapbar.dy + PAD2;
-
-  image[0].picture.dx = image[0].zoom.x - 2*PAD1 - 25; 
-  image[0].picture.dy = graphic[0].dy - 2*PAD1 - PAD2 - COLORPAD - 25;
-  image[0].picture.x = PAD1 + 25;
-  image[0].picture.y = PAD1 + PAD2 + COLORPAD;
-
-  /** everything below is tied in x-dir to the zoom box **/
-  image[0].text_x = image[0].zoom.x;
-  image[0].text_y = image[0].zoom.y + image[0].zoom.dy + PAD2;
-
-  /*  image[0].PS_button.y = graphic[0].dy - BUTTON_HEIGHT - PAD1; */
-  image[0].PS_button.x = image[0].zoom.x + 5;
-  image[0].PS_button.y = 2*ZOOM_Y;
-
-  /** everything below is tied to the PS_button in y-dir **/
-  image[0].grey_button.x = image[0].PS_button.x + image[0].PS_button.dx + PAD1;
-  image[0].grey_button.y = image[0].PS_button.y;
-
-  image[0].rainbow_button.x = image[0].grey_button.x + image[0].grey_button.dx + PAD1;
-  image[0].rainbow_button.y = image[0].PS_button.y;
-
-  image[0].puns_button.x = image[0].rainbow_button.x + image[0].rainbow_button.dx + PAD1;
-  image[0].puns_button.y = image[0].PS_button.y;
-
-  image[0].recenter_button.x = image[0].puns_button.x + image[0].puns_button.dx + PAD1;
-  image[0].recenter_button.y = image[0].PS_button.y;
-
-  image[0].overlay_button[0].x = image[0].zoom.x + 5;
-  image[0].overlay_button[0].y = image[0].PS_button.y - BUTTON_HEIGHT - PAD1;
+  /* the image is placed within the graphic window in region specified by section */
+  Xs = graphic[0].dx * section[0].x;
+  Ys = graphic[0].dy * (1 - section[0].y - section[0].dy);
+  dX = graphic[0].dx * section[0].dx;
+  dY = graphic[0].dy * section[0].dy;
+
+  switch (image[0].location) {
+    case 0:
+      if (section->graph) {
+	  image[0].picture.x  = graph[0].axis[0].fx;
+	  image[0].picture.y  = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+	  image[0].picture.dx = MAX(graph[0].axis[0].dfx + 1, 1);
+	  image[0].picture.dy = MAX(fabs(graph[0].axis[1].dfy) - 1, 1);
+      } else {
+	  image[0].picture.x  = Xs + PAD1;
+	  image[0].picture.y  = Ys + PAD1;
+	  image[0].picture.dx = dX - 2*PAD1; 
+	  image[0].picture.dy = dY - 2*PAD1;
+      }
+      if (USE_XWINDOW) CreatePicture (image, graphic);
+      Remap (graphic, image, &image[0].matrix);
+      return;
+
+    case 1:
+      textpad = graphic[0].font[0].ascent;
+      textdY = 6*textpad + 7*PAD1;
+      WdY = MAX (ZOOM_Y, textdY + 2*BUTTON_HEIGHT + PAD1);
+
+      if (section->graph) {
+	  image[0].picture.x = graph[0].axis[0].fx;
+	  image[0].picture.y = Ys + 2*PAD1 + COLORPAD;
+	  image[0].picture.dx = graph[0].axis[0].dfx;
+	  image[0].picture.dy = dY - 5*PAD1 - WdY - COLORPAD;
+      } else {
+	  image[0].picture.x  = Xs + PAD1;
+	  image[0].picture.y  = Ys + 2*PAD1 + COLORPAD;
+	  image[0].picture.dx = dX - 2*PAD1; 
+	  image[0].picture.dy = dY - 5*PAD1 - WdY - COLORPAD;
+      }
+
+      image[0].cmapbar.dx = dX - 2*PAD1; 
+      image[0].cmapbar.dy = COLORPAD;
+      image[0].cmapbar.x = Xs + PAD1;
+      image[0].cmapbar.y = Ys + PAD1;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].zoom.dx = ZOOM_X; 
+      image[0].zoom.dy = ZOOM_Y;
+      image[0].zoom.x = Xs + PAD1;
+      image[0].zoom.y = image[0].picture.y + image[0].picture.dy + PAD1;
+
+      /** everything below is tied in x-dir to the zoom box **/
+      image[0].text_x = image[0].zoom.x + image[0].zoom.dx + PAD1;
+      image[0].text_y = image[0].zoom.y;
+      image[0].text_dx = ZOOM_X;
+      image[0].text_dy = 6*textpad + 7*PAD1;
+
+      image[0].overlay_button[0].x = image[0].text_x;
+      image[0].overlay_button[0].y = image[0].text_y + image[0].text_dy + PAD1;
    
-  image[0].overlay_button[1].x = image[0].overlay_button[0].x + image[0].overlay_button[0].dx + PAD1;
-  image[0].overlay_button[1].y = image[0].PS_button.y - BUTTON_HEIGHT - PAD1;
-
-  image[0].overlay_button[2].x = image[0].overlay_button[1].x + image[0].overlay_button[1].dx + PAD1;
-  image[0].overlay_button[2].y = image[0].PS_button.y - BUTTON_HEIGHT - PAD1;
-
-  image[0].overlay_button[3].x = image[0].overlay_button[2].x + image[0].overlay_button[2].dx + PAD1;
-  image[0].overlay_button[3].y = image[0].PS_button.y - BUTTON_HEIGHT - PAD1;
-
-  image[0].hms_button.x = image[0].overlay_button[3].x + image[0].overlay_button[3].dx + PAD1;
-  image[0].hms_button.y = image[0].PS_button.y - BUTTON_HEIGHT - PAD1;
+      image[0].overlay_button[1].x = image[0].overlay_button[0].x + image[0].overlay_button[0].dx + PAD1;
+      image[0].overlay_button[1].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[2].x = image[0].overlay_button[1].x + image[0].overlay_button[1].dx + PAD1;
+      image[0].overlay_button[2].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[3].x = image[0].overlay_button[2].x + image[0].overlay_button[2].dx + PAD1;
+      image[0].overlay_button[3].y = image[0].overlay_button[0].y;
+
+      image[0].hms_button.x = image[0].overlay_button[3].x + image[0].overlay_button[3].dx + PAD1;
+      image[0].hms_button.y = image[0].overlay_button[0].y;
+
+      image[0].PS_button.x = image[0].text_x;
+      image[0].PS_button.y = image[0].overlay_button[0].y + BUTTON_HEIGHT + PAD1;
+
+      /** everything below is tied to the PS_button in y-dir + the neighbor in x-dir **/
+      image[0].grey_button.x = image[0].PS_button.x + image[0].PS_button.dx + PAD1;
+      image[0].grey_button.y = image[0].PS_button.y;
+
+      image[0].rainbow_button.x = image[0].grey_button.x + image[0].grey_button.dx + PAD1;
+      image[0].rainbow_button.y = image[0].PS_button.y;
+
+      image[0].puns_button.x = image[0].rainbow_button.x + image[0].rainbow_button.dx + PAD1;
+      image[0].puns_button.y = image[0].PS_button.y;
+
+      image[0].recenter_button.x = image[0].puns_button.x + image[0].puns_button.dx + PAD1;
+      image[0].recenter_button.y = image[0].PS_button.y;
+      break;
+
+    case 3:
+      textpad = graphic[0].font[0].ascent;
+      textdY = 6*textpad + 7*PAD1;
+      WdY = MAX (ZOOM_Y, textdY + 2*BUTTON_HEIGHT + PAD1);
+
+      if (section->graph) {
+	image[0].picture.x = graph[0].axis[0].fx;
+	image[0].picture.y = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+	image[0].picture.dx = MAX(graph[0].axis[0].dfx, 1);
+	image[0].picture.dy = MAX(fabs(graph[0].axis[1].dfy) - 1, 1);
+      } else {
+	image[0].picture.dx = dX - 2*PAD1; 
+	image[0].picture.dy = dY - 5*PAD1 - WdY - COLORPAD;
+	image[0].picture.x = Xs + PAD1;
+	image[0].picture.y = Ys + 4*PAD1 + COLORPAD + WdY;
+      }
+
+      image[0].cmapbar.dx = dX - 2*PAD1; 
+      image[0].cmapbar.dy = COLORPAD;
+      image[0].cmapbar.x = Xs + PAD1;
+      image[0].cmapbar.y = Ys + PAD1;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].zoom.dx = ZOOM_X; 
+      image[0].zoom.dy = ZOOM_Y;
+      image[0].zoom.x = Xs + PAD1;
+      image[0].zoom.y = Ys + 2*PAD1 + COLORPAD;
+
+      /** everything below is tied in x-dir to the zoom box **/
+      image[0].text_x = image[0].zoom.x + image[0].zoom.dx + PAD1;
+      image[0].text_y = image[0].zoom.y;
+      image[0].text_dx = ZOOM_X;
+      image[0].text_dy = 6*textpad + 7*PAD1;
+
+      image[0].overlay_button[0].x = image[0].text_x;
+      image[0].overlay_button[0].y = image[0].text_y + image[0].text_dy + PAD1;
+   
+      image[0].overlay_button[1].x = image[0].overlay_button[0].x + image[0].overlay_button[0].dx + PAD1;
+      image[0].overlay_button[1].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[2].x = image[0].overlay_button[1].x + image[0].overlay_button[1].dx + PAD1;
+      image[0].overlay_button[2].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[3].x = image[0].overlay_button[2].x + image[0].overlay_button[2].dx + PAD1;
+      image[0].overlay_button[3].y = image[0].overlay_button[0].y;
+
+      image[0].hms_button.x = image[0].overlay_button[3].x + image[0].overlay_button[3].dx + PAD1;
+      image[0].hms_button.y = image[0].overlay_button[0].y;
+
+      image[0].PS_button.x = image[0].text_x;
+      image[0].PS_button.y = image[0].overlay_button[0].y + BUTTON_HEIGHT + PAD1;
+
+      /** everything below is tied to the PS_button in y-dir + the neighbor in x-dir **/
+      image[0].grey_button.x = image[0].PS_button.x + image[0].PS_button.dx + PAD1;
+      image[0].grey_button.y = image[0].PS_button.y;
+
+      image[0].rainbow_button.x = image[0].grey_button.x + image[0].grey_button.dx + PAD1;
+      image[0].rainbow_button.y = image[0].PS_button.y;
+
+      image[0].puns_button.x = image[0].rainbow_button.x + image[0].rainbow_button.dx + PAD1;
+      image[0].puns_button.y = image[0].PS_button.y;
+
+      image[0].recenter_button.x = image[0].puns_button.x + image[0].puns_button.dx + PAD1;
+      image[0].recenter_button.y = image[0].PS_button.y;
+      break;
+
+    case 2:
+
+      if (section->graph) {
+	image[0].picture.x = Xs + 2*PAD1 + ZOOM_X;
+	image[0].picture.y = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+	image[0].picture.dx = dX - 3*PAD1 - ZOOM_X; 
+	image[0].picture.dy = MAX(fabs(graph[0].axis[1].dfy) - 1, 1);
+      } else {
+	image[0].picture.dx = dX - 3*PAD1 - ZOOM_X; 
+	image[0].picture.dy = dY - 3*PAD1 - COLORPAD;
+	image[0].picture.x = Xs + 2*PAD1 + ZOOM_X;
+	image[0].picture.y = Ys + 2*PAD1 + COLORPAD;
+      }
+
+      image[0].cmapbar.dx = dX - 2*PAD1; 
+      image[0].cmapbar.dy = COLORPAD;
+      image[0].cmapbar.x = Xs + PAD1;
+      image[0].cmapbar.y = Ys + PAD1;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].zoom.dx = ZOOM_X; 
+      image[0].zoom.dy = ZOOM_Y;
+      image[0].zoom.x = Xs + PAD1;
+      image[0].zoom.y = image[0].picture.y;
+
+      /** everything below is tied in x-dir to the zoom box **/
+      textpad = graphic[0].font[0].ascent;
+      image[0].text_x = image[0].zoom.x;
+      image[0].text_y = image[0].zoom.y + image[0].zoom.dy + PAD1;
+      image[0].text_dx = ZOOM_X;
+      image[0].text_dy = 6*textpad + 7*PAD1;
+
+      image[0].overlay_button[0].x = image[0].text_x;
+      image[0].overlay_button[0].y = image[0].text_y + image[0].text_dy + PAD1;
+   
+      image[0].overlay_button[1].x = image[0].overlay_button[0].x + image[0].overlay_button[0].dx + PAD1;
+      image[0].overlay_button[1].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[2].x = image[0].overlay_button[1].x + image[0].overlay_button[1].dx + PAD1;
+      image[0].overlay_button[2].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[3].x = image[0].overlay_button[2].x + image[0].overlay_button[2].dx + PAD1;
+      image[0].overlay_button[3].y = image[0].overlay_button[0].y;
+
+      image[0].hms_button.x = image[0].overlay_button[3].x + image[0].overlay_button[3].dx + PAD1;
+      image[0].hms_button.y = image[0].overlay_button[0].y;
+
+      image[0].PS_button.x = image[0].zoom.x;
+      image[0].PS_button.y = image[0].overlay_button[0].y + BUTTON_HEIGHT + PAD1;
+
+      /** everything below is tied to the PS_button in y-dir + the neighbor in x-dir **/
+      image[0].grey_button.x = image[0].PS_button.x + image[0].PS_button.dx + PAD1;
+      image[0].grey_button.y = image[0].PS_button.y;
+
+      image[0].rainbow_button.x = image[0].grey_button.x + image[0].grey_button.dx + PAD1;
+      image[0].rainbow_button.y = image[0].PS_button.y;
+
+      image[0].puns_button.x = image[0].rainbow_button.x + image[0].rainbow_button.dx + PAD1;
+      image[0].puns_button.y = image[0].PS_button.y;
+
+      image[0].recenter_button.x = image[0].puns_button.x + image[0].puns_button.dx + PAD1;
+      image[0].recenter_button.y = image[0].PS_button.y;
+      break;
+
+    case 4:
+
+      if (section->graph) {
+	image[0].picture.x = graph[0].axis[0].fx;
+	image[0].picture.y = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+	image[0].picture.dx = dX - 3*PAD1 - ZOOM_X - graph[0].axis[0].fx; 
+	image[0].picture.dy = MAX(fabs(graph[0].axis[1].dfy) - 1, 1);
+      } else {
+	image[0].picture.dx = dX - 3*PAD1 - ZOOM_X; 
+	image[0].picture.dy = dY - 3*PAD1 - COLORPAD;
+	image[0].picture.x = Xs + PAD1;
+	image[0].picture.y = Ys + 2*PAD1 + COLORPAD;
+      }
+
+      image[0].cmapbar.dx = dX - 2*PAD1; 
+      image[0].cmapbar.dy = COLORPAD;
+      image[0].cmapbar.x = Xs + PAD1;
+      image[0].cmapbar.y = Ys + PAD1;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].zoom.dx = ZOOM_X; 
+      image[0].zoom.dy = ZOOM_Y;
+      image[0].zoom.x = image[0].picture.x + image[0].picture.dx + PAD1;
+      image[0].zoom.y = image[0].picture.y;
+
+      /** everything below is tied in x-dir to the zoom box **/
+      textpad = graphic[0].font[0].ascent;
+      image[0].text_x = image[0].zoom.x;
+      image[0].text_y = image[0].zoom.y + image[0].zoom.dy + PAD1;
+      image[0].text_dx = ZOOM_X;
+      image[0].text_dy = 6*textpad + 7*PAD1;
+
+      image[0].overlay_button[0].x = image[0].text_x;
+      image[0].overlay_button[0].y = image[0].text_y + image[0].text_dy + PAD1;
+   
+      image[0].overlay_button[1].x = image[0].overlay_button[0].x + image[0].overlay_button[0].dx + PAD1;
+      image[0].overlay_button[1].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[2].x = image[0].overlay_button[1].x + image[0].overlay_button[1].dx + PAD1;
+      image[0].overlay_button[2].y = image[0].overlay_button[0].y;
+
+      image[0].overlay_button[3].x = image[0].overlay_button[2].x + image[0].overlay_button[2].dx + PAD1;
+      image[0].overlay_button[3].y = image[0].overlay_button[0].y;
+
+      image[0].hms_button.x = image[0].overlay_button[3].x + image[0].overlay_button[3].dx + PAD1;
+      image[0].hms_button.y = image[0].overlay_button[0].y;
+
+      image[0].PS_button.x = image[0].zoom.x;
+      image[0].PS_button.y = image[0].overlay_button[0].y + BUTTON_HEIGHT + PAD1;
+
+      /** everything below is tied to the PS_button in y-dir + the neighbor in x-dir **/
+      image[0].grey_button.x = image[0].PS_button.x + image[0].PS_button.dx + PAD1;
+      image[0].grey_button.y = image[0].PS_button.y;
+
+      image[0].rainbow_button.x = image[0].grey_button.x + image[0].grey_button.dx + PAD1;
+      image[0].rainbow_button.y = image[0].PS_button.y;
+
+      image[0].puns_button.x = image[0].rainbow_button.x + image[0].rainbow_button.dx + PAD1;
+      image[0].puns_button.y = image[0].PS_button.y;
+
+      image[0].recenter_button.x = image[0].puns_button.x + image[0].puns_button.dx + PAD1;
+      image[0].recenter_button.y = image[0].PS_button.y;
+      break;
+
+    default:
+      abort ();
+      break;
+  }
 
   if (USE_XWINDOW) {
Index: /trunk/Ohana/src/kapa2/src/SetLimits.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetLimits.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/SetLimits.c	(revision 13479)
@@ -1,5 +1,5 @@
 # include "Ximage.h"
 
-int SetLimits () {
+int SetLimits (int sock) {
   
   int i;
@@ -14,7 +14,10 @@
 
   section = GetActiveSection();
-  if (section->graph == NULL) return (TRUE);
+  if (section->graph == NULL) {
+    section->graph = InitGraph ();
+    SetSectionSizes (section);
+  }
   graph = section->graph;
-
+  
   graph[0].axis[2].min = graph[0].axis[0].min = xmin;
   graph[0].axis[2].max = graph[0].axis[0].max = xmax;
@@ -32,9 +35,8 @@
   Refresh (1);
 
-  return (TRUE);
-  
+  return (TRUE);  
 }
 
-int GetLimits () {
+int GetLimits (int sock) {
   
   double dX, dY;
Index: /trunk/Ohana/src/kapa2/src/SetNormalHints.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetNormalHints.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/SetNormalHints.c	(revision 13479)
@@ -17,5 +17,6 @@
 
   // XXX : can we drop the position flag 
-  sizehints[0].flags = USPosition | USSize | PMinSize;
+  // sizehints[0].flags = USPosition | USSize | PMinSize;
+  sizehints[0].flags = USSize | PMinSize;
 
   sizehints[0].base_width = graphic->dx;
Index: /trunk/Ohana/src/kapa2/src/SetSection.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetSection.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/SetSection.c	(revision 13479)
@@ -2,5 +2,5 @@
 
 // set active section
-int SetSection () {
+int SetSection (int sock) {
   
   int N;
Index: /trunk/Ohana/src/kapa2/src/SetToolbox.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetToolbox.c	(revision 13479)
+++ /trunk/Ohana/src/kapa2/src/SetToolbox.c	(revision 13479)
@@ -0,0 +1,33 @@
+# include "Ximage.h"
+
+// set the position of the image toolbox
+void SetToolbox (int sock) {
+
+  int location;
+  Section *section;
+  Graphic *graphic;
+
+  KiiScanMessage (sock, "%d", &location);
+  if ((location < 0) || (location > 4)) {
+    fprintf (stderr, "invalid toolbox location %d\n", location);
+    return;
+  }
+
+  graphic = GetGraphic ();
+  section = GetActiveSection();
+  if (section->image == NULL) { 
+    section->image = InitImage ();
+  }
+  section->image->location = location;
+  SetSectionSizes (section);
+
+  if (!USE_XWINDOW) return;
+
+  Remap (graphic, section->image, &section->image->matrix);
+  if (DEBUG) fprintf (stderr, "remapped image\n");
+  Refresh ();
+  if (DEBUG) fprintf (stderr, "refreshed\n");
+  XFlush (graphic->display);
+
+  return;
+}
Index: /trunk/Ohana/src/kapa2/src/UpdatePointer.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/UpdatePointer.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/UpdatePointer.c	(revision 13479)
@@ -6,4 +6,5 @@
   int textpad;
   double  x, y, z;
+  float *data;
   char line[100];
   Section *section;
@@ -13,20 +14,20 @@
   section = GetActiveSection();
   image   = section->image;
+  if (image == NULL) return (TRUE);
+  if (!image[0].location) return (TRUE);
 
   if (image[0].MovePointer && InPicture ((XButtonEvent *)event, &image[0].picture)) {
 
+    data = (float *) image[0].matrix.buffer;
     Screen_to_Image (&x, &y, (double)event[0].x, (double)event[0].y, image);
 
-    if ((x >= 0) && (x < image[0].matrix.Naxis[0]) && (y >= 0) && (y < image[0].matrix.Naxis[1])) {
-      /*
-      X = event[0].x - image[0].picture.x;
-      Y = event[0].y - image[0].picture.y;
-      pix = MIN (MAX (X + Y*image[0].picture.dx, 0), image[0].picture.dx*image[0].picture.dy - 1);
-      z = image[0].range * image[0].picture.data[pix] / image[0].Npixels + image[0].zero;
-      */
-      z = -1;
-    }
-    else
-      z = -1;
+    z = -1;
+    if (x < 0) goto skip;
+    if (x >= image[0].matrix.Naxis[0]) goto skip;
+    if (y < 0) goto skip;
+    if (y >= image[0].matrix.Naxis[1]) goto skip;
+    z = data[(int)(y)*image[0].matrix.Naxis[0] + (int)(x)];
+
+  skip:
     image[0].x = x;
     image[0].y = y;
@@ -43,5 +44,4 @@
     CrossHairs (graphic, image);
     XFlush (graphic[0].display);
-    
   }
   
@@ -54,5 +54,5 @@
     XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
     bzero (line, 100);
-    sprintf (line, "%25.2f", z);
+    sprintf (line, "%22.3f", z);
     XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, 
                  image[0].text_x + PAD1, image[0].text_y + textpad + PAD1, 
Index: /trunk/Ohana/src/kapa2/src/UpdateStatusBox.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/UpdateStatusBox.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/UpdateStatusBox.c	(revision 13479)
@@ -14,8 +14,8 @@
     XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].back);
     XFillRectangle (graphic[0].display, graphic[0].window, graphic[0].gc,
-		    image[0].text_x, image[0].text_y, ZOOM_X, 6*textpad+7*PAD1);  
+		    image[0].text_x, image[0].text_y, image[0].text_dx, image[0].text_dy);  
     XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
     XDrawRectangle (graphic[0].display, graphic[0].window, graphic[0].gc,
-		    image[0].text_x, image[0].text_y, ZOOM_X, 6*textpad+7*PAD1);
+		    image[0].text_x, image[0].text_y, image[0].text_dx, image[0].text_dy);
   
     bzero (line, 100);
@@ -31,5 +31,5 @@
     
     bzero (line, 100);
-    sprintf (line, "(%s)                                          ", image[0].buffer_name); 
+    sprintf (line, "(%s)                                          ", image[0].name); 
     XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, 
 		 image[0].text_x + PAD1, image[0].text_y + 6*textpad + 6*PAD1, line, 25);
@@ -38,14 +38,14 @@
     XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].back);
     XFillRectangle (graphic[0].display, graphic[0].window, graphic[0].gc,
-		    image[0].text_x + 1, image[0].text_y + 1, ZOOM_X - 2, 3*textpad+3*PAD1 +1);  
+		    image[0].text_x+1, image[0].text_y+1, image[0].text_dx-2, image[0].text_dy-2);  
     XSetForeground (graphic[0].display, graphic[0].gc, graphic[0].fore);
   }
   bzero (line, 100);
-  sprintf (line, "%25.3f", z);
+  sprintf (line, "%22.3f", z);
   XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, 
 	       image[0].text_x + PAD1, image[0].text_y + textpad + PAD1, line, strlen(line));
   
   bzero (line, 100);
-  sprintf (line, "%12.1f %12.1f", x, y);
+  sprintf (line, "%10.1f %10.1f", x, y);
   XDrawString (graphic[0].display, graphic[0].window, graphic[0].gc, 
 	       image[0].text_x + PAD1, image[0].text_y + 2*textpad + 2*PAD1, line, strlen(line));
@@ -53,5 +53,5 @@
   bzero (line, 100);
   if (image[0].DecimalDegrees) {
-    sprintf (line, "%12.6f %12.6f", ra, dec); 
+    sprintf (line, "%10.6f %10.6f", ra, dec); 
   } else {
     hh_hms (line, ra, dec, ':');
Index: /trunk/Ohana/src/kapa2/src/bDrawIt.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/bDrawIt.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/bDrawIt.c	(revision 13479)
@@ -22,5 +22,5 @@
       section = GetSectionByNumber (i);
       bDrawGraph (section->graph);
-      // bDrawImage (section->graph);
+      // bDrawImage (section->image);
   }
 
Index: /trunk/Ohana/src/kapa2/src/bDrawOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/bDrawOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/bDrawOverlay.c	(revision 13479)
@@ -23,10 +23,4 @@
     expand = fabs((double)image[0].expand);
   }
-  /* 
-  X = 0.5*image[0].matrix.Naxis[0] - expand*((int)(0.5*image[0].picture.dx + 0.5) - 0.0) - image[0].X;
-  Y = 0.5*image[0].matrix.Naxis[1] - expand*((int)(0.5*image[0].picture.dy + 0.5) - 0.0) - image[0].Y;  
-  X0 =  (image[0].X + 1 - (int)(0.5*image[0].matrix.Naxis[0] + 0.5) - X + (int)X)/expand + image[0].picture.x + 0.5*image[0].picture.dx;
-  Y0 =  (image[0].Y + 1 - (int)(0.5*image[0].matrix.Naxis[1] + 0.5) - Y + (int)Y)/expand + image[0].picture.y + 0.5*image[0].picture.dy;
-  */
 
   Image_to_Screen (&X0, &Y0, 0.0, 0.0, image);
@@ -62,26 +56,26 @@
        for a BOX (x, y) is the center, (dx, dy) is the width */
 
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "LINE")) {
-      bDrawLine (X, Y, (X+dX), (Y+dY));
-      continue;
+    switch (image[0].overlay[N].objects[i].type) {
+      case KII_OVERLAY_LINE:
+	bDrawLine (X, Y, (X+dX), (Y+dY));
+	break;
+      case KII_OVERLAY_TEXT:
+	bDrawRotText (X, Y, image[0].overlay[N].objects[i].text, 8, 0.0);
+	break;
+      case KII_OVERLAY_BOX:
+	dx = MAX (abs(dX),2) / 2;
+	dy = MAX (abs(dY),2) / 2;
+	bDrawRectOpen ((X-dx), (Y-dy), (X+dx), (Y+dy));
+	// bDrawRectOpen ((X-dx), (Y-dy), (X), (Y));
+	break;
+      case KII_OVERLAY_CIRCLE:
+	dx = MAX (abs(dX),2);
+	dy = MAX (abs(dY),2);
+	bDrawArc (X, Y, dx, dy, 0, 360);
+	break;
+      default:
+	fprintf (stderr, "skipping unknown object\n");
+	break;
     }
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "TEXT")) {
-      bDrawRotText (X, Y, image[0].overlay[N].objects[i].text, 8, 0.0);
-      continue;
-    }
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "BOX")) {
-      dx = MAX (abs(dX),2) / 2;
-      dy = MAX (abs(dY),2) / 2;
-      bDrawRectOpen ((X-dx), (Y-dy), (X+dx), (Y+dy));
-      // bDrawRectOpen ((X-dx), (Y-dy), (X), (Y));
-       continue;
-    }
-    if (!strcasecmp (image[0].overlay[N].objects[i].type, "CIRCLE")) {
-      dx = MAX (abs(dX),2);
-      dy = MAX (abs(dY),2);
-      bDrawArc (X, Y, dx, dy, 0, 360);
-      continue;
-    }
-    fprintf (stderr, "don't know %s, skipping (PO)\n", image[0].overlay[N].objects[i].type);
   }
   
Index: /trunk/Ohana/src/kapa2/src/kapa.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/kapa.c	(revision 13478)
+++ /trunk/Ohana/src/kapa2/src/kapa.c	(revision 13479)
@@ -7,6 +7,4 @@
   SetUpGraphic (&argc, argv);
 
-  // XXX get socket connection here?
-
   InitLayout (argc, argv);
   EventLoop ();
Index: /trunk/Ohana/src/kii/event/CheckPipe.c
===================================================================
--- /trunk/Ohana/src/kii/event/CheckPipe.c	(revision 13478)
+++ /trunk/Ohana/src/kii/event/CheckPipe.c	(revision 13479)
@@ -123,4 +123,5 @@
   }
 
+  /* is this no longer used ?
   if (!strcmp (buffer, "NPIX")) {
     sprintf (buffer, "NPIX:   %8d", layout[0].Npixels);
@@ -128,4 +129,5 @@
     return (TRUE);
   }
+  */
 
   fprintf (stderr, "unknown signal %s\n", buffer);
Index: /trunk/Ohana/src/libkapa/Makefile
===================================================================
--- /trunk/Ohana/src/libkapa/Makefile	(revision 13478)
+++ /trunk/Ohana/src/libkapa/Makefile	(revision 13479)
@@ -29,5 +29,6 @@
 $(SRC)/KiiConvert.$(ARCH).o \
 $(SRC)/KapaWindow.$(ARCH).o \
-$(SRC)/KapaColors.$(ARCH).o
+$(SRC)/KapaColors.$(ARCH).o \
+$(SRC)/KapaOpen.$(ARCH).o
 
 DRAW = \
Index: /trunk/Ohana/src/libkapa/doc/api.txt
===================================================================
--- /trunk/Ohana/src/libkapa/doc/api.txt	(revision 13479)
+++ /trunk/Ohana/src/libkapa/doc/api.txt	(revision 13479)
@@ -0,0 +1,37 @@
+
+COMM | Kapa Function  	| libkapa file  | libkapa API 
+-----------------------------------------------------
+DBOX | LoadFrame      	| KapaWindow.c  | KapaBox
+ERSP | ErasePlots       | KapaWindow.c  | KapaClearPlots
+ERSS | EraseSections    | KapaWindow.c  | KapaClearSections
+ERSI | EraseImage       | KapaWindow.c  | KapaClearImage
+ERSC | EraseCurrentPlot | KapaWindow.c  | KapaClearCurrentPlot
+LSEC | ListSection    	| KapaWindow.c  | KapaGetSection
+PNGF | PNGit          	| KiiConvert.c  | KapaPNG
+PPMF | PPMit          	| KiiConvert.c  | KapaPPM
+PLOT | LoadObject     	| KapaWindow.c  | KapaPrepPlot
+SSEC | SetSection     	| KapaWindow.c  | KapaSelectSection
+LABL | LoadLabels     	| KapaWindow.c  | KapaSendLabel
+PTXT | LoadTextlines  	| KapaWindow.c  | KapaSendTextline
+FONT | SetFont        	| KapaWindow.c  | KapaSetFont
+SLIM | SetLimits      	| KapaWindow.c  | KapaSetLimits
+DSEC | DefineSection  	| KapaWindow.c  | KapaSetSection
+MSEC | MoveSection  	| KapaWindow.c  | KapaMoveSection
+CENT | Center           | KapaWindow.c  | KiiCenter
+QUIT | Quit           	| KiiOpen.c     | KiiClose
+NCUR | !ACTIVE_CURSOR 	| KiiCursor.c   | KiiCursorOff
+CURS | +ACTIVE_CURSOR 	| KiiCursor.c   | KiiCursorOn
+ERSO | EraseOverlay     | KiiOverlay.c  | KiiEraseOverlay
+JPEG | JPEGit24         | KiiConvert.c  | KiiJPEG
+LOAD | LoadOverlay      | KiiOverlay.c  | KiiLoadOverlay
+READ | LoadPicture      | KiiPicture.c  | KiiNewPicture1D
+READ | LoadPicture      | KiiPicture.c  | KiiNewPicture2D
+PSIT | PScommand      	| KiiConvert.c  | KiiPS
+RSIZ | Resize         	| KapaWindow.c  | KiiResize
+SAVE | SaveOverlay      | KiiOverlay.c  | KiiSaveOverlay
+CSVE | CSaveOverlay     | KiiOverlay.c  | KiiSaveOverlay
+SLIM | GetLimits      	| KapaWindow.c  | KapaGetLimits
+SSTY | SetGraphData	| KapaWindow.c 	| KapaSetGraphData
+GSTY | GetGraphData	| KapaWindow.c 	| KapaGetGraphData
+SIMD | SetImageData	| KapaWindow.c 	| KapaSetImageData
+GIMD | GetImageData	| KapaWindow.c 	| KapaGetImageData
Index: /trunk/Ohana/src/libkapa/include/kapa.h
===================================================================
--- /trunk/Ohana/src/libkapa/include/kapa.h	(revision 13478)
+++ /trunk/Ohana/src/libkapa/include/kapa.h	(revision 13479)
@@ -2,7 +2,16 @@
 # define KAPA_H
 
+/* linux is happy with this, not solaris */
+# include <netinet/ip.h>
+# include <netdb.h>
+# include <arpa/inet.h>
+
+# include <sys/types.h>
+# include <sys/socket.h>
 # include <X11/Xlib.h>
 # include <png.h>
 # include <dvo.h>
+
+typedef struct sockaddr_in KapaSockAddress;
 
 typedef struct {
@@ -11,13 +20,13 @@
   int Nx;
   int Ny;
-  char *file;
-  char *name;
 } KiiImage;
 
 typedef struct {
-  double zero;
-  double range;
-  int logflux;
-} KiiDisplayMode;
+  float x;
+  float y;
+  float dx;
+  float dy;
+  int type;
+} KiiOverlayBase;
 
 typedef struct {
@@ -73,4 +82,11 @@
 
 typedef struct {
+  int logflux;
+  double zero, range;
+  char name[1024];
+  char file[1024];
+} KapaImageData;
+
+typedef struct {
   int dx, dy, ascent;
   unsigned char *bits;
@@ -98,4 +114,5 @@
 int KiiSendData (int device, char *data, int Nbytes);
 char *KiiRecvData (int device);
+int KiiWaitAnswer (int device, char *expect);
 
 /* KiiOpen.c */
@@ -105,6 +122,6 @@
 
 /* KiiPicture.c */
-int KiiNewPicture1D (int fd, KiiImage *image, KiiDisplayMode *mode, Coords *coords);
-int KiiNewPicture2D (int fd, KiiImage *image, KiiDisplayMode *mode, Coords *coords);
+int KiiNewPicture1D (int fd, KiiImage *image, KapaImageData *data, Coords *coords);
+int KiiNewPicture2D (int fd, KiiImage *image, KapaImageData *data, Coords *coords);
 
 /* KiiOverlay.c */
@@ -125,5 +142,5 @@
 int KiiCursorOn (int fd);
 int KiiCursorOff (int fd);
-int KiiCursorRead (int fd, double *x, double *y, char *key);
+int KiiCursorRead (int fd, double *x, double *y, double *z, double *r, double *d, char *key);
 
 /* KapaWindow.c */
@@ -131,8 +148,11 @@
 int KiiCenter (int fd, double x, double y, int zoom);
 int KapaBox (int fd, Graphdata *graphdata);
-int KapaClear (int fd, int ClearSection);
+int KapaClearCurrentPlot (int fd);
+int KapaClearPlots (int fd);
+int KapaClearSections (int fd);
+int KapaClearImage (int fd);
 int KapaInitGraph (Graphdata *graphdata);
 int KapaPrepPlot (int fd, int Npts, Graphdata *graphmode);
-int KapaPlotVector (int fd, int Npts, float *values);
+int KapaPlotVector (int fd, int Npts, float *values, char *type);
 int KapaSetFont (int fd, char *name, int size);
 int KapaSendLabel (int fd, char *string, int mode);
@@ -142,4 +162,9 @@
 int KapaSelectSection (int fd, char *name);
 int KapaGetSection (int fd, char *name);
+int KapaMoveSection (int fd, char *name, char *direction);
+int KapaSetGraphData (int fd, Graphdata *graphmode);
+int KapaGetGraphData (int fd, Graphdata *graphmode);
+int KapaSetImageData (int fd, KapaImageData *graphmode);
+int KapaGetImageData (int fd, KapaImageData *graphmode);
 
 /* KapaColors */
@@ -196,6 +221,13 @@
 int bDrawRotBitmap (int x, int y, int dx, int dy, unsigned char *bitmap, int mode, double angle, double scale);
 
+/* Kapa Socket functions */
+int KapaOpen (char *kapa_exec, char *kapa_name);
+int KapaServerInit (KapaSockAddress *Address);
+int KapaServerWait (int InitSocket, KapaSockAddress *Address);
+int KapaDefineValidIP (char *ipstring);
+int KapaClientSocket (char *hostname);
+
 /* define Kapa names for shared functions */
-# define KapaOpen(p,n) KiiOpen(p,n)
+// # define KapaOpen(p,n) KiiOpen(p,n)
 # define KapaResize(fd,Nx,Ny) KiiResize(fd,Nx,Ny)
 # define KapaCenter(fd,x,y,z) KiiResize(fd,x,y,z)
Index: /trunk/Ohana/src/libkapa/src/IOfuncs.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/IOfuncs.c	(revision 13478)
+++ /trunk/Ohana/src/libkapa/src/IOfuncs.c	(revision 13479)
@@ -1,3 +1,5 @@
 # include <kapa_internal.h>
+
+/** these function expect to operate with a BLOCKing socket **/
 
 /* why is this not defined in stdarg.h for linux/x64? */
@@ -61,4 +63,5 @@
   status = read (device, buffer, 16);
   buffer[16] = 0;
+  if (status != 16) fprintf (stderr, "dropped message length\n");
 
   /* find the message length, allocate space */
@@ -71,4 +74,6 @@
   message[status] = 0;
   /* make the string easy to parse */
+
+  // fprintf (stderr, "recv: %s\n", message);
 
   /* scan the incoming message */
@@ -104,4 +109,7 @@
 
   write (device, string, length);
+
+  // fprintf (stderr, "send: %s\n", string);
+
   free (string);
   return (TRUE);
@@ -111,6 +119,6 @@
 int KiiScanCommand (int device, int length, char *format, ...) {
 
-  int Nbytes, status;
-  char *buffer, *message;
+  int status;
+  char *message;
   va_list argp;  
 
@@ -118,14 +126,38 @@
 
   /* read Nbytes from the device */
-  status = read (device, message, Nbytes);
-  if (status != Nbytes) fprintf (stderr, "Kii/Kapa comm error\n");
-  message[status] = 0;
-  /* make the string easy to parse */
+  status = read (device, message, length);
+
+  if (status != length) {
+      fprintf (stderr, "Kii/Kapa comm error\n");
+      return (0);
+  }
+  message[status] = 0; // make the string easy to parse
 
   /* scan the incoming message */
   va_start (argp, format);
-  Nbytes = vsscanf (message, format, argp);
+  vsscanf (message, format, argp);
   va_end (argp);
 
-  return (status);
+  return (1);
 }
+
+int KiiWaitAnswer (int device, char *expect) {
+
+  int Nbytes;
+  char *answer;
+
+  Nbytes = strlen (expect);
+  ALLOCATE (answer, char, Nbytes + 1);
+
+  KiiScanCommand (device, Nbytes, "%s", answer);
+  if (strcmp (answer, expect)) {
+      fprintf (stderr, "unexpected response %s, expected %s\n", answer, expect); 
+      REALLOCATE (answer, char, 128);
+      Nbytes = read (device, answer, 127);
+      answer[Nbytes] = 0;
+      fprintf (stderr, "extra data in buffer: %d bytes\n", Nbytes);
+      fprintf (stderr, "garbage: %s\n", answer);
+      return (FALSE);
+  }
+  return (TRUE);
+}
Index: /trunk/Ohana/src/libkapa/src/KapaOpen.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KapaOpen.c	(revision 13478)
+++ /trunk/Ohana/src/libkapa/src/KapaOpen.c	(revision 13479)
@@ -30,4 +30,5 @@
   if (status == -1) {
     if (errno == EADDRINUSE) {
+	close (InitSocket);
 	Address[0].sin_port ++;
 	if (Address[0].sin_port > MY_PORT + 10) exit (2);
@@ -74,7 +75,4 @@
   }
   if (!status) return (-1);
-
-  /* this is a blocking wait; use in a separate thread */
-  // fcntl (InitSocket, F_SETFL, !O_NONBLOCK); 
 
   if (DEBUG) fprintf (stderr, "init sock: %d, len: %d\n", InitSocket, length);
@@ -119,5 +117,4 @@
 accepted:
   if (DEBUG) fprintf (stderr, "connection accepted\n");
-  // fcntl (BindSocket, F_SETFL, O_NONBLOCK); 
   return (BindSocket);
 }
@@ -194,4 +191,5 @@
     if (DEBUG) fprintf (stderr, "error connecting: %d\n", errno);
     if (errno == ECONNREFUSED) {
+      close (InitSocket);
       Address.sin_port ++;
       if (Address.sin_port > MY_PORT + 10) return (-1);
@@ -204,5 +202,7 @@
   if (DEBUG) fprintf (stderr, "connected on port: %d\n", Address.sin_port);
   if (DEBUG) fprintf (stderr, "connected\n");
-  fcntl (InitSocket, F_SETFL, O_NONBLOCK); 
+
+  // the client uses a BLOCKing socket by default
+  fcntl (InitSocket, F_SETFL, !O_NONBLOCK); 
   return (InitSocket);
 }
@@ -225,5 +225,5 @@
     sprintf (line, "%s &", kapa_exec);
   } else {
-    sprintf (line, "%s -name %s &", kapa_exec, kapa_name);
+    sprintf (line, "%s -name '%s' &", kapa_exec, kapa_name);
   }
   system (line);
Index: /trunk/Ohana/src/libkapa/src/KapaWindow.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KapaWindow.c	(revision 13478)
+++ /trunk/Ohana/src/libkapa/src/KapaWindow.c	(revision 13479)
@@ -1,3 +1,12 @@
 # include <kapa_internal.h>
+
+int KiiCenter (int fd, double x, double y, int zoom) {
+
+  KiiSendCommand (fd, 4, "CENT");
+  KiiSendMessage (fd, "%8.3f %8.3f %8d ", x, y, zoom);
+  KiiWaitAnswer (fd, "DONE");
+  
+  return (TRUE);
+}
 
 int KiiResize (int fd, int Nx, int Ny) {
@@ -5,11 +14,5 @@
   KiiSendCommand (fd, 4, "RSIZ");
   KiiSendMessage (fd, "%d %d", Nx, Ny); 
-  return (TRUE);
-}
-
-int KiiCenter (int fd, double x, double y, int zoom) {
-
-  KiiSendCommand (fd, 4, "CENT");
-  KiiSendMessage (fd, "%8.3f %8.3f %8d ", x, y, zoom);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -18,19 +21,45 @@
 
   KiiSendCommand (fd, 4, "DBOX");
-
   KiiSendMessage (fd, "%12.6g %12.6g %12.6g %12.6g", 
 		    graphdata[0].xmin, graphdata[0].xmax, graphdata[0].ymin, graphdata[0].ymax);
 
   KiiSendMessage (fd, "%s %s %s", graphdata[0].axis, graphdata[0].labels, graphdata[0].ticks);
-  return (TRUE);
-}
-
-int KapaClear (int fd, int ClearSection) {
-
-  if (ClearSection) {
-    KiiSendCommand (fd, 4, "ERAS");
-  } else {
-    KiiSendCommand (fd, 4, "ERSS");
-  }
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaClearCurrentPlot (int fd) {
+  
+  KiiSendCommand (fd, 4, "ERSC");
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaClearPlots (int fd) {
+  
+  KiiSendCommand (fd, 4, "ERSP");
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaClearSections (int fd) {
+  
+  KiiSendCommand (fd, 4, "ERSS");
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaClearImage (int fd) {
+  
+  KiiSendCommand (fd, 4, "ERSI");
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaSetToolbox (int fd, int location) {
+  
+  KiiSendCommand (fd, 4, "TOOL");
+  KiiSendMessage (fd, "%d", location); 
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -62,27 +91,147 @@
 }
 
-int KapaPrepPlot (int fd, int Npts, Graphdata *graphmode) {
+int KapaPrepPlot (int fd, int Npts, Graphdata *data) {
 
   /* tell kapa to look for the incoming image */
   KiiSendCommand (fd, 4, "PLOT"); 
   
-  /* send Xgraph the plot details */
+  /* send kapa the plot details */
   KiiSendMessage (fd, "%8d %8d %d %d %d %d %d %f %f", 
-		  Npts, graphmode[0].style, 
-		  graphmode[0].ptype, graphmode[0].ltype, 
-		  graphmode[0].etype, graphmode[0].ebar, graphmode[0].color, 
-		  graphmode[0].lweight, graphmode[0].size);
+		  Npts, data[0].style, 
+		  data[0].ptype, data[0].ltype, 
+		  data[0].etype, data[0].ebar, data[0].color, 
+		  data[0].lweight, data[0].size);
   KiiSendMessage (fd, "%g %g %g %g", 
-		  graphmode[0].xmin, graphmode[0].xmax, 
-		  graphmode[0].ymin, graphmode[0].ymax);
-  return (TRUE);
-}
-
-int KapaPlotVector (int fd, int Npts, float *values) {
+		  data[0].xmin, data[0].xmax, 
+		  data[0].ymin, data[0].ymax);
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaSetGraphData (int fd, Graphdata *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "SSTY"); 
+  
+  /* send kapa the plot details */
+  KiiSendMessage (fd, "%8d %d %d %d %d %d %f %f", 
+		  data[0].style, 
+		  data[0].ptype, data[0].ltype, 
+		  data[0].etype, data[0].ebar, data[0].color, 
+		  data[0].lweight, data[0].size);
+
+  KiiSendMessage (fd, "%g %g %g %g", 
+		  data[0].xmin, data[0].xmax, 
+		  data[0].ymin, data[0].ymax);
+
+  KiiSendMessage (fd, "%g %g %g %g", 
+		  data[0].coords.pc1_1, data[0].coords.pc2_2,
+		  data[0].coords.pc1_2, data[0].coords.pc2_1);
+
+  KiiSendMessage (fd, "%d %d %s", 
+		  data[0].flipeast, data[0].flipnorth,
+		  data[0].coords.ctype);
+
+  KiiSendMessage (fd, "%g %g %g %g %g %g", 
+		  data[0].coords.crval1,
+		  data[0].coords.crval2,
+		  data[0].coords.crpix1,
+		  data[0].coords.crpix2,
+		  data[0].coords.cdelt1,
+		  data[0].coords.cdelt2);
+
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaGetGraphData (int fd, Graphdata *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "GSTY"); 
+  
+  /* send kapa the plot details */
+  KiiScanMessage (fd, "%d %d %d %d %d %d %lf %lf", 
+		  &data[0].style, 
+		  &data[0].ptype, &data[0].ltype, 
+		  &data[0].etype, &data[0].ebar, &data[0].color, 
+		  &data[0].lweight, &data[0].size);
+
+  KiiScanMessage (fd, "%lf %lf %lf %lf", 
+		  &data[0].xmin, &data[0].xmax, 
+		  &data[0].ymin, &data[0].ymax);
+
+  KiiScanMessage (fd, "%f %f %f %f", 
+		  &data[0].coords.pc1_1, &data[0].coords.pc2_2,
+		  &data[0].coords.pc1_2, &data[0].coords.pc2_1);
+
+  KiiScanMessage (fd, "%d %d %s", 
+		  &data[0].flipeast, &data[0].flipnorth,
+		  data[0].coords.ctype);
+
+  KiiScanMessage (fd, "%lf %lf %f %f %f %f", 
+		  &data[0].coords.crval1,
+		  &data[0].coords.crval2,
+		  &data[0].coords.crpix1,
+		  &data[0].coords.crpix2,
+		  &data[0].coords.cdelt1,
+		  &data[0].coords.cdelt2);
+
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaSetImageData (int fd, KapaImageData *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "SIMD"); 
+  
+  /* send kapa the plot details */
+  KiiSendMessage (fd, "%g %g %s %s", 
+		  data[0].zero, data[0].range, data[0].name, data[0].file);
+
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaGetImageData (int fd, KapaImageData *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "GIMD"); 
+  
+  KiiScanMessage (fd, "%lf %lf %s %s", 
+		  &data[0].zero, &data[0].range, data[0].name, data[0].file);
+
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaPlotVector (int fd, int Npts, float *values, char *type) {
 
   int Nbytes;
+  int swap;
+
+# ifdef BYTE_SWAP
+  swap = 1;
+# else
+  swap = 0;
+# endif
 
   Nbytes = Npts * sizeof (float);
+
+  if (!strcmp(type, "x")) goto valid;
+  if (!strcmp(type, "y")) goto valid;
+  if (!strcmp(type, "z")) goto valid;
+  if (!strcmp(type, "dym")) goto valid;
+  if (!strcmp(type, "dyp")) goto valid;
+  if (!strcmp(type, "dxm")) goto valid;
+  if (!strcmp(type, "dxp")) goto valid;
+  return (FALSE);
+
+valid:
+  KiiSendCommand (fd, 4, "PLOB"); 
+  KiiSendMessage (fd, "%s %d %d %d", type, Npts, Nbytes, swap); 
+
   write (fd, values, Nbytes);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -93,12 +242,14 @@
   KiiSendCommand (fd, 16, "%s", name);
   KiiSendCommand (fd, 16, "%d", size);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
 
 int KapaSendLabel (int fd, char *string, int mode) {
-  
+
   KiiSendCommand (fd, 4, "LABL");
   KiiSendMessage (fd, "%6d", mode);
   KiiSendData (fd, string, strlen(string));
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -109,11 +260,22 @@
   KiiSendMessage (fd, "%f %f %f", x, y, angle);
   KiiSendData (fd, string, strlen(string));
-  return (TRUE);
-}
-
-int KapaSetLimits (int fd, Graphdata *graphmode) {
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaSetLimits (int fd, Graphdata *data) {
 
   KiiSendCommand (fd, 4, "SLIM");
-  KiiSendMessage (fd, "%g %g %g %g ", graphmode[0].xmin, graphmode[0].xmax, graphmode[0].ymin, graphmode[0].ymax);
+  KiiSendMessage (fd, "%g %g %g %g ", data[0].xmin, data[0].xmax, data[0].ymin, data[0].ymax);
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+// for now, this just gets the dimensions
+int KapaGetLimits (int fd, float *dx, float *dy) {
+
+  KiiSendCommand (fd, 4, "GLIM"); 
+  KiiScanMessage (fd, "%f %f", dx, dy); 
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -128,4 +290,22 @@
 		  section[0].dx,
 		  section[0].dy);
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaMoveSection (int fd, char *name, char *direction) {
+
+  if (!strcasecmp(direction, "up")) goto valid;
+  if (!strcasecmp(direction, "down")) goto valid;
+  if (!strcasecmp(direction, "top")) goto valid;
+  if (!strcasecmp(direction, "bottom")) goto valid;
+  
+  fprintf (stderr, "unexpected direction %s\n", direction); 
+  return (FALSE);
+
+valid:
+  KiiSendCommand (fd, 4, "MSEC");
+  KiiSendMessage (fd, "%s %s", name, direction);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -135,4 +315,5 @@
   KiiSendCommand (fd, 4, "SSEC");
   KiiSendMessage (fd, "%s", name);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -142,4 +323,5 @@
   KiiSendCommand (fd, 4, "LSEC");
   KiiSendMessage (fd, "%s", name);
-  return (TRUE);
-}
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
Index: /trunk/Ohana/src/libkapa/src/KiiConvert.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KiiConvert.c	(revision 13478)
+++ /trunk/Ohana/src/libkapa/src/KiiConvert.c	(revision 13479)
@@ -3,11 +3,7 @@
 int KiiJPEG (int fd, const char *filename) {
 
-  char buffer[20];
-
   KiiSendCommand (fd, 4, "JPEG");
   KiiSendMessage (fd, "%s", filename);
-
-  /* block for the response, which says the operation completed */
-  read (fd, buffer, 4);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -15,11 +11,7 @@
 int KapaPNG (int fd, const char *filename) {
 
-  char buffer[20];
-
   KiiSendCommand (fd, 4, "PNGF");
   KiiSendMessage (fd, "%s", filename);
-
-  /* block for the response, which says the operation completed */
-  read (fd, buffer, 4);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -27,11 +19,7 @@
 int KapaPPM (int fd, const char *filename) {
 
-  char buffer[20];
-
   KiiSendCommand (fd, 4, "PPMF");
   KiiSendMessage (fd, "%s", filename);
-
-  /* block for the response, which says the operation completed */
-  read (fd, buffer, 4);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -39,13 +27,7 @@
 int KiiPS (int fd, const char *filename, int scaleMode, int pageMode, char *pagename) {
 
-  char buffer[20];
-
-  /* the default operation */
   KiiSendCommand (fd, 4, "PSIT");
-
   KiiSendMessage (fd, "%s %s %d %d", filename, pagename, scaleMode, pageMode);
-
-  /* block for the response, which says the operation completed */
-  read (fd, buffer, 4);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
Index: /trunk/Ohana/src/libkapa/src/KiiCursor.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KiiCursor.c	(revision 13478)
+++ /trunk/Ohana/src/libkapa/src/KiiCursor.c	(revision 13479)
@@ -2,24 +2,21 @@
 
 int KiiCursorOn (int fd) {
-  write (fd, "CURS", 4); /* ask Source to look for the keystrokes */
+
+  KiiSendCommand (fd, 4, "CURS");
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
 
 int KiiCursorOff (int fd) {
-  write (fd, "NCUR", 4); /* ask Source to look for the keystrokes */
+
+  KiiSendCommand (fd, 4, "NCUR");
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
 
-int KiiCursorRead (int fd, double *x, double *y, char *key) {
+int KiiCursorRead (int fd, double *x, double *y, double *z, double *r, double *d, char *key) {
 
-  char buffer[40];
-
-  bzero (buffer, 40);
-  read (fd, buffer, 40);
-  buffer[39] = 0;
-
-  sscanf (buffer, "%s %lf %lf", key, x, y);
+  KiiScanMessage (fd, "%s %lf %lf %lf %lf %lf", key, x, y, z, r, d);
   if (ispunct(key[0])) strcpy (key, "_");
-
   return (TRUE);
 }
Index: /trunk/Ohana/src/libkapa/src/KiiOverlay.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KiiOverlay.c	(revision 13478)
+++ /trunk/Ohana/src/libkapa/src/KiiOverlay.c	(revision 13479)
@@ -50,5 +50,5 @@
 }
 
-int KiiLoadOverlay (int fd, KiiOverlay *overlay, int Noverlay, char *overname) {
+int KiiLoadOverlayOld (int fd, KiiOverlay *overlay, int Noverlay, char *overname) {
 
   int i, n, Nline;
@@ -84,8 +84,61 @@
 
   free (buffer);
+  KiiWaitAnswer (fd, "DONE");
 
   /* this is very inefficient: 128 bytes per object vs 17 as binary, plus the
      conversions back and forth
   */
+
+  return (TRUE);
+}
+
+int KiiLoadOverlay (int fd, KiiOverlay *overlay, int Noverlay, char *overname) {
+
+  int i, overnum, Ntextdata, NTEXTDATA, Ntext, Nchar;
+  char *textdata;
+  KiiOverlayBase *buffer;
+
+  Ntext = 0;
+  KiiSelectOverlay (overname, &overnum);
+
+  Ntextdata = 0;
+  NTEXTDATA = 1024;
+  ALLOCATE (textdata, char, 1024);
+
+  // we send the position information as a binary block
+  ALLOCATE (buffer, KiiOverlayBase, Noverlay);
+  for (i = 0; i < Noverlay; i++) {
+    buffer[i].x    = overlay[i].x;
+    buffer[i].y    = overlay[i].y;
+    buffer[i].dx   = overlay[i].dx;
+    buffer[i].dy   = overlay[i].dy;
+    buffer[i].type = overlay[i].type;
+    if (buffer[i].type == KII_OVERLAY_TEXT) {
+      Ntext ++;
+      Nchar = strlen(overlay[i].text) + 1;
+      if (Ntextdata + Nchar >= NTEXTDATA) {
+	NTEXTDATA += 1024;
+	REALLOCATE (textdata, char, NTEXTDATA);
+      }
+      sprintf (&textdata[Ntextdata], "%s\n", overlay[i].text);
+      Ntextdata += Nchar;
+    }
+  }
+
+  KiiSendCommand (fd,  4, "LOAD");
+  KiiSendMessage (fd, "%d %d %d %d", overnum, Noverlay, Ntext, Ntextdata);
+
+  // we could break this into segments if we want to trap an interrupt, but why bother?
+  Nchar = write (fd, buffer, Noverlay*sizeof(KiiOverlayBase));
+  fprintf (stderr, "sent %d of %d bytes\n", Nchar, Noverlay*sizeof(KiiOverlayBase));
+  KiiWaitAnswer (fd, "DONE");
+
+  write (fd, textdata, Ntextdata);
+  KiiWaitAnswer (fd, "DONE");
+
+  free (buffer);
+  free (textdata);
+
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -97,7 +150,7 @@
   KiiSelectOverlay (overname, &n);
     
-  KiiSendCommand (fd, 4, "ERAS");
+  KiiSendCommand (fd, 4, "ERSO");
   KiiSendCommand (fd, 16, "OVERLAY %7d ", n);
-
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
@@ -116,4 +169,5 @@
 
   KiiSendMessage (fd, "FILE: %d %s", n, file);
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
Index: /trunk/Ohana/src/libkapa/src/KiiPicture.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KiiPicture.c	(revision 13478)
+++ /trunk/Ohana/src/libkapa/src/KiiPicture.c	(revision 13479)
@@ -1,15 +1,50 @@
 # include <kapa_internal.h>
 
-int KiiNewPicture1D (int fd, KiiImage *image, KiiDisplayMode *mode, Coords *coords) {
+int KiiNewPicture1D (int fd, KiiImage *image, KapaImageData *data, Coords *coords) {
 
   int i;
   int Npix, Ncolors, NNcolors, size;
   float *in, min, max;
-  char *out, *outbuffer, *root;
+  char *out, *outbuffer;
   double a1, a2;
 
   Npix = image[0].Nx*image[0].Ny;
 
-  KiiSendCommand (fd, 4, "READ"); /* tell Ximage to look for the incoming image */
+  KiiSendCommand (fd, 4, "READ"); /* tell kapa to look for the incoming image */
+  KiiScanMessage (fd, "%d", &Ncolors);
+
+  in = image[0].data1d;
+
+  /* these are for a future upgrade */
+  min = max = 0.0;
+  size = Npix*sizeof(float);
+
+  /* done with the conversion, now send kapa the converted picture */
+  KiiSendMessage (fd, "%8d %8d", image[0].Nx, image[0].Ny);
+  KiiSendMessage (fd, "-32 1 0.0 1.0");
+  KiiSendMessage (fd, "%f %f %s %s", data[0].zero, data[0].range, data[0].name, data[0].file);
+  KiiSendMessage (fd, "%f %f %d ", min, max, size);
+  KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval1, coords[0].crpix1, coords[0].cdelt1, coords[0].pc1_1, coords[0].pc1_2);
+  KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval2, coords[0].crpix2, coords[0].cdelt2, coords[0].pc2_1, coords[0].pc2_2);
+  KiiSendMessage (fd, "%s", coords[0].ctype);
+
+  /* send the image data */
+  write (fd, image[0].data1d, size);
+
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KiiNewPicture1D_8bit (int fd, KiiImage *image, KapaImageData *data, Coords *coords) {
+
+  int i;
+  int Npix, Ncolors, NNcolors, size;
+  float *in, min, max;
+  char *out, *outbuffer;
+  double a1, a2;
+
+  Npix = image[0].Nx*image[0].Ny;
+
+  KiiSendCommand (fd, 4, "READ"); /* tell kapa to look for the incoming image */
   KiiScanMessage (fd, "%d", &Ncolors);
 
@@ -22,14 +57,14 @@
   /* define color table, */
   NNcolors = Ncolors - 1;
-  if (mode[0].logflux) {
-    mode[0].range = MAX (2, mode[0].range);
-    a1 = Ncolors / log10 (mode[0].range);
-    a2 = mode[0].zero;
+  if (data[0].logflux) {
+    data[0].range = MAX (2, data[0].range);
+    a1 = Ncolors / log10 (data[0].range);
+    a2 = data[0].zero;
     for (i = 0; i < Npix; i++, in++, out++) {
       *out = (char) MIN (a1 * log10 (MAX (*in - a2, 1.0)), NNcolors);
     }
   } else {
-    a1 = Ncolors / mode[0].range;
-    a2 = Ncolors * mode[0].zero / mode[0].range;
+    a1 = Ncolors / data[0].range;
+    a2 = Ncolors * data[0].zero / data[0].range;
     for (i = 0; i < Npix; i++, in++, out++) {
       *out = (char) MIN (MAX (a1 * *in - a2, 0), NNcolors);
@@ -41,16 +76,12 @@
   size = Npix*sizeof(char);
 
-  /* done with the conversion, now send Ximage the converted picture */
+  /* done with the conversion, now send kapa the converted picture */
   KiiSendMessage (fd, "%8d %8d", image[0].Nx, image[0].Ny);
   KiiSendMessage (fd, "8 1 0.0 1.0");
-  KiiSendMessage (fd, "%f %f ", mode[0].zero, mode[0].range);
+  KiiSendMessage (fd, "%f %f %s %s", data[0].zero, data[0].range, data[0].name, data[0].file);
   KiiSendMessage (fd, "%f %f %d ", min, max, size);
   KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval1, coords[0].crpix1, coords[0].cdelt1, coords[0].pc1_1, coords[0].pc1_2);
   KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval2, coords[0].crpix2, coords[0].cdelt2, coords[0].pc2_1, coords[0].pc2_2);
-
-  /* send the filename */
-  root = filerootname (image[0].file);
-  KiiSendMessage (fd, "%s %s %s ", coords[0].ctype, root, image[0].name);
-  free (root);
+  KiiSendMessage (fd, "%s", coords[0].ctype);
 
   /* send the image data */
@@ -58,24 +89,20 @@
   free (outbuffer);
 
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
 
-int KiiNewPicture2D (int fd, KiiImage *image, KiiDisplayMode *mode, Coords *coords) {
+int KiiNewPicture2D (int fd, KiiImage *image, KapaImageData *data, Coords *coords) {
 
   int i, j;
   int Npix, Ncolors, NNcolors, size;
   float *in, min, max;
-  char *out, *outbuffer, *root;
-  char buffer[1024];
+  char *out, *outbuffer;
   double a1, a2;
 
   Npix = image[0].Nx*image[0].Ny;
 
-  KiiSendCommand (fd, 4, "READ"); /* tell Ximage to look for the incoming image */
-
-  /* convert from (float *) to 1 byte chars -- depends on how many colors Kii owns */
-  /* use this response as a handshake test */
-  read (fd, buffer, 16); 
-  sscanf (buffer, "%*s %d", &Ncolors); 
+  KiiSendCommand (fd, 4, "READ"); /* tell kapa to look for the incoming image */
+  KiiScanMessage (fd, "%d", &Ncolors);
 
   ALLOCATE (outbuffer, char, Npix);
@@ -86,8 +113,8 @@
   /* define color table, */
   NNcolors = Ncolors - 1;
-  if (mode[0].logflux) {
-    mode[0].range = MAX (2, mode[0].range);
-    a1 = Ncolors / log10 (mode[0].range);
-    a2 = mode[0].zero;
+  if (data[0].logflux) {
+    data[0].range = MAX (2, data[0].range);
+    a1 = Ncolors / log10 (data[0].range);
+    a2 = data[0].zero;
     for (j = 0; j < image[0].Ny; j++) {
       in = image[0].data2d[j];
@@ -97,6 +124,6 @@
     }
   } else {
-    a1 = Ncolors / mode[0].range;
-    a2 = Ncolors * mode[0].zero / mode[0].range;
+    a1 = Ncolors / data[0].range;
+    a2 = Ncolors * data[0].zero / data[0].range;
     for (j = 0; j < image[0].Ny; j++) {
       in = image[0].data2d[j];
@@ -111,13 +138,12 @@
   size = Npix*sizeof(char);
 
-  /* done with the conversion, now send Ximage the converted picture */
-  KiiSendMessage (fd, "%8d %8d 8 1 %f %f", image[0].Nx, image[0].Ny, 0.0, 1.0);
-  KiiSendMessage (fd, "%f %f %f %f %d ", mode[0].zero, mode[0].range, min, max, size);
+  /* done with the conversion, now send kapa the converted picture */
+  KiiSendMessage (fd, "%8d %8d", image[0].Nx, image[0].Ny);
+  KiiSendMessage (fd, "8 1 0.0 1.0");
+  KiiSendMessage (fd, "%f %f %s %s", data[0].zero, data[0].range, data[0].name, data[0].file);
+  KiiSendMessage (fd, "%f %f %d ", min, max, size);
   KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval1, coords[0].crpix1, coords[0].cdelt1, coords[0].pc1_1, coords[0].pc1_2);
   KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval2, coords[0].crpix2, coords[0].cdelt2, coords[0].pc2_1, coords[0].pc2_2);
-
-  /* send the filename */
-  root = filerootname (image[0].file);
-  KiiSendMessage (fd, "%s %s %s ", coords[0].ctype, root, image[0].name);
+  KiiSendMessage (fd, "%s", coords[0].ctype);
 
   /* send the image data */
@@ -125,4 +151,5 @@
   free (outbuffer);
 
+  KiiWaitAnswer (fd, "DONE");
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.astro/cgrid.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/cgrid.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/cgrid.c	(revision 13479)
@@ -14,8 +14,8 @@
   double x, y;
   Vector Xvec, Yvec;
-  int NorthPole, SouthPole, N, OnPic, LOnPic, status, NELEMENTS, First;
+  int kapa, NorthPole, SouthPole, N, OnPic, LOnPic, status, NELEMENTS, First;
   Graphdata graphmode;
 
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   if (argc != 1) {
@@ -23,5 +23,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
 
   /* are we plotting one of the poles? */
@@ -392,7 +391,5 @@
   graphmode.ptype = 100; /* connect a pair */
   graphmode.etype = 0;
-  PrepPlotting (N, &graphmode);
-  PlotVector (N, Xvec.elements);
-  PlotVector (N, Yvec.elements);
+  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
 
   free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/cmd.astro/cplot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/cplot.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/cplot.c	(revision 13479)
@@ -3,10 +3,10 @@
 int cplot (int argc, char **argv) {
   
-  int i, Npts, status;
+  int i, kapa, Npts, status;
   float *x, *y, *r, *d, Rmin, Rmax;
   Vector Xvec, Yvec, *xvec, *yvec;
   Graphdata graphmode;
 
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   if (argc != 3) {
@@ -14,5 +14,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
 
   Rmin = graphmode.coords.crval1 - 182.0;
@@ -67,7 +66,5 @@
 
   graphmode.etype = 0;
-  PrepPlotting (Npts, &graphmode);
-  PlotVector (Npts, Xvec.elements);
-  PlotVector (Npts, Yvec.elements);
+  PlotVectorPair (kapa, Npts, Xvec.elements, Yvec.elements, &graphmode);
   
   free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/cmd.astro/czplot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/czplot.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/czplot.c	(revision 13479)
@@ -3,5 +3,5 @@
 int czplot (int argc, char **argv) {
   
-  int i, Npts;
+  int i, kapa, Npts;
   double min, range, Rmin, Rmax;
   float *in, *out, *r, *d, *x, *y;
@@ -9,5 +9,5 @@
   Graphdata graphmode;
 
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   if (argc != 6) {
@@ -15,5 +15,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
 
   min = atof(argv[4]);
@@ -59,9 +58,5 @@
   graphmode.etype = 0;
   Npts = Xvec.Nelements;
-  PrepPlotting (Npts, &graphmode);
-
-  PlotVector (Npts, Xvec.elements);
-  PlotVector (Npts, Yvec.elements);
-  PlotVector (Npts, Zvec.elements);
+  PlotVectorTriplet (kapa, Npts, Xvec.elements, Yvec.elements, Zvec.elements, &graphmode);
 
   free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/cmd.astro/gauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/gauss.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/gauss.c	(revision 13479)
@@ -5,15 +5,18 @@
   char key[20];
   int i, N, Npix, Nborder, Nspot;
-  double X, Y, Z, max;
-  int Ximage, Nimage;
+  double X, Y, Z, ZP, RA, DEC, max;
+  int kapa;
+  char *name;
   Buffer *buf;
+  KapaImageData data;
 
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImageData (&data, &kapa, name)) return (FALSE);
+  FREE (name);
 
   Nborder = 3;
@@ -37,5 +40,5 @@
   }
   
-  if (Ximage < 1) {
+  if (kapa < 1) {
     gprint (GP_ERR, "no active TV\n");
     return (FALSE);
@@ -48,14 +51,14 @@
   }
 
-  if ((buf = SelectBuffer (GetImageName(), OLDBUFFER, TRUE)) == NULL) return (FALSE);
+  if ((buf = SelectBuffer (data.name, OLDBUFFER, TRUE)) == NULL) return (FALSE);
 
-  KiiCursorOn (Ximage);
+  KiiCursorOn (kapa);
 
   for (i = 0; (i < Nspot) || (Nspot == 0); i++) {
-    KiiCursorRead (Ximage, &X, &Y, key);
+    KiiCursorRead (kapa, &X, &Y, &ZP, &RA, &DEC, key);
     if (!strcasecmp (key, "Q")) break;
     Z = get_aperture_stats (&buf[0].matrix, (int)(X+0.5), (int)(Y+0.5), Npix, Nborder, max);
   }
-  KiiCursorOff (Ximage);
+  KiiCursorOff (kapa);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.astro/objload.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/objload.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/objload.c	(revision 13479)
@@ -7,15 +7,16 @@
   int i, N, Objtype, type, Nline, status;
   FILE *f;
-  char *buffer, *line;
-  int Ximage, Nimage, Noverlay, NOVERLAY;
+  char *buffer, *line, *name;
+  int kapa, Noverlay, NOVERLAY;
   KiiOverlay *overlay;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   Objtype = 0;
@@ -63,5 +64,5 @@
   free (buffer);
 
-  KiiLoadOverlay (Ximage, overlay, Noverlay, argv[1]);
+  KiiLoadOverlay (kapa, overlay, Noverlay, argv[1]);
 
   free (overlay);
Index: /trunk/Ohana/src/opihi/cmd.astro/outline.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/outline.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/outline.c	(revision 13479)
@@ -145,5 +145,5 @@
     /* code to draw dots on Ximage */
     {
-      int Nimage, Ximage;
+      int kapa;
       float xp, yp, x, y;
       float dx, dy, theta, t, dt;
@@ -151,6 +151,5 @@
       KiiOverlay *overlay;
       
-      Nimage = -1;
-      if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+      if (!GetImage (NULL, &kapa, NULL)) return (FALSE);
       
       Noverlay = 0;
@@ -179,5 +178,5 @@
 	CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 1000);
       }
-      KiiLoadOverlay (Ximage, overlay, Noverlay, "red");
+      KiiLoadOverlay (kapa, overlay, Noverlay, "red");
       free (overlay);
     }
Index: /trunk/Ohana/src/opihi/cmd.astro/outline2.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/outline2.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/outline2.c	(revision 13479)
@@ -303,5 +303,5 @@
 int plot_outline () {
   
-  int Nimage, Ximage;
+  int kapa;
   float xp, yp, x, y;
   float dx, dy, theta, t, dt;
@@ -309,6 +309,5 @@
   KiiOverlay *overlay;
   
-  Nimage = -1;
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, NULL)) return (FALSE);
   
   Noverlay = 0;
@@ -337,5 +336,5 @@
     CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 1000);
   }
-  KiiLoadOverlay (Ximage, overlay, Noverlay, "red");
+  KiiLoadOverlay (kapa, overlay, Noverlay, "red");
   free (overlay);
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.astro/region.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/region.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.astro/region.c	(revision 13479)
@@ -5,10 +5,17 @@
   char string[256];
   double Ra, Dec, Radius;
-  double dx, dy;
-  int N, Ngraph, Xgraph;
+  float dx, dy;
+  int N, kapa;
+  char *name;
   Graphdata graphmode;
 
-  Ngraph = 0;
-  if (!GetGraph (&graphmode, &Xgraph, &Ngraph)) return (FALSE);
+  name = NULL;
+  if ((N = get_argument (argc, argv, "-n"))) {
+    remove_argument (N, &argc, argv);
+    name = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!GetGraph (&graphmode, &kapa, name)) return (FALSE);
+  FREE (name);
 
   if ((N = get_argument (argc, argv, "-ew"))) {
@@ -60,6 +67,5 @@
   
   /* ask kapa for coordinate limits, so get the right aspect ratio */
-  KiiSendCommand (Xgraph, 4, "LIMS"); 
-  KiiScanMessage (Xgraph, "%lf %lf", &dx, &dy); 
+  KapaGetLimits (kapa, &dx, &dy);
   dx = fabs (dx);
   dy = fabs (dy); 
@@ -101,12 +107,13 @@
   graphmode.coords.cdelt1 = graphmode.coords.cdelt2 = 1.0;
 
-  KapaClear (Xgraph, TRUE);
-  KapaSetLimits (Xgraph, &graphmode);
+  KapaClearSections (kapa);
+  KapaSetLimits (kapa, &graphmode);
 
   /* drop this? */
   sprintf (string, "%8.4f %8.4f (%f)", Ra, Dec, Radius);
-  KapaSendLabel (Xgraph, string, 2);
+  KapaSendLabel (kapa, string, 2);
 
-  SetGraph (graphmode);
+  // XXX is this the right thing to be doing?
+  SetGraph (&graphmode);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/box.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/box.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/box.c	(revision 13479)
@@ -3,14 +3,16 @@
 int box (int argc, char **argv) {
   
-  int i, N, Ngraph, Xgraph;
+  int i, N, kapa;
+  char *name;
   Graphdata graphmode;
   
-  Ngraph = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetGraph (&graphmode, &Xgraph, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, &kapa, name)) return (FALSE);
+  FREE (name);
 
   strcpy (graphmode.ticks, "2222");
@@ -49,5 +51,5 @@
   if (argc != 1) goto usage;
 
-  KapaBox (Xgraph, &graphmode);
+  KapaBox (kapa, &graphmode);
   return (TRUE);
       
Index: /trunk/Ohana/src/opihi/cmd.data/center.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/center.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/center.c	(revision 13479)
@@ -5,13 +5,15 @@
   double x, y;
   int zoom;
-  int Ximage, Nimage, N;
+  int kapa, N;
+  char *name;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   if ((argc != 3) && (argc != 4)) {
@@ -25,5 +27,5 @@
   if (argc == 4) zoom = atof (argv[3]);
 
-  KiiCenter (Ximage, x, y, zoom);
+  KiiCenter (kapa, x, y, zoom);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/clear.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/clear.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/clear.c	(revision 13479)
@@ -1,29 +1,48 @@
 # include "data.h"
 
+// default is to clear all plots, but not the sections or the images
 int clear (int argc, char **argv) {
   
-  int N, ClearSection;
-  int Ngraph, Xgraph;
+  int N;
+  int kapa;
+  char *name;
 
-  Ngraph = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetGraph (NULL, &Xgraph, &Ngraph)) return (FALSE);
+  if (!GetGraph (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
-  ClearSection = FALSE;
-  if ((N = get_argument (argc, argv, "-s"))) {
-    remove_argument (N, &argc, argv);
-    ClearSection = TRUE;
+  // clear all sections
+  if ((N = get_argument (argc, argv, "-s")) || 
+      (N = get_argument (argc, argv, "-section"))) {
+      KapaClearSections (kapa);
+      return (TRUE);
+  }
+
+  // clear all sections
+  if ((N = get_argument (argc, argv, "-graph"))) {
+      KapaClearCurrentPlot (kapa);
+      return (TRUE);
+  }
+
+  // clear image
+  if ((N = get_argument (argc, argv, "-image"))) {
+      KapaClearImage (kapa);
+      return (TRUE);
   }
 
   if (argc != 1) {
-    gprint (GP_ERR, "USAGE: clear [-n Xgraph]\n");
+    gprint (GP_ERR, "USAGE: clear [-n Xgraph] [-s|-section] [-image] [-graph]\n");
+    gprint (GP_ERR, "       [-s|-section] : clear all sections\n");
+    gprint (GP_ERR, "       [-graph]      : clear current graph\n");
+    gprint (GP_ERR, "       [-image]      : clear current image\n");
     return (FALSE);
   }
 
-  KapaClear (Xgraph, ClearSection);
+  KapaClearPlots (kapa);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/close.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/close.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/close.c	(revision 13479)
@@ -3,30 +3,19 @@
 int close_device (int argc, char **argv) {
 
-  int N, Source, Nsource, IsImage;
+  int N, kapa, IsImage;
+  char *name;
   /* close current graphics device */
 
-  Nsource = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nsource = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if ((N = get_argument (argc, argv, "-g"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (FALSE);
-  }  
-  if ((N = get_argument (argc, argv, "-i"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (TRUE);
-  }  
 
-  IsImage = GetCurrentDevice ();
-  if (IsImage) {
-    if (!GetImage (&Source, &Nsource)) return (FALSE);
-    close_image (Nsource); 
-  } else {
-    if (!GetGraph (NULL, &Source, &Nsource)) return (FALSE);
-    close_graph (Nsource); 
-  }
+  if (!GetGraph (NULL, &kapa, name)) return (FALSE);
+
+  close_kapa (name); 
+  FREE (name);
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/cursor.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/cursor.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/cursor.c	(revision 13479)
@@ -3,31 +3,23 @@
 int cursor (int argc, char **argv) {
 
-  char string[20], key[20];
-  int i, N, Nsource, Source, IsImage;
+  char string[20], key[20], *name;
+  int i, N, kapa;
   double X, Y, R, D, Z;
   void *oldsignal;
-  Graphdata graphmode;
-  Buffer *buf;
 
-  Nsource = -1;
+  // XXX need to be able to specify graph vs image coords
+  // currently, if only one exists, that frame will be used
+  // if both exist, defaults to ??
+  // if ((N = get_argument (argc, argv, "-g"))) {
+  // if ((N = get_argument (argc, argv, "-i"))) {
+
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nsource = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if ((N = get_argument (argc, argv, "-g"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (FALSE);
-  }  
-  if ((N = get_argument (argc, argv, "-i"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (TRUE);
-  }  
-  IsImage = GetCurrentDevice ();
-  if (IsImage) {
-    if (!GetImage (&Source, &Nsource)) return (FALSE);
-  } else {
-    if (!GetGraph (&graphmode, &Source, &Nsource)) return (FALSE);
-  }
+  if (!GetGraphData (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   N = 0;
@@ -39,14 +31,12 @@
   }
   
-  buf = NULL;
-  if (IsImage) buf = SelectBuffer (GetImageName(), OLDBUFFER, FALSE);
-  
-  KiiCursorOn (Source);
+  KiiCursorOn (kapa);
   
   oldsignal = signal (SIGINT, handle_interrupt);
   interrupt = FALSE;
-  Z = -1.0;
+
   for (i = 0; ((i < N) || (N == 0)) && !interrupt; i++) {
-    KiiCursorRead (Source, &X, &Y, key);
+
+    KiiCursorRead (kapa, &X, &Y, &Z, &R, &D, key);
 
     sprintf (string, "X%s", key);
@@ -54,24 +44,20 @@
     sprintf (string, "Y%s", key);
     set_variable (string, Y);
+    sprintf (string, "Z%s", key);
+    set_variable (string, Z);
+    sprintf (string, "R%s", key);
+    set_variable (string, R);
+    sprintf (string, "D%s", key);
+    set_variable (string, D);
+
     set_str_variable ("KEY", key);
     
-    if (IsImage) {
-      if (buf != NULL) { 
-	Z = gfits_get_matrix_value (&buf[0].matrix, (int) X, (int) Y);
-      }
-      gprint (GP_LOG, "%s %f %f  %f\n", key, X, Y, Z);
-    } else {
-      XY_to_RD (&R, &D, X, Y, &graphmode.coords);
-      sprintf (string, "R%s", key);
-      set_variable (string, R);
-      sprintf (string, "D%s", key);
-      set_variable (string, D);
-      gprint (GP_LOG, "%s %f %f\n", key, X, Y);
-    }
+    gprint (GP_LOG, "%s %f %f %f %f %f\n", key, X, Y, Z, R, D);
+
     if (!strcasecmp (key, "Q")) break;
   }
 
   signal (SIGINT, oldsignal);
-  KiiCursorOff (Source);
+  KiiCursorOff (kapa);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/device.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/device.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/device.c	(revision 13479)
@@ -3,30 +3,25 @@
 int device (int argc, char **argv) {
 
-  int N, Source, Nsource, IsImage;
+  int N, kapa, IsImage;
+  char *name;;
   /* set / get current graphics device */
 
-  Nsource = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nsource = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if ((N = get_argument (argc, argv, "-g"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (FALSE);
-  }  
-  if ((N = get_argument (argc, argv, "-i"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (TRUE);
-  }  
 
-  IsImage = GetCurrentDevice ();
-  if (IsImage) {
-    if (!GetImage (&Source, &Nsource)) return (FALSE);
-    gprint (GP_ERR, "kii %d\n", Nsource); 
+  if (name == NULL) {
+    name = GetKapaName ();
+    if (name == NULL) {
+      gprint (GP_ERR, "no device defined\n");
+      return (NULL);
+    }
   } else {
-    if (!GetGraph (NULL, &Source, &Nsource)) return (FALSE);
-    gprint (GP_ERR, "kapa %d\n", Nsource); 
+    if (!GetGraph (NULL, &kapa, name)) return (FALSE);
   }
+  gprint (GP_ERR, "kapa %s\n", name); 
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/dot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/dot.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/dot.c	(revision 13479)
@@ -3,8 +3,9 @@
 int dot (int argc, char **argv) {
   
+  int kapa;
   Graphdata graphmode;
   float x, y;
 
-  if (!style_args (&graphmode, &argc, argv, -1)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   if (argc != 3) {
@@ -15,15 +16,11 @@
   y = atof(argv[2]);
 
-  /* set plotting options (these are sticky) */
-  SetGraph (graphmode);
-
   /* set point style and errorbar mode (these are NOT sticky) */
   graphmode.style = 2;
   graphmode.etype = 0;
 
-  if (!PrepPlotting (1, &graphmode)) return (FALSE);
-  
-  PlotVector (1, &x);
-  PlotVector (1, &y);
+  if (!KapaPrepPlot (kapa, 1, &graphmode)) return (FALSE);
+  KapaPlotVector (kapa, 1, &x, "x");
+  KapaPlotVector (kapa, 1, &y, "y");
   
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/erase.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/erase.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/erase.c	(revision 13479)
@@ -4,13 +4,15 @@
   
   int i, N;
-  int Ximage, Nimage;
+  int kapa;
+  char *name;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   if (argc < 2) {
@@ -22,8 +24,8 @@
   for (i = 1; i < argc; i++) {
     if (!(strcasecmp (argv[i], "all"))) {
-      KiiEraseOverlay (Ximage, "red");
-      KiiEraseOverlay (Ximage, "green");
-      KiiEraseOverlay (Ximage, "blue");
-      KiiEraseOverlay (Ximage, "yellow");
+      KiiEraseOverlay (kapa, "red");
+      KiiEraseOverlay (kapa, "green");
+      KiiEraseOverlay (kapa, "blue");
+      KiiEraseOverlay (kapa, "yellow");
       continue;
     }
@@ -32,5 +34,5 @@
       return (FALSE);
     }
-    KiiEraseOverlay (Ximage, argv[i]);
+    KiiEraseOverlay (kapa, argv[i]);
   }
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/grid.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/grid.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/grid.c	(revision 13479)
@@ -3,17 +3,10 @@
 int grid (int argc, char **argv) {
   
-  int j, N, MinorTick, MajorTick;
+  int j, kapa, N, MinorTick, MajorTick;
   Vector Xvec, Yvec;
   double range, lrange, factor, mantis, fmantis, power, major, minor, first, next;
   Graphdata graphmode;
-  int Ngraph;
-
-  Ngraph = -1;
-  if ((N = get_argument (argc, argv, "-n"))) {
-    remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return (FALSE);
 
   MajorTick = TRUE;
@@ -200,7 +193,5 @@
   graphmode.ptype = 100; /* connect a pair */
   graphmode.etype = 0;
-  PrepPlotting (N, &graphmode);
-  PlotVector (N, Xvec.elements);
-  PlotVector (N, Yvec.elements);
+  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
 
   free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/init.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/init.c	(revision 13479)
@@ -235,6 +235,5 @@
   int i;
 
-  InitGraph ();
-  InitImage ();
+  InitKapa ();
   InitQueues ();
 
Index: /trunk/Ohana/src/opihi/cmd.data/jpeg.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/jpeg.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/jpeg.c	(revision 13479)
@@ -4,5 +4,6 @@
 
   char filename[1024];
-  int N, Source, Nsource, IsImage, IsPNG;
+  int N, kapa, IsImage, IsPNG, IsPPM;
+  char *name;
   
   if ((N = get_argument (argc, argv, "--help"))) {
@@ -12,9 +13,15 @@
 
   /* image type */
-  IsPNG = TRUE;
+  IsPPM = IsPNG = FALSE;
   if ((N = get_argument (argc, argv, "-ppm"))) {
     remove_argument (N, &argc, argv);
-    IsPNG = FALSE;
+    IsPPM = TRUE;
   }
+  if ((N = get_argument (argc, argv, "-png"))) {
+    remove_argument (N, &argc, argv);
+    IsPNG = TRUE;
+  }
+  if (!strcmp (argv[0], "png")) IsPNG = TRUE;
+  if (!strcmp (argv[0], "ppm")) IsPPM = TRUE;
 
   /* file name */
@@ -27,31 +34,30 @@
 
   /* display source */
-  Nsource = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nsource = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
+
+  /* XXX output png / jpeg needs to include both graph and image
+     if available.  this is a poor mix of data representations 
+     (png for image / jpeg for plots)
   if ((N = get_argument (argc, argv, "-g"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (FALSE);
-  }  
   if ((N = get_argument (argc, argv, "-i"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (TRUE);
-  }  
-  IsImage = GetCurrentDevice ();
-  if (IsImage) {
-    if (!GetImage (&Source, &Nsource)) return (FALSE);
-    if (!filename[0]) strcpy (filename, "Ximage.jpg");
-    KiiJPEG (Source, filename);
-  } else {
-    if (!GetGraph (NULL, &Source, &Nsource)) return (FALSE);
-    if (!filename[0]) strcpy (filename, "Xgraph.png");
-    if (IsPNG) {
-      KapaPNG (Source, filename);
-    } else {
-      KapaPPM (Source, filename);
-    }
+  */
+
+  if (!GetGraph (NULL, &kapa, name)) return (FALSE);
+  if (!IsPNG && !IsPPM) {
+    if (!filename[0]) strcpy (filename, "kapa.jpg");
+    KiiJPEG (kapa, filename);
+  }
+  if (IsPNG) {
+    if (!filename[0]) strcpy (filename, "kapa.png");
+    KapaPNG (kapa, filename);
+  } 
+  if (IsPPM) {
+    if (!filename[0]) strcpy (filename, "kapa.ppm");
+    KapaPPM (kapa, filename);
   }
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/labels.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/labels.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/labels.c	(revision 13479)
@@ -4,7 +4,7 @@
   
   char name[64];
-  int N, size, Xgraph;
+  int N, size, kapa;
 
-  if (!GetGraph (NULL, &Xgraph, NULL)) return (FALSE);
+  if (!GetGraph (NULL, &kapa, NULL)) return (FALSE);
 
   if (get_argument (argc, argv, "-h")) {
@@ -36,10 +36,10 @@
     size = atof (argv[N]);
     remove_argument (N, &argc, argv);
-    KapaSetFont (Xgraph, name, size);
+    KapaSetFont (kapa, name, size);
   } 
 
   if ((N = get_argument (argc, argv, "-x"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 0);
+    KapaSendLabel (kapa, argv[N], 0);
     remove_argument (N, &argc, argv);
   }
@@ -47,5 +47,5 @@
   if ((N = get_argument (argc, argv, "-y"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 1);
+    KapaSendLabel (kapa, argv[N], 1);
     remove_argument (N, &argc, argv);
   }
@@ -53,5 +53,5 @@
   if ((N = get_argument (argc, argv, "+x"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 2);
+    KapaSendLabel (kapa, argv[N], 2);
     remove_argument (N, &argc, argv);
   }
@@ -59,5 +59,5 @@
   if ((N = get_argument (argc, argv, "+y"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 3);
+    KapaSendLabel (kapa, argv[N], 3);
     remove_argument (N, &argc, argv);
   }
@@ -65,5 +65,5 @@
   if ((N = get_argument (argc, argv, "-ul"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 4);
+    KapaSendLabel (kapa, argv[N], 4);
     remove_argument (N, &argc, argv);
   }
@@ -71,5 +71,5 @@
   if ((N = get_argument (argc, argv, "-ur"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 5);
+    KapaSendLabel (kapa, argv[N], 5);
     remove_argument (N, &argc, argv);
   }
@@ -77,5 +77,5 @@
   if ((N = get_argument (argc, argv, "-ll"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 6);
+    KapaSendLabel (kapa, argv[N], 6);
     remove_argument (N, &argc, argv);
   }
@@ -83,5 +83,5 @@
   if ((N = get_argument (argc, argv, "-lr"))) {
     remove_argument (N, &argc, argv);
-    KapaSendLabel (Xgraph, argv[N], 7);
+    KapaSendLabel (kapa, argv[N], 7);
     remove_argument (N, &argc, argv);
   }
Index: /trunk/Ohana/src/opihi/cmd.data/limits.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/limits.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/limits.c	(revision 13479)
@@ -4,5 +4,6 @@
 
   int N, APPLY;
-  int Ngraph, Xgraph;
+  int kapa;
+  char *name;
   Graphdata graphmode;
   Vector *xvec, *yvec;
@@ -15,15 +16,15 @@
     APPLY = TRUE;
   }
-
-  Ngraph = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetGraph (&graphmode, &Xgraph, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, &kapa, name)) return (FALSE);
+  FREE (name);
 
   if (argc == 1) {
-    gprint (GP_ERR, "limits: %f %f %f %f [-a] [-n Xgraph]\n",
+    gprint (GP_ERR, "limits: %f %f %f %f [-a] [-n device]\n",
 	     graphmode.xmin, graphmode.xmax,
 	     graphmode.ymin, graphmode.ymax);
@@ -71,5 +72,5 @@
  success:
   SetLimits (xvec, yvec, &graphmode);
-  if (APPLY) KapaSetLimits (Xgraph, &graphmode);
+  if (APPLY) KapaSetLimits (kapa, &graphmode);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/line.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/line.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/line.c	(revision 13479)
@@ -3,8 +3,9 @@
 int line (int argc, char **argv) {
   
+  int kapa;
   Graphdata graphmode;
   float x[2], y[2];
 
-  if (!style_args (&graphmode, &argc, argv, -1)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   if (argc != 6) {
@@ -17,16 +18,12 @@
   y[1] = atof(argv[5]);
 
-  SetGraph (graphmode);
-
   /* set point style and errorbar mode (these are NOT sticky) */
   graphmode.style = 0;
   graphmode.etype = 0;
 
-  if (!PrepPlotting (2, &graphmode)) return (FALSE);
-  
-  PlotVector (2, x);
-  PlotVector (2, y);
+  if (!KapaPrepPlot (kapa, 2, &graphmode)) return (FALSE);
+  KapaPlotVector (kapa, 2, x, "x");
+  KapaPlotVector (kapa, 2, y, "y");
   
   return (TRUE);
-
 }
Index: /trunk/Ohana/src/opihi/cmd.data/load.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/load.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/load.c	(revision 13479)
@@ -4,21 +4,23 @@
   
   int i, N, n, ISCEL;
-  int Ximage, Nimage, Noverlay, NOVERLAY;
+  int kapa, Noverlay, NOVERLAY;
   char *c, type[10], string[128], line[1024];
   double x, y, dx, dy, x1, y1;
   double dra, ddec, ra1, dec1, ra, dec;
   FILE *f;
-  char *buffer;
+  char *buffer, *name;
   Coords coords;
   Buffer *buf;
   KiiOverlay *overlay;
+  KapaImageData data;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImageData (&data, &kapa, name)) return (FALSE);
+  FREE (name);
 
   ISCEL = FALSE;
@@ -45,5 +47,5 @@
 
   if (ISCEL) {
-    if ((buf = SelectBuffer (GetImageName(), OLDBUFFER, TRUE)) == NULL) return (FALSE);
+    if ((buf = SelectBuffer (data.name, OLDBUFFER, TRUE)) == NULL) return (FALSE);
     GetCoords (&coords, &buf[0].header);
   }
@@ -125,5 +127,5 @@
   }
 
-  KiiLoadOverlay (Ximage, overlay, Noverlay, argv[1]);
+  KiiLoadOverlay (kapa, overlay, Noverlay, argv[1]);
 
   for (i = 0; i < Noverlay; i++) {
Index: /trunk/Ohana/src/opihi/cmd.data/plot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/plot.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/plot.c	(revision 13479)
@@ -3,9 +3,9 @@
 int plot (int argc, char **argv) {
   
-  int N, Npts;
+  int kapa, N, Npts;
   Graphdata graphmode;
   Vector *xvec, *yvec, *dxmvec, *dxpvec, *dymvec, *dypvec;
 
-  if (!style_args (&graphmode, &argc, argv, -1)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   /* decide on error bars */
@@ -36,5 +36,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
 
   /* set errorbar mode (these are NOT sticky) */
@@ -57,18 +56,16 @@
   if (Npts == 0) return (TRUE);
 
-  if (!PrepPlotting (Npts, &graphmode)) return (FALSE);
+  if (!KapaPrepPlot (kapa, Npts, &graphmode)) return (FALSE);
   
-  PlotVector (Npts, xvec[0].elements);
-  PlotVector (Npts, yvec[0].elements);
+  KapaPlotVector (kapa, Npts, xvec[0].elements, "x");
+  KapaPlotVector (kapa, Npts, yvec[0].elements, "y");
   if (graphmode.etype & 0x01) {
-    PlotVector (Npts, dymvec[0].elements);
-    PlotVector (Npts, dypvec[0].elements);
+    KapaPlotVector (kapa, Npts, dymvec[0].elements, "dym");
+    KapaPlotVector (kapa, Npts, dypvec[0].elements, "dyp");
   }
   if (graphmode.etype & 0x02) {
-    PlotVector (Npts, dxmvec[0].elements);
-    PlotVector (Npts, dxpvec[0].elements);
+    KapaPlotVector (kapa, Npts, dxmvec[0].elements, "dxm");
+    KapaPlotVector (kapa, Npts, dxpvec[0].elements, "dxp");
   }
-  
   return (TRUE);
-
 }
Index: /trunk/Ohana/src/opihi/cmd.data/point.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/point.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/point.c	(revision 13479)
@@ -4,19 +4,22 @@
   
   int N, celestial, pixscale;
-  int Ximage, Nimage;
+  int kapa;
   double ra, dec, dra, ddec;
   double x1, y1, ra1, dec1;
+  char *name;
   Coords coords;
   Buffer *buf;
   KiiOverlay overlay;
+  KapaImageData data;
 
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
-  
+  if (!GetImageData (&data, &kapa, name)) return (FALSE);
+  FREE (name);
+
   celestial = FALSE;
   if ((N = get_argument (argc, argv, "-c"))) {
@@ -37,5 +40,5 @@
   
   if (celestial) {
-    if ((buf = SelectBuffer (GetImageName(), OLDBUFFER, TRUE)) == NULL) return (FALSE);
+    if ((buf = SelectBuffer (data.name, OLDBUFFER, TRUE)) == NULL) return (FALSE);
     GetCoords (&coords, &buf[0].header);
   }
@@ -66,5 +69,5 @@
   }
   overlay.type = KiiOverlayTypeByName (argv[2]);
-  KiiLoadOverlay (Ximage, &overlay, 1, argv[1]);
+  KiiLoadOverlay (kapa, &overlay, 1, argv[1]);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/ps.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/ps.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/ps.c	(revision 13479)
@@ -3,6 +3,6 @@
 int ps (int argc, char **argv) {
 
-  char filename[1024], pagename[1024];
-  int N, Source, Nsource, scaleMode, pageMode, IsImage;
+  char filename[1024], pagename[1024], *name;
+  int N, kapa, scaleMode, pageMode, IsImage;
   
   if ((N = get_argument (argc, argv, "--help"))) goto help;
@@ -44,35 +44,23 @@
 
   /* which tool */
-  Nsource = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nsource = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  /* which device */
-  if ((N = get_argument (argc, argv, "-g"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (FALSE);
-  }  
-  if ((N = get_argument (argc, argv, "-i"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (TRUE);
-  }  
-  
+
   if ((argc > 1) && filename[0]) goto help;
 
   if (argc > 1) strcpy (filename, argv[1]);
 
-  IsImage = GetCurrentDevice ();
-  if (IsImage) {
-    if (!GetImage (&Source, &Nsource)) return (FALSE);
-    if (!filename[0]) strcpy (filename, "Ximage.ps");
-  } else {
-    if (!GetGraph (NULL, &Source, &Nsource)) return (FALSE);
-    if (!filename[0]) strcpy (filename, "Xgraph.ps");
-  }
+  // get the connection to kapa, false if none available
+  if (!GetGraphData (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
+
+  if (!filename[0]) strcpy (filename, "kapa.ps");
   
   /* tell Ximage/Xgraph to ps the image */
-  KiiPS (Source, filename, scaleMode, pageMode, pagename);
+  KiiPS (kapa, filename, scaleMode, pageMode, pagename);
   return (TRUE);
 
Index: /trunk/Ohana/src/opihi/cmd.data/rd.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/rd.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/rd.c	(revision 13479)
@@ -59,5 +59,8 @@
 
   /* find matrix, free old data */
-  if ((buf = SelectBuffer (argv[1], ANYBUFFER, TRUE)) == NULL) return (FALSE);
+  if ((buf = SelectBuffer (argv[1], ANYBUFFER, TRUE)) == NULL) {
+      fclose (f);
+      return (FALSE);
+  }
   gfits_free_matrix (&buf[0].matrix);
   gfits_free_header (&buf[0].header);
@@ -79,4 +82,5 @@
       gprint (GP_ERR, "entry in %s not found\n", argv[2]);
       DeleteBuffer (buf);
+      fclose (f);
       return (FALSE);
     }
@@ -99,4 +103,5 @@
 	DeleteBuffer (buf);
 	free (CCDKeyword);
+	fclose (f);
 	return (FALSE);
       }
@@ -105,4 +110,5 @@
 	DeleteBuffer (buf);
 	free (CCDKeyword);
+	fclose (f);
 	return (FALSE);
       }
@@ -143,4 +149,5 @@
     buf[0].header.bzero = 0;
     buf[0].header.bscale = 1;
+    fclose (f);
     return (TRUE);
   }
@@ -152,4 +159,5 @@
     gprint (GP_ERR, "-plane is too large: %d total planes\n", Nplane);
     DeleteBuffer (buf);
+    fclose (f);
     return (FALSE);
   }
Index: /trunk/Ohana/src/opihi/cmd.data/resize.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/resize.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/resize.c	(revision 13479)
@@ -5,27 +5,16 @@
   char *end;
   double NX, NY;
-  int N, Source, Nsource, IsImage;
+  int N, kapa;
+  char *name;
   
   /* display source */
-  Nsource = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nsource = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if ((N = get_argument (argc, argv, "-g"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (FALSE);
-  }  
-  if ((N = get_argument (argc, argv, "-i"))) {
-    remove_argument (N, &argc, argv);
-    SetImageDevice (TRUE);
-  }  
-  IsImage = GetCurrentDevice ();
-  if (IsImage) {
-    if (!GetImage (&Source, &Nsource)) return (FALSE);
-  } else {
-    if (!GetGraph (NULL, &Source, &Nsource)) return (FALSE);
-  }
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   if (argc != 3) {
@@ -49,5 +38,5 @@
   if (!strcmp (end, "cm")) { NY *= 38; }
 
-  KiiResize (Source, NX, NY);
+  KiiResize (kapa, NX, NY);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/save.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/save.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/save.c	(revision 13479)
@@ -4,13 +4,15 @@
   
   int N, celestial;
-  int Ximage, Nimage;
+  int kapa;
+  char *name;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   celestial = FALSE;
@@ -26,5 +28,5 @@
   }
 
-  KiiSaveOverlay (Ximage, celestial, argv[1], argv[2]);
+  KiiSaveOverlay (kapa, celestial, argv[1], argv[2]);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/section.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/section.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/section.c	(revision 13479)
@@ -1,29 +1,61 @@
 # include "data.h"
+
+enum {NONE, LIST, UP, DOWN, TOP, BOTTOM, TOOL};
 
 int section (int argc, char **argv) {
   
-  int N, List;
-  int Ngraph, Xgraph;
+  int N, action, kapa;
+  char *name, *location;
   Graphdata graphmode;
   KapaSection section;
 
-  List = FALSE;
+  action = NONE;
   if ((N = get_argument (argc, argv, "-list"))) {
+    action = LIST;
     remove_argument (N, &argc, argv);
-    List = TRUE;
+  }
+  if ((N = get_argument (argc, argv, "-up"))) {
+    action = UP;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-down"))) {
+    action = DOWN;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-top"))) {
+    action = TOP;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-bottom"))) {
+    action = BOTTOM;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-imtool"))) {
+    action = TOOL;
+    remove_argument (N, &argc, argv);
+    location = argv[N];
+    remove_argument (N, &argc, argv);
   }
 
-  Ngraph = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetGraph (&graphmode, &Xgraph, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, &kapa, name)) return (FALSE);
+  FREE (name);
 
   /* list sections */
-  if (argc == 1) {
-    KapaGetSection (Xgraph, "*");
-    gprint (GP_ERR, "USAGE: section name [x y dx dy]\n");
+  if ((argc == 1) && (action == NONE)) {
+    KapaGetSection (kapa, "*");
+    gprint (GP_ERR, "USAGE: section name [x y dx dy] [options]\n");
+    gprint (GP_ERR, "OPTIONS: -list   : show properties of all sections\n");
+    gprint (GP_ERR, "         -up     : move section up in display stack\n");
+    gprint (GP_ERR, "         -down   : move section down in display stack\n");
+    gprint (GP_ERR, "         -top    : move section to top of display stack\n");
+    gprint (GP_ERR, "         -bottom : move section to bottom of display stack\n");
+    gprint (GP_ERR, "         -imtool (position) : set location of image zoom / status box\n");
+    gprint (GP_ERR, "                 (position may be: -x, +x, -y, +y, none)\n");
     return (TRUE);
   } 
@@ -31,8 +63,50 @@
   if (argc == 2) {
     /* select / show section */
-    if (List) {
-      KapaGetSection (Xgraph, argv[1]);
-    } else {
-      KapaSelectSection (Xgraph, argv[1]);
+    switch (action) {
+      case NONE:
+	KapaSelectSection (kapa, argv[1]);
+	break;
+
+      case UP:
+	KapaMoveSection (kapa, argv[1], "up");
+	break;
+      case DOWN:
+	KapaMoveSection (kapa, argv[1], "down");
+	break;
+      case TOP:
+	KapaMoveSection (kapa, argv[1], "top");
+	break;
+      case BOTTOM:
+	KapaMoveSection (kapa, argv[1], "bottom");
+	break;
+
+      case TOOL:
+	if (!strcmp(location, "-x")) {
+	  KapaSetToolbox (kapa, 1);
+	  break;
+	}
+	if (!strcmp(location, "+x")) {
+	  KapaSetToolbox (kapa, 3);
+	  break;
+	}
+	if (!strcmp(location, "-y")) {
+	  KapaSetToolbox (kapa, 2);
+	  break;
+	}
+	if (!strcmp(location, "+y")) {
+	  KapaSetToolbox (kapa, 4);
+	  break;
+	}
+	if (!strcmp(location, "none")) {
+	  KapaSetToolbox (kapa, 0);
+	  break;
+	}
+	gprint (GP_ERR, "unknown toolbox location %s\n", location);
+	gprint (GP_ERR, "valid values: -x, +x, -y, +y, none\n");
+	return (FALSE);
+
+      case LIST:
+	KapaGetSection (kapa, argv[1]);
+	break;
     }
     return (TRUE);
@@ -46,8 +120,9 @@
     section.dx = atof (argv[4]);
     section.dy = atof (argv[5]);
-    KapaSetSection (Xgraph, &section);
+    KapaSetSection (kapa, &section);
     return (TRUE);
   }
   gprint (GP_ERR, "USAGE: section name [x y dx dy]\n");
+  gprint (GP_ERR, "USAGE: section name [-list] [-up] [-down] [-top] [-bottom]\n");
   return (FALSE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/style.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/style.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/style.c	(revision 13479)
@@ -3,7 +3,8 @@
 int style (int argc, char **argv) {
   
-  Graphdata graphmode;
+  int kapa;
+  Graphdata data;
 
-  if (!style_args (&graphmode, &argc, argv, -1)) return FALSE;
+  if (!style_args (&data, &argc, argv, &kapa)) return FALSE;
 
   if (argc > 1) {
@@ -11,5 +12,5 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
+  KapaSetGraphData (kapa, &data);
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/textline.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/textline.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/textline.c	(revision 13479)
@@ -6,14 +6,8 @@
   char name[64];
   double x, y, angle;
-  int Ngraph, Xgraph;
+  int kapa;
   Graphdata graphmode;
 
-  Ngraph = -1;
-  if ((N = get_argument (argc, argv, "-n"))) {
-    remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  if (!GetGraph (&graphmode, &Xgraph, &Ngraph)) return (FALSE);
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return (FALSE);
 
   if ((N = get_argument (argc, argv, "-fn"))) {
@@ -23,5 +17,5 @@
     size = atof (argv[N]);
     remove_argument (N, &argc, argv);
-    KapaSetFont (Xgraph, name, size);
+    KapaSetFont (kapa, name, size);
   } 
 
@@ -58,5 +52,5 @@
   }    
 
-  KapaSendTextline (Xgraph, argv[3], x, y, angle);
+  KapaSendTextline (kapa, argv[3], x, y, angle);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/tv.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/tv.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/tv.c	(revision 13479)
@@ -3,31 +3,33 @@
 int tv (int argc, char **argv) {
   
-  int N, Ximage, Nimage;
+  int N, kapa;
+  char *name, *file;
   Coords coords;
   Buffer *buf;
   KiiImage image;
-  KiiDisplayMode mode;
+  KapaImageData data;
 
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (&data, &kapa, name)) return (FALSE);
+  FREE (name);
 
   /* shell exits on pipe close, FIX */
   if ((N = get_argument (argc, argv, "-kill"))) {
-    KiiClose (Ximage);
-    Ximage = 0;
+    KiiClose (kapa);
     return (TRUE);
   }
 
-  mode.logflux = FALSE;
+  data.logflux = FALSE;
   if ((N = get_argument (argc, argv, "-log"))) {
     remove_argument (N, &argc, argv);
-    mode.logflux = TRUE;
+    data.logflux = TRUE;
   }
 
+  // use the currently-set zero,range values if not supplied
   if ((argc != 2) && (argc != 4)) {
     gprint (GP_ERR, "USAGE: tv <buffer> [zero range] [-n Nimage] [-log] [-kill]\n");
@@ -35,10 +37,8 @@
   }
 
-  GetImageScale (&mode.zero, &mode.range);
   if (argc == 4) {
-    mode.zero = atof (argv[2]);
-    mode.range = atof (argv[3]);
-    if (mode.range == 0.0) mode.range = 0.001;
-    SetImageScale (mode.zero, mode.range);
+    data.zero = atof (argv[2]);
+    data.range = atof (argv[3]);
+    if (data.range == 0.0) data.range = 0.001;
   }
 
@@ -49,89 +49,15 @@
   image.Nx = buf[0].matrix.Naxis[0];
   image.Ny = buf[0].matrix.Naxis[1];
-  image.file = buf[0].file;
-  image.name = buf[0].name;
 
-  KiiNewPicture1D (Ximage, &image, &mode, &coords);
+  // send only the root of the file, not the full path
+  file = filerootname (buf[0].file);
+  strcpy (data.file, file);
+  free (file);
 
-  SetImageName (argv[1]);
+  strcpy (data.name, argv[1]);
+  
+  KiiNewPicture1D (kapa, &image, &data, &coords);
+
   set_str_variable ("TV", argv[1]);
   return (TRUE);
 }
-
-
-/* 
-projections and coordinates:
-
-IRAS:
-CTYPE1  = 'LL      '                    /TANGENT PLANE (L)                     
-CRVAL1  =         0.100000D+02          /R.A. OF MAP CENTER  *** SEE COMMENT   
-CDELT1  =        -0.133333D-01          /SEPARATION IN L (DEG)                 
-CRPIX1  =                  128          /MAPCENTER IN L                        
-CROTA1  =         0.000000E+00          /NO ROTATION            
-                                                                               
-CTYPE2  = 'MM      '                    /TANGENT PLANE (M)                     
-CRVAL2  =         0.410000D+02          /DEC. OF MAP CENTER  *** SEE COMMENT   
-CDELT2  =         0.133333D-01          /SEPARATION IN M (DEG)                 
-CRPIX2  =                  128          /MAP CENTER IN M                       
-CROTA2  =         0.000000E+00          /NO ROTATION                           
-
-HIRAS:
-CTYPE1  = 'RA---TAN          ' / PRIMARY AXIS NAME                             
-CRVAL1  =   1.000000000000E+01 / PRIMARY REFERENCE VALUE                       
-CDELT1  =  -5.555555555556E-03 / PRIMARY PIXEL SEPARATION                      
-CRPIX1  =   2.560000000000E+02 / PRIMARY REFERENCE PIXEL                       
-CUNIT1  = 'DEGREE            ' / PRIMARY AXIS UNITS                            
-
-CDELT2  =   5.555555555556E-03 / PRIMARY PIXEL SEPARATION                      
-CRPIX2  =   2.560000000000E+02 / PRIMARY REFERENCE PIXEL                       
-CRVAL2  =   4.100000000000E+01 / PRIMARY REFERENCE VALUE                       
-CTYPE2  = 'DEC--TAN          ' / PRIMARY AXIS NAME                             
-CUNIT2  = 'DEGREE            ' / PRIMARY AXIS UNITS                            
-
-PROJTYPE= 'GNOMON    '                                                         
-COORDSYS= 'EQUATORIAL     '                                                    
-
-gene (small FOV linear):
-RA_O
-RA_X 
-RA_Y 
-DEC_O
-DEC_X
-DEC_Y
-
-
-*/
-
-# ifdef NEWTVMODE  
-  {
-    double *pixvalues, slope;
-
-    ALLOCATE (pixvalues, double, Ncolors + 1);
-    range = fabs (range);
-    for (i = 0; i < Ncolors + 1; i++) {
-      if (ISLOG) {
-	pixvalues[i] = i*range / NNcol + zero;
-      }
-      if (!ISLOG) {
-	pixvalues[i] = pow (10.0, i*log10(range - 1.0) / NNcol) + zero - 1.0;
-      }      
-    } 
-    for (j = 0; j < Npix; j++, in++, out++) {
-      if (*in < pixvalues[0]) {
-	i = 0;
-      } else {
-	if (*in > pixvalues[NNcol]) {
-	  i = NNcol;
-	} else {
-	  for (i = 0; (*in < pixvalues[i]) || (*in > pixvalues[i+1]); ) {
-	    slope = 1.0 / (pixvalues[i+1] - pixvalues[i]);
-	    i = MIN (MAX (0, i + (*in - pixvalues[i]) * slope), NNcol);
-	  }
-	}	
-      }
-      /* for (i = 0; (i < Ncolors - 1) && (pixvalues[i] < *in); i++); */
-      *out = i;
-    }
-    free (pixvalues);
-  }
-# endif
Index: /trunk/Ohana/src/opihi/cmd.data/tvcontour.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/tvcontour.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/tvcontour.c	(revision 13479)
@@ -58,15 +58,17 @@
   float *v00, *v01, *v10, *v11;
   float *Vout, *Vin, *matrix;
-  int Ximage, Nimage, N, Noverlay, NOVERLAY;
+  char *name;
+  int kapa, N, Noverlay, NOVERLAY;
   Buffer *buf;
   KiiOverlay *overlay;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   if ((argc != 4) && (argc != 5)) {
@@ -277,5 +279,5 @@
   }
   
-  KiiLoadOverlay (Ximage, overlay, Noverlay, argv[2]);
+  KiiLoadOverlay (kapa, overlay, Noverlay, argv[2]);
   free (overlay);
 
Index: /trunk/Ohana/src/opihi/cmd.data/tvgrid.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/tvgrid.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/tvgrid.c	(revision 13479)
@@ -11,16 +11,18 @@
   char format[16];
   Coords coords;
-  int Ximage, Nimage, N, Noverlay, NOVERLAY;
+  int kapa, N, Noverlay, NOVERLAY;
+  char *name;
   Buffer *buf;
   KiiOverlay *overlay;
 
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
-  
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
+
   if (argc != 3) {
     gprint (GP_ERR, "USAGE: tvgrid (overlay) (buffer)\n");
@@ -144,25 +146,5 @@
   }
 
-  # if (0)
-  /* write the labels on the axes */
-  dDEC = fabs(dec1 - dec0) / 100;
-  for (ra = dRA * ((int)(MIN(ra0, ra1)/dRA) + 1); ra < MAX(ra0, ra1); ra += dRA) {
-    RD_to_XY (&x0, &y0, ra + 0.1*dRA, MIN(dec0, dec1), &coords);
-    sprintf (label, format, ra);
-    sprintf (buffer, "%15s %20.10f %20.10f %20.10f %20.10f ", "TEXT", x0, y0, (double)(strlen(label) + 1), 0.0);
-    write (Ximage, buffer, 128);
-    write (Ximage, label, strlen(label) + 1);
-    RD_to_XY (&x0, &y0, ra, MIN(dec0, dec1), &coords);
-    for (dec = MIN(dec0, dec1) + dDEC; dec < MAX(dec0,dec1); dec += dDEC) {
-      RD_to_XY (&x1, &y1, ra, dec, &coords);
-      sprintf (buffer, "%15s %20.10f %20.10f %20.10f %20.10f ", "LINE", x0, y0, (x1 - x0), (y1 - y0));
-      write (Ximage, buffer, 128);
-      x0 = x1;
-      y0 = y1;
-    }
-  }
-  # endif
-
-  KiiLoadOverlay (Ximage, overlay, Noverlay, argv[1]);
+  KiiLoadOverlay (kapa, overlay, Noverlay, argv[1]);
   free (overlay);
 
Index: /trunk/Ohana/src/opihi/cmd.data/vload.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vload.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/vload.c	(revision 13479)
@@ -4,16 +4,18 @@
   
   int i, N, Noverlay;
-  int Ximage, Nimage, type;
+  int kapa, type;
+  char *name;
   double dx, dy, size;
   KiiOverlay *overlay;
   Vector *vecx, *vecy;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   type = KII_OVERLAY_BOX;
@@ -65,5 +67,5 @@
   }
 
-  KiiLoadOverlay (Ximage, overlay, Noverlay, argv[1]);
+  KiiLoadOverlay (kapa, overlay, Noverlay, argv[1]);
   free (overlay);
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/zplot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/zplot.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/cmd.data/zplot.c	(revision 13479)
@@ -3,5 +3,5 @@
 int zplot (int argc, char **argv) {
   
-  int i, N, Npts, Ngraph;
+  int i, kapa, N, Npts;
   float *in, *out;
   double min, range;
@@ -9,11 +9,5 @@
   Vector *xvec, *yvec, *zvec, Zvec;
 
-  Ngraph = -1;
-  if ((N = get_argument (argc, argv, "-n"))) {
-    remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return (FALSE);
 
   if (argc != 6) {
@@ -51,9 +45,5 @@
   graphmode.etype = 0; /* no errorbars */
   Npts = xvec[0].Nelements;
-  PrepPlotting (Npts, &graphmode);
-
-  PlotVector (Npts, xvec[0].elements);
-  PlotVector (Npts, yvec[0].elements);
-  PlotVector (Npts, Zvec.elements);
+  PlotVectorTriplet (kapa, Npts, xvec[0].elements, yvec[0].elements, Zvec.elements, &graphmode);
 
   free (Zvec.elements);
Index: /trunk/Ohana/src/opihi/dimm/dimm.c.in
===================================================================
--- /trunk/Ohana/src/opihi/dimm/dimm.c.in	(revision 13478)
+++ /trunk/Ohana/src/opihi/dimm/dimm.c.in	(revision 13479)
@@ -50,6 +50,5 @@
 /* add program-dependent exit functions here */
 void cleanup () {
-  QuitImage ();
-  QuitGraph ();
+  QuitKapa ();
   return;
 }
Index: /trunk/Ohana/src/opihi/dvo/ImageSelection.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/ImageSelection.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/ImageSelection.c	(revision 13479)
@@ -20,6 +20,6 @@
   
   if (RegionSelect) {
-    Ngraph = 0;
-    if (!GetGraphData (&graphsky, NULL, &Ngraph)) {
+    // how does this know which sky plot to use?
+    if (!GetGraphData (&graphsky, NULL, NULL)) {
       gprint (GP_ERR, "region display not available\n");
       return (FALSE);
Index: /trunk/Ohana/src/opihi/dvo/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/dvo/Makefile	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/Makefile	(revision 13479)
@@ -21,12 +21,22 @@
 $(SRC)/init.$(ARCH).o            	\
 $(SRC)/ImageOps.$(ARCH).o		\
-$(SRC)/ImageSelection.$(ARCH).o	\
+$(SRC)/ImageSelection.$(ARCH).o	        \
 $(SRC)/LoadImages.$(ARCH).o		\
 $(SRC)/cmpReadFile.$(ARCH).o		\
-$(SRC)/compare.$(ARCH).o               \
+$(SRC)/compare.$(ARCH).o                \
 $(SRC)/match_image.$(ARCH).o		\
-$(SRC)/photometry.$(ARCH).o            \
+$(SRC)/photometry.$(ARCH).o             \
 $(SRC)/dvomisc.$(ARCH).o		\
 $(SRC)/region_list.$(ARCH).o		\
+$(SRC)/dvomisc.$(ARCH).o		\
+$(SRC)/dbBooleanCond.$(ARCH).o		\
+$(SRC)/dbCheckStack.$(ARCH).o		\
+$(SRC)/dbCmdlineFields.$(ARCH).o	\
+$(SRC)/dbExtractAverages.$(ARCH).o	\
+$(SRC)/dbExtractMeasures.$(ARCH).o	\
+$(SRC)/dbFields.$(ARCH).o		\
+$(SRC)/dbRPN.$(ARCH).o			\
+$(SRC)/dbStackMath.$(ARCH).o		\
+$(SRC)/dbStackOps.$(ARCH).o		\
 $(SRC)/dvo.$(ARCH).o
 
Index: /trunk/Ohana/src/opihi/dvo/avextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/avextract.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/avextract.c	(revision 13479)
@@ -3,12 +3,17 @@
 int avextract (int argc, char **argv) {
   
-  int i, j, m, N, NPTS, param;
+  int i, j, n, m, Npts, NPTS, last, Nfields, Nreturn, Ncstack, Nstack;
   int Nsecfilt, mode;
   char *RegionName, *RegionList, *p;
+  char **cstack;
+  float *values;
 
   Catalog catalog;
   SkyList *skylist;
   PhotCode *code;
-  Vector *vec;
+  Vector **vec;
+
+  dbField *fields;
+  dbStack *stack;
 
   /* defaults */
@@ -24,31 +29,36 @@
   Nsecfilt = GetPhotcodeNsecfilt ();
 
-  /* interpret command-line options */
-  SetSelectionParam (0);
+  // remove skyregion options
+  // XXX this needs to explicitly handle -qregion and -skyregion
   if (!SetRegionSelection (&argc, argv, &RegionName, &RegionList)) goto escape;
-  if (!SetPhotSelections (&argc, argv, 1)) goto usage;
 
-  /* interpret required command-line arguments: mextract (value) */
-  if (argc != 2) { goto usage; }
-  param = GetAverageParam (argv[1]);
-  if (param == AVE_ZERO) {
-    if (!GetPhotcodeInfo (argv[1], &code, &mode)) {
-      GetAverageParamHelp ();
-      goto escape;
-    }
-    param = AVE_MAG;
-    for (p = argv[1]; *p != 0; p++) { 
-      if (*p == '.') *p = ':';
-    }
-  } 
-  if (!TestPhotSelections (&code, &mode, param)) goto escape;
+  // command-line is of the form: avextract field,field, field [where (field op value)...]
+
+  // parse the fields to be extracted and returned
+  fields = dbCmdlineFields (argc, argv, DVO_TABLE_AVERAGE, &last, &Nfields);
+  if (fields == NULL) return (FALSE);
+
+  // parse the remainder of the line as a boolean math expression
+  cstack = isolate_elements (argc-last, &argv[last], &Ncstack);
+  
+  // construct the db Boolean math stack (frees cstack)
+  stack = dbRPN (Ncstack, cstack, &Nstack);
+
+  Nreturn = Nfields; 
+  dbCheckStack (stack, Nstack, DVO_TABLE_AVERAGE, &fields, &Nfields);
+  // XXX handle errors
 
   /* load region corresponding to selection above */
   if ((skylist = SelectRegions (RegionName, RegionList)) == NULL) goto escape;
 
-  /* create storage vector */
-  N = 0;
+  /* create output storage vectors */
+  ALLOCATE (values, float, Nfields);
+  ALLOCATE (vec, Vector *, Nreturn);
+  for (i = 0; i < Nreturn; i++) {
+    if ((vec[i] = SelectVector (fields[i].name, ANYVECTOR, TRUE)) == NULL) goto escape;
+  }
+
+  Npts = 0;
   NPTS = 1;
-  if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) goto escape;
 
   // XXX need to add interrupt test to this loop
@@ -68,12 +78,30 @@
     for (j = 0; j < catalog.Naverage; j++) {
       m = catalog.average[j].offset;
-      vec[0].elements[N] = ExtractAverages (code, mode, &catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], param);
-      N++;
-      CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 2000);
+      // extract the relevant values
+      // XXX for measure values, this could be optimized for one loop over measures...
+      for (n = 0; n < Nfields; n++) {
+	values[n] = dbExtractAverages (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &fields[n]);
+      }
+      // test the conditional statement
+      if (!dbBooleanCond (stack, Nstack, values)) continue;
+      for (n = 0; n < Nreturn; n++) {
+	vec[n][0].elements[Npts] = values[n];
+      }
+      Npts++;
+      if (Npts >= NPTS) {
+	NPTS += 2000;
+	for (n = 0; n < Nreturn; n++) {
+	  REALLOCATE (vec[n][0].elements, float, NPTS);
+	}
+      }
     }
     dvo_catalog_free (&catalog);
   }
-  vec[0].Nelements = N;
-  REALLOCATE (vec[0].elements, float, MAX(1,N));
+  for (n = 0; n < Nreturn; n++) {
+    vec[n][0].Nelements = Npts;
+    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
+  }
+
+  // XXX free fields and stack 
 
   SkyListFree (skylist, ((RegionName != NULL) || (RegionList != NULL)));
Index: /trunk/Ohana/src/opihi/dvo/catalog.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/catalog.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/catalog.c	(revision 13479)
@@ -28,6 +28,5 @@
   int Ngraph;
 
-  Ngraph = 0;
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, NULL, NULL)) return (FALSE);
 
   VarConfig ("GSCDIR", "%s", gscdir);
@@ -392,7 +391,7 @@
     PrepPlotting (N, &graphmode);
     
-    PlotVector (N, Xvec.elements);
-    PlotVector (N, Yvec.elements);
-    PlotVector (N, Zvec.elements);
+    PlotVector (N, Xvec.elements, "x");
+    PlotVector (N, Yvec.elements, "y");
+    PlotVector (N, Zvec.elements, "z");
     
     free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/dvo/cmpload.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/cmpload.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/cmpload.c	(revision 13479)
@@ -8,19 +8,20 @@
   int i, Noverlay, NOVERLAY, Nstar, N, Nin, Nextra, Objtype, type;
   int doneread, done, Nskip, Nbytes, nbytes, Ninstar;
-  char *c, *c2;
+  char *c, *c2, *name;
   double dtmp;
   FILE *f;
   char *buffer;
-  int Ximage, Nimage;
+  int kapa;
   Header header;
   KiiOverlay *overlay;
   
-  Nimage = -1;
+  name = NULL;
   if ((N = get_argument (argc, argv, "-n"))) {
     remove_argument (N, &argc, argv);
-    Nimage = atof (argv[N]);
+    name = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!GetImage (&Ximage, &Nimage)) return (FALSE);
+  if (!GetImage (NULL, &kapa, name)) return (FALSE);
+  FREE (name);
 
   Objtype = 0;
@@ -131,5 +132,5 @@
   fclose (f);
 
-  KiiLoadOverlay (Ximage, overlay, Noverlay, argv[1]);
+  KiiLoadOverlay (kapa, overlay, Noverlay, argv[1]);
   free (overlay);
 
Index: /trunk/Ohana/src/opihi/dvo/dbBooleanCond.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbBooleanCond.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbBooleanCond.c	(revision 13479)
@@ -0,0 +1,81 @@
+# include "dvoshell.h"
+
+// evaluate the expression in inStack as a boolean; necessary db field values are
+// supplied by fields, in order 0 - Nfields (validate before calling)
+int dbBooleanCond (dbStack *inStack, int NinStack, float *fields) {
+  
+  float value;
+  int i, j, N, Nstack;
+  dbStack **stack, *output;
+
+  // 'no stack' means 'no where statement'
+  if (NinStack == 0) return (TRUE);
+
+  Nstack = NinStack;
+  ALLOCATE (stack, dbStack *, NinStack);
+  for (i = 0; i < NinStack; i++) {
+    stack[i] = &inStack[i];
+  }
+
+  for (i = 0; i < Nstack; i++) {
+
+    /***** binary operators *****/
+    if ((stack[i][0].type >= 3) && (stack[i][0].type <= 8)) {
+
+      // pre-test that op and entries match
+      output = dbBinary (stack[i-2], stack[i-1], stack[i][0].name, fields); 
+
+      // free temporary stack items, drop external items
+      dbFreeEntry (stack[i-2]);
+      dbFreeEntry (stack[i-1]);
+
+      stack[i-2] = output;
+      for (j = i + 1; j < Nstack; j++) {
+	stack[j-2] = stack[j];
+      }
+
+      Nstack -= 2;
+      i -= 2;
+      continue;
+    }
+
+    /***** unary operators **/
+    if (stack[i][0].type == 9) {
+
+      // pre-test that op and entries match
+      output = dbUnary (stack[i-1], stack[i][0].name, fields); 
+
+      // free temporary stack items, drop external items
+      dbFreeEntry (stack[i-1]);
+
+      stack[i-1] = output;
+      for (j = i + 1; j < Nstack; j++) {
+	stack[j-1] = stack[j];
+      }
+
+      Nstack -= 1;
+      i -= 1;
+      continue;
+    } 
+  }
+
+  // the result here is a single stack entry with a value:
+  if (stack[0][0].type == 'F') {
+    N = stack[0][0].field;
+    value = fields[N];
+  } else {
+    value = stack[0][0].Float;
+  }
+    
+  free (stack);
+
+  // XXX fix this limit
+  if (fabs(value) > 1e-7) {
+    return (TRUE);
+  } else {
+    return (FALSE);
+  }
+
+  // pre-test that op and entries match
+  return (TRUE);
+}
Index: /trunk/Ohana/src/opihi/dvo/dbCheckStack.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbCheckStack.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbCheckStack.c	(revision 13479)
@@ -0,0 +1,57 @@
+# include "dvoshell.h"
+
+int dbCheckStack (dbStack *stack, int Nstack, int table, dbField **inFields, int *Nfields) {
+
+  int i, j, status, NFIELDS;
+  char *c;
+  dbField *fields;
+
+  NFIELDS = *Nfields + 10;
+  REALLOCATE (*inFields, dbField, NFIELDS);
+  fields = *inFields;
+
+  for (i = 0; i < Nstack; i++) {
+    if (stack[i].type == 'X') {
+
+      /** if this is a number, put it on the list of scalers and move on **/
+      stack[i].Float = strtod (stack[i].name, &c);
+      if (c == stack[i].name + strlen (stack[i].name)) {
+	stack[i].type  = 'S';
+	continue;
+      } 
+
+      // this must be a field : is it already in the list?
+      for (j = 0; (j < *Nfields) && strcasecmp (stack[i].name, fields[j].name); j++);
+      if (j < *Nfields) {
+	stack[i].field = j;
+	stack[i].type  = 'F';
+	continue;
+      }
+
+      // this must be a field : is it a valid name?
+      if (table == DVO_TABLE_MEASURE) {
+	status = ParseMeasureField (&fields[*Nfields], stack[i].name);
+      } 
+      if (table == DVO_TABLE_AVERAGE) {
+	status = ParseAverageField (&fields[*Nfields], stack[i].name);
+      } 
+      if (!status) {
+	gprint (GP_ERR, "unknown database field %s\n", stack[i].name);
+	return (FALSE);
+      }
+      stack[i].field = *Nfields;
+      stack[i].type  = 'F';
+
+      *Nfields ++;
+      CHECK_REALLOCATE (*inFields, dbField, NFIELDS, *Nfields, 10);
+      fields = *inFields;
+    }
+  }
+  return (TRUE);
+}
+
+/* check stack identifies the data elements as plain scalars or table fields
+   operators have already been identified.  
+   check stack returns the total stack dimensionality (0,1,2)
+   on error, check stack returns FALSE
+*/
Index: /trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 13479)
@@ -0,0 +1,74 @@
+# include "dvoshell.h"
+
+// identify the fields to be extracted (test for where, check syntax)
+dbField *dbCmdlineFields (int argc, char **argv, int table, int *last, int *nfields) {
+
+  int i, j, status, Nfields, NFIELDS;
+  char *p, *q, *field;
+  dbField *fields;
+
+  *nfields = 0;
+  Nfields = 0;
+  NFIELDS = 10;
+  ALLOCATE (fields, dbField, NFIELDS);
+  dbInitField (&fields[0]);
+
+  // examine each argv[i] entry until we reach a where 
+  for (i = 1; (i < argc) && strcasecmp (argv[i], "where"); i++) {
+    // split the word by ","
+    p = argv[i];
+    while (*p) {
+      q = strchr (p, ',');
+      if (q == NULL) {
+	field = strcreate (p);
+	p = p + strlen(p);
+      } else {
+	field = strncreate (p, q-p);
+	p = q + 1;
+      }
+      // identify field for word
+      // need to know which type of fields to look for...
+      // xxx extend this more generally later
+      if (table == DVO_TABLE_MEASURE) {
+	status = ParseMeasureField (&fields[Nfields], field);
+      } 
+      if (table == DVO_TABLE_AVERAGE) {
+	status = ParseAverageField (&fields[Nfields], field);
+      } 
+      if (!status) {
+	gprint (GP_ERR, "unknown database field %s\n", field);
+	free (field);
+	for (j = 0; j <= Nfields; j++) {
+	  if (fields->name != NULL) free (fields->name);
+	}
+	free (fields);
+	return (NULL);
+      }
+      free (field);
+
+      Nfields ++;
+      CHECK_REALLOCATE (fields, dbField, NFIELDS, Nfields, 10);
+      dbInitField (&fields[Nfields]);
+    }
+  }
+
+  // require 'where' before boolean math
+  if (i != argc) {
+    if (strcasecmp(argv[i], "where")) {
+      gprint (GP_ERR, "syntax error\n");
+      free (fields);
+      return (NULL);
+    }
+    if (i > argc - 2) {
+      gprint (GP_ERR, "missing boolean expression\n");
+      free (fields);
+      return (NULL);
+    }
+    i++; // skip over the 'where'
+  }
+
+  *last = i;
+  *nfields = Nfields;
+
+  return (fields);
+}
Index: /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 13479)
@@ -0,0 +1,112 @@
+# include "dvoshell.h"
+
+/* return average.field based on the selection */
+double dbExtractAverages (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+
+  int i;
+  double value;
+
+  value = NO_MAG;
+
+  /* assign vector values */
+  switch (field->ID) {
+    case AVE_RA:
+      value = average[0].R;
+      break;
+    case AVE_DEC:
+      value = average[0].D;
+      break;
+    case AVE_RA_ERR:
+      value = average[0].dR;
+      break;
+    case AVE_DEC_ERR:
+      value = average[0].dD;
+      break;
+
+    case AVE_U_RA:
+      value = average[0].uR;
+      break;
+    case AVE_U_DEC:
+      value = average[0].uD;
+      break;
+    case AVE_U_RA_ERR:
+      value = average[0].duR;
+      break;
+    case AVE_U_DEC_ERR:
+      value = average[0].duD;
+      break;
+
+    case AVE_PAR:
+      value = average[0].P;
+      break;
+    case AVE_PAR_ERR:
+      value = average[0].dP;
+      break;
+
+    case AVE_NMEAS:
+      value = average[0].Nm;
+      break;
+    case AVE_NMISS:
+      value = average[0].Nn;
+      break;
+    case AVE_Xp:
+      value = 0.01*average[0].Xp;
+      break;
+    case AVE_FLAG:
+      value = average[0].code;
+      break;
+
+    case AVE_MAG:
+      switch (field->magMode) {
+	case MAG_AVE:
+	  value = PhotAve  (field->photcode, average, secfilt);
+	  break;
+	case MAG_REF:
+	  value = PhotRef  (field->photcode, average, secfilt, measure);
+	  break;
+	case MAG_INST:
+	case MAG_CAT:
+	case MAG_SYS:
+	case MAG_REL:
+	case MAG_CAL:
+	  // XXX need to code this correctly: this returns just the first matching value
+	  value = NO_MAG;
+	  for (i = 0; i < average[0].Nm; i++) {
+	    if (field->photcode->code != measure[i].photcode) continue;
+	    value = measure[i].M;
+	    break;
+	  }
+	  break;
+      }
+      break;
+    case AVE_dMAG:
+      value = PhotdM (field->photcode, average, secfilt);
+      break;
+    case AVE_Xm:
+      value = PhotXm (field->photcode, average, secfilt);
+      break;
+    case AVE_TYPE:
+      break;
+    case AVE_TYPEFRAC:
+      break;
+    case AVE_NCODE:
+      value = 0;
+      for (i = 0; i < average[0].Nm; i++) {
+	if (field->photcode->code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
+	value ++;
+      }
+      break;
+    case AVE_NPHOT:
+      value = 0;
+      for (i = 0; i < average[0].Nm; i++) {
+	if (field->photcode->code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
+	if (measure[i].flags & (ID_MEAS_POOR | ID_MEAS_SKIP)) continue;
+	value ++;
+      }
+      break;
+    case AVE_NCRIT:
+      break;
+  }
+  return (value);
+}  
+
Index: /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 13479)
@@ -0,0 +1,135 @@
+# include "dvoshell.h"
+
+/* time concepts */
+static time_t TimeReference;
+static int TimeFormat;
+
+void dbExtractMeasuresInit () {
+  GetTimeFormat (&TimeReference, &TimeFormat);
+}
+
+/* return measure.field based on the selection */
+double dbExtractMeasures (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+
+  int i;
+  double value;
+  double ra, dec, x, y;
+
+  Image *image;
+  Coords *mosaic;
+
+  value = NO_MAG;
+
+  switch (field->ID) {
+    // XXX not sure how to apply the photcode here....
+    case MEAS_MAG: /* magnitudes are already determined above */
+      switch (field->magMode) {
+	case MAG_INST:
+	  value = PhotInst (measure);  
+	  break;
+	case MAG_CAT:
+	  value = PhotCat  (measure); 
+	  break;
+	case MAG_SYS:
+	  value = PhotSys  (measure, average, secfilt); 
+	  break;
+	case MAG_REL:
+	  value = PhotRel  (measure, average, secfilt); 
+	  break;
+	case MAG_CAL:
+	  value = PhotCal  (measure, average, secfilt, measure, GetPhotcodeEquivbyCode (measure[0].photcode)); 
+	  break;
+	case MAG_AVE:
+	  value = PhotAve  (GetPhotcodeEquivbyCode (measure[0].photcode), average, secfilt); 
+	  break;
+	case MAG_REF:
+	  value = PhotRef  (GetPhotcodeEquivbyCode (measure[0].photcode), average, secfilt, measure); 
+	  break;
+      }
+      break;
+    case MEAS_RA: /* OK */
+      value = average[0].R - measure[0].dR / 3600.0;
+      break;
+    case MEAS_DEC: /* OK */
+      value = average[0].D - measure[0].dD / 3600.0;
+      break;
+    case MEAS_dMAG: /* OK */
+      value = measure[0].dM;
+      break;
+    case MEAS_AIRMASS: /* OK */
+      value = measure[0].airmass;
+      break;
+    case MEAS_EXPTIME: /* OK */
+      value = pow (10.0, measure[0].dt * 0.4);
+      break;
+    case MEAS_PHOTCODE: /* OK */
+      value = measure[0].photcode;
+      break;
+    case MEAS_TIME: /* OK */
+      value = TimeValue (measure[0].t, TimeReference, TimeFormat);
+      break;
+    case MEAS_dR: /* OK */
+      value = measure[0].dR;
+      break;
+    case MEAS_dD: /* OK */
+      value = measure[0].dD;
+      break;
+    case MEAS_FWHM: /* OK */
+      value = 0.01*measure[0].FWx;
+      break;
+    case MEAS_DOPHOT: /* OK */
+      value = measure[0].dophot;
+      break;
+    case MEAS_FLAGS: /* ? */
+      value = measure[0].flags;
+      break;
+    case MEAS_XCCD: /* OK */
+/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
+# if 0
+      value = measure[0].Xccd;
+# else
+      ra  = average[0].R - measure[0].dR / 3600.0;
+      dec = average[0].D - measure[0].dD / 3600.0;
+      image = MatchImage (measure[0].t, measure[0].photcode);
+      if (image == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, &image[0].coords);
+      value = x;
+# endif
+      break;
+    case MEAS_YCCD: /* OK */
+/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
+# if 0
+      value = measure[0].Yccd;
+# else
+      ra  = average[0].R - measure[0].dR / 3600.0;
+      dec = average[0].D - measure[0].dD / 3600.0;
+      image = MatchImage (measure[0].t, measure[0].photcode);
+      if (image == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, &image[0].coords);
+      value = y;
+# endif
+      break;
+    case MEAS_XMOSAIC: /* OK */
+      ra  = average[0].R - measure[0].dR / 3600.0;
+      dec = average[0].D - measure[0].dD / 3600.0;
+      mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
+      if (mosaic == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, mosaic);
+      value = x;
+      break;
+    case MEAS_YMOSAIC: /* OK */
+      ra  = average[0].R - measure[0].dR / 3600.0;
+      dec = average[0].D - measure[0].dD / 3600.0;
+      mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
+      if (mosaic == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, mosaic);
+      value = y;
+      break;
+  }
+  return (value);
+}
+
+/** the mosaic entries do not use the registered mosaic found 
+    by MatchImage (via FindMosaicForImage).  Rather, they use
+    a coordinate frame saved by SetImageSelection 
+**/
Index: /trunk/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbFields.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbFields.c	(revision 13479)
@@ -0,0 +1,142 @@
+# include "dvoshell.h"
+
+dbInitField (dbField *field) {
+  field->name = NULL;
+  field->extract = FALSE;
+  field->table = 0;
+  field->ID = 0;
+  field->magMode = 0;
+  field->photcode = NULL;
+}
+
+int GetMagMode (char *string) {
+
+  if (!strcasecmp (string, "inst"))  return (MAG_INST);
+  if (!strcasecmp (string, "cat"))   return (MAG_CAT);
+  if (!strcasecmp (string, "sys"))   return (MAG_SYS);
+  if (!strcasecmp (string, "rel"))   return (MAG_REL);
+  if (!strcasecmp (string, "cal"))   return (MAG_CAL);
+  if (!strcasecmp (string, "ave"))   return (MAG_AVE);
+  if (!strcasecmp (string, "ref"))   return (MAG_REF);
+  if (!strcasecmp (string, "err"))   return (MAG_ERR);
+  if (!strcasecmp (string, "chisq")) return (MAG_CHISQ);
+  return (MAG_NONE);
+}
+
+PhotCode *ParsePhotcodeField (char *field, int *mode, int defMode) {
+
+  char *tmpstring, *p;
+  PhotCode *code;
+
+  *mode = defMode;
+
+  p = strchr (field, ':');
+  if (p != NULL) {
+    *mode = GetMagMode (p + 1);
+    if (*mode == MAG_NONE) return (NULL);
+    tmpstring = strncreate (field, p - field);
+  } else {
+    tmpstring = strcreate (field);
+  }
+  code = GetPhotcodebyName (tmpstring);
+  free (tmpstring);
+
+  return (code);
+}
+
+# define ESCAPE(F,M) { \
+  field->ID = (F); \
+  field->magMode = (M); \
+  field->photcode = NULL; \
+  return (TRUE); }
+
+int ParseMeasureField (dbField *field, char *fieldName) {
+
+  int mode;
+  PhotCode *code;
+
+  field->table = DVO_TABLE_MEASURE;
+  field->name  = strcreate (fieldName);
+
+  if (!strcasecmp (fieldName, "RA"))       ESCAPE (MEAS_RA,   	  MAG_NONE);
+  if (!strcasecmp (fieldName, "DEC"))      ESCAPE (MEAS_DEC,  	  MAG_NONE);
+  // if (!strcasecmp (fieldName, "MAG"))      ESCAPE (MEAS_MAG,  	  MAG_REL);
+  // if (!strcasecmp (fieldName, "dMAG"))     ESCAPE (MEAS_dMAG, 	  MAG_ERR);
+  if (!strcasecmp (fieldName, "AIRMASS"))  ESCAPE (MEAS_AIRMASS,  MAG_NONE);
+  if (!strcasecmp (fieldName, "EXPTIME"))  ESCAPE (MEAS_EXPTIME,  MAG_NONE);
+  if (!strcasecmp (fieldName, "PHOTCODE")) ESCAPE (MEAS_PHOTCODE, MAG_NONE);
+  if (!strcasecmp (fieldName, "TIME"))     ESCAPE (MEAS_TIME,     MAG_NONE);
+  if (!strcasecmp (fieldName, "dR"))       ESCAPE (MEAS_dR, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "dD"))       ESCAPE (MEAS_dD, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "FWHM"))     ESCAPE (MEAS_FWHM,     MAG_NONE);
+  if (!strcasecmp (fieldName, "DOPHOT"))   ESCAPE (MEAS_DOPHOT,   MAG_NONE);
+  if (!strcasecmp (fieldName, "FLAGS"))    ESCAPE (MEAS_FLAGS,    MAG_NONE);
+  if (!strcasecmp (fieldName, "XCCD"))     ESCAPE (MEAS_XCCD, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "YCCD"))     ESCAPE (MEAS_YCCD, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "XMOSAIC"))  ESCAPE (MEAS_XMOSAIC,  MAG_NONE);
+  if (!strcasecmp (fieldName, "YMOSAIC"))  ESCAPE (MEAS_YMOSAIC,  MAG_NONE);
+
+  // for words that don't parse, try a photcode
+
+  // check for code:mode in photcode name 
+  code = ParsePhotcodeField (fieldName, &mode, MAG_REL);
+  if (code == NULL) return (FALSE);
+
+  if (mode == MAG_ERR) {
+    field->ID = MEAS_dMAG;
+  } else {
+    field->ID = MEAS_MAG;
+  }    
+  
+  field->magMode = mode;
+  field->photcode = code;
+  return (TRUE);
+}
+  
+int ParseAverageField (dbField *field, char *fieldName) {
+
+  int mode;
+  PhotCode *code;
+
+  field->table = DVO_TABLE_AVERAGE;
+  field->name  = strcreate (fieldName);
+
+  if (!strcasecmp (fieldName, "RA"))    ESCAPE (AVE_RA,        MAG_NONE);
+  if (!strcasecmp (fieldName, "DEC"))   ESCAPE (AVE_DEC,       MAG_NONE);
+  if (!strcasecmp (fieldName, "dRA"))   ESCAPE (AVE_RA_ERR,    MAG_NONE);
+  if (!strcasecmp (fieldName, "dDEC"))  ESCAPE (AVE_DEC_ERR,   MAG_NONE);
+  if (!strcasecmp (fieldName, "uRA"))   ESCAPE (AVE_U_RA,      MAG_NONE);
+  if (!strcasecmp (fieldName, "uDEC"))  ESCAPE (AVE_U_DEC,     MAG_NONE);
+  if (!strcasecmp (fieldName, "duRA"))  ESCAPE (AVE_U_RA_ERR,  MAG_NONE);
+  if (!strcasecmp (fieldName, "duDEC")) ESCAPE (AVE_U_DEC_ERR, MAG_NONE);
+  if (!strcasecmp (fieldName, "PAR"))   ESCAPE (AVE_PAR,       MAG_NONE);
+  if (!strcasecmp (fieldName, "dPAR"))  ESCAPE (AVE_PAR_ERR,   MAG_NONE);
+  if (!strcasecmp (fieldName, "MAG"))   ESCAPE (AVE_MAG,       MAG_AVE);
+  if (!strcasecmp (fieldName, "dMAG"))  ESCAPE (AVE_dMAG,      MAG_ERR);
+  if (!strcasecmp (fieldName, "NMEAS")) ESCAPE (AVE_NMEAS,     MAG_NONE);
+  if (!strcasecmp (fieldName, "NMISS")) ESCAPE (AVE_NMISS,     MAG_NONE);
+  if (!strcasecmp (fieldName, "Xp"))    ESCAPE (AVE_Xp,        MAG_NONE);
+  if (!strcasecmp (fieldName, "Xm"))    ESCAPE (AVE_Xm,        MAG_CHISQ);
+  if (!strcasecmp (fieldName, "FLAG"))  ESCAPE (AVE_FLAG,      MAG_NONE);
+  if (!strcasecmp (fieldName, "TYPE"))  ESCAPE (AVE_TYPE,      MAG_NONE);
+  if (!strcasecmp (fieldName, "NPHOT")) ESCAPE (AVE_NPHOT,     MAG_NONE);
+  if (!strcasecmp (fieldName, "NCODE")) ESCAPE (AVE_NCODE,     MAG_NONE);
+  if (!strcasecmp (fieldName, "NCRIT")) ESCAPE (AVE_NCRIT,     MAG_NONE);
+
+  // for words that don't parse, try a photcode
+
+  // check for code:mode in photcode name 
+  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
+  if (code == NULL) return (FALSE);
+
+  // need to distinguish phot, sys errors and scatter
+  if (mode == MAG_ERR) {
+    field->ID = AVE_dMAG;
+  } else {
+    field->ID = AVE_MAG;
+  }    
+  
+  field->magMode = mode;
+  field->photcode = code;
+  return (TRUE);
+}
Index: /trunk/Ohana/src/opihi/dvo/dbRPN.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbRPN.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbRPN.c	(revision 13479)
@@ -0,0 +1,210 @@
+# include "dvoshell.h"
+# define DUMPSTACK 0
+
+dbStack *dbRPN (int argc, char **argv, int *nstack) {
+  
+  int type, Nx, Ny;
+  int i, j, Nstack, Nop_stack, NSTACK;
+  dbStack *stack, *op_stack;
+
+  /* max total stack size is argc, though should be less, this is safe */
+  NSTACK = argc + 5;
+  ALLOCATE (stack, dbStack, NSTACK);
+  ALLOCATE (op_stack, dbStack, NSTACK);
+  for (i = 0; i < NSTACK; i++) {
+    dbInitStack (&stack[i]);
+    dbInitStack (&op_stack[i]);
+  }
+  
+  Nx = Ny = Nstack = Nop_stack = 0;
+  for (i = 0; i < argc; i++) {
+    
+    /* decide on priority of object */
+    type = 0;
+    /* unary operations */
+    if (!strcmp (argv[i], "abs"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "int"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "exp"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ten"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "log"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ln"))     { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "sqrt"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "erf"))    { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "sinh"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "cosh"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "asinh"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "acosh"))  { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "sin"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "cos"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "tan"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dsin"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dcos"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dtan"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "asin"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "acos"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "atan"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dasin"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dacos"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "datan"))  { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "lgamma")) { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "rnd"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "xramp"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "yramp"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ramp"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "zero"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "--"))     { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "not"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "isinf"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "isnan"))  { type = 9; goto gotit; }
+
+    /* binary operations */
+    if (!strcmp (argv[i], "^"))      { type = 8; goto gotit; }
+
+    if (!strcmp (argv[i], "@"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "/"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "*"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "%"))      { type = 7; goto gotit; }
+
+    if (!strcmp (argv[i], "+"))      { type = 6; goto gotit; }
+    if (!strcmp (argv[i], "-"))      { type = 6; goto gotit; }
+	
+    if (!strcmp (argv[i], "&"))      { type = 5; goto gotit; }
+    if (!strcmp (argv[i], "|"))      { type = 5; goto gotit; }
+
+    if (!strcmp (argv[i], "<"))      { type = 4; goto gotit; }
+    if (!strcmp (argv[i], ">"))      { type = 4; goto gotit; }
+    if (!strcmp (argv[i], "=="))     { type = 4; strcpy (argv[i], "E"); goto gotit; }
+    if (!strcmp (argv[i], "!="))     { type = 4; strcpy (argv[i], "N"); goto gotit; }
+    if (!strcmp (argv[i], "<="))     { type = 4; strcpy (argv[i], "L"); goto gotit; }
+    if (!strcmp (argv[i], ">="))     { type = 4; strcpy (argv[i], "G"); goto gotit; }
+    if (!strcmp (argv[i], ">>"))     { type = 4; strcpy (argv[i], "U"); goto gotit; }
+    if (!strcmp (argv[i], "<<"))     { type = 4; strcpy (argv[i], "D"); goto gotit; }
+
+    if (!strcmp (argv[i], "&&"))     { type = 3; strcpy (argv[i], "A"); goto gotit; }
+    if (!strcmp (argv[i], "||"))     { type = 3; strcpy (argv[i], "O"); goto gotit; }
+
+    if (!strcmp (argv[i], "("))      { type = 2; goto gotit; }
+    if (!strcmp (argv[i], ")"))      { type = 1; goto gotit; }
+
+  gotit:
+    /* choose how to deal with object */
+    switch (type) {
+      case 8:  /* exponentiation: 2^2^3 = 64 != 256 (precedence is right-to-left, not left-to-right!) */
+	/* pop previous, higher operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type > type); j--) {
+	  stack[Nstack] = op_stack[j];
+	  op_stack[j].name = NULL;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	op_stack[Nop_stack].name = strcreate (argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 9: /* unary OPs */
+      case 7: /* binary OPs */
+      case 6:
+      case 5: 
+      case 4: 
+      case 3: 
+	/* pop previous, higher or equal operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
+	  stack[Nstack] = op_stack[j];
+	  op_stack[j].name = NULL;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	op_stack[Nop_stack].name = strcreate (argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 2:  
+	/* push operator on OP stack */
+	op_stack[Nop_stack].name = strcreate (argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 1: 
+	/* pop rest of operators from OP stack to stack, looking for '(' */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != 2); j--) {
+	  stack[Nstack] = op_stack[j];
+	  op_stack[j].name = NULL;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	if ((j == -1) || (op_stack[j].type != 2)) {
+	  push_error ("syntax error: mismatched parenthesis");
+	  Nstack = 0;
+	  goto cleanup;
+	}
+	Nop_stack --;
+	break;
+      case 0:
+	/* place the value (number or vector/matrix name) on stack */
+	/* value of 'X' is used as sentinel until we sort out values */
+	stack[Nstack].name = strcreate (argv[i]);
+	stack[Nstack].type = 'X';
+	Nstack ++;
+	break;
+    }
+  }
+
+  /* dump remaining operators on stack, checking for ')' */
+  for (j = Nop_stack - 1; j >= 0; j--) {
+    if (op_stack[j].type == 2) {
+      push_error ("syntax error: mismatched parenthesis");
+      Nstack = 0;
+      goto cleanup;
+    }
+    stack[Nstack] = op_stack[j];
+    op_stack[j].name = NULL;
+    Nstack ++;
+  }
+
+cleanup: 
+  /*** free up unused stack space ***/
+  dbFreeStack (op_stack, NSTACK);
+  free (op_stack);
+  dbFreeStack (&stack[Nstack], NSTACK - Nstack);
+  REALLOCATE (stack, dbStack, MAX (Nstack, 1));
+  *nstack = Nstack;
+
+  for (i = 0; i < argc; i++) {
+    free (argv[i]);
+  }
+  free (argv);
+
+# if (DUMPSTACK)
+  for (i = 0; i < Nstack; i++) {
+    gprint (GP_ERR, "%s ", stack[i].name);
+  }
+  if (Nstack > 0) gprint (GP_ERR, "\n");
+  for (i = 0; i < Nstack; i++) {
+    gprint (GP_ERR, "%d ", stack[i].type);
+  }
+  if (Nstack > 0) gprint (GP_ERR, "\n");
+# endif
+
+  return (stack);
+
+}
+
+/* here are the rules for parsing a math AOL expression to RPN:
+
+1) if object is a number, push on stack
+2) if object is a third order operand (exp, sin, cos), push on op stack
+3) if object is an open paren, push on op stack,
+4) if object is a second order operand, push on stack
+5) if object is a first order operand, pop all second order operands from stack 
+until paren, push on stack
+6) if object is an end paren, pop all objects from stack until paren, 
+pop next stack, if third order op
+7) if end of line, pop all remaining objects, second order first, etc.
+   
+*/
Index: /trunk/Ohana/src/opihi/dvo/dbStackMath.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbStackMath.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbStackMath.c	(revision 13479)
@@ -0,0 +1,140 @@
+# include "dvoshell.h"
+
+dbStack *dbBinary (dbStack *V1, dbStack *V2, char *op, float *fields) {
+
+  int N;
+  float M1, M2;
+  dbStack *OUT;
+  
+  if (V1->type == 'F') {
+    N = V1->field;
+    M1 = fields[N];
+  } else {
+    M1 = V1->Float;
+  }
+  
+  if (V2->type == 'F') {
+    N = V2->field;
+    M2 = fields[N];
+  } else {
+    M2 = V2->Float;
+  }
+
+  ALLOCATE (OUT, dbStack, 1);
+  OUT->type = 'T';
+
+  // use an enum for the op...
+  switch (op[0]) { 
+  case '+': 
+    OUT->Float = M1 + M2;
+    break; 
+  case '-': 
+    OUT->Float = M1 - M2;
+    break; 
+  case '*': 
+    OUT->Float = M1 * M2;
+    break; 
+  case '/': 
+    OUT->Float = M1 / M2;
+    break; 
+  case '%': 
+    OUT->Float = (int) M1 % (int) M2;
+    break; 
+  case 0x5e: 
+    OUT->Float = pow (M1, M2);
+    break; 
+  case 'D': 
+    OUT->Float = MIN (M1, M2);
+    break; 
+  case 'U': 
+    OUT->Float = MAX (M1, M2);
+    break; 
+  case '<': 
+    OUT->Float = (M1 < M2) ? 1 : 0;
+    break; 
+  case '>': 
+    OUT->Float = (M1 > M2) ? 1 : 0;
+    break; 
+  case '&': 
+    OUT->Float = ((int)M1 & (int)M2);
+    break; 
+  case '|': 
+    OUT->Float = ((int)M1 | (int)M2);
+    break; 
+  case 'E': 
+    OUT->Float = (M1 == M2) ? 1 : 0;
+    break; 
+  case 'N': 
+    OUT->Float = (M1 != M2) ? 1 : 0;
+    break; 
+  case 'L': 
+    OUT->Float = (M1 <= M2) ? 1 : 0;
+    break; 
+  case 'G': 
+    OUT->Float = (M1 >= M2) ? 1 : 0;
+    break; 
+  case 'A': 
+    OUT->Float = (M1 && M2) ? 1 : 0;
+    break; 
+  case 'O': 
+    OUT->Float = (M1 || M2) ? 1 : 0;
+    break; 
+  default:
+    return (NULL);
+  }
+
+  return (OUT);
+}
+
+dbStack *dbUnary (dbStack *V1, char *op, float *fields) {
+
+  int N;
+  float M1;
+  dbStack *OUT;
+
+  if (V1->type == 'F') {
+    N = V1->field;
+    M1 = fields[N];
+  } else {
+    M1 = V1->Float;
+  }
+  
+  ALLOCATE (OUT, dbStack, 1);
+  OUT->type = 'T';
+
+  if (!strcmp (op, "="))      {   OUT->Float = M1;                 }
+  if (!strcmp (op, "abs"))    {   OUT->Float = fabs(M1);           }
+  if (!strcmp (op, "int"))    {   OUT->Float = (float)(int)(M1);   }
+  if (!strcmp (op, "exp"))    {   OUT->Float = exp (M1);           }
+  if (!strcmp (op, "ten"))    {   OUT->Float = pow (10.0,M1);      }
+  if (!strcmp (op, "log"))    {   OUT->Float = log10 (M1);         }
+  if (!strcmp (op, "ln"))     {   OUT->Float = log (M1);           }
+  if (!strcmp (op, "sqrt"))   {   OUT->Float = sqrt (M1);          }
+  if (!strcmp (op, "erf"))    {   OUT->Float = erf (M1);           }
+			      			      
+  if (!strcmp (op, "sinh"))   {   OUT->Float = sinh (M1);          }
+  if (!strcmp (op, "cosh"))   {   OUT->Float = cosh (M1);          }
+  if (!strcmp (op, "asinh"))  {   OUT->Float = asinh (M1);         }
+  if (!strcmp (op, "acosh"))  {   OUT->Float = acosh (M1);         }
+  if (!strcmp (op, "lgamma")) {   OUT->Float = lgamma (M1);        }
+
+  if (!strcmp (op, "sin"))    {   OUT->Float = sin (M1);           }
+  if (!strcmp (op, "cos"))    {   OUT->Float = cos (M1);           }
+  if (!strcmp (op, "tan"))    {   OUT->Float = tan (M1);           }
+  if (!strcmp (op, "dsin"))   {   OUT->Float = sin (M1*RAD_DEG);   }
+  if (!strcmp (op, "dcos"))   {   OUT->Float = cos (M1*RAD_DEG);   }
+  if (!strcmp (op, "dtan"))   {   OUT->Float = tan (M1*RAD_DEG);   }
+  if (!strcmp (op, "asin"))   {   OUT->Float = asin (M1);          }
+  if (!strcmp (op, "acos"))   {   OUT->Float = acos (M1);          }
+  if (!strcmp (op, "atan"))   {   OUT->Float = atan (M1);          }
+  if (!strcmp (op, "dasin"))  {   OUT->Float = asin (M1)*DEG_RAD;  }
+  if (!strcmp (op, "dacos"))  {   OUT->Float = acos (M1)*DEG_RAD;  }
+  if (!strcmp (op, "datan"))  {   OUT->Float = atan (M1)*DEG_RAD;  }
+  if (!strcmp (op, "rnd"))    {   OUT->Float = drand48();          }
+  if (!strcmp (op, "not"))    {   OUT->Float = !(M1);              }
+  if (!strcmp (op, "--"))     {   OUT->Float = - (M1);             }
+  if (!strcmp (op, "isinf"))  {   OUT->Float = !finite(M1);        }
+  if (!strcmp (op, "isnan"))  {   OUT->Float = isnan(M1);          } 
+
+  return (OUT);
+}
Index: /trunk/Ohana/src/opihi/dvo/dbStackOps.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbStackOps.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dbStackOps.c	(revision 13479)
@@ -0,0 +1,26 @@
+# include "dvoshell.h"
+
+void dbInitStack (dbStack *stack) {
+  stack[0].type   = 0;
+  stack[0].name   = NULL;
+}
+
+// free data for stack entries (free stack explicitly)
+void dbFreeStack (dbStack *stack, int Nstack) {
+
+  int i;
+
+  for (i = 0; i < Nstack; i++) {
+    if (stack[i].name != NULL) {
+      free (stack[i].name);
+      stack[i].name = NULL;
+    }
+  }
+}
+
+/* delete name and data */
+void dbFreeEntry (dbStack *stack) {
+
+  if (stack->type != 'T') return;
+  free (stack);
+}
Index: /trunk/Ohana/src/opihi/dvo/db_check_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/db_check_stack.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/db_check_stack.c	(revision 13479)
@@ -0,0 +1,54 @@
+# include "opihi.h"
+
+int db_check_stack (dvoStack *stack, int Nstack, int table, dvoField *fields, int *Nfields) {
+
+  int i, Nx, Ny, Nv, size;
+  char *c;
+
+  NFIELDS = *Nfields + 10;
+  REALLOCATE (fields, dvoField, NFIELDS);
+
+  for (i = 0; i < Nstack; i++) {
+    if (stack[i].type == 'X') {
+
+      /** if this is a number, put it on the list of scalers and move on **/
+      stack[i].Float = strtod (stack[i].name, &c);
+      if (c == stack[i].name + strlen (stack[i].name)) {
+	stack[i].type  = 'S';
+	continue;
+      } 
+
+      // this must be a field : is it already in the list?
+      for (j = 0; (j < *Nfields) && strcasecmp (stack[i].name, fields[j].name); j++);
+      if (j < *Nfields) {
+	stack[i].field = j;
+	stack[i].type  = 'F';
+	continue;
+      }
+
+      // this must be a field : is it a valid name?
+      if (table == DVO_TABLE_MEASURE) {
+	status = ParseMeasureField (&fields[*Nfields], stack[i].name);
+      } 
+      if (table == DVO_TABLE_AVERAGE) {
+	status = ParseAverageField (&fields[*Nfields], stack[i].name);
+      } 
+      if (!status) {
+	gprint (GP_ERR, "unknown database field %s\n", stack[i].name);
+	return (FALSE);
+      }
+      stack[i].field = *Nfields;
+      stack[i].type  = 'F';
+
+      *Nfields ++;
+      CHECK_REALLOCATE (fields, dvoField, NFIELDS, *Nfields, 10);
+    }
+  }
+  return (TRUE);
+}
+
+/* check stack identifies the data elements as plain scalars or table fields
+   operators have already been identified.  
+   check stack returns the total stack dimensionality (0,1,2)
+   on error, check stack returns FALSE
+*/
Index: /trunk/Ohana/src/opihi/dvo/db_convert_to_RPN.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/db_convert_to_RPN.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/db_convert_to_RPN.c	(revision 13479)
@@ -0,0 +1,210 @@
+# include "opihi.h"
+# define DUMPSTACK 0
+
+dvoStack *convert_to_RPN (int argc, char **argv, int *nstack) {
+  
+  int type, Nx, Ny;
+  int i, j, Nstack, Nop_stack, NSTACK;
+  dvoStack *stack, *op_stack;
+
+  /* max total stack size is argc, though should be less, this is safe */
+  NSTACK = argc + 5;
+  ALLOCATE (stack, dvoStack, NSTACK);
+  ALLOCATE (op_stack, dvoStack, NSTACK);
+  for (i = 0; i < NSTACK; i++) {
+    init_stack (&stack[i]);
+    init_stack (&op_stack[i]);
+  }
+  
+  Nx = Ny = Nstack = Nop_stack = 0;
+  for (i = 0; i < argc; i++) {
+    
+    /* decide on priority of object */
+    type = 0;
+    /* unary operations */
+    if (!strcmp (argv[i], "abs"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "int"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "exp"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ten"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "log"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ln"))     { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "sqrt"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "erf"))    { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "sinh"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "cosh"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "asinh"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "acosh"))  { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "sin"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "cos"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "tan"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dsin"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dcos"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dtan"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "asin"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "acos"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "atan"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dasin"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dacos"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "datan"))  { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "lgamma")) { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "rnd"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "xramp"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "yramp"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ramp"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "zero"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "--"))     { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "not"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "isinf"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "isnan"))  { type = 9; goto gotit; }
+
+    /* binary operations */
+    if (!strcmp (argv[i], "^"))      { type = 8; goto gotit; }
+
+    if (!strcmp (argv[i], "@"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "/"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "*"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "%"))      { type = 7; goto gotit; }
+
+    if (!strcmp (argv[i], "+"))      { type = 6; goto gotit; }
+    if (!strcmp (argv[i], "-"))      { type = 6; goto gotit; }
+	
+    if (!strcmp (argv[i], "&"))      { type = 5; goto gotit; }
+    if (!strcmp (argv[i], "|"))      { type = 5; goto gotit; }
+
+    if (!strcmp (argv[i], "<"))      { type = 4; goto gotit; }
+    if (!strcmp (argv[i], ">"))      { type = 4; goto gotit; }
+    if (!strcmp (argv[i], "=="))     { type = 4; strcpy (argv[i], "E"); goto gotit; }
+    if (!strcmp (argv[i], "!="))     { type = 4; strcpy (argv[i], "N"); goto gotit; }
+    if (!strcmp (argv[i], "<="))     { type = 4; strcpy (argv[i], "L"); goto gotit; }
+    if (!strcmp (argv[i], ">="))     { type = 4; strcpy (argv[i], "G"); goto gotit; }
+    if (!strcmp (argv[i], ">>"))     { type = 4; strcpy (argv[i], "U"); goto gotit; }
+    if (!strcmp (argv[i], "<<"))     { type = 4; strcpy (argv[i], "D"); goto gotit; }
+
+    if (!strcmp (argv[i], "&&"))     { type = 3; strcpy (argv[i], "A"); goto gotit; }
+    if (!strcmp (argv[i], "||"))     { type = 3; strcpy (argv[i], "O"); goto gotit; }
+
+    if (!strcmp (argv[i], "("))      { type = 2; goto gotit; }
+    if (!strcmp (argv[i], ")"))      { type = 1; goto gotit; }
+
+  gotit:
+    /* choose how to deal with object */
+    switch (type) {
+      case 8:  /* exponentiation: 2^2^3 = 64 != 256 (precedence is right-to-left, not left-to-right!) */
+	/* pop previous, higher operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type > type); j--) {
+	  strcpy (stack[Nstack].name, op_stack[j].name);
+	  stack[Nstack].type = op_stack[j].type;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	strcpy (op_stack[Nop_stack].name, argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 9: /* unary OPs */
+      case 7: /* binary OPs */
+      case 6:
+      case 5: 
+      case 4: 
+      case 3: 
+	/* pop previous, higher or equal operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
+	  strcpy (stack[Nstack].name, op_stack[j].name);
+	  stack[Nstack].type = op_stack[j].type;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	strcpy (op_stack[Nop_stack].name, argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 2:  
+	/* push operator on OP stack */
+	strcpy (op_stack[Nop_stack].name, argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 1: 
+	/* pop rest of operators from OP stack to stack, looking for '(' */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != 2); j--) {
+	  strcpy (stack[Nstack].name, op_stack[j].name);
+	  stack[Nstack].type = op_stack[j].type;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	if ((j == -1) || (op_stack[j].type != 2)) {
+	  push_error ("syntax error: mismatched parenthesis");
+	  Nstack = 0;
+	  goto cleanup;
+	}
+	Nop_stack --;
+	break;
+      case 0:
+	/* place the value (number or vector/matrix name) on stack */
+	/* value of 'X' is used as sentinel until we sort out values */
+	strcpy (stack[Nstack].name, argv[i]);
+	stack[Nstack].type = 'X';
+	Nstack ++;
+	break;
+    }
+  }
+
+  /* dump remaining operators on stack, checking for ')' */
+  for (j = Nop_stack - 1; j >= 0; j--) {
+    if (op_stack[j].type == 2) {
+      push_error ("syntax error: mismatched parenthesis");
+      Nstack = 0;
+      goto cleanup;
+    }
+    strcpy (stack[Nstack].name, op_stack[j].name);
+    stack[Nstack].type = op_stack[j].type;
+    Nstack ++;
+  }
+
+cleanup: 
+  /*** free up unused stack space ***/
+  clean_stack (op_stack, NSTACK);
+  free (op_stack);
+  clean_stack (&stack[Nstack], NSTACK - Nstack);
+  REALLOCATE (stack, dvoStack, MAX (Nstack, 1));
+  *nstack = Nstack;
+
+  for (i = 0; i < argc; i++) {
+    free (argv[i]);
+  }
+  free (argv);
+
+# if (DUMPSTACK)
+  for (i = 0; i < Nstack; i++) {
+    gprint (GP_ERR, "%s ", stack[i].name);
+  }
+  if (Nstack > 0) gprint (GP_ERR, "\n");
+  for (i = 0; i < Nstack; i++) {
+    gprint (GP_ERR, "%d ", stack[i].type);
+  }
+  if (Nstack > 0) gprint (GP_ERR, "\n");
+# endif
+
+  return (stack);
+
+}
+
+/* here are the rules for parsing a math AOL line to RPN:
+
+1) if object is a number, push on stack
+2) if object is a third order operand (exp, sin, cos), push on op stack
+3) if object is an open paren, push on op stack,
+4) if object is a second order operand, push on stack
+5) if object is a first order operand, pop all second order operands from stack 
+until paren, push on stack
+6) if object is an end paren, pop all objects from stack until paren, 
+pop next stack, if third order op
+7) if end of line, pop all remaining objects, second order first, etc.
+   
+*/
Index: /trunk/Ohana/src/opihi/dvo/dmt.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dmt.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/dmt.c	(revision 13479)
@@ -4,5 +4,5 @@
 int dmt (int argc, char **argv) {
   
-  int i, m, k, N, Ngraph, SaveVectors;
+  int i, m, k, N, kapa, SaveVectors;
   int Nsec, Nsecfilt, NPTS;
   double Radius;
@@ -38,6 +38,8 @@
   }
 
-  Ngraph = 0;
-  if (!GetGraphData (&graphsky, NULL, &Ngraph)) return (FALSE);
+  // XXX this needs to be fixed: how to access different graphs at once?
+  gprint (GP_ERR, "ERROR: this function is currently disabled\n");
+  return (FALSE);
+  if (!GetGraphData (&graphsky, &kapa, NULL)) return (FALSE);
   if (!GetGraph (&graphmode, NULL, NULL)) return (FALSE);
 
@@ -142,8 +144,5 @@
   } else {
     graphmode.style = 2; /* set style to points */
-    PrepPlotting (N, &graphmode);
-    
-    PlotVector (N, Xvec.elements);
-    PlotVector (N, Yvec.elements);
+    PlotVector (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
 
     free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/dvo/dvo.c.in
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dvo.c.in	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/dvo.c.in	(revision 13479)
@@ -55,6 +55,5 @@
 /* add program-dependent exit functions here */
 void cleanup () {
-  QuitImage ();
-  QuitGraph ();
+  QuitKapa ();
   return;
 }
Index: /trunk/Ohana/src/opihi/dvo/dvoBooleanElements.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dvoBooleanElements.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dvoBooleanElements.c	(revision 13479)
@@ -0,0 +1,158 @@
+# include "opihi.h"
+
+/* local private functions */
+void InsertValue (char c);
+void EndOfString (void);
+int IsAnOp (char *c);
+int IsTwoOp (char *c);
+
+/* local private static variables */
+int Nchar, Nout, NOUT;
+char **out;
+
+// split up the input arguments into appropriate blocks
+char **dvoBooleanElements (int Nin, char **in, int *nout) {
+  
+  int i, j, minus, negate, plus, posate, OpStat, SciNotation;
+
+  NOUT = Nin;
+  Nchar = Nout = 0;
+  ALLOCATE (out, char *, NOUT);
+  ALLOCATE (out[Nout], char, NCHARS);
+
+  for (i = 0; i < Nin; i++) {
+    for (j = 0; j < strlen(in[i]); j++) {
+      SciNotation = FALSE;
+      /* identify 'negate' or 'minus' ops */
+      negate = minus = FALSE;
+      if (in[i][j] == '-') { 
+	minus = TRUE;  
+	/* if - is first thing on line, must be a negator */
+	if ((Nout == 0) && (Nchar == 0)) {  
+	  minus = FALSE;
+	  negate = TRUE;
+	  goto skip1;
+	}
+	/* check previous entry on line */
+	if (Nchar) {
+	  OpStat = IsAnOp (out[Nout]);
+	  if (out[Nout][0] == ')') OpStat = FALSE;
+	} else {
+	  OpStat = IsAnOp (out[Nout-1]);
+	  if (out[Nout-1][0] == ')') OpStat = FALSE;
+	}
+	/* if - follows an operator, must be negator */
+	if (OpStat) {
+	  minus = FALSE;
+	  negate = TRUE;
+	  goto skip1;
+	}
+	/* if - follows 'e' is part of 1e-5 */
+	if (j == 0) goto skip1;
+	if ((in[i][j-1] == 'e') || (in[i][j-1] == 'E')) {
+	  SciNotation = TRUE;
+	  negate = minus = FALSE;
+	}
+      }
+    skip1:
+      /* idenfity 'posate' or 'plus' ops */
+      posate = plus = FALSE;
+      if (in[i][j] == '+') { 
+	plus = TRUE;  
+	/* if + is first thing on line, must be a posator */
+	if ((Nout == 0) && (Nchar == 0)) {  
+	  plus = FALSE;
+	  posate = TRUE;
+	  goto skip2;
+	}
+	/* check previous entry on line */
+	if (Nchar) {
+	  OpStat = IsAnOp (out[Nout]);
+	  if (out[Nout][0] == ')') OpStat = FALSE;
+	} else {
+	  OpStat = IsAnOp (out[Nout-1]);
+	  if (out[Nout-1][0] == ')') OpStat = FALSE;
+	}
+	/* if + follows an operator, must be posator */
+	if (OpStat) {
+	  plus = FALSE;
+	  posate = TRUE;
+	  goto skip2;
+	}
+	/* if + follows 'e' is part of 1e+5 */
+	if (j == 0) goto skip2;
+	if ((in[i][j-1] == 'e') || (in[i][j-1] == 'E')) {
+	  SciNotation = TRUE;
+	  posate = plus = FALSE;
+	}
+      }
+    skip2:
+      /* operators */
+      if (negate || minus || posate || plus || (IsAnOp (&in[i][j]) && !SciNotation)) {
+	if (posate) continue;
+	EndOfString ();
+	/* copy operator to out[Nout] */
+	InsertValue (in[i][j]);
+	if (negate) InsertValue ('-');
+
+	if (IsTwoOp (&in[i][j])) {
+	  InsertValue (in[i][j+1]);
+	  j++;
+	} 
+	EndOfString ();
+	continue;
+      }
+      /* quoted string */
+      if (in[i][j] == '"') {
+	InsertValue (in[i][j]);
+	j++;
+	while ((j < strlen(in[i])) && (in[i][j] != '"')) {
+	  InsertValue (in[i][j]);
+	  j++;
+	}
+	if (in[i][j] != '"') continue;
+	/* 
+	  gprint (GP_ERR, "mismatched quotes\n");
+	  return (FALSE);
+	}
+	*/
+	InsertValue (in[i][j]);
+	EndOfString ();
+	continue;
+      }
+      /* not an operator, not a quoted string */
+      if (!OHANA_WHITESPACE (in[i][j])) {
+	InsertValue (in[i][j]);
+      } else {
+	EndOfString ();
+      }
+    }
+    EndOfString ();
+  }
+
+  /* one extra entry is allocated, free here */
+  free (out[Nout]);
+  *nout = Nout;
+  return (out);
+
+}
+
+void InsertValue (char c) {
+  out[Nout][Nchar] = c;
+  Nchar ++;
+  out[Nout][Nchar] = 0;
+}
+
+void EndOfString () {
+  if (Nchar > 0) {
+    out[Nout][Nchar] = 0;
+    Nout ++;
+    Nchar = 0;
+    
+    if (Nout >= NOUT - 1) {
+      NOUT += 10; 
+      REALLOCATE (out, char *, NOUT); 
+    } 
+    ALLOCATE (out[Nout], char, NCHARS); 
+  }
+}
Index: /trunk/Ohana/src/opihi/dvo/dvoEvaluateStack.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dvoEvaluateStack.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dvoEvaluateStack.c	(revision 13479)
@@ -0,0 +1,65 @@
+# include "opihi.h"
+
+int CheckBooleanCondition (dvoStack dbStack, int NdbStack, float *values, dvoFields *fields, int Nfields) {
+  
+  int i, j, Nstack;
+  dvoStack **stack, *output;
+
+  Nstack = NdbStack;
+  ALLOCATE (stack, dvoStack *, NdbStack);
+  for (i = 0; i < NdbStack; i++) {
+    stack[i] = &dbStack[i];
+  }
+
+  for (i = 0; i < Nstack; i++) {
+
+    /***** binary operators *****/
+    if ((stack[i].type >= 3) && (stack[i].type <= 8)) {
+
+      // pre-test that op and entries match
+      output = db_binary (stack[i-2], stack[i-1], stack[i].name, fields, Nfields); 
+
+      // free temporary stack items, drop external items
+      clear_stack (stack[i-2]);
+      clear_stack (stack[i-1]);
+
+      stack[i-2] = output;
+      for (j = i + 1; j < Nstack; j++) {
+	stack[j-2] = stack[j];
+      }
+
+      Nstack -= 2;
+      i -= 2;
+      continue;
+    }
+
+    /***** unary operators **/
+    if (stack[i].type == 9) {
+
+      // pre-test that op and entries match
+      output = db_unary (&stack[i-1], stack[i].name, fields, Nfields); 
+
+      // free temporary stack items, drop external items
+      clear_stack (stack[i-2]);
+      clear_stack (stack[i-1]);
+
+      for (j = i + 1; j < Nstack; j++) {
+	stack[j-1] = stack[j];
+      }
+
+      Nstack -= 1;
+      i -= 1;
+      continue;
+    } 
+  }
+
+  // pre-test that op and entries match
+  return (TRUE);
+}
+
+/* delete name and data */
+void clear_stack (dvoStack *stack) {
+
+  if (stack->type != 'T') return;
+  free (stack);
+}
Index: /trunk/Ohana/src/opihi/dvo/dvodb.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dvodb.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dvodb.c	(revision 13479)
@@ -0,0 +1,77 @@
+
+/* dvo fields and boolean expressions
+   - evaluate the command line:
+     * avextract ra,dec,g,r,i where (uRA < 0.1)
+     1) identify all fields in extraction list
+     2) parse boolean expression
+     3) identify additional fields from expression
+*/
+
+enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE};
+
+// a single db field 
+typedef struct {
+  char *name;
+  int extract;
+  int table;
+  int ID;
+  int magMode;
+  PhotCode *photcode;
+} dvoField;
+
+// db boolean operations
+typedef struct {
+  char   *name;
+  char    type;
+  int     field;
+  float   Float;
+} dvoStack;
+
+dvoField *ParseCmdlineFields (int argc, char **argv, int table, int *last, int *nfields) {
+
+  int i, Nfields, NFIELDS, 
+
+  *nfields = 0;
+  Nfields = 0;
+  NFIELDS = 10;
+  ALLOCATE (fields, dvoField, NFIELDS);
+
+  // examine each argv[i] entry until we reach a where 
+  for (i = 1; (i < argc) && strcasecmp (argv[i], "where"); i++) {
+    // split the word by ","
+    p = argv[i];
+    while (*p) {
+      q = strchr (p, ',');
+      if (q == NULL) {
+	field = strcreate (p);
+	p = p + strlen(p);
+      } else {
+	field = strncreate (p, q-p);
+	p = q + 1;
+      }
+      // identify field for word
+      // need to know which type of fields to look for...
+      // xxx extend this more generally later
+      if (table == DVO_TABLE_MEASURE) {
+	status = ParseMeasureField (&fields[Nfields], field);
+      } 
+      if (table == DVO_TABLE_AVERAGE) {
+	status = ParseAverageField (&fields[Nfields], field);
+      } 
+      if (!status) {
+	gprint (GP_ERR, "unknown database field %s\n", field);
+	free (field);
+	free (fields);
+	return (NULL);
+      }
+      free (field);
+
+      Nfields ++;
+      CHECK_REALLOCATE (fields, dvoField, NFIELDS, Nfields, 10);
+    }
+  }
+
+  *last = i;
+  *nfields = Nfields;
+  return (fields);
+}
Index: /trunk/Ohana/src/opihi/dvo/dvofields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dvofields.c	(revision 13479)
+++ /trunk/Ohana/src/opihi/dvo/dvofields.c	(revision 13479)
@@ -0,0 +1,129 @@
+
+int GetMagMode (char *string) {
+
+  if (!strcasecmp (string, "inst"))  return (MAG_INST);
+  if (!strcasecmp (string, "cat"))   return (MAG_CAT);
+  if (!strcasecmp (string, "sys"))   return (MAG_SYS);
+  if (!strcasecmp (string, "rel"))   return (MAG_REL);
+  if (!strcasecmp (string, "cal"))   return (MAG_CAL);
+  if (!strcasecmp (string, "ave"))   return (MAG_AVE);
+  if (!strcasecmp (string, "ref"))   return (MAG_REF);
+  if (!strcasecmp (string, "err"))   return (MAG_ERR);
+  if (!strcasecmp (string, "chisq")) return (MAG_CHISQ);
+  return (MAG_NONE);
+}
+
+PhotCode *ParsePhotcodeField (char *field, int *mode, int default) {
+
+  char *tmpstring, *p;
+  PhotCode *code;
+
+  *mode = default;
+
+  p = strchr (field, ':');
+  if (p != NULL) {
+    *mode = GetMagMode (p + 1);
+    if (*mode == MAG_NONE) return (NULL);
+    tmpstring = strncreate (field, p - field);
+  } else {
+    tmpstring = strcreate (field);
+  }
+  code = GetPhotcodebyName (tmpstring);
+  free (tmpstring);
+
+  return (code);
+}
+
+# define ESCAPE(F,M) { \
+  field->ID = (F); \
+  field->magMode = (M); \
+  field->photcode = NULL; \
+  return (TRUE);
+
+int ParseMeasureField (dvoField *field, char *fieldName) {
+
+  PhotCode *code;
+
+  field->table = DVO_TABLE_MEASURE;
+  field->name  = strcreate (fieldName);
+
+  if (!strcasecmp (fieldName, "RA"))       ESCAPE (MEAS_RA,   	  MAG_NONE);
+  if (!strcasecmp (fieldName, "DEC"))      ESCAPE (MEAS_DEC,  	  MAG_NONE);
+  if (!strcasecmp (fieldName, "MAG"))      ESCAPE (MEAS_MAG,  	  MAG_REL);
+  if (!strcasecmp (fieldName, "dMAG"))     ESCAPE (MEAS_dMAG, 	  MAG_ERR);
+  if (!strcasecmp (fieldName, "AIRMASS"))  ESCAPE (MEAS_AIRMASS,  MAG_NONE);
+  if (!strcasecmp (fieldName, "EXPTIME"))  ESCAPE (MEAS_EXPTIME,  MAG_NONE);
+  if (!strcasecmp (fieldName, "PHOTCODE")) ESCAPE (MEAS_PHOTCODE, MAG_NONE);
+  if (!strcasecmp (fieldName, "TIME"))     ESCAPE (MEAS_TIME,     MAG_NONE);
+  if (!strcasecmp (fieldName, "dR"))       ESCAPE (MEAS_dR, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "dD"))       ESCAPE (MEAS_dD, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "FWHM"))     ESCAPE (MEAS_FWHM,     MAG_NONE);
+  if (!strcasecmp (fieldName, "DOPHOT"))   ESCAPE (MEAS_DOPHOT,   MAG_NONE);
+  if (!strcasecmp (fieldName, "FLAGS"))    ESCAPE (MEAS_FLAGS,    MAG_NONE);
+  if (!strcasecmp (fieldName, "XCCD"))     ESCAPE (MEAS_XCCD, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "YCCD"))     ESCAPE (MEAS_YCCD, 	  MAG_NONE);
+  if (!strcasecmp (fieldName, "XMOSAIC"))  ESCAPE (MEAS_XMOSAIC,  MAG_NONE);
+  if (!strcasecmp (fieldName, "YMOSAIC"))  ESCAPE (MEAS_YMOSAIC,  MAG_NONE);
+
+  // for words that don't parse, try a photcode
+
+  // check for code:mode in photcode name 
+  code = ParsePhotcodeField (&mode, MAG_REL);
+  if (code == NULL) return (FALSE);
+
+  if (mode == MAG_ERR) {
+    field->ID = MEAS_dMAG;
+  } else {
+    field->ID = MEAS_MAG;
+  }    
+  
+  field->magMode = mode;
+  field->photcode = code;
+  return (TRUE);
+}
+  
+int ParseAverageField (char *fieldName) {
+
+  PhotCode *code;
+
+  field->table = DVO_TABLE_AVERAGE;
+
+  if (!strcasecmp (fieldName, "RA"))    ESCAPE (AVE_RA,        MAG_NONE);
+  if (!strcasecmp (fieldName, "DEC"))   ESCAPE (AVE_DEC,       MAG_NONE);
+  if (!strcasecmp (fieldName, "dRA"))   ESCAPE (AVE_RA_ERR,    MAG_NONE);
+  if (!strcasecmp (fieldName, "dDEC"))  ESCAPE (AVE_DEC_ERR,   MAG_NONE);
+  if (!strcasecmp (fieldName, "uRA"))   ESCAPE (AVE_U_RA,      MAG_NONE);
+  if (!strcasecmp (fieldName, "uDEC"))  ESCAPE (AVE_U_DEC,     MAG_NONE);
+  if (!strcasecmp (fieldName, "duRA"))  ESCAPE (AVE_U_RA_ERR,  MAG_NONE);
+  if (!strcasecmp (fieldName, "duDEC")) ESCAPE (AVE_U_DEC_ERR, MAG_NONE);
+  if (!strcasecmp (fieldName, "PAR"))   ESCAPE (AVE_PAR,       MAG_NONE);
+  if (!strcasecmp (fieldName, "dPAR"))  ESCAPE (AVE_PAR_ERR,   MAG_NONE);
+  if (!strcasecmp (fieldName, "MAG"))   ESCAPE (AVE_MAG,       MAG_AVE);
+  if (!strcasecmp (fieldName, "dMAG"))  ESCAPE (AVE_dMAG,      MAG_AVE_ERR);
+  if (!strcasecmp (fieldName, "NMEAS")) ESCAPE (AVE_NMEAS,     MAG_NONE);
+  if (!strcasecmp (fieldName, "NMISS")) ESCAPE (AVE_NMISS,     MAG_NONE);
+  if (!strcasecmp (fieldName, "Xp"))    ESCAPE (AVE_Xp,        MAG_NONE);
+  if (!strcasecmp (fieldName, "Xm"))    ESCAPE (AVE_Xm,        MAG_CHISQ);
+  if (!strcasecmp (fieldName, "FLAG"))  ESCAPE (AVE_FLAG,      MAG_NONE);
+  if (!strcasecmp (fieldName, "TYPE"))  ESCAPE (AVE_TYPE,      MAG_NONE);
+  if (!strcasecmp (fieldName, "NPHOT")) ESCAPE (AVE_NPHOT,     MAG_NONE);
+  if (!strcasecmp (fieldName, "NCODE")) ESCAPE (AVE_NCODE,     MAG_NONE);
+  if (!strcasecmp (fieldName, "NCRIT")) ESCAPE (AVE_NCRIT,     MAG_NONE);
+
+  // for words that don't parse, try a photcode
+
+  // check for code:mode in photcode name 
+  code = ParsePhotcodeField (&mode, MAG_AVE);
+  if (code == NULL) return (FALSE);
+
+  // need to distinguish phot, sys errors and scatter
+  if (mode == MAG_ERR) {
+    field->ID = MEAS_dMAG;
+  } else {
+    field->ID = MEAS_MAG;
+  }    
+  
+  field->magMode = mode;
+  field->photcode = code;
+  return (TRUE);
+}
Index: /trunk/Ohana/src/opihi/dvo/extract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/extract.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/extract.c	(revision 13479)
@@ -31,6 +31,5 @@
   RegionFile *regions;
 
-  Ngraph = 0;
-  if (!GetGraphData (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraphData (&graphmode, NULL, NULL)) return (FALSE);
   if (!InitPhotcodes ()) return (FALSE);
 
Index: /trunk/Ohana/src/opihi/dvo/fitcolors.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/fitcolors.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/fitcolors.c	(revision 13479)
@@ -20,5 +20,5 @@
   float *out, *colorFit, *deltaFit, dColor, C0, C1;
   float minDelta, maxDelta, minColor, maxColor;
-  int fd, Npx, Npy, NPX, NPY, Nplot, PLOT;
+  int kapa, Npx, Npy, NPX, NPY, Nplot, PLOT;
   Graphdata graphdata;
   KapaSection section;
@@ -86,5 +86,5 @@
 
   if (PLOT) {
-    if (!GetGraph (&graphdata, &fd, NULL)) return (FALSE);
+    if (!GetGraph (&graphdata, &kapa, NULL)) return (FALSE);
     Nplot = 0;
     Npx = Npy = 0;
@@ -95,6 +95,6 @@
     graphdata.style = 2;
     graphdata.ptype = 2;
-    KapaClear (fd, TRUE);
-    KapaSetFont (fd, "helvetica", 14);
+    KapaClearSections (kapa);
+    KapaSetFont (kapa, "helvetica", 14);
 
     ALLOCATE (colorFit, float, 11);
@@ -301,10 +301,10 @@
 	  strcpy (graphdata.labels, "1100");
 	}
-	KapaSetSection (fd, &section);
-	KapaSetLimits (fd, &graphdata);
-	KapaBox (fd, &graphdata);
-	KapaPrepPlot (fd, Npts, &graphdata);
-	KapaPlotVector (fd, Npts, xvec[0].elements);
-	KapaPlotVector (fd, Npts, yvec[0].elements);
+	KapaSetSection (kapa, &section);
+	KapaSetLimits (kapa, &graphdata);
+	KapaBox (kapa, &graphdata);
+	KapaPrepPlot (kapa, Npts, &graphdata);
+	KapaPlotVector (kapa, Npts, xvec[0].elements, "x");
+	KapaPlotVector (kapa, Npts, yvec[0].elements, "y");
 
 	for (i = 0; i < 11; i++) {
@@ -313,14 +313,14 @@
 	graphdata.style = 0;
 	graphdata.color = KapaColorByName ("red");
-	KapaPrepPlot (fd, 11, &graphdata);
-	KapaPlotVector (fd, 11, colorFit);
-	KapaPlotVector (fd, 11, deltaFit);
-
-	KapaSetFont (fd, "helvetica", 8);
+	KapaPrepPlot (kapa, 11, &graphdata);
+	KapaPlotVector (kapa, 11, colorFit, "x");
+	KapaPlotVector (kapa, 11, deltaFit, "y");
+
+	KapaSetFont (kapa, "helvetica", 8);
 	sprintf (label, "%s", code[0][0].name);
-	KapaSendTextline (fd, label, 0.2*maxColor + 0.8*minColor, 0.8*maxDelta + 0.2*minDelta, 0.0);
+	KapaSendTextline (kapa, label, 0.2*maxColor + 0.8*minColor, 0.8*maxDelta + 0.2*minDelta, 0.0);
 	sprintf (label, "%s", code[1][0].name);
-	KapaSendTextline (fd, label, 0.2*maxColor + 0.8*minColor, 0.2*maxDelta + 0.8*minDelta, 0.0);
-	KapaSetFont (fd, "helvetica", 14);
+	KapaSendTextline (kapa, label, 0.2*maxColor + 0.8*minColor, 0.2*maxDelta + 0.8*minDelta, 0.0);
+	KapaSetFont (kapa, "helvetica", 14);
 
 	graphdata.style = 2;
@@ -336,6 +336,6 @@
 	    Npy = 0;
 	    sprintf (filename, "%s.%02d.png", plotname, Nplot);
-	    KapaPNG (fd, filename);
-	    KapaClear (fd, TRUE);
+	    KapaPNG (kapa, filename);
+	    KapaClearSections (kapa);
 	    Nplot++;
 	  }
Index: /trunk/Ohana/src/opihi/dvo/fitsed.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/fitsed.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/fitsed.c	(revision 13479)
@@ -31,6 +31,6 @@
   float *fitmags, *fiterrs, *wavecode, *vegaToAB;
   float color;
-  double X, Y;
-  int fd, PLOT;
+  double X, Y, ZP, RA, DEC;
+  int kapa, PLOT;
   int Nrow, NROW, idx, Nfilter, start, row;
   unsigned short colorP, colorM, code, USNOred, USNOblu;
@@ -157,9 +157,9 @@
 
   if (PLOT) {
-    if (!GetGraph (&graphdata, &fd, NULL)) return (FALSE);
+    if (!GetGraph (&graphdata, &kapa, NULL)) return (FALSE);
     SetLimitsRaw (wavecode, NULL, Nfilter, &graphdata);
     graphdata.style = 2;
     graphdata.ptype = 2;
-    KapaClear (fd, TRUE);
+    KapaClearSections (kapa);
     magSection.name = strcreate ("mag");
     magSection.x  = 0;
@@ -173,5 +173,5 @@
     resSection.dy = 0.5;
     
-    KapaSetFont (fd, "helvetica", 14);
+    KapaSetFont (kapa, "helvetica", 14);
     ALLOCATE (fitmags, float, Nfilter);
     ALLOCATE (fiterrs, float, Nfilter);
@@ -261,13 +261,13 @@
 	SWAP (graphdata.ymin, graphdata.ymax);
 
-	KapaClear (fd, TRUE);
-	KapaSetSection (fd, &magSection);
-    	KapaSetLimits (fd, &graphdata);
-	KapaBox (fd, &graphdata);
+	KapaClearSections (kapa);
+	KapaSetSection (kapa, &magSection);
+    	KapaSetLimits (kapa, &graphdata);
+	KapaBox (kapa, &graphdata);
 	graphdata.color = KapaColorByName ("blue");
 	graphdata.etype = 0;
-	KapaPrepPlot (fd, Nfilter, &graphdata);
-	KapaPlotVector (fd, Nfilter, wavecode);
-	KapaPlotVector (fd, Nfilter, SEDtable[minFit.row][0].mags);
+	KapaPrepPlot (kapa, Nfilter, &graphdata);
+	KapaPlotVector (kapa, Nfilter, wavecode, "x");
+	KapaPlotVector (kapa, Nfilter, SEDtable[minFit.row][0].mags, "y");
 	graphdata.color = KapaColorByName ("red");
 	graphdata.etype = 1;
@@ -279,22 +279,22 @@
 	  fiterrs[j] = sourceError.mags[j];
 	}
-	KapaPrepPlot (fd, Nfilter, &graphdata);
-	KapaPlotVector (fd, Nfilter, wavecode);
-	KapaPlotVector (fd, Nfilter, fitmags);
-	KapaPlotVector (fd, Nfilter, fiterrs);
-	KapaPlotVector (fd, Nfilter, fiterrs);
-	KapaSendLabel (fd, "model,fit (mags)", 1);
+	KapaPrepPlot (kapa, Nfilter, &graphdata);
+	KapaPlotVector (kapa, Nfilter, wavecode, "x");
+	KapaPlotVector (kapa, Nfilter, fitmags, "y");
+	KapaPlotVector (kapa, Nfilter, fiterrs, "dym");
+	KapaPlotVector (kapa, Nfilter, fiterrs, "dyp");
+	KapaSendLabel (kapa, "model,fit (mags)", 1);
 
 	sprintf (line, "star: %10.6f %10.6f  T: %5.0fK  A_V|: %4.2f  M_D|: %5.2f  &sc&h^2|: %5.2f", 
 		 catalog.average[i].R, catalog.average[i].D, 
 		 SEDtable[minFit.row][0].Temp, SEDtable[minFit.row][0].Av, minFit.Md, minFit.chisq);
-	KapaSendLabel (fd, line, 2);
-	KapaSendLabel (fd, "model,fit (mags)", 1);
-
-	KapaSetSection (fd, &resSection);
+	KapaSendLabel (kapa, line, 2);
+	KapaSendLabel (kapa, "model,fit (mags)", 1);
+
+	KapaSetSection (kapa, &resSection);
 	graphdata.ymin = -1.0;
 	graphdata.ymax = +1.0;
-    	KapaSetLimits (fd, &graphdata);
-	KapaBox (fd, &graphdata);
+    	KapaSetLimits (kapa, &graphdata);
+	KapaBox (kapa, &graphdata);
 	graphdata.color = KapaColorByName ("red");
 	graphdata.etype = 1;
@@ -307,21 +307,21 @@
 	  fiterrs[j] = sourceError.mags[j];
 	}
-	KapaPrepPlot (fd, Nfilter, &graphdata);
-	KapaPlotVector (fd, Nfilter, wavecode);
-	KapaPlotVector (fd, Nfilter, fitmags);
-	KapaPlotVector (fd, Nfilter, fiterrs);
-	KapaPlotVector (fd, Nfilter, fiterrs);
-	KapaSendLabel (fd, "wavelength (nm)", 0);
-	KapaSendLabel (fd, "resid (mags)", 1);
-
-	KiiCursorOn (fd);
-	while (KiiCursorRead (fd, &X, &Y, key)) {
+	KapaPrepPlot (kapa, Nfilter, &graphdata);
+	KapaPlotVector (kapa, Nfilter, wavecode, "x");
+	KapaPlotVector (kapa, Nfilter, fitmags, "y");
+	KapaPlotVector (kapa, Nfilter, fiterrs, "dym");
+	KapaPlotVector (kapa, Nfilter, fiterrs, "dyp");
+	KapaSendLabel (kapa, "wavelength (nm)", 0);
+	KapaSendLabel (kapa, "resid (mags)", 1);
+
+	KiiCursorOn (kapa);
+	while (KiiCursorRead (kapa, &X, &Y, &ZP, &RA, &DEC, key)) {
 	  gprint (GP_ERR, "window: %f %f (%s)\n", X, Y, key);
 	  if (!strcasecmp (key, "Q")) {
-	    KiiCursorOff (fd);
+	    KiiCursorOff (kapa);
 	    break;
 	  }
 	  if (!strcasecmp (key, "ESCAPE")) {
-	    KiiCursorOff (fd);
+	    KiiCursorOff (kapa);
 	    goto escape;
 	  }
Index: /trunk/Ohana/src/opihi/dvo/images.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/images.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/images.c	(revision 13479)
@@ -14,5 +14,5 @@
   int WITH_MOSAIC, SOLO_MOSAIC, HIDDEN;
   time_t tzero, tend;
-  int N, NPTS, n, npts, Npts;
+  int N, NPTS, n, npts, Npts, kapa;
   Vector Xvec, Yvec;
   double r[8], d[8], x[8], y[8], Rmin, Rmax, Rmid, trange, Radius;
@@ -22,5 +22,5 @@
   int typehash;
 
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   WITH_MOSAIC = FALSE;
@@ -101,5 +101,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
   
   /* it is not an error for the database not to have any images */
@@ -282,7 +281,5 @@
     graphmode.ptype = 100; /* connect pairs of points */
     graphmode.etype = 0;
-    PrepPlotting (N, &graphmode);
-    PlotVector (N, Xvec.elements);
-    PlotVector (N, Yvec.elements);
+    PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
   }
 
Index: /trunk/Ohana/src/opihi/dvo/imbox.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imbox.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/imbox.c	(revision 13479)
@@ -3,5 +3,5 @@
 int imbox (int argc, char **argv) {
   
-  int j, Nskip, status, InPic, flipped;
+  int j, kapa, Nskip, status, InPic, flipped;
   Vector Xvec, Yvec;
   double r, d, x[4], y[4], Rmin, Rmax, Rmid;
@@ -12,5 +12,5 @@
   FILE *f;
 
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   if (argc != 2) {
@@ -18,5 +18,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
 
   f = fopen (argv[1], "r");
@@ -77,7 +76,5 @@
       graphmode.ptype = 100; /* connect pairs of points */
       graphmode.etype = 0;
-      PrepPlotting (8, &graphmode);
-      PlotVector (8, Xvec.elements);
-      PlotVector (8, Yvec.elements);
+      PlotVectorPair (kapa, 8, Xvec.elements, Yvec.elements, &graphmode);
     }
   skip:
Index: /trunk/Ohana/src/opihi/dvo/imdense.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imdense.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/imdense.c	(revision 13479)
@@ -5,9 +5,11 @@
   
   long A, B;
-  int i, N, Nimage, status, NPTS, Ngraph;
+  int i, kapa, N, Nimage, status, NPTS;
   double r, d, x, y, Rmin, Rmax;
   Vector Xvec, Yvec;
   Image *image;
   Graphdata graphmode;
+
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   /* need options to list only images in region and only images in a time range */
@@ -17,6 +19,4 @@
     return (FALSE);
   }
-  Ngraph = 0;
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
 
   if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
@@ -62,7 +62,5 @@
     graphmode.style = 2; /* points */
     graphmode.etype = 0;
-    PrepPlotting (N, &graphmode);
-    PlotVector (N, Xvec.elements);
-    PlotVector (N, Yvec.elements);
+    PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
   }
 
Index: /trunk/Ohana/src/opihi/dvo/imextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 13479)
@@ -5,5 +5,5 @@
 int imextract (int argc, char **argv) {
   
-  int i, j, Nimage, mode, N, Ngraph, PhotcodeSelect;
+  int i, j, Nimage, mode, N, PhotcodeSelect;
   int TimeSelect, RegionSelect, *subset, Nsubset, TimeFormat, FlagSelect, FlagValue;
   double x, y, ra, dec, t, trange;
@@ -15,6 +15,5 @@
   Vector *vec;
 
-  Ngraph = 0;
-  if (!GetGraphData (&graphsky, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraphData (&graphsky, NULL, NULL)) return (FALSE);
   if (!InitPhotcodes ()) return (FALSE);
 
Index: /trunk/Ohana/src/opihi/dvo/imlist.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imlist.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/imlist.c	(revision 13479)
@@ -8,11 +8,9 @@
   double r, d, trange, t;
   char *name;
-  int Ngraph;
   Image *image;
   Graphdata graphmode;
   PhotCode *PhotcodeValue;
 
-  Ngraph = 0;
-  if (!GetGraphData (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraphData (&graphmode, NULL, NULL)) return (FALSE);
 
   TimeSelect = FALSE;
Index: /trunk/Ohana/src/opihi/dvo/imstats.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imstats.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/imstats.c	(revision 13479)
@@ -3,6 +3,6 @@
 int imstats (int argc, char **argv) {
   
-  int i, Nimage, N;
-  int Mcal, AutoLimits, Ngraph;
+  int i, kapa, Nimage, N;
+  int Mcal, AutoLimits;
   double r, d;
   Image *image;
@@ -10,11 +10,5 @@
   Graphdata graphmode;
 
-  Ngraph = -1;
-  if ((N = get_argument (argc, argv, "-n"))) {
-    remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return (FALSE);
 
   Mcal = TRUE;
@@ -60,7 +54,5 @@
   graphmode.style = 2;
   graphmode.etype = 0;
-  PrepPlotting (Nimage, &graphmode);
-  PlotVector (Nimage, Xvec.elements);
-  PlotVector (Nimage, Yvec.elements);
+  PlotVectorPair (kapa, Nimage, Xvec.elements, Yvec.elements, &graphmode);
   
   free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/dvo/lcat.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lcat.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/lcat.c	(revision 13479)
@@ -8,10 +8,8 @@
   struct stat filestat;
   Graphdata graphmode;
-  int Ngraph;
   SkyTable *sky;
   SkyList *skylist;
 
-  Ngraph = 0;
-  if (!GetGraphData (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraphData (&graphmode, NULL, NULL)) return (FALSE);
 
   ShowAll = FALSE;
Index: /trunk/Ohana/src/opihi/dvo/lcurve.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lcurve.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/lcurve.c	(revision 13479)
@@ -6,5 +6,5 @@
   double Ra, Dec, Radius, Radius2, r;
   float *RA, *DEC;
-  int Ngraph, Xgraph, TimeFormat;
+  int kapa, TimeFormat;
   int Nstars, found, AutoLimits, ErrorBars, GalMag, AbsPhot, SaveVectors;
   int i, j, m, N, NPTS, *N1;
@@ -19,12 +19,5 @@
 
   if (!InitPhotcodes ()) return (FALSE);
-
-  Ngraph = -1;
-  if ((N = get_argument (argc, argv, "-n"))) {
-    remove_argument (N, &argc, argv);
-    Ngraph = atof (argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  if (!GetGraph (&graphmode, &Xgraph, &Ngraph)) return (FALSE);
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return (FALSE);
 
   AutoLimits = FALSE;
@@ -161,10 +154,10 @@
     graphmode.etype = 0;  
 
-  PrepPlotting (N, &graphmode);
-  PlotVector (N, Xvec.elements);
-  PlotVector (N, Yvec.elements);
+  KapaPrepPlot (kapa, N, &graphmode);
+  KapaPlotVector (kapa, N, Xvec.elements, "x");
+  KapaPlotVector (kapa, N, Yvec.elements, "y");
   if (ErrorBars) {
-    PlotVector (N, dYvec.elements);
-    PlotVector (N, dYvec.elements);
+    KapaPlotVector (kapa, N, dYvec.elements, "dym");
+    KapaPlotVector (kapa, N, dYvec.elements, "dyp");
   }
 
@@ -175,5 +168,5 @@
 	   timeptr[0].tm_year, timeptr[0].tm_mon+1, timeptr[0].tm_mday);
   free (p);
-  KapaSendLabel (Xgraph, string, 0);
+  KapaSendLabel (kapa, string, 0);
 
   free (RA);
Index: /trunk/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/mextract.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/mextract.c	(revision 13479)
@@ -3,13 +3,18 @@
 int mextract (int argc, char **argv) {
   
-  int i, j, k, m, N, N1, NPTS;
+  int i, j, k, m, n, N, N1, Npts, NPTS, last, Nfields, Nreturn, Ncstack, Nstack;
   int param, mode, Nsecfilt;
   char *RegionName, *RegionList, *p;
   double *M1;
+  char **cstack;
+  float *values;
 
-  PhotCode *code;
   Catalog catalog;
   SkyList *skylist;
-  Vector *vec;
+  PhotCode *code;
+  Vector **vec;
+
+  dbField *fields;
+  dbStack *stack;
 
   /* defaults */
@@ -24,35 +29,47 @@
   if (!InitPhotcodes ()) goto escape;
   Nsecfilt = GetPhotcodeNsecfilt ();
+  
+  // init locally static variables (time refs)
+  dbExtractMeasuresInit();
 
-  /* interpret command-line options */
-  SetSelectionParam (0);
+  // remove skyregion options
+  // XXX this needs to explicitly handle -qregion and -skyregion
   if (!SetRegionSelection (&argc, argv, &RegionName, &RegionList)) goto escape;
-  if (!SetPhotSelections (&argc, argv, 1)) goto usage;
 
-  /* interpret required command-line arguments: mextract (value) */
-  if (argc != 2) goto usage;
-  param = GetMeasureParam (argv[1]);
-  if (param == MEAS_ZERO) {
-    if (!GetPhotcodeInfo (argv[1], &code, &mode)) {
-      GetMeasureParam ("help");
-      goto escape;
-    }
-    param = MEAS_MAG;
-    for (p = argv[1]; *p != 0; p++) { 
-      if (*p == '.') *p = ':';
-    }
-  }
-  if (!TestPhotSelections (&code, &mode, MEAS_ZERO)) goto escape;
+  // command-line is of the form: avextract field,field, field [where (field op value)...]
+
+  // parse the fields to be extracted and returned
+  fields = dbCmdlineFields (argc, argv, DVO_TABLE_MEASURE, &last, &Nfields);
+  if (fields == NULL) return (FALSE);
+
+  // parse the remainder of the line as a boolean math expression
+  cstack = isolate_elements (argc-last, &argv[last], &Ncstack);
+  
+  // construct the db Boolean math stack (frees cstack)
+  stack = dbRPN (Ncstack, cstack, &Nstack);
+
+  Nreturn = Nfields; 
+  dbCheckStack (stack, Nstack, DVO_TABLE_MEASURE, &fields, &Nfields);
+  // XXX handle errors
 
   /* load region corresponding to selection above */
   if ((skylist = SelectRegions (RegionName, RegionList)) == NULL) goto escape;
-  if (!SetImageSelection (param, ((RegionName == NULL) && (RegionList == NULL)))) goto escape;
+
+  // XXX is this still needed?
+  // if (!SetImageSelection (param, ((RegionName == NULL) && (RegionList == NULL)))) goto escape;
 
   /* create storage vector */
-  N = 0;
+  ALLOCATE (values, float, Nfields);
+  ALLOCATE (vec, Vector *, Nreturn);
+  for (i = 0; i < Nreturn; i++) {
+    if ((vec[i] = SelectVector (fields[i].name, ANYVECTOR, TRUE)) == NULL) goto escape;
+  }
+
+  Npts = 0;
   NPTS = 1;
-  if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) goto escape;
 
+  // XXX need to add interrupt test to this loop
   for (i = 0; i < skylist[0].Nregions; i++) {
+    /* lock, load, unlock catalog */
     catalog.filename = skylist[0].filename[i];
     catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_SECF;
@@ -69,18 +86,34 @@
 
     for (j = 0; j < catalog.Naverage; j++) {
-      M1 = NULL;
       m = catalog.average[j].offset;
-      M1 = ExtractMeasures (code, mode, &catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &N1, param);
-      for (k = 0; k < N1; k++) {
-	vec[0].elements[N] = M1[k];
-	N++;
-	CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 2000);
+      for (k = 0; k < catalog.average[j].Nm; k++, m++) {
+
+	// extract the relevant values for this measurement
+	for (n = 0; n < Nfields; n++) {
+	  values[n] = dbExtractMeasures (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &fields[n]);
+	}
+	
+	// test the conditional statement
+	if (!dbBooleanCond (stack, Nstack, values)) continue;
+	for (n = 0; n < Nreturn; n++) {
+	  vec[n][0].elements[Npts] = values[n];
+	}
+	Npts++;
+	if (Npts >= NPTS) {
+	  NPTS += 2000;
+	  for (n = 0; n < Nreturn; n++) {
+	    REALLOCATE (vec[n][0].elements, float, NPTS);
+	  }
+	}
       }
-      if (M1 != NULL) free (M1);
     }
     dvo_catalog_free (&catalog);
   }
-  vec[0].Nelements = N;
-  REALLOCATE (vec[0].elements, float, MAX(1,N));
+  for (n = 0; n < Nreturn; n++) {
+    vec[n][0].Nelements = Npts;
+    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
+  }
+
+  // XXX free fields and stack 
 
   FreeImageSelection ();
Index: /trunk/Ohana/src/opihi/dvo/paverage.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/paverage.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/paverage.c	(revision 13479)
@@ -5,5 +5,5 @@
   
   FILE *f;
-  int i, j, Narg, Npts, NPTS, status, VERBOSE;
+  int i, j, kapa, Narg, Npts, NPTS, status, VERBOSE;
   int Nsecfilt, Nsec;
   double Mz, Mr, mag;
@@ -23,5 +23,5 @@
   Nsecfilt = GetPhotcodeNsecfilt ();
 
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   f = (FILE *) NULL;
@@ -82,5 +82,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
   graphmode.style = 2; /* set style to points */
   graphmode.size = -1; /* point size determined by Zvec */
@@ -141,5 +140,5 @@
       }
       if (Npts > NCHUNK) {
-	  PlotVectorTriplet (Npts, Xvec, Yvec, Zvec, &graphmode);
+	  PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
 	  Npts = 0;
       }
@@ -147,5 +146,5 @@
     dvo_catalog_free (&catalog);
   }
-  if (Npts > 0) PlotVectorTriplet (Npts, Xvec, Yvec, Zvec, &graphmode);
+  if (Npts > 0) PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
 
   free (Xvec);
Index: /trunk/Ohana/src/opihi/dvo/pcat.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/pcat.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/pcat.c	(revision 13479)
@@ -6,5 +6,5 @@
   
   double Radius;
-  int i, j, N, Nregions, ShowAll, NPTS, Npts, leftside;
+  int i, j, kapa, N, Nregions, ShowAll, NPTS, Npts, leftside;
   RegionFile *regions;
   char filename[128];
@@ -14,5 +14,5 @@
   double X[4], Y[4], Rmin, Rmax, Rmid;
   char catdir[256];
-  int Ngraph, VERBOSE;
+  int VERBOSE;
 
   VarConfig ("CATDIR", "%s", catdir);
@@ -33,6 +33,5 @@
     return (FALSE);
   }
-  Ngraph = 0;
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, &kapa, NULL)) return (FALSE);
   
   Radius = MAX (fabs(graphmode.xmax), fabs(graphmode.ymax));
@@ -84,7 +83,5 @@
     graphmode.ptype = 100; /* connect pairs of points */
     graphmode.etype = 0;
-    PrepPlotting (Npts, &graphmode);
-    PlotVector (Npts, Xvec.elements);
-    PlotVector (Npts, Yvec.elements);
+    PlotVectorPair (kapa, Npts, Xvec.elements, Yvec.elements, &graphmode);
   }
 
Index: /trunk/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/photometry.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/photometry.c	(revision 13479)
@@ -174,4 +174,6 @@
 }
 
+// XXX moved to dbFields
+# if (0)
 int GetMagMode (char *string) {
 
@@ -188,4 +190,5 @@
   return (mode);
 }
+# endif
 
 int GetMeasureParam (char *parname) {
Index: /trunk/Ohana/src/opihi/dvo/pmeasure.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/pmeasure.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/pmeasure.c	(revision 13479)
@@ -5,5 +5,5 @@
   
   FILE *f;
-  int i, j, k, m, Narg, Npts, NPTS, status, VERBOSE;
+  int i, j, k, m, kapa, Narg, Npts, NPTS, status, VERBOSE;
   double Mz, Mr, mag;
   double Radius, Rmin, Rmax, R, D;
@@ -19,5 +19,5 @@
 
   if (!InitPhotcodes ()) return (FALSE);
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   f = (FILE *) NULL;
@@ -75,5 +75,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
   graphmode.style = 2; /* set style to points */
   graphmode.size = -1; /* point size determined by Zvec */
@@ -144,5 +143,5 @@
 	}
 	if (Npts > NCHUNK) {
-	    PlotVectorTriplet (Npts, Xvec, Yvec, Zvec, &graphmode);
+	    PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
 	    Npts = 0;
 	}
@@ -151,5 +150,5 @@
     dvo_catalog_free (&catalog);
   }
-  if (Npts > 0) PlotVectorTriplet (Npts, Xvec, Yvec, Zvec, &graphmode);
+  if (Npts > 0) PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
 
   free (Xvec);
Index: /trunk/Ohana/src/opihi/dvo/procks.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/procks.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/procks.c	(revision 13479)
@@ -16,5 +16,5 @@
   FILE *f;
   Vector Xvec, Yvec;
-  int i, j, N, NROCKS;
+  int kapa, i, j, N, NROCKS;
   int N0, N1, SpeedClip, Reload;
   unsigned int t0, t1;
@@ -23,9 +23,7 @@
   Graphdata graphmode;
   char rockcat[256];
-  int Ngraph;
 
-  Ngraph = 0;
   VarConfig ("ROCK_CATALOG", "%s", rockcat);
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, &kapa, NULL)) return (FALSE);
 
   f = (FILE *) NULL;
@@ -115,8 +113,5 @@
   graphmode.style = 2; /* set style to points */
   graphmode.etype = 0; /* no errorbars */
-  PrepPlotting (N, &graphmode);
-  
-  PlotVector (N, Xvec.elements);
-  PlotVector (N, Yvec.elements);
+  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
 
   /* now plot vectors between two extrema */
@@ -148,8 +143,6 @@
   graphmode.ptype = 100; /* connect pairs */
   graphmode.etype = 0; /* no errorbars */
-  PrepPlotting (N, &graphmode);
-  
-  PlotVector (N, Xvec.elements);
-  PlotVector (N, Yvec.elements);
+
+  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
 
   free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/dvo/region_list.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/region_list.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/region_list.c	(revision 13479)
@@ -95,5 +95,4 @@
 
   double Radius;
-  int Ngraph;
   Graphdata graphsky;
   SkyList *skylist;
@@ -121,6 +120,5 @@
   }
 
-  Ngraph = 0;
-  if (!GetGraphData (&graphsky, NULL, &Ngraph)) {
+  if (!GetGraphData (&graphsky, NULL, NULL)) {
     gprint (GP_ERR, "region display not available\n");
     return (NULL);
Index: /trunk/Ohana/src/opihi/dvo/scripts/navigate
===================================================================
--- /trunk/Ohana/src/opihi/dvo/scripts/navigate	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/scripts/navigate	(revision 13479)
@@ -11,5 +11,5 @@
   $KEY = "none"
   while ("$KEY" != "q")
-    cursor -g 1
+    cursor 1
 
     # help list
@@ -147,5 +147,5 @@
       $ok = $KEY
       echo "type 'd' again at endpoint"
-      cursor -g 1
+      cursor 1
       $r1 = $R$KEY
       $d1 = $D$KEY
@@ -168,5 +168,5 @@
       $ok = $KEY
       echo "type 'z' again at radius"
-      cursor -g 1
+      cursor 1
       $r1 = $R$KEY
       $d1 = $D$KEY
@@ -400,5 +400,5 @@
     if ("$KEY" == "p") 
       echo "P - new coords; p - old coords"
-      cursor -g 1
+      cursor 1
       exec echo $Rp $Dp $RP $DP >> fix.coords
     end
Index: /trunk/Ohana/src/opihi/dvo/showtile.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/showtile.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/showtile.c	(revision 13479)
@@ -5,5 +5,5 @@
 int showtile (int argc, char **argv) {
 
-  int Nd, N, NPTS, Ngraph, status, i, InPic;
+  int kapa, Nd, N, NPTS, status, i, InPic;
   Graphdata graphmode;
   Coords coords;
@@ -13,7 +13,5 @@
 
   /* show tile pattern in viewed region */
-
-  Ngraph = 0;
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, &kapa, NULL)) return (FALSE);
 
   if (argc != 1) {
@@ -88,7 +86,5 @@
     graphmode.ptype = 100; /* connect pairs of points */
     graphmode.etype = 0;
-    PrepPlotting (N, &graphmode);
-    PlotVector (N, Xvec.elements);
-    PlotVector (N, Yvec.elements);
+    PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
   }
 
Index: /trunk/Ohana/src/opihi/dvo/simage.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/simage.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/simage.c	(revision 13479)
@@ -12,10 +12,8 @@
   Header header;
   Coords coords;
-  int i, j, Nstars, nstars, Nbytes, nbytes, Npts, N;
+  int i, j, kapa, Nstars, nstars, Nbytes, nbytes, Npts, N;
   Graphdata graphmode;
-  int Ngraph;
 
-  Ngraph = 0;
-  if (!GetGraph (&graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraph (&graphmode, &kapa, NULL)) return (FALSE);
 
   zero = 17.0;
@@ -156,9 +154,6 @@
   graphmode.etype = 0;
   Npts = Xvec.Nelements;
-  PrepPlotting (Npts, &graphmode);
 
-  PlotVector (Npts, Xvec.elements);
-  PlotVector (Npts, Yvec.elements);
-  PlotVector (Npts, Zvec.elements);
+  PlotVectorTriplet (kapa, Npts, Xvec.elements, Yvec.elements, Zvec.elements, &graphmode);
 
   free (Xvec.elements);
Index: /trunk/Ohana/src/opihi/dvo/skycat.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/skycat.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/dvo/skycat.c	(revision 13479)
@@ -6,5 +6,5 @@
   
   double Radius;
-  int i, j, N, Nregions, ShowAll, NPTS, Npts, leftside, Depth, VERBOSE;
+  int i, j, N, Nregions, kapa, ShowAll, NPTS, Npts, leftside, Depth, VERBOSE;
   struct stat filestat;
   Vector Xvec, Yvec;
@@ -32,5 +32,5 @@
   }
 
-  if (!style_args (&graphmode, &argc, argv, 0)) return FALSE;
+  if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
   if (argc != 1) {
@@ -38,5 +38,4 @@
     return (FALSE);
   }
-  SetGraph (graphmode);
 
   Radius = MAX (fabs(graphmode.xmax), fabs(graphmode.ymax));
@@ -97,7 +96,5 @@
     graphmode.ptype = 100; /* connect pairs of points */
     graphmode.etype = 0;
-    PrepPlotting (Npts, &graphmode);
-    PlotVector (Npts, Xvec.elements);
-    PlotVector (Npts, Yvec.elements);
+    PlotVectorPair (kapa, Npts, Xvec.elements, Yvec.elements, &graphmode);
   }
 
Index: /trunk/Ohana/src/opihi/include/data.h
===================================================================
--- /trunk/Ohana/src/opihi/include/data.h	(revision 13478)
+++ /trunk/Ohana/src/opihi/include/data.h	(revision 13479)
@@ -162,5 +162,5 @@
 void          SetLimitsRaw          PROTO((float *xvec, float *yvec, int Npts, Graphdata *graphmode));
 void          ApplyLimits           PROTO((int Xgraph, Graphdata *graphmode, int apply));
-int           style_args            PROTO((Graphdata *graphmode, int *argc, char **argv, int Nforce));
+int           style_args            PROTO((Graphdata *graphmode, int *argc, char **argv, int *kapa));
 
 int read_table_vectors (int argc, char **argv, char *extname);
Index: /trunk/Ohana/src/opihi/include/display.h
===================================================================
--- /trunk/Ohana/src/opihi/include/display.h	(revision 13478)
+++ /trunk/Ohana/src/opihi/include/display.h	(revision 13479)
@@ -5,43 +5,24 @@
 # define DISPLAY_H
 
-# if (0)
-typedef struct {
-  double xmin, xmax, ymin, ymax;
-  int style, ptype, ltype, etype, ebar, color;
-  double lweight, size;
-  Coords coords;
-  int flipeast, flipnorth;
-  char axis[8], labels[8], ticks[8];
-} Graphdata;
-# endif
+/*** kapa graph functions ***/
+int           PlotVectorPair        PROTO((int kapa, int Npts, float *xValues, float *yValues, Graphdata *graphmode));
+int           PlotVectorTriplet     PROTO((int kapa, int Npts, float *xValues, float *yValues, float *zValues, Graphdata *graphmode));
+int           GetGraphData          PROTO((Graphdata *data, int *kapa, char *name));
+int           GetGraph              PROTO((Graphdata *data, int *kapa, char *name));
+int           SetGraph              PROTO((Graphdata *data));
 
-/*** plotting functions ***/
-int           GetCurrentDevice      PROTO((void));
-int           PrepPlotting          PROTO((int Npts, Graphdata *graphmode));
-int           PlotVector            PROTO((int, float *));
-int           PlotVectorTriplet     PROTO((int N, float *xValues, float *yValues, float *zValues, Graphdata *graphmode));
-int           GetGraphData          PROTO((Graphdata *data, int *sock, int *N));
-int           GetGraph              PROTO((Graphdata *data, int *socket, int *N));
-void          InitGraph             PROTO((void));
-int           open_graph            PROTO((int N));
-int           close_graph           PROTO((int N));
-void          QuitGraph             PROTO((void));
-void          SetGraph              PROTO((Graphdata data));
-void          XGraphDead            PROTO((int input));
-int           GetColor              PROTO((char *name));
+/*** kapa image functions */
+int           GetImageData          PROTO((KapaImageData *data, int *kapa, char *name));
+int           GetImage              PROTO((KapaImageData *data, int *kapa, char *name));
+int           SetImage              PROTO((KapaImageData *data));
 
-/* image (tv) functions */
-int           GetImage              PROTO((int *socket, int *N));
-char         *GetImageName          PROTO((void));
-void          GetImageScale         PROTO((double *zero, double *range));
-void          InitImage             PROTO((void));
-int           open_image            PROTO((int N));
-int           close_image           PROTO((int N));
-void          QuitImage             PROTO((void));
-void          SetImageDevice        PROTO((int state));
-void          SetImageName          PROTO((char *name));
-void          SetImageScale         PROTO((double zero, double range));
-void          XImageDead            PROTO((int input));
-int           SelectOverlay         PROTO((char *name, int *number));
+void	      QuitKapa              PROTO(());
+void	      InitKapa		    PROTO(());
+int 	      open_kapa		    PROTO((int entry));
+int 	      close_kapa	    PROTO((char *name));
+int 	      AddKapaDevice	    PROTO((char *name));
+int 	      DelKapaDevice	    PROTO((char *name));
+int 	      FindKapaDevice	    PROTO((char *name));
+char	     *GetKapaName	    PROTO(());
 
 /* calling program need to define a function 'get_variable' which
Index: /trunk/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 13478)
+++ /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 13479)
@@ -7,16 +7,36 @@
 
 /* magnitude types */
-enum {MAG_NONE, MAG_INST, MAG_CAT, MAG_SYS, MAG_REL, MAG_CAL, MAG_AVE, MAG_REF};
+enum {MAG_NONE, MAG_INST, MAG_CAT, MAG_SYS, MAG_REL, MAG_CAL, MAG_AVE, MAG_REF, MAG_ERR, MAG_CHISQ};
 
-/* measure params */
+/* measure fields */
 enum {MEAS_ZERO, MEAS_RA, MEAS_DEC, MEAS_MAG, MEAS_dMAG, MEAS_MINST, MEAS_MCAT, 
       MEAS_MSYS, MEAS_MREL, MEAS_MCAL, MEAS_PHOTCODE, MEAS_TIME, MEAS_dR, MEAS_dD, 
       MEAS_FWHM, MEAS_DOPHOT, MEAS_XCCD, MEAS_YCCD, MEAS_XMOSAIC, MEAS_YMOSAIC, MEAS_FLAGS, MEAS_EXPTIME, MEAS_AIRMASS};
 
-/* average params */
+/* average fields */
 enum {AVE_ZERO, AVE_RA, AVE_DEC, AVE_RA_ERR, AVE_DEC_ERR, AVE_U_RA, AVE_U_DEC, 
       AVE_U_RA_ERR, AVE_U_DEC_ERR, AVE_PAR, AVE_PAR_ERR, AVE_MAG, AVE_REF, AVE_dMAG, 
       AVE_Xm, AVE_Xp, AVE_NMEAS, AVE_NMISS, AVE_TYPE, AVE_NPHOT, AVE_NCODE, AVE_NCRIT, 
       AVE_FLAG, AVE_TYPEFRAC};
+
+enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE};
+
+// a single db field 
+typedef struct {
+  char *name;
+  int extract;
+  int table;
+  int ID;
+  int magMode;
+  PhotCode *photcode;
+} dbField;
+
+// db boolean operations
+typedef struct {
+  char   *name;
+  char    type;
+  int     field;
+  float   Float;
+} dbStack;
 
 typedef struct {
@@ -96,3 +116,24 @@
 int           RD_to_XYpic           PROTO((double *x, double *y, double r, double d, Coords *coords, double Rmin, double Rmax, double Rmid, int *leftside));
 
+// dvo DB field functions
+dbField     *dbCmdlineFields        PROTO((int argc, char **argv, int table, int *last, int *nfields));
+dbStack     *dbRPN                  PROTO((int argc, char **argv, int *nstack));
+int          dbCheckStack           PROTO((dbStack *stack, int Nstack, int table, dbField **inFields, int *Nfields));
+int          dbBooleanCond          PROTO((dbStack *inStack, int NinStack, float *fields));
+void         dbInitStack            PROTO((dbStack *stack));
+void 	     dbFreeStack            PROTO((dbStack *stack, int Nstack));
+void 	     dbFreeEntry            PROTO((dbStack *stack));
+
+dbStack     *dbBinary               PROTO((dbStack *V1, dbStack *V2, char *op, float *fields));
+dbStack     *dbUnary                PROTO((dbStack *V1, char *op, float *fields));
+
+int          GetMagMode             PROTO((char *string));
+PhotCode    *ParsePhotcodeField     PROTO((char *field, int *mode, int def));
+int          ParseMeasureField      PROTO((dbField *field, char *fieldName));
+int          ParseAverageField      PROTO((dbField *field, char *fieldName));
+
+double       dbExtractAverages      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
+double       dbExtractMeasures      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
+void         dbExtractMeasuresInit  PROTO(());
+
 # endif
Index: /trunk/Ohana/src/opihi/lib.data/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/Makefile	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.data/Makefile	(revision 13479)
@@ -29,9 +29,11 @@
 $(SDIR)/gaussian.$(ARCH).o		\
 $(SDIR)/graphtools.$(ARCH).o            \
-$(SDIR)/open_graph.$(ARCH).o            \
-$(SDIR)/open_image.$(ARCH).o            \
 $(SDIR)/queues.$(ARCH).o		\
 $(SDIR)/PlotVectors.$(ARCH).o		\
+$(SDIR)/open_kapa.$(ARCH).o             \
 $(SDIR)/style_args.$(ARCH).o
+
+#$(SDIR)/open_graph.$(ARCH).o            \
+#$(SDIR)/open_image.$(ARCH).o            \
 
 # dependancy rules for include files ########################
Index: /trunk/Ohana/src/opihi/lib.data/PlotVectors.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/PlotVectors.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.data/PlotVectors.c	(revision 13479)
@@ -1,52 +1,20 @@
 # include "display.h"
 
-static int Xgraph;
+int PlotVectorPair (int kapa, int Npts, float *xValues, float *yValues, Graphdata *graphmode) {
 
-int PrepPlotting (int Npts, Graphdata *graphmode) {
+  KapaPrepPlot (kapa, Npts, graphmode);
+  KapaPlotVector (kapa, Npts, xValues, "x");
+  KapaPlotVector (kapa, Npts, yValues, "y");
 
-  if (!GetGraph (NULL, &Xgraph, NULL)) return (FALSE);
-  
-  /* tell kapa to look for the incoming image */
-  KiiSendCommand (Xgraph, 4, "PLOT"); 
-  
-  /* send Xgraph the plot details */
-  KiiSendMessage (Xgraph, "%8d %8d %d %d %d %d %d %f %f", 
-		  Npts, graphmode[0].style, 
-		  graphmode[0].ptype, graphmode[0].ltype, 
-		  graphmode[0].etype, graphmode[0].ebar, graphmode[0].color, 
-		  graphmode[0].lweight, graphmode[0].size);
-  KiiSendMessage (Xgraph, "%g %g %g %g", 
-		  graphmode[0].xmin, graphmode[0].xmax, 
-		  graphmode[0].ymin, graphmode[0].ymax);
   return (TRUE);
 }
 
-int PlotVector (int Npts, float *values) {
+int PlotVectorTriplet (int kapa, int Npts, float *xValues, float *yValues, float *zValues, Graphdata *graphmode) {
 
-  int Nbytes;
+  KapaPrepPlot   (kapa, Npts, graphmode);
+  KapaPlotVector (kapa, Npts, xValues, "x");
+  KapaPlotVector (kapa, Npts, yValues, "y");
+  KapaPlotVector (kapa, Npts, zValues, "z");
 
-  Nbytes = Npts * sizeof (float);
-  write (Xgraph, values, Nbytes);
   return (TRUE);
 }
-
-int PlotVectorPair (int N, float *xValues, float *yValues, Graphdata *graphmode) {
-
-    PrepPlotting (N, graphmode);
-    PlotVector (N, xValues);
-    PlotVector (N, yValues);
-
-    return (TRUE);
-}
-
-int PlotVectorTriplet (int N, float *xValues, float *yValues, float *zValues, Graphdata *graphmode) {
-
-    PrepPlotting (N, graphmode);
-    PlotVector (N, xValues);
-    PlotVector (N, yValues);
-    PlotVector (N, zValues);
-
-    return (TRUE);
-}
-
-/* we don't use GetGraph in PlotVector because it flushes the connection */
Index: /trunk/Ohana/src/opihi/lib.data/graphtools.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/graphtools.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.data/graphtools.c	(revision 13479)
@@ -33,5 +33,5 @@
     graphmode[0].ymax = maxY + 0.05*range;
   }
-  SetGraph (graphmode[0]);
+  SetGraph (graphmode);
 
   set_variable ("XMIN", graphmode[0].xmin);
@@ -73,5 +73,5 @@
     graphmode[0].ymax = maxY + 0.05*range;
   }
-  SetGraph (graphmode[0]);
+  SetGraph (graphmode);
 
   set_variable ("XMIN", graphmode[0].xmin);
Index: /trunk/Ohana/src/opihi/lib.data/open_image.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/open_image.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.data/open_image.c	(revision 13479)
@@ -122,5 +122,6 @@
   return (Ximbuffer[Active]);
 }
-  
+ 
+// leave this information on kapa, request when needed? 
 void SetImageScale (double zero, double range) {
   Xzero[Active] = zero;
Index: /trunk/Ohana/src/opihi/lib.data/open_kapa.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/open_kapa.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.data/open_kapa.c	(revision 13479)
@@ -1,4 +1,6 @@
 # include "display.h"
 # include "shell.h"
+# include <assert.h>
+
 
 /* kapa support for the new version of kapa (v2.0), which has both graph and image
@@ -9,53 +11,84 @@
 
 /* list of available socket connections */
-static int        Active;        // currently active socket (not device)
+static int        Active;        // currently active socket entry (index value, not socket value)
 static int       *Socket = NULL; // list of available sockets
-static int       *Device = NULL; // list of device numbers for each socked
-static int       Nsocket = 0;    // number of available sockets / devices
+static char     **Device = NULL; // list of device names for each socket
+static int       Ndevice = 0;    // number of available sockets / devices
 
 void InitKapa () {
 
-  Active  = -1;		      // -1 is the INVALID entry
-  Nsocket = 0;		      // number of defined sockets
-  ALLOCATE (Device, int, 1);
-  ALLOCATE (Socket, int, 1);
-  Device[Active] = 0;  
-  Socket[Active] = 0;  
-}
-
-// returns the number of the requested device, or -1 if not found
-int FindKapaDevice (int thisDevice) {
+  Active  = -1;					  // -1 is the INVALID entry
+  Ndevice = 0;					  // number of defined sockets
+  ALLOCATE (Device, char *, 1);			  // for future REALLOCATE calls
+  ALLOCATE (Socket, int, 1);			  // for future REALLOCATE calls
+}
+
+// add new device name if not found
+int AddKapaDevice (char *name) {
+
+  int N;
+
+  N = FindKapaDevice (name);
+  if (N != -1) return (N);
+  N = Ndevice;
+  Ndevice ++;
+  REALLOCATE (Device, char *, Ndevice);
+  REALLOCATE (Socket, int, Ndevice);
+  Device[N] = strcreate (name);
+  Socket[N] = -1;
+  return (N);
+}
+
+// delete device by name, close if not closed
+int DelKapaDevice (char *name) {
+
+  int i, N;
+
+  N = FindKapaDevice (name);
+  if (N == -1) return (FALSE);
+
+  if (Socket[N] != -1) close (Socket[N]);
+  free (Device[N]);
+  for (i = N; i < Ndevice - 1; i++) {
+    Device[i] = Device[i+1];
+    Socket[i] = Socket[i+1];
+  }
+
+  if (N == Active) {
+    Active = -1;
+  }
+
+  Ndevice --;
+  REALLOCATE (Device, char *, Ndevice);
+  REALLOCATE (Socket, int, Ndevice);
+
+  return (TRUE);
+}
+
+// returns the entry of the requested device, or -1 if not found
+int FindKapaDevice (char *name) {
 
   int i;
 
-  for (i = 0; i < Nsocket; i++) {
-    if (Device[i] == thisDevice) {
-      return (i);
-    }
+  if (name == NULL) return (-1); 
+
+  for (i = 0; i < Ndevice; i++) {
+    if (!strcmp(Device[i], name)) return (i);
   }
   return (-1);
 }
 
-// set the active device to the given device number, open if needed
-int open_kapa (int thisDevice) {
-
-  int fd, entry;
-  char *kapa_exec, name[16];
+// set the active device to the given device, open if needed
+int open_kapa (int entry) {
+
+  int fd;
+  char *kapa_exec, *kapa_name;
 
   // find the given device number, or create. set this to active
-  entry = FindKapaDevice (thisDevice);
-  if (entry < 0) {
-    Active = Nsocket;
-    Nsocket ++;
-    REALLOCATE (Device, int, Nsocket);
-    REALLOCATE (Socket, int, Nsocket);
-    Device[Active] = -1;
-    Socket[Active] = -1;
-  } else {
-    Active = entry;
-  }
+  assert (entry >= 0);
+  assert (entry <  Ndevice);
 
   // if the (now) active socket is not open, open it
-  if (Socket[Active] < 0) {
+  if (Socket[entry] < 0) {
     kapa_exec = get_variable ("KAPA");
     if (kapa_exec == (char *) NULL) {
@@ -65,77 +98,50 @@
 
     // KAPA may be either kapa://host or /path/to/program
-
-    snprintf (name, 16, "[%d]", thisDevice);
-    fd = KapaOpen (kapa_exec, name);
+    ALLOCATE (kapa_name, char, strlen(Device[entry]) + 5);
+    snprintf (kapa_name, strlen(Device[entry]) + 5, "[%s]", Device[entry]);
+    fd = KapaOpen (kapa_exec, kapa_name);
     free (kapa_exec);
+    free (kapa_name);
 
     if (fd < 0) {
-      gprint (GP_ERR, "error starting kapa\n");
-      // delete the active entry
+      gprint (GP_ERR, "error starting kapa device %s\n", Device[entry]);
       return (FALSE);
     } 
-    Device[Active] = thisDevice;
-    Socket[Active] = fd;
+    Socket[entry] = fd;
   } 
-  return (TRUE);
-}
-
-/**************** graph ops */
-
-// XXX for now, use a local variable.  later: get from kapa
-static Graphdata graphdata;
-
-void InitGraph () {
-  graphdata.xmin = graphdata.ymin = 0.0;
-  graphdata.xmax = graphdata.ymax = 1.0;
-  graphdata.style = graphdata.ptype = 0;
-  graphdata.ltype = graphdata.color = 0;
-  graphdata.etype = graphdata.ebar = 0;
-  graphdata.lweight = graphdata.size = 1.0;
-    
-  graphdata.coords.pc1_1 = graphdata.coords.pc2_2 = 1.0;
-  graphdata.coords.pc1_2 = graphdata.coords.pc2_1 = 0.0;
-  strcpy (graphdata.coords.ctype, "RA---LIN");
-  graphdata.coords.crval1 = 0.0;
-  graphdata.coords.crval2 = 0.0;
-  graphdata.coords.crpix1 = 0.0;
-  graphdata.coords.crpix2 = 0.0;
-  graphdata.coords.cdelt1 = graphdata.coords.cdelt2 = 1.0;
-  graphdata.flipeast = TRUE;
-  graphdata.flipnorth = FALSE;
-  strcpy (graphdata.axis, "2222");
-  strcpy (graphdata.ticks, "2222");
-  strcpy (graphdata.labels, "2222");
-}
-
-# if (0)
-  /* test Xgraph[0], flush junk from pipe */
-  signal (SIGPIPE, XGraphDead);
-  fcntl (Socket[n], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Socket[n], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Socket[n], F_SETFL, !O_NONBLOCK); 
-# endif
-
-/* return pointers for current Xgraph, set if desired, test, open if needed */
-int GetGraph (Graphdata *data, int *fd, int *dev) {
-
-  int thisDevice;
-
-  SetImageDevice (FALSE);
-  if (dev == NULL) {
-    if (Active < 0) {
-      thisDevice = 0;
+  Active = entry;
+  return (TRUE);
+}
+
+/**************** graph specific ops *******************/
+
+// return the current device name, if set 
+char *GetKapaName () {
+  if (Active < 0) return NULL;
+  return Device[Active];
+}
+
+/* return pointers for named device or current; open if needed */
+// if fd == NULL, don't return the value
+// if name == NULL, use the currently active device
+int GetGraph (Graphdata *data, int *fd, char *name) {
+
+  int entry;
+
+  if (name == NULL) {
+    if (Active < 0) {
+      entry = AddKapaDevice ("0");
     } else {
-      thisDevice = Device[Active];
-    }
-  } else {
-    thisDevice = *dev;
-  }
-  
-  if (!open_kapa (thisDevice)) {
-    return (FALSE);
-  }
-  
-  if (data != NULL) *data = graphdata;
+      entry = Active;
+    }
+  } else {
+    entry = AddKapaDevice (name);
+  }
+  
+  if (!open_kapa (entry)) {
+    return (FALSE);
+  }
+  
+  if (data != NULL) KapaGetGraphData (Socket[Active], data);
   if (fd != NULL) *fd = Socket[Active];
 
@@ -143,84 +149,130 @@
 }
 
-/* return pointers for given Xgraph, don't set or open */
-int GetGraphData (Graphdata *data, int *fd, int *dev) {
-
-  int n;
-
-  if (dev == NULL) {
-    if (Active < 0) {
-      gprint (GP_ERR, "invalid Xgraph window %d\n", *dev); 
-      return (FALSE);
-    }
-    *fd = Socket[Active];
-    return (TRUE);
-  } 
-
-  n = FindKapaDevice (*dev);
-  if (n < 0) {
-    gprint (GP_ERR, "invalid Xgraph window %d\n", *dev); 
-    return (FALSE);
-  }
-
-  Active = n;
-
+/* return pointers for given kapa, don't set or open */
+int GetGraphData (Graphdata *data, int *fd, char *name) {
+
+  int entry;
+
+  if (name == NULL) {
+    if (Active < 0) {
+      gprint (GP_ERR, "no active kapa window\n"); 
+      return (FALSE);
+    }
+    entry = Active;
+  } else {
+    entry = FindKapaDevice (name);
+    if (entry < 0) {
+      gprint (GP_ERR, "invalid kapa window %s\n", name); 
+      return (FALSE);
+    }
+  }
+
+  if (fd != NULL) *fd = Socket[entry];
+  if (data != NULL) KapaGetGraphData (Socket[entry], data);
+  return (TRUE);
+}
+
+/* assign given values to current kapa */
+int SetGraph (Graphdata *data) {
+  if (Active < 0) {
+    gprint (GP_ERR, "no active kapa window\n"); 
+    return (FALSE);
+  }
+  if (Socket[Active] == -1) {
+    gprint (GP_ERR, "no active kapa window\n"); 
+    return (FALSE);
+  }
+  KapaSetGraphData (Socket[Active], data);
+}
+
+/************* image ops ***********/
+
+/* return pointers for current Ximage, set if desired, test, open if needed */
+int GetImage (KapaImageData *data, int *fd, char *name) {
+
+  int entry;
+
+  if (name == NULL) {
+    if (Active < 0) {
+      entry = AddKapaDevice ("0");
+    } else {
+      entry = Active;
+    }
+  } else {
+    entry = AddKapaDevice (name);
+  }
+  
+  if (!open_kapa (entry)) {
+    return (FALSE);
+  }
+  
+  if (data != NULL) KapaGetImageData (Socket[Active], data);
   if (fd != NULL) *fd = Socket[Active];
-  if (data != NULL) *data = graphdata;
-
-  return (TRUE);
-}
-
-/* assign given values to current Xgraph */
-void SetGraph (Graphdata data) {
-  graphdata = data;
-}
-
-/** internal tracking of current active device type **/
-/* drop this stuff */
-static int       IsImage = FALSE;
-
-int GetCurrentDevice () {
-  return (IsImage);
-}
-
-void SetImageDevice (int state) {
-  IsImage = state;
-}
-
-/************* image ops ***********/
-// XXX for now, use local static:
-
-static char      Ximbuffer[512];
-static double    Xzero;
-static double    Xrange;
-
-void InitImage () {
-  Xzero = 0;
-  Xrange = 1024;
-  strcpy (Ximbuffer, "none");
-}
-
-/* return pointers for current Ximage, set if desired, test, open if needed */
-int GetImage (int *fd, int *N) {
-  int status;
-  status = GetGraph (NULL, fd, N);
-  return (status);
-}
-
-void SetImageName (char *name) {
-  strcpy (Ximbuffer, name);
-}
-
-char *GetImageName () {
-  return (Ximbuffer);
-}
- 
-// leave this information on kapa, request when needed? 
-void SetImageScale (double zero, double range) {
-  Xzero = zero;
-  Xrange = range;
-}
-void GetImageScale (double *zero, double *range) {
-  *zero = Xzero;
-  *range = Xrange;
-}
+
+  return (TRUE);
+}
+
+/* return pointers for given kapa, don't set or open */
+int GetImageData (KapaImageData *data, int *fd, char *name) {
+
+  int entry;
+
+  if (name == NULL) {
+    if (Active < 0) {
+      gprint (GP_ERR, "no active kapa window\n"); 
+      return (FALSE);
+    }
+    entry = Active;
+  } else {
+    entry = FindKapaDevice (name);
+    if (entry < 0) {
+      gprint (GP_ERR, "invalid kapa window %s\n", name); 
+      return (FALSE);
+    }
+  }
+
+  if (fd != NULL) *fd = Socket[entry];
+  if (data != NULL) KapaGetImageData (Socket[entry], data);
+  return (TRUE);
+}
+
+/* assign given values to current kapa */
+int SetImage (KapaImageData *data) {
+  if (Active < 0) {
+    gprint (GP_ERR, "no active kapa window\n"); 
+    return (FALSE);
+  }
+  if (Socket[Active] == -1) {
+    gprint (GP_ERR, "no active kapa window\n"); 
+    return (FALSE);
+  }
+  KapaSetImageData (Socket[Active], data);
+}
+
+int close_kapa (char *name) {
+
+  int N;
+
+  N = FindKapaDevice (name);
+  if (N == -1) {
+    if (Active < 0) return (FALSE);
+    name = Device[Active];
+  }
+  DelKapaDevice (name);
+  return (TRUE);
+}
+
+void QuitKapa () {
+
+  int i;
+  
+  for (i = 0; i < Ndevice; i++) {
+    if (Socket[i] != -1) close (Socket[i]);
+    if (Device[i] != NULL) free (Device[i]);
+  }
+  REALLOCATE (Socket, int, 1);
+  REALLOCATE (Device, char *, 1);
+
+  Ndevice = 0;
+  Active = -1;
+}
Index: /trunk/Ohana/src/opihi/lib.data/style_args.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/style_args.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.data/style_args.c	(revision 13479)
@@ -2,22 +2,24 @@
 # include "display.h"
 
-int style_args (Graphdata *graphmode, int *argc, char **argv, int Nforce) {
+int style_args (Graphdata *graphmode, int *argc, char **argv, int *kapa) {
   
-  int N, Ngraph;
-  char *name;
+  int N;
+  char *colorName;
+  char *kapaName;
 
-  Ngraph = -1;
+  kapaName = NULL;
   if ((N = get_argument (*argc, argv, "-n"))) {
     remove_argument (N, argc, argv);
-    Ngraph = atof (argv[N]);
+    kapaName = strcreate (argv[N]);
     remove_argument (N, argc, argv);
   }
-  if (Nforce != -1) Ngraph = Nforce;
-  if (!GetGraph (graphmode, NULL, &Ngraph)) return (FALSE);
+  if (!GetGraph (graphmode, kapa, kapaName)) return (FALSE);
+  FREE (kapaName);
 
   if (*argc == 1) {
-    name = KapaColorName (graphmode[0].color);
-    gprint (GP_ERR, "current style (%d): -x %d -c %s -pt %d -lt %d -lw %f -sz %f\n", Ngraph,
-	     graphmode[0].style, name, graphmode[0].ptype, 
+    kapaName = GetKapaName();
+    colorName = KapaColorName (graphmode[0].color);
+    gprint (GP_ERR, "current style (%s): -x %d -c %s -pt %d -lt %d -lw %f -sz %f\n", kapaName,
+	     graphmode[0].style, colorName, graphmode[0].ptype, 
 	     graphmode[0].ltype, graphmode[0].lweight,
 	     graphmode[0].size);
Index: /trunk/Ohana/src/opihi/lib.shell/BufferOps.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/BufferOps.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.shell/BufferOps.c	(revision 13479)
@@ -195,25 +195,4 @@
 }
 
-int SelectOverlay (char *name, int *number) {
-
-  *number = -1;
-  if (!strcmp (name, "red") || !strcmp (name, "0"))
-    *number = 0;
-  if (!strcmp (name, "green") || !strcmp (name, "1"))
-    *number = 1;
-  if (!strcmp (name, "blue") || !strcmp (name, "2"))
-    *number = 2;
-  if (!strcmp (name, "yellow") || !strcmp (name, "3"))
-    *number = 3;
-
-  if (*number < 0) {
-    gprint (GP_ERR, "valid overlays may be: red (0), green (1), blue (2), yellow (3)\n");
-    return (FALSE);
-  }
-  else {
-    return (TRUE);
-  }
-}
-
 void dump_buffers (int n) {
 
Index: /trunk/Ohana/src/opihi/lib.shell/startup.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/startup.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/lib.shell/startup.c	(revision 13479)
@@ -43,5 +43,4 @@
     else 
       set_str_variable ("HOME", home);
-    set_str_variable ("KII", "kii");
     set_str_variable ("KAPA", "kapa");
     set_variable ("PID", getpid());
Index: /trunk/Ohana/src/opihi/mana/mana.c.in
===================================================================
--- /trunk/Ohana/src/opihi/mana/mana.c.in	(revision 13478)
+++ /trunk/Ohana/src/opihi/mana/mana.c.in	(revision 13479)
@@ -51,6 +51,5 @@
 /* add program-dependent exit functions here */
 void cleanup () {
-  QuitImage ();
-  QuitGraph ();
+  QuitKapa ();
   return;
 }
Index: /trunk/Ohana/src/opihi/mana/opihi.c
===================================================================
--- /trunk/Ohana/src/opihi/mana/opihi.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/mana/opihi.c	(revision 13479)
@@ -64,7 +64,5 @@
 /* add program-dependent exit functions here */
 void cleanup () {
-  /* -libdisplay
-  QuitImage ();
-  QuitGraph (); */
+  QuitKapa ();
   return;
 }
Index: /trunk/Ohana/src/opihi/pantasks/pantasks.c.in
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/pantasks.c.in	(revision 13478)
+++ /trunk/Ohana/src/opihi/pantasks/pantasks.c.in	(revision 13479)
@@ -64,6 +64,5 @@
 /* add program-dependent exit functions here */
 void cleanup () {
-  QuitImage ();
-  QuitGraph ();
+  QuitKapa ();
   QuitController ();
   return;
Index: /trunk/Ohana/src/opihi/pantasks/pantasks_client.c.in
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/pantasks_client.c.in	(revision 13478)
+++ /trunk/Ohana/src/opihi/pantasks/pantasks_client.c.in	(revision 13479)
@@ -54,6 +54,5 @@
 /* add program-dependent exit functions here */
 void cleanup () {
-  QuitImage ();
-  QuitGraph ();
+  QuitKapa ();
   return;
 }
Index: /trunk/Ohana/src/opihi/pantasks/pantasks_server.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/pantasks_server.c	(revision 13478)
+++ /trunk/Ohana/src/opihi/pantasks/pantasks_server.c	(revision 13479)
@@ -74,7 +74,6 @@
 /* add program-dependent exit functions here */
 void cleanup () {
-  // QuitImage ();
-  // QuitGraph ();
-  // QuitController ();
+  QuitKapa ();
+  QuitController ();
   return;
 }
Index: /trunk/Ohana/src/relastro/src/plotstuff.c
===================================================================
--- /trunk/Ohana/src/relastro/src/plotstuff.c	(revision 13478)
+++ /trunk/Ohana/src/relastro/src/plotstuff.c	(revision 13479)
@@ -21,5 +21,9 @@
 int open_graph (int N) {
 
-  Xgraph[N] = KiiOpen ("kapa", NULL);
+  char name[100];
+
+  sprintf (name, "gastro [%d]", N);
+  Xgraph[N] = KapaOpen ("kapa", name);
+
   if (Xgraph[N] < 0) {
     fprintf (stderr, "error starting kapa\n");
@@ -59,18 +63,7 @@
   if (Xgraph[N] < 1) if (!open_graph(N)) return;
 
-  KapaClear (Xgraph[N], TRUE);
+  KapaClearSections (Xgraph[N]);
 
-  KiiSendCommand (Xgraph[N], 4, "PLOT");
-  
-  /* send Xgraph the plot details */
-  KiiSendMessage (Xgraph[N], "%8d %8d %d %d %d %d %d %f %f", 
-		  Npts, graphmode[0].style, 
-		  graphmode[0].ptype, graphmode[0].ltype, 
-		  graphmode[0].etype, graphmode[0].ebar, graphmode[0].color, 
-		  graphmode[0].lweight, graphmode[0].size);
-  KiiSendMessage (Xgraph[N], "%g %g %g %g", 
-		  graphmode[0].xmin, graphmode[0].xmax, 
-		  graphmode[0].ymin, graphmode[0].ymax);
-
+  KapaPrepPlot (Xgraph[N], Npts, graphmode);
   return;
 }
@@ -83,5 +76,5 @@
 }
 
-void PlotVector (int Npts, double *vect, int mode, int N) {
+void PlotVector (int Npts, double *vect, int mode, int N, char *type) {
 
   float *values;
@@ -95,6 +88,5 @@
   }
 
-  Nbytes = Npts * sizeof (float);
-  write (Xgraph[N], values, Nbytes);
+  KapaPlotVector (Xgraph[N], Npts, values, type);
   free (values);
   return;
@@ -123,6 +115,6 @@
 
   PrepPlotting (N, graphdata, 0);
-  PlotVector (N, xlist, 0, 0);
-  PlotVector (N, ylist, 1, 0);
+  PlotVector (N, xlist, 0, 0, "x");
+  PlotVector (N, ylist, 1, 0, "y");
   if (label != NULL) PlotLabel (label, 0);
   DonePlotting (graphdata, 0);
Index: /trunk/Ohana/src/relphot/src/plotstuff.c
===================================================================
--- /trunk/Ohana/src/relphot/src/plotstuff.c	(revision 13478)
+++ /trunk/Ohana/src/relphot/src/plotstuff.c	(revision 13479)
@@ -21,5 +21,9 @@
 int open_graph (int N) {
 
-  Xgraph[N] = KiiOpen ("kapa", NULL);
+  char name[100];
+
+  sprintf (name, "gastro [%d]", N);
+  Xgraph[N] = KapaOpen ("kapa", name);
+
   if (Xgraph[N] < 0) {
     fprintf (stderr, "error starting kapa\n");
@@ -59,18 +63,7 @@
   if (Xgraph[N] < 1) if (!open_graph(N)) return;
 
-  KapaClear (Xgraph[N], TRUE);
+  KapaClearSections (Xgraph[N]);
 
-  KiiSendCommand (Xgraph[N], 4, "PLOT");
-  
-  /* send Xgraph the plot details */
-  KiiSendMessage (Xgraph[N], "%8d %8d %d %d %d %d %d %f %f", 
-		  Npts, graphmode[0].style, 
-		  graphmode[0].ptype, graphmode[0].ltype, 
-		  graphmode[0].etype, graphmode[0].ebar, graphmode[0].color, 
-		  graphmode[0].lweight, graphmode[0].size);
-  KiiSendMessage (Xgraph[N], "%g %g %g %g", 
-		  graphmode[0].xmin, graphmode[0].xmax, 
-		  graphmode[0].ymin, graphmode[0].ymax);
-
+  KapaPrepPlot (Xgraph[N], Npts, graphmode);
   return;
 }
@@ -83,5 +76,5 @@
 }
 
-void PlotVector (int Npts, double *vect, int mode, int N) {
+void PlotVector (int Npts, double *vect, int mode, int N, char *type) {
 
   float *values;
@@ -95,6 +88,5 @@
   }
 
-  Nbytes = Npts * sizeof (float);
-  write (Xgraph[N], values, Nbytes);
+  KapaPlotVector (Xgraph[N], Npts, values, type);
   free (values);
   return;
@@ -123,6 +115,6 @@
 
   PrepPlotting (N, graphdata, 0);
-  PlotVector (N, xlist, 0, 0);
-  PlotVector (N, ylist, 1, 0);
+  PlotVector (N, xlist, 0, 0, "x");
+  PlotVector (N, ylist, 1, 0, "y");
   if (label != NULL) PlotLabel (label, 0);
   DonePlotting (graphdata, 0);
Index: /trunk/Ohana/src/uniphot/src/plotstuff.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/plotstuff.c	(revision 13478)
+++ /trunk/Ohana/src/uniphot/src/plotstuff.c	(revision 13479)
@@ -13,120 +13,40 @@
 int open_graph (int N) {
 
-  int i, InitSocket, status, addreslen;
-  struct sockaddr_un Address;
-  char temp[100], *display_name;
-  char socket_name[100];
-  FILE *f;
+  char name[100];
   
   active = N;
-  sprintf (socket_name, "/tmp/kapa%d", N);
-  sprintf (temp, "rm -f %s", socket_name);
-  system (temp);
-    
-  strcpy (Address.sun_path, socket_name); 
-  Address.sun_family = AF_UNIX; 
-  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
-  status = bind (InitSocket, &Address, sizeof (Address));
-  status = listen (InitSocket, 1);
-  
-  sprintf (temp, "kapa %s &", socket_name);
-# ifndef DEBUG
-  system (temp);
-# else  
-  fprintf (stderr, "start kapa, press return: %s\n", temp);
-  fscanf (stdin, "%d", &i);
-# endif
-  
-  addreslen =  sizeof (Address);
-  Xgraph[N] = accept (InitSocket, &Address, &addreslen);
+
+  sprintf (name, "gastro [%d]", N);
+  Xgraph[N] = KapaOpen ("kapa", name);
+
   if (Xgraph[N] < 0) {
     fprintf (stderr, "error starting kapa\n");
     return (FALSE);
   }
-  else {
-    return (TRUE);
-  }
-  
+  return (TRUE);
 }
 
 void DonePlotting (Graphdata *graphmode, int N) {
-  char buffer[65], buffer2[65];
 
   if (Xgraph[N] == 0) return;
-
-  write (Xgraph[N], "DBOX", 4);
-  sprintf (buffer, "%f %f %f %f", graphmode[0].xmin, graphmode[0].xmax, graphmode[0].ymin, graphmode[0].ymax);
-  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-
-  sprintf (buffer, "%s %s %s", "2222", "2222", "2222");
-  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-}
-
-void JpegPlot (Graphdata *graphmode, int N, char *filename) {
-  char buffer[65], buffer2[65];
-
-  if (Xgraph[N] == 0) return;
-
-  write (Xgraph[N], "PNGF", 4);
-  sprintf (buffer, "LEN: %11d", strlen (filename));
-  write (Xgraph[N], buffer, 16);
-  write (Xgraph[N], filename, strlen (filename));
-  read (Xgraph[N], buffer, 4);
-}
-
-void PSPlot (Graphdata *graphmode, int N, char *filename) {
-  char buffer[65], buffer2[65];
-
-  if (Xgraph[N] == 0) return;
-
-  write (Xgraph[N], "PSIT", 4);
-  sprintf (buffer, "LEN: %11d", strlen (filename));
-  write (Xgraph[N], buffer, 16);
-  write (Xgraph[N], filename, strlen (filename));
-  read (Xgraph[N], buffer, 4);
+  KapaBox (Xgraph[N], graphmode);
+  return;
 }
 
 void PrepPlotting (int Npts, Graphdata *graphmode, int N) {
 
-  int i, status;
-  char buffer[128], buffer2[128];
-
   active = N;
   if (Npts < 1) return;
 
-  if (Xgraph[N] < 1) if (!open_graph(N)) return;
+  KapaPrepPlot (Xgraph[N], Npts, graphmode);
+}
 
-  /* test Xgraph[N], flush junk from pipe */
-  signal (SIGPIPE, XDead);
-  fcntl (Xgraph[N], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Xgraph[N], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Xgraph[N], F_SETFL, !O_NONBLOCK); 
-  
-  write (Xgraph[N], "ERAS", 4);
-  
-  /* tell kapa to look for the incoming image */
-  status = write (Xgraph[N], "PLOT", 4); 
+void PlotVector (int Npts, float *vect, int mode, int N) {
 
-  /* send Xgraph[N] the plot details */
-  sprintf (buffer, "%8d %8d %d %d %d %d %f %f", 
-	   Npts, graphmode[0].style, 
-	   graphmode[0].ptype, graphmode[0].ltype, 
-	   graphmode[0].etype, graphmode[0].color, 
-	   graphmode[0].lweight, graphmode[0].size);
-  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
-  
-  sprintf (buffer, "%f %f %f %f", 
-	   graphmode[0].xmin, graphmode[0].xmax, 
-	   graphmode[0].ymin, graphmode[0].ymax);
-  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
-  write (Xgraph[N], buffer2, 16);
-  write (Xgraph[N], buffer, strlen (buffer));
+  int Nbytes;
 
+  if (Npts < 1) return;
+  active = N;
+  KapaPlotVector (Xgraph[N], Npts, vect);
 }
 
@@ -137,27 +57,36 @@
   if (Xgraph[N] == 0) return;
 
-  write (Xgraph[N], "LABL", 4);
-  sprintf (buffer, " %6d %6d", strlen (string), 2);
-  write (Xgraph[N], buffer, 16);
-  write (Xgraph[N], string, strlen (string));
+  KapaSendLabel (Xgraph[N[, string, 4);
 }
 
-void PlotVector (int Npts, double *vect, int mode, int N) {
+void PlotReset (int N) {
 
-  float *values;
-  int i, Nbytes;
+  char buffer[128];
+  int i;
 
-  active = N;
-  if (Npts < 1) return;
+  /* test Xgraph[N], flush junk from pipe */
+  signal (SIGPIPE, XDead);
+  fcntl (Xgraph[N], F_SETFL,  O_NONBLOCK); 
+  for (i = 0; (read (Xgraph[N], buffer, 64) > 0) && (i < 20); i++);
+  fcntl (Xgraph[N], F_SETFL, !O_NONBLOCK); 
+  
+  if (Xgraph[N] < 1) if (!open_graph(N)) return;
+  KapaClearSections (Xgraph[N]);
+}
 
-  ALLOCATE (values, float, Npts);
-  for (i = 0; i < Npts; i++) {
-    values[i] = vect[i];
-  }
+void JpegPlot (Graphdata *graphmode, int N, char *filename) {
 
-  Nbytes = Npts * sizeof (float);
-  write (Xgraph[N], values, Nbytes);
-  free (values);
+  if (Xgraph[N] == 0) return;
 
+  KapaPNG (Xgraph[N], filename);
+  return;
+}
+
+void PSPlot (Graphdata *graphmode, int N, char *filename) {
+
+  if (Xgraph[N] == 0) return;
+
+  KiiPS (Xgraph[N], filename, TRUE, KAPA_PS_NEWPLOT, "default");
+  return;
 }
 
