Index: trunk/Ohana/src/kapa2/Makefile
===================================================================
--- trunk/Ohana/src/kapa2/Makefile	(revision 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 13336)
+++ 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 ();
