[xiph-commits] r13549 - trunk/sushivision

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Wed Aug 15 12:44:40 PDT 2007


Author: xiphmont
Date: 2007-08-15 12:44:39 -0700 (Wed, 15 Aug 2007)
New Revision: 13549

Modified:
   trunk/sushivision/Makefile
   trunk/sushivision/dimension.c
   trunk/sushivision/dimension.h
   trunk/sushivision/example_fractal.c
   trunk/sushivision/function.c
   trunk/sushivision/gtksucks.c
   trunk/sushivision/internal.h
   trunk/sushivision/main.c
   trunk/sushivision/objective.c
   trunk/sushivision/panel-1d.c
   trunk/sushivision/panel-2d.c
   trunk/sushivision/panel-xy.c
   trunk/sushivision/panel.c
   trunk/sushivision/sushivision.h
   trunk/sushivision/undo.c
Log:
Begiinning of API rework to make simple usage less verbose.

Eliminate multiple instances (no real value over multiple panels)

Alter execution flow; make sv 'injectable' by having its own
independent gtk mainloop internally



Modified: trunk/sushivision/Makefile
===================================================================
--- trunk/sushivision/Makefile	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/Makefile	2007-08-15 19:44:39 UTC (rev 13549)
@@ -29,8 +29,8 @@
 	example_fractal.c example_discrete.c example_chirp.c example_spirograph.c
 INC       = sushivision.h sushimacro.h
 MAN	  =
-EXAMPLES  = sushivision_fractal sushivision_discrete sushivision_chirp
-EX_OBJ    = example_fractal.o example_discrete.o example_chirp.o example_spirograph.o
+EXAMPLES  = sushivision_fractal #sushivision_discrete sushivision_chirp
+EX_OBJ    = example_fractal.o #example_discrete.o example_chirp.o example_spirograph.o
 OBJ       = main.o scale.o plot.o slider.o slice.o spinner.c panel.o panel-1d.o panel-2d.o \
 	panel-xy.o mapping.o dimension.o function.o objective.o undo.o gtksucks.o xml.o
 LIBS      = -lpthread -ldl
@@ -94,9 +94,9 @@
 
 examples:  $(OBJ) $(EX_OBJ)
 	$(LD) $(OBJ) example_fractal.o $(CFLAGS) -o sushivision_fractal $(LIBS) $(LDF)
-	$(LD) $(OBJ) example_discrete.o $(CFLAGS) -o sushivision_discrete $(LIBS) $(LDF)
-	$(LD) $(OBJ) example_chirp.o $(CFLAGS) -o sushivision_chirp $(LIBS) $(LDF)
-	$(LD) $(OBJ) example_spirograph.o $(CFLAGS) -o sushivision_spirograph $(LIBS) $(LDF)
+	#$(LD) $(OBJ) example_discrete.o $(CFLAGS) -o sushivision_discrete $(LIBS) $(LDF)
+	#$(LD) $(OBJ) example_chirp.o $(CFLAGS) -o sushivision_chirp $(LIBS) $(LDF)
+	#$(LD) $(OBJ) example_spirograph.o $(CFLAGS) -o sushivision_spirograph $(LIBS) $(LDF)
 
 $(TARGET): all
 

Modified: trunk/sushivision/dimension.c
===================================================================
--- trunk/sushivision/dimension.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/dimension.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -233,15 +233,14 @@
   _sv_dim_widget_t *dw = (_sv_dim_widget_t *)data;
 
   sv_dim_t *d = dw->dl->d;
-  sv_panel_t *p = dw->dl->p;
   double val = _sv_slider_get_value(dw->scale,1);
   char buffer[80];
   
   val = discrete_quantize_val(d,val);
   
   if(buttonstate == 0){
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
   }
   
   if(d->val != val){
@@ -268,7 +267,7 @@
   }
   
   if(buttonstate == 2)
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
   
   snprintf(buffer,80,"%.10g",d->bracket[0]);
   gtk_entry_set_text(GTK_ENTRY(dw->entry[0]),buffer);
@@ -286,7 +285,6 @@
   _sv_dim_widget_t *dw = (_sv_dim_widget_t *)data;
 
   sv_dim_t *d = dw->dl->d;
-  sv_panel_t *p = dw->dl->p;
   double lo = _sv_slider_get_value(dw->scale,0);
   double hi = _sv_slider_get_value(dw->scale,2);
   char buffer[80];
@@ -295,8 +293,8 @@
   lo = discrete_quantize_val(d,lo);
   
   if(buttonstate == 0){
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
   }
   
   if(d->bracket[0] != lo || d->bracket[1] != hi){
@@ -322,7 +320,7 @@
   }
   
   if(buttonstate == 2)
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
   
   snprintf(buffer,80,"%.10g",d->bracket[0]);
   gtk_entry_set_text(GTK_ENTRY(dw->entry[0]),buffer);
@@ -340,12 +338,11 @@
   _sv_dim_widget_t *dw = (_sv_dim_widget_t *)data;
 
   sv_dim_t *d = dw->dl->d;
-  sv_panel_t *p = dw->dl->p;
   int bin = gtk_combo_box_get_active(GTK_COMBO_BOX(dw->menu));
   double val = d->scale->val_list[bin];
     
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
     
   if(d->val != val){
     int i;
@@ -371,7 +368,7 @@
     }
 
   }
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
   
   gdk_threads_leave();
 }
@@ -662,12 +659,10 @@
   return dw;
 };
 
-sv_dim_t *sv_dim_new(sv_instance_t *in,
-		     int number,
+sv_dim_t *sv_dim_new(int number,
 		     char *name,
 		     unsigned flags){
 
-  sv_instance_t *s = (sv_instance_t *)in;
   sv_dim_t *d;
   
   if(number<0){
@@ -676,27 +671,26 @@
     return NULL;
   }
 
-  if(number<s->dimensions){
-    if(s->dimension_list[number]!=NULL){
+  if(number<_sv_dimensions){
+    if(_sv_dimension_list[number]!=NULL){
       fprintf(stderr,"Dimension number %d already exists\n",number);
       errno = -EINVAL;
       return NULL;
     }
   }else{
-    if(s->dimensions == 0){
-      s->dimension_list = calloc (number+1,sizeof(*s->dimension_list));
+    if(_sv_dimensions == 0){
+      _sv_dimension_list = calloc (number+1,sizeof(*_sv_dimension_list));
     }else{
-      s->dimension_list = realloc (s->dimension_list,(number+1) * sizeof(*s->dimension_list));
-      memset(s->dimension_list + s->dimensions, 0, sizeof(*s->dimension_list)*(number + 1 - s->dimensions));
+      _sv_dimension_list = realloc (_sv_dimension_list,(number+1) * sizeof(*_sv_dimension_list));
+      memset(_sv_dimension_list + _sv_dimensions, 0, sizeof(*_sv_dimension_list)*(number + 1 - _sv_dimensions));
     }
-    s->dimensions=number+1;
+    _sv_dimensions=number+1;
   }
 
-  d = s->dimension_list[number] = calloc(1, sizeof(**s->dimension_list));
+  d = _sv_dimension_list[number] = calloc(1, sizeof(**_sv_dimension_list));
   d->number = number;
   d->name = strdup(name);
   d->flags = flags;
-  d->sushi = s;
   d->type = SV_DIM_CONTINUOUS;
   d->private = calloc(1, sizeof(*d->private));
 
@@ -774,7 +768,7 @@
 };
 
 int _sv_dim_load(sv_dim_t *d,
-		 _sv_instance_undo_t *u,
+		 _sv_undo_t *u,
 		 xmlNodePtr dn,
 		 int warn){
 

Modified: trunk/sushivision/dimension.h
===================================================================
--- trunk/sushivision/dimension.h	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/dimension.h	2007-08-15 19:44:39 UTC (rev 13549)
@@ -71,4 +71,4 @@
 					   void (*center_callback)(sv_dim_list_t *),
 					   void (*bracket_callback)(sv_dim_list_t *));
 extern int _sv_dim_save(sv_dim_t *d, xmlNodePtr instance);
-extern int _sv_dim_load(sv_dim_t *d, _sv_instance_undo_t *u, xmlNodePtr dn, int warn);
+extern int _sv_dim_load(sv_dim_t *d, _sv_undo_t *u, xmlNodePtr dn, int warn);

Modified: trunk/sushivision/example_fractal.c
===================================================================
--- trunk/sushivision/example_fractal.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/example_fractal.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -24,8 +24,6 @@
 #include <math.h>
 #include "sushivision.h"
 
-sv_instance_t *s;
-
 static void fractal_objective(double *d, double *ret){
   int max_iter = d[4];
   int i;
@@ -50,23 +48,29 @@
   ret[1] = sqrt(z*z + zi*zi)/4.;
 }
 
-int sv_submain(int argc, char *argv[]){
+int main(int argc, char *argv[]){
 
-  sv_instance_t *s = sv_new(0,"fractal");
+  // before any gtk, gdk or glib setup
+  sv_init(&argc,&argv);
   
-  sv_dim_t *d0 = sv_dim_new(s, 0, "Re(c)", 0);
+  //g_thread_init (NULL);
+  //gtk_init (&argc, &argv);
+  //gdk_threads_init ();
+
+
+  sv_dim_t *d0 = sv_dim_new(0, "Re(c)", 0);
   sv_dim_make_scale(d0, 5, (double []){-2.25,-0.75,0,0.25,0.75}, NULL, 0);
   
-  sv_dim_t *d1 = sv_dim_new(s, 1, "Im(c)", 0);
+  sv_dim_t *d1 = sv_dim_new(1, "Im(c)", 0);
   sv_dim_make_scale(d1, 5, (double []){-2,-1,0,1,2}, NULL, 0);
 
-  sv_dim_t *d2 = sv_dim_new(s, 2, "Re(z0)", 0);
+  sv_dim_t *d2 = sv_dim_new(2, "Re(z0)", 0);
   sv_dim_make_scale(d2, 5, (double []){-2.25,-1,0,1,2.25}, NULL, 0);
 
-  sv_dim_t *d3 = sv_dim_new(s, 3, "Im(z0)", 0);
+  sv_dim_t *d3 = sv_dim_new(3, "Im(z0)", 0);
   sv_dim_make_scale(d3, 5, (double []){-2.25,-1,0,1,2.25}, NULL, 0);
 
-  sv_dim_t *d4 = sv_dim_new(s, 4, "Max Iterations", 0);
+  sv_dim_t *d4 = sv_dim_new(4, "Max Iterations", 0);
   sv_dim_make_scale(d4, 4, (double []){100,1000,10000,100000},
 		    (char *[]){"one hundred",
 				 "one thousand",
@@ -75,30 +79,27 @@
   sv_dim_set_picklist(d4);
   sv_dim_set_value(d4,1,100);
 
-  sv_func_t *f = sv_func_new(s, 0, 2, fractal_objective, 0);
+  sv_func_t *f = sv_func_new(0, 2, fractal_objective, 0);
   
-  sv_obj_t *o0 = sv_obj_new(s,0,"outer",
+  sv_obj_t *o0 = sv_obj_new(0,"outer",
 			    (sv_func_t *[]){f},
 			    (int []){0},
 			    "Y", 0);
   sv_obj_make_scale(o0, 5, (double []){0, .001, .01, .1, 1.0}, NULL, 0);
   
-  sv_obj_t *o1 = sv_obj_new(s,1,"inner",
+  sv_obj_t *o1 = sv_obj_new(1,"inner",
 			    (sv_func_t *[]){f},
 			    (int []){1},
 			    "Y", 0);
   sv_obj_make_scale(o1, 5, (double []){0, .001, .01, .1, 1.0}, NULL, 0);
   
-  sv_panel_new_2d(s,0,"Mandel/Julia Fractal",
+  sv_panel_new_2d(0,"Mandel/Julia Fractal",
 		  (sv_obj_t *[]){o0,o1,NULL},
 		  (sv_dim_t *[]){d0,d1,d2,d3,d4,NULL},
 		  0);
   
-  return 0;
-}
+  sv_go();
+  sv_join();
 
-/* sushiv_atexit is entirely optional and may be ommitted */
-int sv_atexit(void){
-  fprintf(stderr,"Done!\n");
   return 0;
 }

Modified: trunk/sushivision/function.c
===================================================================
--- trunk/sushivision/function.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/function.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -25,12 +25,10 @@
 #include <errno.h>
 #include "internal.h"
 
-sv_func_t *sv_func_new(sv_instance_t *in,
-		       int number,
+sv_func_t *sv_func_new(int number,
 		       int out_vals,
 		       void(*callback)(double *,double *),
 		       unsigned flags){
-  sv_instance_t *s = (sv_instance_t *)in; // unwrap
   sv_func_t *f;
 
   if(number<0){
@@ -39,26 +37,25 @@
     return NULL;
   }
 
-  if(number<s->functions){
-    if(s->function_list[number]!=NULL){
+  if(number<_sv_functions){
+    if(_sv_function_list[number]!=NULL){
       fprintf(stderr,"Function number %d already exists\n",number);
       errno = -EINVAL;
       return NULL;
     }
   }else{
-    if(s->functions == 0){
-      s->function_list = calloc (number+1,sizeof(*s->function_list));
+    if(_sv_functions == 0){
+      _sv_function_list = calloc (number+1,sizeof(*_sv_function_list));
     }else{
-      s->function_list = realloc (s->function_list,(number+1) * sizeof(*s->function_list));
-      memset(s->function_list + s->functions, 0, sizeof(*s->function_list)*(number +1 - s->functions));
+      _sv_function_list = realloc (_sv_function_list,(number+1) * sizeof(*_sv_function_list));
+      memset(_sv_function_list + _sv_functions, 0, sizeof(*_sv_function_list)*(number +1 - _sv_functions));
     }
-    s->functions=number+1;
+    _sv_functions=number+1;
   }
 
-  f = s->function_list[number] = calloc(1, sizeof(**s->function_list));
+  f = _sv_function_list[number] = calloc(1, sizeof(**_sv_function_list));
   f->number = number;
   f->flags = flags;
-  f->sushi = s;
   f->callback = callback;
   f->outputs = out_vals;
   f->type = SV_FUNC_BASIC;

Modified: trunk/sushivision/gtksucks.c
===================================================================
--- trunk/sushivision/gtksucks.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/gtksucks.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -210,6 +210,7 @@
 static pthread_mutex_t gdkm;
 static pthread_mutexattr_t gdkma;
 static int depth = 0;
+static int firstunder = 0;
 
 static void recursive_gdk_lock(void){
   pthread_mutex_lock(&gdkm);
@@ -219,10 +220,21 @@
 static void recursive_gdk_unlock(void){
   depth--;
   if(depth<0){
-    fprintf(stderr,"Internal locking error; refcount < 0. Dumping core for debugging\n");
-    abort();
-  }
-  pthread_mutex_unlock(&gdkm);
+    if(!firstunder){ // annoying detail of gtk locking; in apps that
+      // don't normally use threads, onr does not lock before entering
+      // mainloop; in apps that do thread, the mainloop must be
+      // locked.  We can't tell which situation was in place before
+      // setting up our own threading, so allow one refcount error
+      // which we assume was the unlocked mainloop of a normally
+      // unthreaded gtk app.
+      firstunder++;
+      depth=0;
+    }else{
+      fprintf(stderr,"Internal locking error; refcount < 0. Dumping core for debugging\n");
+      abort();
+    }
+  }else
+    pthread_mutex_unlock(&gdkm);
 }
 
 void _gtk_mutex_fixup(){

Modified: trunk/sushivision/internal.h
===================================================================
--- trunk/sushivision/internal.h	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/internal.h	2007-08-15 19:44:39 UTC (rev 13549)
@@ -19,7 +19,7 @@
  * 
  */
 
-typedef struct _sv_instance_undo _sv_instance_undo_t;
+typedef struct _sv_undo _sv_undo_t;
 
 #include <time.h>
 #include <signal.h>
@@ -147,26 +147,19 @@
   void (*undo_restore)(_sv_panel_undo_t *u, sv_panel_t *p);
 };
 
-struct _sv_instance_undo {
+struct _sv_undo {
   _sv_panel_undo_t *panels;
   double *dim_vals[3];
 };
 
-struct _sv_instance_internal {
-  int undo_level;
-  int undo_suspend;
-  _sv_instance_undo_t **undo_stack;
-};
-
-extern void _sv_clean_exit(int sig);
-extern void _sv_wake_workers();
-extern int  _sv_main_save();
-extern int  _sv_main_load();
+extern void _sv_clean_exit(void);
+extern void _sv_wake_workers(void);
+extern int  _sv_main_save(void);
+extern int  _sv_main_load(void);
 extern void _sv_first_load_warning(int *);
 
 
-extern sv_panel_t *_sv_panel_new(sv_instance_t *s,
-				 int number,
+extern sv_panel_t *_sv_panel_new(int number,
 				 char *name, 
 				 sv_obj_t **objectives,
 				 sv_dim_t **dimensions,	
@@ -183,25 +176,38 @@
 extern void _sv_panel_undo_log(sv_panel_t *p, _sv_panel_undo_t *u);
 extern void _sv_panel_undo_restore(sv_panel_t *p, _sv_panel_undo_t *u);
 extern void _sv_panel_update_menus(sv_panel_t *p);
-extern int  _sv_panel_save(sv_panel_t *p, xmlNodePtr instance);
-extern int  _sv_panel_load(sv_panel_t *p, _sv_panel_undo_t *u, xmlNodePtr instance, int warn);
+extern int  _sv_panel_save(sv_panel_t *p, xmlNodePtr n);
+extern int  _sv_panel_load(sv_panel_t *p, _sv_panel_undo_t *u, xmlNodePtr n, int warn);
 
 extern void _sv_panel1d_mark_recompute_linked(sv_panel_t *p); 
 extern void _sv_panel1d_update_linked_crosshairs(sv_panel_t *p, int xflag, int yflag); 
 
 extern void _sv_map_set_throttle_time(sv_panel_t *p);
 
-extern void _sv_undo_log(sv_instance_t *s);
-extern void _sv_undo_push(sv_instance_t *s);
-extern void _sv_undo_pop(sv_instance_t *s);
-extern void _sv_undo_suspend(sv_instance_t *s);
-extern void _sv_undo_resume(sv_instance_t *s);
-extern void _sv_undo_restore(sv_instance_t *s);
-extern void _sv_undo_up(sv_instance_t *s);
-extern void _sv_undo_down(sv_instance_t *s);
+extern void _sv_undo_log();
+extern void _sv_undo_push();
+extern void _sv_undo_pop();
+extern void _sv_undo_suspend();
+extern void _sv_undo_resume();
+extern void _sv_undo_restore();
+extern void _sv_undo_up();
+extern void _sv_undo_down();
 
 extern sig_atomic_t _sv_exiting;
 extern char *_sv_filebase;
 extern char *_sv_filename;
 extern char *_sv_dirname;
 extern char *_sv_cwdname;
+
+extern int _sv_functions;
+extern sv_func_t **_sv_function_list;
+extern int _sv_dimensions;
+extern sv_dim_t **_sv_dimension_list;
+extern int _sv_objectives;
+extern sv_obj_t **_sv_objective_list;
+extern int _sv_panels;
+extern sv_panel_t **_sv_panel_list;
+extern int _sv_undo_level;
+extern int _sv_undo_suspended;
+extern _sv_undo_t **_sv_undo_stack;
+

Modified: trunk/sushivision/main.c
===================================================================
--- trunk/sushivision/main.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/main.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -45,28 +45,31 @@
 static int wake_pending = 0;
 static int num_threads;
 
-static int instances=0;
-static sv_instance_t **instance_list;
+int _sv_functions=0;
+sv_func_t **_sv_function_list=NULL;
+int _sv_dimensions=0;
+sv_dim_t **_sv_dimension_list=NULL;
+int _sv_objectives=0;
+sv_obj_t **_sv_objective_list=NULL;
+int _sv_panels=0;
+sv_panel_t **_sv_panel_list=NULL;
+int _sv_undo_level=0;
+int _sv_undo_suspended=0;
+_sv_undo_t **_sv_undo_stack=NULL;
 
 void _sv_wake_workers(){
-  if(instances){
-    pthread_mutex_lock(&m);
-    wake_pending = num_threads;
-    pthread_cond_broadcast(&mc);
-    pthread_mutex_unlock(&m);
-  }
+  pthread_mutex_lock(&m);
+  wake_pending = num_threads;
+  pthread_cond_broadcast(&mc);
+  pthread_mutex_unlock(&m);
 }
 
-void _sv_clean_exit(int sig){
+void _sv_clean_exit(){
   _sv_exiting = 1;
   _sv_wake_workers();
-
-  //signal(sig,SIG_IGN);
-  if(sig!=SIGINT)
-    fprintf(stderr,
-            "\nTrapped signal %d; exiting!\n",sig);
-
-  gtk_main_quit();
+  if(!gtk_main_iteration_do(FALSE)) // side effect: returns true if
+				    // there are no main loops active
+    gtk_main_quit();
 }
 
 static int num_proccies(){
@@ -92,69 +95,58 @@
 static void *worker_thread(void *dummy){
   /* set up temporary working space for function rendering; this saves
      continuously recreating it in the loop below */
-  _sv_bythread_cache_t **c; // [instance][panel]
-  int i,j;
+  _sv_bythread_cache_t *c=calloc(_sv_panels,sizeof(*c));
+  int i;
   
-  c = calloc(instances,sizeof(*c));
-  for(j=0;j<instances;j++){
-    sv_instance_t *s = instance_list[j];
-    c[j] = calloc(s->panels,sizeof(**c));
-  }
-
   while(1){
     if(_sv_exiting)break;
     
     // look for work
     {
       int flag=0;
-      // by instance
-      for(j=0;j<instances;j++){
-	sv_instance_t *s = instance_list[j];
-				 
-	for(i=0;i<s->panels;i++){
-	  sv_panel_t *p = s->panel_list[i];
+      for(i=0;i<_sv_panels;i++){
+	sv_panel_t *p = _sv_panel_list[i];
 
-	  if(_sv_exiting)break;
-
-	  // pending remap work?
-	  gdk_threads_enter();
-	  if(p && p->private && p->private->realized && p->private->graph){
-
-	    // pending computation work?
-	    if(p->private->plot_active){
-	      _sv_spinner_set_busy(p->private->spinner);
-
-	      if(p->private->plot_progress_count==0){    
-		if(p->private->callback_precompute)
-		  p->private->callback_precompute(p,p->private->callback_precompute_data);
-	      }
-
-	      flag |= p->private->compute_action(p,&c[j][i]); // may drop lock internally
-	    }
+	if(_sv_exiting)break;
+	
+	// pending remap work?
+	gdk_threads_enter();
+	if(p && p->private && p->private->realized && p->private->graph){
+	  
+	  // pending computation work?
+	  if(p->private->plot_active){
+	    _sv_spinner_set_busy(p->private->spinner);
 	    
-	    if(p->private->map_active){
-	      int ret = 1;
-	      while(ret){ // favor completing remaps over other ops
-		_sv_spinner_set_busy(p->private->spinner);
-		flag |= ret = p->private->map_action(p,&c[j][i]); // may drop lock internally
-		if(!p->private->map_active)
-		  _sv_map_set_throttle_time(p);
-	      }
+	    if(p->private->plot_progress_count==0){    
+	      if(p->private->callback_precompute)
+		p->private->callback_precompute(p,p->private->callback_precompute_data);
 	    }
 	    
-	    // pending legend work?
-	    if(p->private->legend_active){
+	    flag |= p->private->compute_action(p,&c[i]); // may drop lock internally
+	  }
+	  
+	  if(p->private->map_active){
+	    int ret = 1;
+	    while(ret){ // favor completing remaps over other ops
 	      _sv_spinner_set_busy(p->private->spinner);
-	      flag |= p->private->legend_action(p); // may drop lock internally
+	      flag |= ret = p->private->map_action(p,&c[i]); // may drop lock internally
+	      if(!p->private->map_active)
+		_sv_map_set_throttle_time(p);
 	    }
-	    
-	    if(!p->private->plot_active &&
-	       !p->private->legend_active &&
-	       !p->private->map_active)
-	      _sv_spinner_set_idle(p->private->spinner);
 	  }
-	  gdk_threads_leave ();
+	  
+	  // pending legend work?
+	  if(p->private->legend_active){
+	    _sv_spinner_set_busy(p->private->spinner);
+	    flag |= p->private->legend_action(p); // may drop lock internally
+	  }
+	  
+	  if(!p->private->plot_active &&
+	     !p->private->legend_active &&
+	     !p->private->map_active)
+	    _sv_spinner_set_idle(p->private->spinner);
 	}
+	gdk_threads_leave ();
       }
       if(flag==1)continue;
     }
@@ -176,77 +168,58 @@
   return _SUSHI_GTKRC_STRING;
 }
 
-static void _sv_instance_realize(sv_instance_t *s){
-  int i;
-  for(i=0;i<s->panels;i++)
-    _sv_panel_realize(s->panel_list[i]);
-  for(i=0;i<s->panels;i++)
-    if(s->panel_list[i])
-      s->panel_list[i]->private->request_compute(s->panel_list[i]);
-}
-
 static void _sv_realize_all(void){
   int i;
-  for(i=0;i<instances;i++)
-    _sv_instance_realize(instance_list[i]);
+  for(i=0;i<_sv_panels;i++)
+    _sv_panel_realize(_sv_panel_list[i]);
+  for(i=0;i<_sv_panels;i++)
+    if(_sv_panel_list[i])
+      _sv_panel_list[i]->private->request_compute(_sv_panel_list[i]);
 }
 
-/* externally visible interface */
-
-sv_instance_t *sv_new(int number, char *name) {
-  sv_instance_t *ret;
-
-  if(number<0){
-    fprintf(stderr,"Instance number must be >= 0\n");
-    errno = -EINVAL;
-    return NULL;
-  }
-  
-  if(number<instances){
-    if(instance_list[number]!=NULL){
-      fprintf(stderr,"Instance number %d already exists\n",number);
-      errno = -EINVAL;
-      return NULL;
-    }
-  }else{
-    if(instances == 0){
-      instance_list = calloc (number+1,sizeof(*instance_list));
-    }else{
-      instance_list = realloc (instance_list,(number+1) * sizeof(*instance_list));
-      memset(instance_list + instances, 0, sizeof(*instance_list)*(number+1 - instances));
-    }
-    instances = number+1; 
-  }
-
-  ret = instance_list[number] = calloc(1, sizeof(**instance_list));
-  ret->private = calloc(1,sizeof(*ret->private));
-  if(name)
-    ret->name = strdup(name);
-
-  return ret;
-}
-
 char *_sv_appname = NULL;
 char *_sv_filename = NULL;
 char *_sv_filebase = NULL;
 char *_sv_dirname = NULL;
 char *_sv_cwdname = NULL;
 
-int main (int argc, char *argv[]){
-  int ret;
+static void *event_thread(void *dummy){
 
-  num_threads = num_proccies();
+  gdk_threads_enter();
+  gtk_main ();
+  gdk_threads_leave();
+  
+  gtk_main_quit(); // in case there's another mainloop in the main app
 
+  return 0;
+}
+
+/* externally visible interface */
+int sv_init(){
+  
+  num_threads = num_proccies();
   _gtk_mutex_fixup();
-  g_thread_init (NULL);
-  gtk_init (&argc, &argv);
+  gtk_init (NULL,NULL);
+
+  return 0;
+}
+
+int sv_join(){
+  while(!_sv_exiting){
+    pthread_mutex_lock(&m);
+    pthread_cond_wait(&mc,&m);
+    pthread_mutex_unlock(&m);
+  }
+  return 0;
+}
+
+int sv_go(){
+    
+  if (!g_thread_supported ()) g_thread_init (NULL);
   gdk_threads_init ();
   gtk_rc_parse_string(gtkrc_string());
   gtk_rc_add_default_file("sushi-gtkrc");
 
-  ret = sv_submain(argc,argv);
-  if(ret)return ret;
-  
   gdk_threads_enter();
   _sv_realize_all();
   _gtk_button3_fixup();
@@ -254,7 +227,7 @@
   _sv_appname = g_get_prgname ();
   _sv_cwdname = getcwd(NULL,0);
   _sv_dirname = strdup(_sv_cwdname);
-  if(argc>1){
+  /*if(argc>1){
     // file to load specified on commandline
     if(argv[argc-1][0] != '-'){
       _sv_filebase = strdup(argv[argc-1]);
@@ -293,7 +266,7 @@
     }else
       _sv_filebase = strdup("default.sushi");
     asprintf(&_sv_filename,"%s/%s",_sv_dirname,_sv_filebase);
-  }
+    }*/
 
   {
     pthread_t dummy;
@@ -302,44 +275,16 @@
       pthread_create(&dummy, NULL, &worker_thread,NULL);
   }
 
-  signal(SIGINT,_sv_clean_exit);
+  //signal(SIGINT,_sv_clean_exit);
   //signal(SIGSEGV,_sv_clean_exit);
 
-
-  gtk_main ();
-  gdk_threads_leave();
-  
   {
-    int (*optional_exit)(void) = dlsym(RTLD_DEFAULT, "sv_atexit");
-    if(optional_exit)
-      return optional_exit();
+    pthread_t dummy;
+    gdk_threads_leave();
+    return pthread_create(&dummy, NULL, &event_thread,NULL);
   }
-
-  return 0;
 }
 
-static int _sv_instance_save(sv_instance_t *s, xmlNodePtr root){
-  if(!s) return 0;
-  int i, ret=0;
-
-  xmlNodePtr instance = xmlNewChild(root, NULL, (xmlChar *) "instance", NULL);
-
-  _xmlNewPropI(instance, "number", s->number);
-  _xmlNewPropS(instance, "name", s->name);
-  
-  // dimension values are independent of panel
-  for(i=0;i<s->dimensions;i++)
-    ret|=_sv_dim_save(s->dimension_list[i], instance);
-  
-  // objectives have no independent settings
-
-  // panel settings (by panel)
-  for(i=0;i<s->panels;i++)
-    ret|=_sv_panel_save(s->panel_list[i], instance);
-
-  return ret;
-}
-
 void _sv_first_load_warning(int *warn){
   if(!*warn)
     fprintf(stderr,"\nWARNING: The data file to be opened is not a perfect match to\n"
@@ -349,74 +294,6 @@
   *warn = 1;
 }
 
-static int _sv_instance_load(sv_instance_t *s, xmlNodePtr in, int warn){
-  int i;
-
-  // piggyback off undo (as it already goes through the trouble of
-  // doing correct unrolling, which can be tricky)
-
-  // if this instance has an undo stack, pop it all, then log current state into it
-  s->private->undo_level=0;
-  _sv_undo_log(s);
-
-  _sv_instance_undo_t *u = s->private->undo_stack[s->private->undo_level];
-
-  // load dimensions
-  for(i=0;i<s->dimensions;i++){
-    sv_dim_t *d = s->dimension_list[i];
-    if(d){
-      xmlNodePtr dn = _xmlGetChildI(in,"dimension","number",d->number);
-      if(!dn){
-	_sv_first_load_warning(&warn);
-	fprintf(stderr,"Could not find data for dimension \"%s\" in save file.\n",
-		d->name);
-      }else{
-	warn |= _sv_dim_load(d,u,dn,warn);
-	xmlFreeNode(dn);
-      }
-    }
-  }
-  
-  // load panels
-  for(i=0;i<s->panels;i++){
-    sv_panel_t *p = s->panel_list[i];
-    if(p){
-      xmlNodePtr pn = _xmlGetChildI(in,"panel","number",p->number);
-      if(!pn){ 
-	_sv_first_load_warning(&warn);
-	fprintf(stderr,"Could not find data for panel \"%s\" in save file.\n",
-		p->name);
-      }else{
-	warn |= _sv_panel_load(p,u->panels+i,pn,warn);
-	xmlFreeNode(pn);
-      }
-    }
-  }
-  
-  // if any elements are unclaimed, warn 
-  xmlNodePtr node = in->xmlChildrenNode;
-  while(node){
-    if (node->type == XML_ELEMENT_NODE) {
-      xmlChar *name = xmlGetProp(node, (xmlChar *)"name");
-      _sv_first_load_warning(&warn);
-      if(name){
-	fprintf(stderr,"Save file contains data for nonexistant object \"%s\".\n",
-		name);
-	xmlFree(name);
-      }else
-	fprintf(stderr,"Save file root node contains an extra unknown elements.\n");
-    }
-    node = node->next;
-  }
-  
-  // effect the loaded values
-  _sv_undo_suspend(s);
-  _sv_undo_restore(s);
-  _sv_undo_resume(s);
-
-  return warn;
-}
-
 int _sv_main_save(){
   xmlDocPtr doc = NULL;
   xmlNodePtr root_node = NULL;
@@ -428,10 +305,16 @@
   root_node = xmlNewNode(NULL, (xmlChar *)_sv_appname);
   xmlDocSetRootElement(doc, root_node);
 
-  // save each instance 
-  for(i=0;i<instances;i++)
-    ret |= _sv_instance_save(instance_list[i],root_node);
+  // dimension values are independent of panel
+  for(i=0;i<_sv_dimensions;i++)
+    ret|=_sv_dim_save(_sv_dimension_list[i], root_node);
+  
+  // objectives have no independent settings
 
+  // panel settings (by panel)
+  for(i=0;i<_sv_panels;i++)
+    ret|=_sv_panel_save(_sv_panel_list[i], root_node);
+
   xmlSaveFormatFileEnc(_sv_filename, doc, "UTF-8", 1);
 
   xmlFreeDoc(doc);
@@ -476,39 +359,67 @@
 
   root = xmlDocGetRootElement(doc);
 
-  // load each instance 
-  for(i=0;i<instances;i++){
-    sv_instance_t *s = instance_list[i];
-    if(s){
-      xmlNodePtr in = _xmlGetChildI(root,"instance","number",s->number);
-      if(!in){ 
+  // piggyback off undo (as it already goes through the trouble of
+  // doing correct unrolling, which can be tricky)
+  
+  // if this instance has an undo stack, pop it all, then log current state into it
+  _sv_undo_level=0;
+  _sv_undo_log();
+  
+  _sv_undo_t *u = _sv_undo_stack[_sv_undo_level];
+
+  // load dimensions
+  for(i=0;i<_sv_dimensions;i++){
+    sv_dim_t *d = _sv_dimension_list[i];
+    if(d){
+      xmlNodePtr dn = _xmlGetChildI(root,"dimension","number",d->number);
+      if(!dn){
 	_sv_first_load_warning(&warn);
-	fprintf(stderr,"Could not find data for instance \"%s\" in save file.\n",
-		s->name);
+	fprintf(stderr,"Could not find data for dimension \"%s\" in save file.\n",
+		d->name);
+      }else{
+	warn |= _sv_dim_load(d,u,dn,warn);
+	xmlFreeNode(dn);
       }
-      // load even if no node; need to set fallbacks
-      warn |= _sv_instance_load(s,in,warn);
-      if(in)xmlFreeNode(in);
     }
   }
-
-  // if any instances are unclaimed, warn 
-  xmlNodePtr node = root->xmlChildrenNode;
   
+  // load panels
+  for(i=0;i<_sv_panels;i++){
+    sv_panel_t *p = _sv_panel_list[i];
+    if(p){
+      xmlNodePtr pn = _xmlGetChildI(root,"panel","number",p->number);
+      if(!pn){ 
+	_sv_first_load_warning(&warn);
+	fprintf(stderr,"Could not find data for panel \"%s\" in save file.\n",
+		p->name);
+      }else{
+	warn |= _sv_panel_load(p,u->panels+i,pn,warn);
+	xmlFreeNode(pn);
+      }
+    }
+  }
+  
+  // if any elements are unclaimed, warn 
+  xmlNodePtr node = root->xmlChildrenNode;
   while(node){
     if (node->type == XML_ELEMENT_NODE) {
-      char *name = NULL;
-      _xmlGetPropS(node, "name", &name);
+      xmlChar *name = xmlGetProp(node, (xmlChar *)"name");
       _sv_first_load_warning(&warn);
       if(name){
 	fprintf(stderr,"Save file contains data for nonexistant object \"%s\".\n",
-		  name);
+		name);
 	xmlFree(name);
       }else
 	fprintf(stderr,"Save file root node contains an extra unknown elements.\n");
     }
-    node = node->next; 
+    node = node->next;
   }
+  
+  // effect the loaded values
+  _sv_undo_suspend();
+  _sv_undo_restore();
+  _sv_undo_resume();
 
   xmlFreeDoc(doc);
   xmlCleanupParser();

Modified: trunk/sushivision/objective.c
===================================================================
--- trunk/sushivision/objective.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/objective.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -25,15 +25,13 @@
 #include <errno.h>
 #include "internal.h"
 
-sv_obj_t *sv_obj_new(sv_instance_t *in,
-		     int number,
+sv_obj_t *sv_obj_new(int number,
 		     char *name,
 		     sv_func_t **function_map,
 		     int *function_output_map,
 		     char *output_type_map,
 		     unsigned flags){
   
-  sv_instance_t *s = (sv_instance_t *)in; // unwrap
   sv_obj_t *o;
   sv_obj_internal_t *p;
   int i;
@@ -45,23 +43,23 @@
     return NULL;
   }
   
-  if(number<s->objectives){
-    if(s->objective_list[number]!=NULL){
+  if(number<_sv_objectives){
+    if(_sv_objective_list[number]!=NULL){
       fprintf(stderr,"Objective number %d already exists\n",number);
     errno = -EINVAL;
     return NULL;
     }
   }else{
-    if(s->objectives == 0){
-      s->objective_list = calloc (number+1,sizeof(*s->objective_list));
+    if(_sv_objectives == 0){
+      _sv_objective_list = calloc (number+1,sizeof(*_sv_objective_list));
     }else{
-      s->objective_list = realloc (s->objective_list,(number+1) * sizeof(*s->objective_list));
-      memset(s->objective_list + s->objectives, 0, sizeof(*s->objective_list)*(number +1 - s->objectives));
+      _sv_objective_list = realloc (_sv_objective_list,(number+1) * sizeof(*_sv_objective_list));
+      memset(_sv_objective_list + _sv_objectives, 0, sizeof(*_sv_objective_list)*(number +1 - _sv_objectives));
     }
-    s->objectives=number+1;
+    _sv_objectives=number+1;
   }
   
-  o = s->objective_list[number] = calloc(1, sizeof(**s->objective_list));
+  o = _sv_objective_list[number] = calloc(1, sizeof(**_sv_objective_list));
   p = o->private = calloc(1,sizeof(*o->private));
 
   /* sanity check the maps */
@@ -170,7 +168,6 @@
   o->type = SV_OBJ_BASIC;
   o->outputs = outputs;
   o->flags = flags;
-  o->sushi = s;
 
   /* copy in the maps */
   o->function_map = malloc(outputs * sizeof(*o->function_map));

Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/panel-1d.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -463,8 +463,8 @@
   _sv_panel1d_t *p1 = p->subtype->p1;
   int onum = optr - p->objective_list;
   
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   // update colormap
   // oh, the wasteful
@@ -474,7 +474,7 @@
   
   _sv_panel_dirty_map(p);
   _sv_panel_dirty_legend(p);
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panel1d_alpha_callback(void * in, int buttonstate){
@@ -484,15 +484,15 @@
   //  int onum = optr - p->objective_list;
 
   if(buttonstate == 0){
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
   }
 
   _sv_panel_dirty_map(p);
   _sv_panel_dirty_legend(p);
 
   if(buttonstate == 2)
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
 }
 
 static void _sv_panel1d_linetype_callback(GtkWidget *w,gpointer in){
@@ -501,15 +501,15 @@
   _sv_panel1d_t *p1 = p->subtype->p1;
   int onum = optr - p->objective_list;
   
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   // update colormap
   int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
   p1->linetype[onum] = line_name[pos]->value;
 
   _sv_panel_dirty_map(p);
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panel1d_pointtype_callback(GtkWidget *w,gpointer in){
@@ -518,15 +518,15 @@
   _sv_panel1d_t *p1 = p->subtype->p1;
   int onum = optr - p->objective_list;
   
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   // update colormap
   int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
   p1->pointtype[onum] = point_name[pos]->value;
 
   _sv_panel_dirty_map(p);
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panel1d_map_callback(void *in,int buttonstate){
@@ -535,8 +535,8 @@
   _sv_plot_t *plot = PLOT(p->private->graph);
   
   if(buttonstate == 0){
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
   }
 
   // has new bracketing changed the plot range scale?
@@ -568,7 +568,7 @@
   //redraw the plot
   _sv_panel_dirty_map(p);
   if(buttonstate == 2)
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
 }
 
 static void _sv_panel1d_update_xsel(sv_panel_t *p){
@@ -609,12 +609,12 @@
 				     _sv_bythread_cache_1d_t *c){
   _sv_panel1d_t *p1 = p->subtype->p1;
   double work[w];
-  int i,j,fn=p->sushi->functions;
+  int i,j,fn=_sv_functions;
 
   /* by function */
   for(i=0;i<fn;i++){
     if(c->call[i]){
-      sv_func_t *f = p->sushi->function_list[i];
+      sv_func_t *f = _sv_function_list[i];
       int step = f->outputs;
       double *fout = c->fout[i];
       
@@ -657,6 +657,35 @@
   }
 }
 
+// subtype entry point for plot remaps; lock held
+int _sv_panel1d_map_redraw(sv_panel_t *p, _sv_bythread_cache_t *c){
+  if(p->private->map_progress_count)return 0;
+  p->private->map_progress_count++;
+
+  // render to a temp surface so that we can release the lock occasionally
+  _sv_plot_t *plot = PLOT(p->private->graph);
+  cairo_surface_t *back = plot->back;
+  cairo_surface_t *cs = cairo_surface_create_similar(back,CAIRO_CONTENT_COLOR,
+						     cairo_image_surface_get_width(back),
+						     cairo_image_surface_get_height(back));
+  cairo_t *ct = cairo_create(cs);
+  
+  if(_sv_panel1d_remap(p,ct) == -1){ // returns -1 on abort
+    cairo_destroy(ct);
+    cairo_surface_destroy(cs);
+  }else{
+    // else complete
+    cairo_surface_destroy(plot->back);
+    plot->back = cs;
+    cairo_destroy(ct);
+    
+    _sv_panel_clean_map(p);
+    _sv_plot_expose_request(plot);
+  }
+
+  return 1;
+}
+
 // call only from main gtk thread
 void _sv_panel1d_mark_recompute(sv_panel_t *p){
   if(!p->private->realized) return;
@@ -767,9 +796,8 @@
   int i;
 
   /* look to see if any 1d panels link to passed in panel */
-  sv_instance_t *s = p->sushi;
-  for(i=0;i<s->panels;i++){
-    sv_panel_t *q = s->panel_list[i];
+  for(i=0;i<_sv_panels;i++){
+    sv_panel_t *q = _sv_panel_list[i];
     if(q != p && q->type == SV_PANEL_1D){
       _sv_panel1d_t *q1 = q->subtype->p1;
       if(q1->link_x == p)
@@ -834,9 +862,8 @@
   int i;
 
   /* look to see if any 1d panels link to passed in panel */
-  sv_instance_t *s = p->sushi;
-  for(i=0;i<s->panels;i++){
-    sv_panel_t *q = s->panel_list[i];
+  for(i=0;i<_sv_panels;i++){
+    sv_panel_t *q = _sv_panel_list[i];
     if(q != p && q->type == SV_PANEL_1D){
       _sv_panel1d_t *q1 = q->subtype->p1;
       if(q1->link_x == p){
@@ -883,15 +910,15 @@
 
   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))){
 
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
 
     _sv_panel1d_update_xsel(p);
     _sv_panel1d_update_crosshair(p);
     _sv_plot_unset_box(PLOT(p->private->graph));
     _sv_panel1d_mark_recompute(p);
 
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
   }
 }
 
@@ -922,8 +949,8 @@
     link->private->crosshair_action(link);
   }else{
 
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
 
     for(i=0;i<p->dimensions;i++){
       sv_dim_t *d = p->dimension_list[i].d;
@@ -932,7 +959,7 @@
 	            
       p->private->oldbox_active = 0;
     }
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
   }
 }
 
@@ -943,20 +970,20 @@
   
   switch(state){
   case 0: // box set
-    _sv_undo_push(p->sushi);
+    _sv_undo_push();
     _sv_plot_box_vals(plot,p1->oldbox);
     p->private->oldbox_active = plot->box_active;
     break;
   case 1: // box activate
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
 
     _sv_panel1d_crosshair_callback(p);
     
     _sv_dim_set_value(p1->x_scale,0,p1->oldbox[0]);
     _sv_dim_set_value(p1->x_scale,2,p1->oldbox[1]);
     p->private->oldbox_active = 0;
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
     break;
   }
   _sv_panel_update_menus(p);
@@ -969,13 +996,13 @@
     int i,j;
     
     /* determine which functions are actually needed */
-    c->call = calloc(p->sushi->functions,sizeof(*c->call));
-    c->fout = calloc(p->sushi->functions,sizeof(*c->fout));
+    c->call = calloc(_sv_functions,sizeof(*c->call));
+    c->fout = calloc(_sv_functions,sizeof(*c->fout));
     for(i=0;i<p->objectives;i++){
       sv_obj_t *o = p->objective_list[i].o;
       for(j=0;j<o->outputs;j++)
 	c->call[o->function_map[j]]=
-	  p->sushi->function_list[o->function_map[j]]->callback;
+	  _sv_function_list[o->function_map[j]]->callback;
     }
   }
 
@@ -984,45 +1011,16 @@
     int i;
     c->storage_width = w;
 
-    for(i=0;i<p->sushi->functions;i++){
+    for(i=0;i<_sv_functions;i++){
       if(c->call[i]){
 	if(c->fout[i])free(c->fout[i]);
-	c->fout[i] = malloc(w * p->sushi->function_list[i]->outputs *
+	c->fout[i] = malloc(w * _sv_function_list[i]->outputs *
 			    sizeof(**c->fout));
       }
     }
   }
 }
 
-// subtype entry point for plot remaps; lock held
-int _sv_panel1d_map_redraw(sv_panel_t *p, _sv_bythread_cache_t *c){
-  if(p->private->map_progress_count)return 0;
-  p->private->map_progress_count++;
-
-  // render to a temp surface so that we can release the lock occasionally
-  _sv_plot_t *plot = PLOT(p->private->graph);
-  cairo_surface_t *back = plot->back;
-  cairo_surface_t *cs = cairo_surface_create_similar(back,CAIRO_CONTENT_COLOR,
-						     cairo_image_surface_get_width(back),
-						     cairo_image_surface_get_height(back));
-  cairo_t *ct = cairo_create(cs);
-  
-  if(_sv_panel1d_remap(p,ct) == -1){ // returns -1 on abort
-    cairo_destroy(ct);
-    cairo_surface_destroy(cs);
-  }else{
-    // else complete
-    cairo_surface_destroy(plot->back);
-    plot->back = cs;
-    cairo_destroy(ct);
-    
-    _sv_panel_clean_map(p);
-    _sv_plot_expose_request(plot);
-  }
-
-  return 1;
-}
-
 // subtype entry point for legend redraws; lock held
 int _sv_panel1d_legend_redraw(sv_panel_t *p){
   _sv_plot_t *plot = PLOT(p->private->graph);
@@ -1075,7 +1073,7 @@
   
   /* render using local dimension array; several threads will be
      computing objectives */
-  double dim_vals[p->sushi->dimensions];
+  double dim_vals[_sv_dimensions];
 
   /* get iterator bounds, use iterator scale */
   x_d = p->private->x_d->number;
@@ -1093,8 +1091,8 @@
   }
 
   // Initialize local dimension value array
-  for(i=0;i<p->sushi->dimensions;i++){
-    sv_dim_t *dim = p->sushi->dimension_list[i];
+  for(i=0;i<_sv_dimensions;i++){
+    sv_dim_t *dim = _sv_dimension_list[i];
     dim_vals[i]=dim->val;
   }
 
@@ -1187,7 +1185,7 @@
   _sv_panel1d_t *p1 = p->subtype->p1;
   char buffer[160];
   int i;
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_suspend();
 
   p->private->toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   g_signal_connect_swapped (G_OBJECT (p->private->toplevel), "delete-event",
@@ -1413,7 +1411,7 @@
   gtk_widget_realize(GTK_WIDGET(p->private->spinner));
   gtk_widget_show_all(p->private->toplevel);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 
@@ -1525,15 +1523,14 @@
   return warn;
 }
 
-sv_panel_t *sv_panel_new_1d(sv_instance_t *s,
-			    int number,
+sv_panel_t *sv_panel_new_1d(int number,
 			    char *name,
 			    sv_scale_t *scale,
 			    sv_obj_t **objectives,
 			    sv_dim_t **dimensions,	
 			    unsigned flags){
   
-  sv_panel_t *p = _sv_panel_new(s,number,name,objectives,dimensions,flags);
+  sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensions,flags);
   _sv_panel1d_t *p1;
 
   if(!p)return p;
@@ -1591,13 +1588,6 @@
     return errno;
   }
 
-  if(panel_2d->sushi != p->sushi){
-    fprintf(stderr,"Panel %d (\"%s\"): Cannot link panel number %d (\"%s\") from a differnet instance\n",
-	    p->number,p->name,panel_2d->number, panel_2d->name);
-    errno = -EINVAL;
-    return errno;
-  }
-
   _sv_panel1d_t *p1 = p->subtype->p1;
 
   if(flags && SV_PANEL_LINK_Y)

Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/panel-2d.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -142,7 +142,7 @@
 // used by the legend code. this lets us get away with having only a mapped display pane
 // call with lock
 static void _sv_panel2d_compute_point(sv_panel_t *p,sv_obj_t *o, double x, double y, compute_result *out){
-  double dim_vals[p->sushi->dimensions];
+  double dim_vals[_sv_dimensions];
   int i,j;
   int pflag=0;
   int eflag=0;
@@ -151,8 +151,8 @@
   int x_d = p->private->x_d->number;
   int y_d = p->private->y_d->number;
 
-  for(i=0;i<p->sushi->dimensions;i++){
-    sv_dim_t *dim = p->sushi->dimension_list[i];
+  for(i=0;i<_sv_dimensions;i++){
+    sv_dim_t *dim = _sv_dimension_list[i];
     dim_vals[i]=dim->val;
   }
 
@@ -164,8 +164,8 @@
   *out = (compute_result){NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN};
 
   // compute
-  for(i=0;i<p->sushi->functions;i++){
-    sv_func_t *f = p->sushi->function_list[i];
+  for(i=0;i<_sv_functions;i++){
+    sv_func_t *f = _sv_function_list[i];
     int compflag = 0;
     double fout[f->outputs];
     double val;
@@ -935,8 +935,8 @@
   _sv_panel2d_t *p2 = p->subtype->p2;
   int onum = optr - p->objective_list;
 
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   _sv_mapping_set_func(&p2->mappings[onum],gtk_combo_box_get_active(GTK_COMBO_BOX(w)));
   
@@ -949,7 +949,7 @@
   //redraw the plot
   _sv_panel2d_mark_map_plane(p,onum,1,0,0);
   _sv_panel_dirty_map(p);
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panel2d_map_callback(void *in,int buttonstate){
@@ -960,8 +960,8 @@
   int onum = optr - p->objective_list;
 
   if(buttonstate == 0){
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
   }
 
   // recache alpha del */
@@ -975,7 +975,7 @@
     _sv_panel_dirty_map(p);
   }
   if(buttonstate == 2)
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
 }
 
 static void _sv_panel2d_update_xysel(sv_panel_t *p){
@@ -1262,8 +1262,8 @@
 
   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))){
 
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
 
     _sv_plot_unset_box(PLOT(p->private->graph));
     _sv_panel2d_update_xysel(p);
@@ -1272,7 +1272,7 @@
     _sv_panel2d_mark_recompute(p);
     _sv_panel2d_update_crosshairs(p);
 
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
   }
 }
 
@@ -1281,8 +1281,8 @@
   double y=PLOT(p->private->graph)->sely;
   int i;
   
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   //plot_snap_crosshairs(PLOT(p->private->graph));
 
@@ -1307,7 +1307,7 @@
   _sv_plot_set_crosshairs(PLOT(p->private->graph),x,y);
 
   _sv_panel_dirty_legend(p);
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panel2d_box_callback(void *in, int state){
@@ -1317,13 +1317,13 @@
   
   switch(state){
   case 0: // box set
-    _sv_undo_push(p->sushi);
+    _sv_undo_push();
     _sv_plot_box_vals(plot,p2->oldbox);
     p->private->oldbox_active = plot->box_active;
     break;
   case 1: // box activate
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
 
     _sv_panel2d_crosshairs_callback(p);
 
@@ -1332,7 +1332,7 @@
     _sv_dim_set_value(p2->y_scale,0,p2->oldbox[2]);
     _sv_dim_set_value(p2->y_scale,2,p2->oldbox[3]);
     p->private->oldbox_active = 0;
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
     break;
   }
   _sv_panel_update_menus(p);
@@ -1348,7 +1348,7 @@
     /* allocate output temporary buffer */
     for(i=0;i<p2->used_functions;i++){
       int fnum = p2->used_function_list[i]->number;
-      sv_func_t *f = p->sushi->function_list[fnum];
+      sv_func_t *f = _sv_function_list[fnum];
       count += f->outputs;
     }
     c->fout = calloc(count, sizeof(*c->fout));
@@ -1540,7 +1540,7 @@
 
   /* render using local dimension array; several threads will be
      computing objectives */
-  double dim_vals[p->sushi->dimensions];
+  double dim_vals[_sv_dimensions];
   int y = _v_swizzle(p->private->plot_progress_count-1,dh);
   p->private->plot_progress_count++;
 
@@ -1551,8 +1551,8 @@
   y_max = _sv_scalespace_value(&p2->y_i,dh);
 
   // Initialize local dimension value array
-  for(i=0;i<p->sushi->dimensions;i++){
-    sv_dim_t *dim = p->sushi->dimension_list[i];
+  for(i=0;i<_sv_dimensions;i++){
+    sv_dim_t *dim = _sv_dimension_list[i];
     dim_vals[i]=dim->val;
   }
 
@@ -1664,7 +1664,7 @@
   _sv_panel2d_t *p2 = p->subtype->p2;
   int i;
 
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_suspend();
 
   p->private->toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   g_signal_connect_swapped (G_OBJECT (p->private->toplevel), "delete-event",
@@ -1830,7 +1830,7 @@
 			       // insensitive buttons when it realized
 			       // them.  This call will restore them.
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static int _sv_panel2d_save(sv_panel_t *p, xmlNodePtr pn){  
@@ -1928,19 +1928,18 @@
   return warn;
 }
 
-sv_panel_t *sv_panel_new_2d(sv_instance_t *s,
-			    int number,
+sv_panel_t *sv_panel_new_2d(int number,
 			    char *name, 
 			    sv_obj_t **objectives,
 			    sv_dim_t **dimensions,
 			    unsigned flags){
   
   int i,j;
-  sv_panel_t *p = _sv_panel_new(s,number,name,objectives,dimensions,flags);
+  sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensions,flags);
   if(!p)return NULL;
 
   _sv_panel2d_t *p2 = calloc(1, sizeof(*p2));
-  int fout_offsets[s->functions];
+  int fout_offsets[_sv_functions];
   
   p->subtype = 
     calloc(1, sizeof(*p->subtype)); /* the union is alloced not
@@ -1976,7 +1975,7 @@
   /* determine which functions are actually needed; if it's referenced
      by an objective, it's used.  Precache them in dense form. */
   {
-    int fn = p->sushi->functions;
+    int fn = _sv_functions;
     int used[fn],count=0,offcount=0;
     memset(used,0,sizeof(used));
     memset(fout_offsets,-1,sizeof(fout_offsets));
@@ -1989,7 +1988,7 @@
 
     for(i=0;i<fn;i++)
       if(used[i]){
-	sv_func_t *f = p->sushi->function_list[i];
+	sv_func_t *f = _sv_function_list[i];
 	fout_offsets[i] = offcount;
 	offcount += f->outputs;
 	count++;
@@ -2000,7 +1999,7 @@
 
     for(count=0,i=0;i<fn;i++)
      if(used[i]){
-        p2->used_function_list[count]=p->sushi->function_list[i];
+        p2->used_function_list[count]=_sv_function_list[i];
 	count++;
       }
   }

Modified: trunk/sushivision/panel-xy.c
===================================================================
--- trunk/sushivision/panel-xy.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/panel-xy.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -488,8 +488,8 @@
   int onum = optr - p->objective_list;
   _sv_plot_t *plot = PLOT(p->private->graph);
 
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   // update colormap
   // oh, the wasteful
@@ -505,7 +505,7 @@
   _sv_panel_dirty_map(p);
   _sv_panel_dirty_legend(p);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panelxy_alpha_callback(void * in, int buttonstate){
@@ -513,15 +513,15 @@
   sv_panel_t *p = optr->p;
 
   if(buttonstate == 0){
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
   }
 
   _sv_panel_dirty_map(p);
   _sv_panel_dirty_legend(p);
 
   if(buttonstate == 2)
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
 }
 
 static void _sv_panelxy_linetype_callback(GtkWidget *w,gpointer in){
@@ -530,15 +530,15 @@
   _sv_panelxy_t *xy = p->subtype->xy;
   int onum = optr - p->objective_list;
   
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   // update colormap
   int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
   xy->linetype[onum] = line_name[pos]->value;
 
   _sv_panel_dirty_map(p);
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panelxy_pointtype_callback(GtkWidget *w,gpointer in){
@@ -547,15 +547,15 @@
   _sv_panelxy_t *xy = p->subtype->xy;
   int onum = optr - p->objective_list;
   
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   // update colormap
   int pos = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
   xy->pointtype[onum] = point_name[pos]->value;
 
   _sv_panel_dirty_map(p);
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void _sv_panelxy_map_callback(void *in,int buttonstate){
@@ -564,8 +564,8 @@
   _sv_plot_t *plot = PLOT(p->private->graph);
   
   if(buttonstate == 0){
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
   }
 
   // has new bracketing changed the plot range scale?
@@ -602,7 +602,7 @@
   }
 
   if(buttonstate == 2)
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
 }
 
 static void _sv_panelxy_update_xsel(sv_panel_t *p){
@@ -643,7 +643,7 @@
 				     double **y_vec,
 				     _sv_bythread_cache_xy_t *c){
 
-  int i,j,fn=p->sushi->functions;
+  int i,j,fn=_sv_functions;
   int w = sxi.pixels;
 
 
@@ -697,6 +697,35 @@
   _sv_panel_dirty_plot(p);
 }
 
+// subtype entry point for plot remaps; lock held
+int _sv_panelxy_map_redraw(sv_panel_t *p, _sv_bythread_cache_t *c){
+  if(p->private->map_progress_count)return 0;
+  p->private->map_progress_count++;
+
+  // render to a temp surface so that we can release the lock occasionally
+  _sv_plot_t *plot = PLOT(p->private->graph);
+  cairo_surface_t *back = plot->back;
+  cairo_surface_t *cs = cairo_surface_create_similar(back,CAIRO_CONTENT_COLOR,
+						     cairo_image_surface_get_width(back),
+						     cairo_image_surface_get_height(back));
+  cairo_t *ct = cairo_create(cs);
+  
+  if(_sv_panelxy_remap(p,ct) == -1){ // returns -1 on abort
+    cairo_destroy(ct);
+    cairo_surface_destroy(cs);
+  }else{
+    // else complete
+    cairo_surface_destroy(plot->back);
+    plot->back = cs;
+    cairo_destroy(ct);
+    
+    _sv_panel_clean_map(p);
+    _sv_plot_expose_request(plot);
+  }
+
+  return 1;
+}
+
 static void _sv_panelxy_recompute_callback(void *ptr){
   sv_panel_t *p = (sv_panel_t *)ptr;
   _sv_panelxy_t *xy = p->subtype->xy;
@@ -791,8 +820,8 @@
 
   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))){
 
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
 
     _sv_panelxy_update_xsel(p);
     
@@ -805,7 +834,7 @@
     xy->curr_zoom = xy->prev_zoom = xy->req_zoom = 0;
     _sv_panelxy_mark_recompute(p);
 
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
   }
 }
 
@@ -815,8 +844,8 @@
   double y=PLOT(p->private->graph)->sely;
   int i,j;
 
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
   
   // snap crosshairs to the closest plotted x/y point
   int besto=-1;
@@ -855,7 +884,7 @@
   PLOT(p->private->graph)->sely = y;
   
   p->private->oldbox_active = 0;
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
   _sv_panel_dirty_legend(p);
 
 }
@@ -867,13 +896,13 @@
   
   switch(state){
   case 0: // box set
-    _sv_undo_push(p->sushi);
+    _sv_undo_push();
     _sv_plot_box_vals(plot,xy->oldbox);
     p->private->oldbox_active = plot->box_active;
     break;
   case 1: // box activate
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
 
     _sv_panelxy_crosshair_callback(p);
 
@@ -883,7 +912,7 @@
     _sv_slider_set_value(xy->y_slider,1,xy->oldbox[3]);
 
     p->private->oldbox_active = 0;
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
     break;
   }
   _sv_panel_update_menus(p);
@@ -896,53 +925,24 @@
     int i,j;
     
     /* determine which functions are actually needed */
-    c->call = calloc(p->sushi->functions,sizeof(*c->call));
-    c->fout = calloc(p->sushi->functions,sizeof(*c->fout));
+    c->call = calloc(_sv_functions,sizeof(*c->call));
+    c->fout = calloc(_sv_functions,sizeof(*c->fout));
     for(i=0;i<p->objectives;i++){
       sv_obj_t *o = p->objective_list[i].o;
       for(j=0;j<o->outputs;j++)
 	c->call[o->function_map[j]]=
-	  p->sushi->function_list[o->function_map[j]]->callback;
+	  _sv_function_list[o->function_map[j]]->callback;
     }
 
-    for(i=0;i<p->sushi->functions;i++){
+    for(i=0;i<_sv_functions;i++){
       if(c->call[i]){
-	c->fout[i] = malloc(p->sushi->function_list[i]->outputs *
+	c->fout[i] = malloc(_sv_function_list[i]->outputs *
 			    sizeof(**c->fout));
       }
     }
   }
 }
 
-// subtype entry point for plot remaps; lock held
-int _sv_panelxy_map_redraw(sv_panel_t *p, _sv_bythread_cache_t *c){
-  if(p->private->map_progress_count)return 0;
-  p->private->map_progress_count++;
-
-  // render to a temp surface so that we can release the lock occasionally
-  _sv_plot_t *plot = PLOT(p->private->graph);
-  cairo_surface_t *back = plot->back;
-  cairo_surface_t *cs = cairo_surface_create_similar(back,CAIRO_CONTENT_COLOR,
-						     cairo_image_surface_get_width(back),
-						     cairo_image_surface_get_height(back));
-  cairo_t *ct = cairo_create(cs);
-  
-  if(_sv_panelxy_remap(p,ct) == -1){ // returns -1 on abort
-    cairo_destroy(ct);
-    cairo_surface_destroy(cs);
-  }else{
-    // else complete
-    cairo_surface_destroy(plot->back);
-    plot->back = cs;
-    cairo_destroy(ct);
-    
-    _sv_panel_clean_map(p);
-    _sv_plot_expose_request(plot);
-  }
-
-  return 1;
-}
-
 // subtype entry point for legend redraws; lock held
 int _sv_panelxy_legend_redraw(sv_panel_t *p){
   _sv_plot_t *plot = PLOT(p->private->graph);
@@ -1090,7 +1090,7 @@
   
   /* render using local dimension array; several threads will be
      computing objectives */
-  double dim_vals[p->sushi->dimensions];
+  double dim_vals[_sv_dimensions];
 
   /* get iterator bounds, use iterator scale */
   x_d = p->private->x_d->number;
@@ -1114,8 +1114,8 @@
 		      &newv,new_x_vec,new_y_vec,prefilled, p->objectives);
 
   // Initialize local dimension value array
-  for(i=0;i<p->sushi->dimensions;i++){
-    sv_dim_t *dim = p->sushi->dimension_list[i];
+  for(i=0;i<_sv_dimensions;i++){
+    sv_dim_t *dim = _sv_dimension_list[i];
     dim_vals[i]=dim->val;
   }
 
@@ -1256,7 +1256,7 @@
   _sv_panelxy_t *xy = p->subtype->xy;
   char buffer[160];
   int i;
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_suspend();
 
   p->private->toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   g_signal_connect_swapped (G_OBJECT (p->private->toplevel), "delete-event",
@@ -1480,7 +1480,7 @@
   gtk_widget_realize(GTK_WIDGET(p->private->spinner));
   gtk_widget_show_all(p->private->toplevel);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 
@@ -1604,8 +1604,7 @@
   return warn;
 }
 
-sv_panel_t *sv_panel_new_xy(sv_instance_t *s,
-			    int number,
+sv_panel_t *sv_panel_new_xy(int number,
 			    char *name,
 			    sv_scale_t *xscale,
 			    sv_scale_t *yscale,
@@ -1613,7 +1612,7 @@
 			    sv_dim_t **dimensions,	
 			    unsigned flags){
 
-  sv_panel_t *p = _sv_panel_new(s,number,name,objectives,dimensions,flags);
+  sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensions,flags);
   _sv_panelxy_t *xy;
 
   if(!p)return NULL;

Modified: trunk/sushivision/panel.c
===================================================================
--- trunk/sushivision/panel.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/panel.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -166,7 +166,7 @@
 }
 
 static void wrap_exit(sv_panel_t *dummy, GtkWidget *dummyw){
-  _sv_clean_exit(SIGINT);
+  _sv_clean_exit();
 }
 
 // precipitated actions perform undo push
@@ -175,34 +175,34 @@
 }
 
 static void wrap_escape(sv_panel_t *p, GtkWidget *dummy){
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   _sv_plot_set_crossactive(PLOT(p->private->graph),0);
   _sv_panel_dirty_legend(p);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void wrap_legend(sv_panel_t *p, GtkWidget *dummy){
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   _sv_plot_toggle_legend(PLOT(p->private->graph));
   _sv_panel_dirty_legend(p);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void set_grid(sv_panel_t *p, int mode){
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   _sv_plot_set_grid(PLOT(p->private->graph),mode);
   _sv_panel_update_menus(p);
   refg_if_running(p);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void wrap_grid(sv_panel_t *p, GtkWidget *w){
@@ -215,8 +215,8 @@
   
   sv_panel_internal_t *pi = p->private;
   
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   pi->bg_type = bg;
   
@@ -225,7 +225,7 @@
   redraw_if_running(p);
   _sv_panel_update_menus(p);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
   return 0;
 }
 
@@ -247,14 +247,14 @@
 }
 
 static void set_text(sv_panel_t *p, int mode){
-  _sv_undo_push(p->sushi);
-  _sv_undo_suspend(p->sushi);
+  _sv_undo_push();
+  _sv_undo_suspend();
 
   _sv_plot_set_bg_invert(PLOT(p->private->graph),mode);
   _sv_panel_update_menus(p);
   refg_if_running(p);
 
-  _sv_undo_resume(p->sushi);
+  _sv_undo_resume();
 }
 
 static void wrap_text(sv_panel_t *p, GtkWidget *w){
@@ -283,15 +283,15 @@
   if(n != p->private->oversample_n ||
      d != p->private->oversample_d){
 
-    _sv_undo_push(p->sushi);
-    _sv_undo_suspend(p->sushi);
+    _sv_undo_push();
+    _sv_undo_suspend();
     
     p->private->oversample_n = n;
     p->private->oversample_d = d;
     _sv_panel_update_menus(p);
     recompute_if_running(p);
 
-    _sv_undo_resume(p->sushi);
+    _sv_undo_resume();
   }
 }
 
@@ -404,10 +404,10 @@
 }
 
 static void wrap_undo_down(sv_panel_t *p, GtkWidget *dummy){
-  _sv_undo_down(p->sushi);
+  _sv_undo_down();
 }
 static void wrap_undo_up(sv_panel_t *p, GtkWidget *dummy){
-  _sv_undo_up(p->sushi);
+  _sv_undo_up();
 }
 
 static void wrap_save(sv_panel_t *p, GtkWidget *dummy){
@@ -481,17 +481,17 @@
 void _sv_panel_update_menus(sv_panel_t *p){
 
   // is undo active?
-  if(!p->sushi->private->undo_stack ||
-     !p->sushi->private->undo_level){
+  if(!_sv_undo_stack ||
+     !_sv_undo_level){
     gtk_widget_set_sensitive(_gtk_menu_get_item(GTK_MENU(p->private->popmenu),4),FALSE);
   }else{
     gtk_widget_set_sensitive(_gtk_menu_get_item(GTK_MENU(p->private->popmenu),4),TRUE);
   }
 
   // is redo active?
-  if(!p->sushi->private->undo_stack ||
-     !p->sushi->private->undo_stack[p->sushi->private->undo_level] ||
-     !p->sushi->private->undo_stack[p->sushi->private->undo_level+1]){
+  if(!_sv_undo_stack ||
+     !_sv_undo_stack[_sv_undo_level] ||
+     !_sv_undo_stack[_sv_undo_level+1]){
     gtk_widget_set_sensitive(_gtk_menu_get_item(GTK_MENU(p->private->popmenu),5),FALSE);
   }else{
     gtk_widget_set_sensitive(_gtk_menu_get_item(GTK_MENU(p->private->popmenu),5),TRUE);
@@ -620,18 +620,18 @@
   case GDK_Q:
   case GDK_q:
     // quit
-    _sv_clean_exit(SIGINT);
+    _sv_clean_exit();
     return TRUE;
     
   case GDK_BackSpace:
     // undo 
-    _sv_undo_down(p->sushi);
+    _sv_undo_down();
     return TRUE;
     
   case GDK_r:
   case GDK_space:
     // redo/forward
-    _sv_undo_up(p->sushi);
+    _sv_undo_up();
     return TRUE;
 
   case GDK_p:
@@ -755,22 +755,21 @@
   gdk_threads_leave ();
 }
 
-int sv_panel_oversample(sv_instance_t *s,
-			    int number,
-			    int numer,
-			    int denom){
+int sv_panel_oversample(int number,
+			int numer,
+			int denom){
   
   if(number<0){
     fprintf(stderr,"sv_panel_background: Panel number must be >= 0\n");
     return -EINVAL;
   }
 
-  if(number>s->panels || !s->panel_list[number]){
+  if(number>_sv_panels || !_sv_panel_list[number]){
     fprintf(stderr,"sv_panel_background: Panel number %d does not exist\n",number);
     return -EINVAL;
   }
   
-  sv_panel_t *p = s->panel_list[number];
+  sv_panel_t *p = _sv_panel_list[number];
   sv_panel_internal_t *pi = p->private;
 
   if(denom == 0){
@@ -784,32 +783,29 @@
   return 0;
 }
 
-int sv_panel_background(sv_instance_t *s,
-			    int number,
-			    enum sv_background bg){
+int sv_panel_background(int number,
+			enum sv_background bg){
 
   if(number<0){
     fprintf(stderr,"sv_panel_background: Panel number must be >= 0\n");
     return -EINVAL;
   }
 
-  if(number>s->panels || !s->panel_list[number]){
+  if(number>_sv_panels || !_sv_panel_list[number]){
     fprintf(stderr,"sv_panel_background: Panel number %d does not exist\n",number);
     return -EINVAL;
   }
   
-  sv_panel_t *p = s->panel_list[number];
+  sv_panel_t *p = _sv_panel_list[number];
   return set_background(p,bg);
 }
 
-sv_panel_t * _sv_panel_new(sv_instance_t *in,
-			   int number,
+sv_panel_t * _sv_panel_new(int number,
 			   char *name, 
 			   sv_obj_t **objectives,
 			   sv_dim_t **dimensions,	
 			   unsigned flags){
 
-  sv_instance_t *s = (sv_instance_t *)in; // unwrap 
   sv_panel_t *p;
   int i;
 
@@ -819,28 +815,27 @@
     return NULL;
   }
 
-  if(number<s->panels){
-    if(s->panel_list[number]!=NULL){
+  if(number<_sv_panels){
+    if(_sv_panel_list[number]!=NULL){
       fprintf(stderr,"Panel number %d already exists\n",number);
       errno = -EINVAL;
       return NULL;
     }
   }else{
-    if(s->panels == 0){
-      s->panel_list = calloc (number+1,sizeof(*s->panel_list));
+    if(_sv_panels == 0){
+      _sv_panel_list = calloc (number+1,sizeof(*_sv_panel_list));
     }else{
-      s->panel_list = realloc (s->panel_list,(number+1) * sizeof(*s->panel_list));
-      memset(s->panel_list + s->panels, 0, sizeof(*s->panel_list)*(number+1 - s->panels));
+      _sv_panel_list = realloc (_sv_panel_list,(number+1) * sizeof(*_sv_panel_list));
+      memset(_sv_panel_list + _sv_panels, 0, sizeof(*_sv_panel_list)*(number+1 - _sv_panels));
     }
-    s->panels = number+1; 
+    _sv_panels = number+1; 
   }
 
-  p = s->panel_list[number] = calloc(1, sizeof(**s->panel_list));
+  p = _sv_panel_list[number] = calloc(1, sizeof(**_sv_panel_list));
 
   p->number = number;
   p->name = strdup(name);
   p->flags = flags;
-  p->sushi = s;
   p->private = calloc(1, sizeof(*p->private));
   p->private->spinner = _sv_spinner_new();
   p->private->def_oversample_n = p->private->oversample_n = 1;
@@ -851,13 +846,6 @@
   p->objectives = i;
   p->objective_list = malloc(i*sizeof(*p->objective_list));
   for(i=0;i<p->objectives;i++){
-    if(objectives[i]->sushi != s){
-      fprintf(stderr,"Panel %d (\"%s\"): Objective number %d (\"%s\") belongs to a differnet instance\n",
-	      number,p->name,objectives[i]->number,objectives[i]->name);
-      errno = -EINVAL;
-      return NULL;
-    }
-
     p->objective_list[i].o = (sv_obj_t *)objectives[i];
     p->objective_list[i].p = p;
   }
@@ -867,13 +855,6 @@
   p->dimensions = i;
   p->dimension_list = malloc(i*sizeof(*p->dimension_list));
   for(i=0;i<p->dimensions;i++){
-    if(dimensions[i]->sushi != s){
-      fprintf(stderr,"Panel %d (\"%s\"): Dimension number %d (\"%s\") belongs to a differnet instance\n",
-	      number,p->name,dimensions[i]->number,dimensions[i]->name);
-      errno = -EINVAL;
-      return NULL;
-    }
-
     if(!dimensions[i]->scale){
       fprintf(stderr,"Panel %d (\"%s\"): Dimension number %d (\"%s\") has a NULL scale\n",
 	      number,p->name,dimensions[i]->number,dimensions[i]->name);

Modified: trunk/sushivision/sushivision.h
===================================================================
--- trunk/sushivision/sushivision.h	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/sushivision.h	2007-08-15 19:44:39 UTC (rev 13549)
@@ -27,7 +27,6 @@
 typedef struct sv_dim   sv_dim_t;
 typedef struct sv_obj   sv_obj_t;
 typedef struct sv_func  sv_func_t;
-typedef struct _sv_instance_internal sv_instance_internal_t;
 typedef struct _sv_scale_internal sv_scale_internal_t;
 typedef struct _sv_dim_internal sv_dim_internal_t;
 typedef union  _sv_dim_subtype sv_dim_subtype_t;
@@ -43,30 +42,11 @@
 int sv_save(char *filename);
 int sv_load(char *filename);
 
-/* toplevel instances ********************************************/
+/* toplevel ******************************************************/
+extern int sv_init();
+extern int sv_go();
+extern int sv_join();
 
-typedef struct sv_instance {
-  int number;
-  char *name;
-
-  int functions;
-  sv_func_t **function_list;
-
-  int dimensions;
-  sv_dim_t **dimension_list;
-
-  int objectives;
-  sv_obj_t **objective_list;
-
-  int panels;
-  sv_panel_t **panel_list;
-
-  sv_instance_internal_t *private;
-} sv_instance_t;
-
-sv_instance_t           *sv_new (int number, 
-				 char *name);
-
 /* scales ********************************************************/
 
 struct sv_scale{
@@ -112,13 +92,11 @@
   unsigned flags;
   
   int (*callback)(sv_dim_t *);
-  sv_instance_t *sushi;
   sv_dim_subtype_t *subtype;
   sv_dim_internal_t *private;
 };
 
-sv_dim_t            *sv_dim_new (sv_instance_t *s, 
-				 int number, 
+sv_dim_t            *sv_dim_new (int number, 
 				 char *name,
 				 unsigned flags);
 
@@ -158,13 +136,11 @@
   void (*callback)(double *,double *);
   unsigned flags;
 
-  sv_instance_t *sushi;
   sv_func_subtype_t *subtype;
   sv_func_internal_t *private;
 };
 
-sv_func_t          *sv_func_new (sv_instance_t *s, 
-				 int number,
+sv_func_t          *sv_func_new (int number,
 				 int out_vals,
 				 void (*function)(double *,double *),
 				 unsigned flags);
@@ -185,21 +161,18 @@
   char *output_types;
   unsigned flags;
 
-  sv_instance_t *sushi;
   sv_obj_subtype_t *subtype;
   sv_obj_internal_t *private;
 };
 
-sv_obj_t            *sv_obj_new (sv_instance_t *s,
-				 int number,
+sv_obj_t            *sv_obj_new (int number,
 				 char *name,
 				 sv_func_t **function_map,
 				 int *function_output_map,
 				 char *output_type_map,
 				 unsigned flags);
 
-sv_obj_t   *sv_obj_new_defaults (sv_instance_t *s,
-				 int number,
+sv_obj_t   *sv_obj_new_defaults (int number,
 				 char *name,
 				 sv_func_t *function,
 				 unsigned flags);
@@ -246,23 +219,20 @@
   int objectives;
   sv_obj_list_t *objective_list;
 
-  sv_instance_t *sushi;
   unsigned flags;
 
   sv_panel_subtype_t *subtype;
   sv_panel_internal_t *private;
 };
 
-sv_panel_t     *sv_panel_new_1d (sv_instance_t *s,
-				 int number,
+sv_panel_t     *sv_panel_new_1d (int number,
 				 char *name,
 				 sv_scale_t *y_scale,
 				 sv_obj_t **objectives,
 				 sv_dim_t **dimensions,	
 				 unsigned flags);
 
-sv_panel_t     *sv_panel_new_xy (sv_instance_t *s,
-				 int number,
+sv_panel_t     *sv_panel_new_xy (int number,
 				 char *name,
 				 sv_scale_t *x_scale,
 				 sv_scale_t *y_scale,
@@ -270,8 +240,7 @@
 				 sv_dim_t **dimensions,	
 				 unsigned flags);
 
-sv_panel_t     *sv_panel_new_2d (sv_instance_t *s,
-				 int number,
+sv_panel_t     *sv_panel_new_2d (int number,
 				 char *name, 
 				 sv_obj_t **objectives,
 				 sv_dim_t **dimensions,

Modified: trunk/sushivision/undo.c
===================================================================
--- trunk/sushivision/undo.c	2007-08-15 09:06:13 UTC (rev 13548)
+++ trunk/sushivision/undo.c	2007-08-15 19:44:39 UTC (rev 13549)
@@ -28,44 +28,44 @@
 
 /* encapsulates some amount of common undo/redo infrastructure */
 
-static void update_all_menus(sv_instance_t *s){
+static void update_all_menus(){
   int i;
-  if(s->panel_list){
-    for(i=0;i<s->panels;i++)
-      if(s->panel_list[i])
-	_sv_panel_update_menus(s->panel_list[i]);
+  if(_sv_panel_list){
+    for(i=0;i<_sv_panels;i++)
+      if(_sv_panel_list[i])
+	_sv_panel_update_menus(_sv_panel_list[i]);
   }
 }
 
-void _sv_undo_suspend(sv_instance_t *s){
-  s->private->undo_suspend++;
+void _sv_undo_suspend(){
+  _sv_undo_suspended++;
 }
 
-void _sv_undo_resume(sv_instance_t *s){
-  s->private->undo_suspend--;
-  if(s->private->undo_suspend<0){
+void _sv_undo_resume(){
+  _sv_undo_suspended--;
+  if(_sv_undo_suspended<0){
     fprintf(stderr,"Internal error: undo suspend refcount count < 0\n");
-    s->private->undo_suspend=0;
+    _sv_undo_suspended=0;
   }
 }
 
-void _sv_undo_pop(sv_instance_t *s){
-  _sv_instance_undo_t *u;
+void _sv_undo_pop(){
+  _sv_undo_t *u;
   int i,j;
-  if(!s->private->undo_stack)
-    s->private->undo_stack = calloc(2,sizeof(*s->private->undo_stack));
+  if(!_sv_undo_stack)
+    _sv_undo_stack = calloc(2,sizeof(*_sv_undo_stack));
   
-  if(s->private->undo_stack[s->private->undo_level]){
-    i=s->private->undo_level;
-    while(s->private->undo_stack[i]){
-      u = s->private->undo_stack[i];
+  if(_sv_undo_stack[_sv_undo_level]){
+    i=_sv_undo_level;
+    while(_sv_undo_stack[i]){
+      u = _sv_undo_stack[i];
       
       if(u->dim_vals[0]) free(u->dim_vals[0]);
       if(u->dim_vals[1]) free(u->dim_vals[1]);
       if(u->dim_vals[2]) free(u->dim_vals[2]);
       
       if(u->panels){
-	for(j=0;j<s->panels;j++){
+	for(j=0;j<_sv_panels;j++){
 	  _sv_panel_undo_t *pu = u->panels+j;
 	  if(pu->mappings) free(pu->mappings);
 	  if(pu->scale_vals[0]) free(pu->scale_vals[0]);
@@ -74,31 +74,31 @@
 	}
 	free(u->panels);
       }
-      free(s->private->undo_stack[i]);
-      s->private->undo_stack[i]= NULL;
+      free(_sv_undo_stack[i]);
+      _sv_undo_stack[i]= NULL;
       i++;
     }
   }
   
   // alloc new undos
-  u = s->private->undo_stack[s->private->undo_level] = calloc(1,sizeof(*u));
-  u->panels = calloc(s->panels,sizeof(*u->panels));
-  u->dim_vals[0] = calloc(s->dimensions,sizeof(**u->dim_vals));
-  u->dim_vals[1] = calloc(s->dimensions,sizeof(**u->dim_vals));
-  u->dim_vals[2] = calloc(s->dimensions,sizeof(**u->dim_vals));
+  u = _sv_undo_stack[_sv_undo_level] = calloc(1,sizeof(*u));
+  u->panels = calloc(_sv_panels,sizeof(*u->panels));
+  u->dim_vals[0] = calloc(_sv_dimensions,sizeof(**u->dim_vals));
+  u->dim_vals[1] = calloc(_sv_dimensions,sizeof(**u->dim_vals));
+  u->dim_vals[2] = calloc(_sv_dimensions,sizeof(**u->dim_vals));
 }
 
-void _sv_undo_log(sv_instance_t *s){
-  _sv_instance_undo_t *u;
+void _sv_undo_log(){
+  _sv_undo_t *u;
   int i,j;
 
   // log into a fresh entry; pop this level and all above it 
-  _sv_undo_pop(s);
-  u = s->private->undo_stack[s->private->undo_level];
+  _sv_undo_pop();
+  u = _sv_undo_stack[_sv_undo_level];
   
   // save dim values
-  for(i=0;i<s->dimensions;i++){
-    sv_dim_t *d = s->dimension_list[i];
+  for(i=0;i<_sv_dimensions;i++){
+    sv_dim_t *d = _sv_dimension_list[i];
     if(d){
       u->dim_vals[0][i] = d->bracket[0];
       u->dim_vals[1][i] = d->val;
@@ -107,19 +107,19 @@
   }
 
   // pass off panel population to panels
-  for(j=0;j<s->panels;j++)
-    if(s->panel_list[j])
-      _sv_panel_undo_log(s->panel_list[j], u->panels+j);
+  for(j=0;j<_sv_panels;j++)
+    if(_sv_panel_list[j])
+      _sv_panel_undo_log(_sv_panel_list[j], u->panels+j);
 }
 
-void _sv_undo_restore(sv_instance_t *s){
+void _sv_undo_restore(){
   int i;
-  _sv_instance_undo_t *u = s->private->undo_stack[s->private->undo_level];
+  _sv_undo_t *u = _sv_undo_stack[_sv_undo_level];
 
   // dims 
   // need to happen first as setting dims can have side effect (like activating crosshairs)
-  for(i=0;i<s->dimensions;i++){
-    sv_dim_t *d = s->dimension_list[i];
+  for(i=0;i<_sv_dimensions;i++){
+    sv_dim_t *d = _sv_dimension_list[i];
     if(d){
       sv_dim_set_value(d, 0, u->dim_vals[0][i]);
       sv_dim_set_value(d, 1, u->dim_vals[1][i]);
@@ -128,53 +128,53 @@
   }
 
   // panels
-  for(i=0;i<s->panels;i++){
-    sv_panel_t *p = s->panel_list[i];
+  for(i=0;i<_sv_panels;i++){
+    sv_panel_t *p = _sv_panel_list[i];
     if(p)
-      _sv_panel_undo_restore(s->panel_list[i],u->panels+i);
+      _sv_panel_undo_restore(_sv_panel_list[i],u->panels+i);
   }
 
 }
 
-void _sv_undo_push(sv_instance_t *s){
-  if(s->private->undo_suspend)return;
+void _sv_undo_push(){
+  if(_sv_undo_suspended)return;
 
-  _sv_undo_log(s);
+  _sv_undo_log();
 
   // realloc stack 
-  s->private->undo_stack = 
-    realloc(s->private->undo_stack,
-	    (s->private->undo_level+3)*sizeof(*s->private->undo_stack));
-  s->private->undo_level++;
-  s->private->undo_stack[s->private->undo_level]=NULL;
-  s->private->undo_stack[s->private->undo_level+1]=NULL;
-  update_all_menus(s);
+  _sv_undo_stack = 
+    realloc(_sv_undo_stack,
+	    (_sv_undo_level+3)*sizeof(*_sv_undo_stack));
+  _sv_undo_level++;
+  _sv_undo_stack[_sv_undo_level]=NULL;
+  _sv_undo_stack[_sv_undo_level+1]=NULL;
+  update_all_menus();
 }
 
-void _sv_undo_up(sv_instance_t *s){
-  if(!s->private->undo_stack)return;
-  if(!s->private->undo_stack[s->private->undo_level])return;
-  if(!s->private->undo_stack[s->private->undo_level+1])return;
+void _sv_undo_up(){
+  if(!_sv_undo_stack)return;
+  if(!_sv_undo_stack[_sv_undo_level])return;
+  if(!_sv_undo_stack[_sv_undo_level+1])return;
   
-  s->private->undo_level++;
-  _sv_undo_suspend(s);
-  _sv_undo_restore(s);
-  _sv_undo_resume(s);
-  update_all_menus(s);
+  _sv_undo_level++;
+  _sv_undo_suspend();
+  _sv_undo_restore();
+  _sv_undo_resume();
+  update_all_menus();
 }
 
-void _sv_undo_down(sv_instance_t *s){
-  if(!s->private->undo_stack)return;
-  if(!s->private->undo_level)return;
+void _sv_undo_down(){
+  if(!_sv_undo_stack)return;
+  if(!_sv_undo_level)return;
 
-  if(!s->private->undo_stack[s->private->undo_level+1])
-    _sv_undo_log(s);
-  s->private->undo_level--;
+  if(!_sv_undo_stack[_sv_undo_level+1])
+    _sv_undo_log();
+  _sv_undo_level--;
 
-  _sv_undo_suspend(s);
-  _sv_undo_restore(s);
-  _sv_undo_resume(s);
-  update_all_menus(s);
+  _sv_undo_suspend();
+  _sv_undo_restore();
+  _sv_undo_resume();
+  update_all_menus();
 }
 
 



More information about the commits mailing list