[xiph-cvs] cvs commit: postfish feedback.c feedback.h subpanel.c subpanel.h windowbutton.c windowbutton.h Makefile clippanel.c clippanel.h declip.c declip.h input.c input.h main.c mainpanel.c mainpanel.h multibar.c output.c output.h version.h

Monty xiphmont at xiph.org
Wed Dec 24 01:49:18 PST 2003



xiphmont    03/12/24 04:49:17

  Modified:    .        Makefile clippanel.c clippanel.h declip.c declip.h
                        input.c input.h main.c mainpanel.c mainpanel.h
                        multibar.c output.c output.h version.h
  Added:       .        feedback.c feedback.h subpanel.c subpanel.h
                        windowbutton.c windowbutton.h
  Log:
  Changes leading up to hooking in declipping filter; it's not there
  yet, but I don;t want to lose work.
  
  Monty

Revision  Changes    Path
1.10      +2 -2      postfish/Makefile

Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/postfish/Makefile,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Makefile	20 Dec 2003 11:24:17 -0000	1.9
+++ Makefile	24 Dec 2003 09:49:16 -0000	1.10
@@ -6,9 +6,9 @@
 LD=gcc
 
 SRC = main.c mainpanel.c multibar.c readout.c input.c output.c clippanel.c declip.c \
-	reconstruct.c smallft.c
+	reconstruct.c smallft.c windowbutton.c subpanel.c feedback.c
 OBJ = main.o mainpanel.o multibar.o readout.o input.o output.o clippanel.o declip.o \
-	reconstruct.o smallft.o
+	reconstruct.o smallft.o windowbutton.o subpanel.o feedback.o
 GCF = `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
 
 all:	

<p><p>1.4       +267 -53   postfish/clippanel.c

Index: clippanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/clippanel.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- clippanel.c	18 Oct 2003 11:12:43 -0000	1.3
+++ clippanel.c	24 Dec 2003 09:49:16 -0000	1.4
@@ -1,73 +1,287 @@
+/*
+ *
+ *  postfish
+ *    
+ *      Copyright (C) 2002-2004 Monty
+ *
+ *  Postfish is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  Postfish is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with Postfish; see the file COPYING.  If not, write to the
+ *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ */
 
 #include "postfish.h"
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 #include "readout.h"
+#include "multibar.h"
 #include "mainpanel.h"
+#include "subpanel.h"
+#include "declip.h"
+
+extern sig_atomic_t declip_active;
+extern int input_ch;
+extern int input_size;
+extern int input_rate;
+extern sig_atomic_t declip_converge;
+
+GtkWidget **feedback_bars;
+
+GtkWidget *samplereadout;
+GtkWidget *msreadout;
+GtkWidget *hzreadout;
+GtkWidget *creadout;
+GtkWidget *ireadout;
+
+typedef struct {
+  GtkWidget *slider;
+  GtkWidget *readout;
+  GtkWidget *readoutdB;
+  int number;
+} clipslider;
+
+static void trigger_slider_change(GtkWidget *w,gpointer in){
+  char buffer[80];
+  clipslider *p=(clipslider *)in;
+  gdouble linear=gtk_range_get_value(GTK_RANGE(p->slider));
+  
+  sprintf(buffer,"%1.2f",linear);
+  readout_set(READOUT(p->readout),buffer);
+
+  sprintf(buffer,"%3.0f dB",todB(linear));
+  readout_set(READOUT(p->readoutdB),buffer);
+
+  declip_settrigger(linear,p->number);
 
-void clippanel_show(postfish_clippanel *p){
-  gtk_widget_show_all(p->toplevel);
-}
-void clippanel_hide(postfish_clippanel *p){
-  gtk_widget_hide_all(p->toplevel);
 }
 
-static gboolean forward_events(GtkWidget *widget,
-			       GdkEvent *event,
-			       gpointer in){
-  postfish_clippanel *p=in;
-  GdkEvent copy=*(GdkEvent *)event;
-  copy.any.window=p->mainpanel->toplevel->window;
-  gtk_main_do_event((GdkEvent *)(&copy));
-  return TRUE;
-}
-
-void clippanel_create(postfish_clippanel *panel,postfish_mainpanel *mp){
-  GdkWindow *root=gdk_get_default_root_window();
-  GtkWidget *topframe=gtk_frame_new (NULL);
-  GtkWidget *toplabel=gtk_label_new (NULL);
-  GtkWidget *topvbox=gtk_vbox_new (0,0);
-
-  GtkWidget *indframe=gtk_frame_new (NULL);
-  GtkWidget *allframe=gtk_frame_new (NULL);
-  GtkWidget *indcheck=
-    gtk_radio_button_new_with_label (NULL, 
-				     "individual channels ");
-  GtkWidget *allcheck=
-    gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON(indcheck), 
-						 "all channels ");
-
-  gtk_label_set_markup(GTK_LABEL(toplabel),
-		       "<span weight=\"bold\" "
-		       "style=\"italic\">"
-		       " declipping filter </span>");
+static void blocksize_slider_change(GtkWidget *w,gpointer in){
+  char buffer[80];
+  int choice=rint(gtk_range_get_value(GTK_RANGE(w)));
+  int blocksize=64<<choice;
 
-  gtk_frame_set_label_widget(GTK_FRAME(indframe),indcheck);
-  gtk_frame_set_label_widget(GTK_FRAME(allframe),allcheck);
+  sprintf(buffer,"%5d   ",blocksize*3/4);
+  readout_set(READOUT(samplereadout),buffer);
 
-  gtk_box_pack_end(GTK_BOX(topvbox),allframe,0,1,4);
-  gtk_box_pack_end(GTK_BOX(topvbox),indframe,0,1,4);
+  sprintf(buffer,"%3.1f ms",blocksize*3000./4/input_rate);
+  readout_set(READOUT(msreadout),buffer);
 
-  panel->toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  panel->mainpanel=mp;
-    
-  gtk_container_add (GTK_CONTAINER (panel->toplevel), topframe);
-  gtk_container_add (GTK_CONTAINER (topframe), topvbox);
-  gtk_container_set_border_width (GTK_CONTAINER (topframe), 3);
-  gtk_container_set_border_width (GTK_CONTAINER (topvbox), 5);
-  gtk_frame_set_shadow_type(GTK_FRAME(topframe),GTK_SHADOW_ETCHED_IN);
-  gtk_frame_set_label_widget(GTK_FRAME(topframe),toplabel);
+  sprintf(buffer,"%5d Hz",(int)rint(input_rate*2./blocksize));
+  readout_set(READOUT(hzreadout),buffer);
+  
+  declip_setblock(blocksize);
+}
 
-    
+static void converge_slider_change(GtkWidget *w,gpointer in){
+  char buffer[80];
+  double percent=gtk_range_get_value(GTK_RANGE(w));
+  double sigfigs=percent*.05+2.8;
+  double epsilon=pow(1.,-sigfigs);
 
+  sprintf(buffer,"%3.1f",sigfigs);
+  readout_set(READOUT(creadout),buffer);
 
+  sprintf(buffer,"%3.0f%%",percent);
+  readout_set(READOUT(ireadout),buffer);
 
-  /* forward unhandled events to the main window */
-  g_signal_connect_after (G_OBJECT (panel->toplevel), "key-press-event",
-			  G_CALLBACK (forward_events), 
-			  panel);
+  declip_setconvergence(epsilon);
+  declip_setiterations(percent);
+}
 
+void clippanel_create(postfish_mainpanel *mp,
+		      GtkWidget *windowbutton,
+		      GtkWidget *activebutton){
+  int i;
+  char *labels[3]={"1%","10%","100%"};
+  double levels[4]={0.,1.,10.,100.};
+  int block_choices=0;
+
+  subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
+					  &declip_active,
+					  "_Declipping filter setup"," [d] ");
+  
+  GtkWidget *framebox=gtk_hbox_new(1,0);
+  GtkWidget *blocksize_box=gtk_vbox_new(0,0);
+  GtkWidget *blocksize_frame=gtk_frame_new (" filter width / approx. lowest response ");
+  GtkWidget *converge_frame=gtk_frame_new (" filter convergence ");
+  GtkWidget *converge_box=gtk_vbox_new(0,0);
+  GtkWidget *channel_table=gtk_table_new(input_ch,4,0);
+
+  gtk_widget_set_name(blocksize_box,"choiceframe");
+  gtk_widget_set_name(converge_box,"choiceframe");
+  gtk_container_set_border_width(GTK_CONTAINER(blocksize_box),2);
+  gtk_container_set_border_width(GTK_CONTAINER(converge_box),2);
+
+  feedback_bars=calloc(input_ch,sizeof(*feedback_bars));
+
+  /* set up blocksize config */
+  for(i=64;i<=input_size*2;i*=2)block_choices++;
+  {
+    GtkWidget *table=gtk_table_new(4,2,0);
+    GtkWidget *sliderbox=gtk_hbox_new(0,0);
+    GtkWidget *fastlabel=gtk_label_new("fastest");
+    GtkWidget *qualitylabel=gtk_label_new("best");
+    GtkWidget *slider=gtk_hscale_new_with_range(0,block_choices-1,1);
+    GtkWidget *samplelabel=gtk_label_new("window sample width");
+    GtkWidget *mslabel=gtk_label_new("window time width");
+    GtkWidget *hzlabel=gtk_label_new("approx. lowest response");
+    samplereadout=readout_new("00000   ");
+    msreadout=readout_new("00000 ms");
+    hzreadout=readout_new("00000 Hz");
+
+    gtk_scale_set_draw_value(GTK_SCALE(slider),FALSE);
+    gtk_misc_set_alignment(GTK_MISC(samplelabel),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(mslabel),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(hzlabel),1,.5);
+
+    gtk_box_pack_start(GTK_BOX(sliderbox),fastlabel,0,0,4);
+    gtk_box_pack_start(GTK_BOX(sliderbox),slider,1,1,0);
+    gtk_box_pack_start(GTK_BOX(sliderbox),qualitylabel,0,0,4);
+    gtk_table_attach(GTK_TABLE(table),sliderbox,0,2,0,1,GTK_FILL|GTK_EXPAND,0,0,8);
+    gtk_table_attach(GTK_TABLE(table),samplelabel,0,1,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+    gtk_table_attach(GTK_TABLE(table),mslabel,0,1,2,3,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+    gtk_table_attach(GTK_TABLE(table),hzlabel,0,1,3,4,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+
+    gtk_table_attach(GTK_TABLE(table),samplereadout,1,2,1,2,GTK_FILL,0,5,0);
+    gtk_table_attach(GTK_TABLE(table),msreadout,1,2,2,3,GTK_FILL,0,5,0);
+    gtk_table_attach(GTK_TABLE(table),hzreadout,1,2,3,4,GTK_FILL,0,5,0);
+    gtk_container_add(GTK_CONTAINER(blocksize_box),table);
+
+
+    g_signal_connect (G_OBJECT (slider), "key-press-event",
+		      G_CALLBACK (slider_keymodify), NULL);
+    g_signal_connect_after (G_OBJECT(slider), "value-changed",
+			    G_CALLBACK(blocksize_slider_change), 0);
+    gtk_range_set_value(GTK_RANGE(slider),3.);
+    
+  }
+  gtk_container_add(GTK_CONTAINER(blocksize_frame),blocksize_box);
 
-  gtk_window_set_resizable(GTK_WINDOW(panel->toplevel),0);
+  /* set up convergence config */
+  {
+    GtkWidget *table=gtk_table_new(3,2,0);
+    GtkWidget *sliderbox=gtk_hbox_new(0,0);
+    GtkWidget *fastlabel=gtk_label_new("fastest");
+    GtkWidget *qualitylabel=gtk_label_new("best");
+    GtkWidget *slider=gtk_hscale_new_with_range(10,200,1);
+    GtkWidget *clabel=gtk_label_new("significant figure target");
+    GtkWidget *ilabel=gtk_label_new("iteration bound");
+    creadout=readout_new("000 ");
+    ireadout=readout_new("000%");
+
+    gtk_scale_set_draw_value(GTK_SCALE(slider),FALSE);
+    gtk_misc_set_alignment(GTK_MISC(clabel),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(ilabel),1,.5);
+
+    gtk_box_pack_start(GTK_BOX(sliderbox),fastlabel,0,0,4);
+    gtk_box_pack_start(GTK_BOX(sliderbox),slider,1,1,0);
+    gtk_box_pack_start(GTK_BOX(sliderbox),qualitylabel,0,0,4);
+    gtk_table_attach(GTK_TABLE(table),sliderbox,0,2,0,1,GTK_FILL|GTK_EXPAND,0,0,8);
+    gtk_table_attach(GTK_TABLE(table),clabel,0,1,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+    gtk_table_attach(GTK_TABLE(table),ilabel,0,1,2,3,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+
+    gtk_table_attach(GTK_TABLE(table),creadout,1,2,1,2,GTK_FILL,0,5,0);
+    gtk_table_attach(GTK_TABLE(table),ireadout,1,2,2,3,GTK_FILL,0,5,0);
+    gtk_container_add(GTK_CONTAINER(converge_box),table);
+
+    g_signal_connect (G_OBJECT (slider), "key-press-event",
+		      G_CALLBACK (slider_keymodify), NULL);
+    g_signal_connect_after (G_OBJECT(slider), "value-changed",
+			    G_CALLBACK(converge_slider_change), 0);
+    gtk_range_set_value(GTK_RANGE(slider),25.);
+  }
+  gtk_container_add(GTK_CONTAINER(converge_frame),converge_box);
+
+  gtk_box_pack_start(GTK_BOX(framebox),blocksize_frame,0,1,4);
+  gtk_box_pack_start(GTK_BOX(framebox),converge_frame,0,1,4);
+
+  gtk_box_pack_start(GTK_BOX(panel->subpanel_box),framebox,0,1,4);
+  gtk_box_pack_start(GTK_BOX(panel->subpanel_box),channel_table,0,1,4);
+
+  for(i=0;i<input_ch;i++){
+    char buffer[80];
+    clipslider *cs=calloc(1,sizeof(*cs));
+    GtkWidget *label;
+    GtkWidget *slider=gtk_hscale_new_with_range(.01,1.,.01);
+    GtkWidget *readout=readout_new("0.00");
+    GtkWidget *readoutdB=readout_new("-40 dB");
+    GtkWidget *barframe=gtk_frame_new(NULL);
+    GtkWidget *bar=multibar_new(3,labels,levels,0);
+
+    cs->slider=slider;
+    cs->readout=readout;
+    cs->readoutdB=readoutdB;
+    cs->number=i;
+    feedback_bars[i]=bar;
+
+    gtk_widget_set_size_request (slider,200,-1);
+    gtk_widget_set_name(bar,"clipbar");
+    gtk_scale_set_draw_value(GTK_SCALE(slider),FALSE);
+    gtk_range_set_value(GTK_RANGE(slider),1.);
+    gtk_frame_set_shadow_type(GTK_FRAME(barframe),GTK_SHADOW_ETCHED_IN);
+
+    switch(input_ch){
+    case 1:
+      sprintf(buffer,"trigger level:");
+      break;
+    case 2:
+      switch(i){
+      case 0:
+	sprintf(buffer,"left trigger level:");
+	break;
+      case 1:
+	sprintf(buffer,"right trigger level:");
+	break;
+      }
+      break;
+    default:
+      sprintf(buffer,"%d trigger level:",i+1);
+    }
+    label=gtk_label_new(buffer);
+    gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+    gtk_table_attach(GTK_TABLE(channel_table),label,0,1,i,i+1,GTK_FILL,GTK_FILL,2,0);
+    gtk_table_attach(GTK_TABLE(channel_table),readout,1,2,i,i+1,GTK_FILL,GTK_FILL,0,0);
+    gtk_table_attach(GTK_TABLE(channel_table),readoutdB,2,3,i,i+1,GTK_FILL,GTK_FILL,0,0);
+    gtk_table_attach_defaults(GTK_TABLE(channel_table),slider,3,4,i,i+1);
+    gtk_table_attach(GTK_TABLE(channel_table),barframe,4,5,i,i+1,GTK_FILL,GTK_FILL,0,0);
+    gtk_container_add(GTK_CONTAINER(barframe),bar);
+
+
+    g_signal_connect_after (G_OBJECT(slider), "value-changed",
+			    G_CALLBACK(trigger_slider_change), (gpointer)cs);
+    g_signal_connect (G_OBJECT (slider), "key-press-event",
+		      G_CALLBACK (slider_keymodify), NULL);
+    
+    trigger_slider_change(NULL,cs);
+  }
   
 }
+
+void clippanel_feedback(void){
+  int clip[input_ch],count;
+  if(pull_declip_feedback(clip,&count)){
+    int i;
+    for(i=0;i<input_ch;i++){
+      double val=clip[i]*100./count,zero=0;
+      multibar_set(MULTIBAR(feedback_bars[i]),&zero,&val,1);
+    }
+  }
+}
+
+void clippanel_reset(void){
+  int i;
+  for(i=0;i<input_ch;i++)
+    multibar_reset(MULTIBAR(feedback_bars[i]));
+}

<p><p>1.2       +5 -11     postfish/clippanel.h

Index: clippanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/clippanel.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- clippanel.h	18 Oct 2003 09:53:22 -0000	1.1
+++ clippanel.h	24 Dec 2003 09:49:16 -0000	1.2
@@ -1,13 +1,7 @@
 #include "postfish.h"
 
-typedef struct postfish_clippanel {
-  GtkWidget *toplevel;
-
-  postfish_mainpanel *mainpanel;
-} postfish_clippanel;
-
-
-extern void clippanel_create(postfish_clippanel *panel,
-			     postfish_mainpanel *mp);
-extern void clippanel_show(postfish_clippanel *p);
-extern void clippanel_hide(postfish_clippanel *p);
+extern void clippanel_create(postfish_mainpanel *mp,
+			     GtkWidget *windowbutton,
+			     GtkWidget *activebutton);
+extern void clippanel_feedback(void);
+extern void clippanel_reset(void);

<p><p>1.2       +139 -75   postfish/declip.c

Index: declip.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/declip.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- declip.c	20 Dec 2003 11:24:17 -0000	1.1
+++ declip.c	24 Dec 2003 09:49:16 -0000	1.2
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 #include "smallft.h"
 #include "reconstruct.h"
+#include "feedback.h"
 #include <stdio.h>
 
 extern int input_rate;
@@ -76,25 +77,61 @@
 static int fillstate=0; /* 0: uninitialized
                            1: normal
                            2: eof processed */
-
 static time_linkage out;
 
 /* accessed across threads */
-static sig_atomic_t declip_active=0;
-static sig_atomic_t declip_converge=2; /* 0=over, 1=full, 2=half, 3=partial, 4=approx */
-static sig_atomic_t *chtrigger=0;
-static sig_atomic_t *chactive=0;
+sig_atomic_t declip_active=0;
+sig_atomic_t declip_converge=2; /* 0=over, 1=full, 2=half, 3=partial, 4=approx */
+
+static double *chtrigger=0;
 static sig_atomic_t pending_blocksize=0;
+static double convergence=0.;
+static double iterations=0.;
+
+
+/* feedback! */
+typedef struct declip_feedback{
+  feedback_generic parent_class;
+  int *clipcount;
+  int total;
+} declip_feedback;
+
+static feedback_generic_pool feedpool;
+
+static feedback_generic *new_declip_feedback(void){
+  declip_feedback *ret=malloc(sizeof(*ret));
+  ret->clipcount=malloc((input_ch)*sizeof(*ret->clipcount));
+  return (feedback_generic *)ret;
+}
+
+static void push_declip_feedback(int *clip,int total){
+  int i,n=input_ch;
+  declip_feedback *f=(declip_feedback *)
+    feedback_new(&feedpool,new_declip_feedback);
+  memcpy(f->clipcount,clip,n*sizeof(*clip));
+  f->total=total;
+  feedback_push(&feedpool,(feedback_generic *)f);
+}
+
+int pull_declip_feedback(int *clip,int *total){
+  declip_feedback *f=(declip_feedback *)feedback_pull(&feedpool);
+  int i,j;
+
+  if(!f)return 0;
+
+  if(clip)memcpy(clip,f->clipcount,sizeof(*clip)*input_ch);
+  if(total)*total=f->total;
+
+  feedback_old(&feedpool,(feedback_generic *)f);
+  return 1;
+}
 
 /* called only by initial setup */
 int declip_load(void){
   int i;
   chtrigger=malloc(input_ch*sizeof(*chtrigger));
-  chactive=malloc(input_ch*sizeof(*chactive));
-  for(i=0;i<input_ch;i++){
-    chtrigger[i]=0x80000000UL;
-    chactive[i]=1;
-  }
+  for(i=0;i<input_ch;i++)
+    chtrigger[i]=1.;
   
   out.size=input_size;
   out.channels=input_ch;
@@ -121,22 +158,31 @@
   return 0;
 }
 
-int declip_setactive(int activep,int ch){
+int declip_settrigger(double trigger,int ch){
   if(ch<0 || ch>=input_ch)return -1;
-  chactive[ch]=activep;
+  pthread_mutex_lock(&master_mutex);
+  chtrigger[ch]=trigger;
+  pthread_mutex_unlock(&master_mutex);
   return 0;
 }
 
-int declip_settrigger(double trigger,int ch){
-  if(ch<0 || ch>=input_ch)return -1;
-  chtrigger[ch]=rint(trigger*(1.*0x80000000UL));
-  return 0;
+int declip_setiterations(double it){
+  pthread_mutex_lock(&master_mutex);
+  iterations=it;
+  pthread_mutex_unlock(&master_mutex);
+}
+
+int declip_setconvergence(double c){
+  pthread_mutex_lock(&master_mutex);
+  convergence=c;
+  pthread_mutex_unlock(&master_mutex);
 }
 
 /* called only in playback thread */
 int declip_reset(void){
   /* reset cached pipe state */
   fillstate=0;
+  while(pull_declip_feedback(NULL,NULL));
   return 0;
 }
 
@@ -199,12 +245,12 @@
 }
 
 static void declip(double *data,double *lap,double *out,
-		   int blocksize,unsigned long trigger){
+		   int blocksize,double trigger,
+		   double epsilon, double iteration,
+		   int *runningtotal, int *runningcount){
   double freq[blocksize];
   int    flag[blocksize];
-  double triggerlevel=trigger*(1./0x80000000UL);
-  double epsilon=1e-12;
-  int    iterbound=blocksize,i,j,count=0;
+  int    iterbound,i,j,count=0;
   
   for(i=0;i<blocksize/8;i++)flag[i]=0;
   for(;i<blocksize*7/8;i++){
@@ -212,52 +258,67 @@
     if(data[i]>=trigger || data[i]<=-trigger){
       flag[i]=1;
       count++;
+      *runningcount++;
     }
   }
-  for(;i<blocksize;i++)flag[i]=0;
-  for(i=0;i<blocksize;i++)data[i]*=window[i];
-  memcpy(freq,data,sizeof(freq));
-  drft_forward(&fft,freq);
-  sliding_bark_average(freq,freq,blocksize,width);
   
-  switch(declip_converge){
-  case 0:
-    epsilon=1e-12;
-    iterbound=blocksize*2;
-    break;
-  case 1:
-    epsilon=1e-8;
-    iterbound=count;
-    break;
-  case 2:
-    epsilon=1e-6;
-    iterbound=count/2;
-    break;
-  case 3:
-    epsilon=1e-5;
-    iterbound=count/4;
-    break;
-  case 4:
-    epsilon=1e-3;
-    iterbound=count/8;
-    break;
-  }
-  if(iterbound<20)iterbound=20;
+  *runningtotal+=blocksize*3/4;
+
+  if(declip_active){
+
+    for(;i<blocksize;i++)flag[i]=0;
+    for(i=0;i<blocksize;i++)data[i]*=window[i];
+    memcpy(freq,data,sizeof(freq));
+    drft_forward(&fft,freq);
+    sliding_bark_average(freq,freq,blocksize,width);
+    
+    if(iteration<1.){
+      iterbound=count*iteration;
+    }else{
+      iterbound=count+blocksize*(iteration-1.);
+    }
+    if(iterbound<20)iterbound=20;
+    
+    reconstruct(&fft,data,freq,flag,epsilon*count,iterbound,blocksize);
+
+    if(out)
+      for(i=0;i<blocksize/2;i++)
+	out[i]=lap[i]+data[i]*window[i];
+    
+    for(i=blocksize/2,j=0;i<blocksize;i++)
+      lap[j]=data[i]*window[i];
 
-  reconstruct(&fft,data,freq,flag,epsilon*count,iterbound,blocksize);
+  }else{
 
-  if(out)
-    for(i=0;i<blocksize/2;i++)
-      out[i]=lap[i]+data[i]*window[i];
+    if(out)
+      for(i=0;i<blocksize/2;i++)
+	out[i]=data[i];
+  
+    for(i=blocksize/2,j=0;i<blocksize;i++)
+      lap[j]=data[i]*window[i]*window[i];
 
-  for(i=blocksize/2,j=0;i<blocksize;i++)
-    lap[j]=data[i]*window[i];
+  }
 }
 
 /* called only by playback thread */
 time_linkage *declip_read(time_linkage *in){
   int i;
   double work[blocksize];
+  double local_trigger[input_ch];
+  int total=0;
+  int count[input_ch];
+  time_linkage dummy;
+
+  double local_convergence;
+  double local_iterations;
+  
+  pthread_mutex_lock(&master_mutex);
+  local_convergence=convergence;
+  local_iterations=iterations;
+  memcpy(local_trigger,chtrigger,sizeof(local_trigger));
+  pthread_mutex_unlock(&master_mutex);
+
+  memset(count,0,sizeof(count));
 
   if(pending_blocksize!=blocksize){
     if(blocksize){
@@ -292,19 +353,19 @@
 
   }
 
+
   switch(fillstate){
   case 0: /* prime the lapping and cache */
     for(i=0;i<input_ch;i++){
       int j;
       double *temp=in->data[i];
-      if(chactive[i] && declip_active){
-	memset(work,0,sizeof(*work)*blocksize/2);
-	memcpy(work+blocksize/2,temp,sizeof(*work)*blocksize/2);
-	declip(work,lap[i],0,blocksize,chtrigger[i]);
-      }else{
-	for(j=0;j<blocksize/2;j++)
-	  lap[i][j]=window[j+blocksize/2]*temp[j];
-      }
+      total=0;
+      memset(work,0,sizeof(*work)*blocksize/2);
+      memcpy(work+blocksize/2,temp,sizeof(*work)*blocksize/2);
+      declip(work,lap[i],0,blocksize,
+	     local_trigger[i],local_convergence,local_iterations,
+	     &total,count+i);
+
       memset(cache[i],0,sizeof(**cache)*input_size);
       in->data[i]=cache[i];
       cache[i]=temp;
@@ -317,20 +378,19 @@
   case 1: /* nominal processing */
     for(i=0;i<input_ch;i++){
       double *temp=cache[i];
-	int j;
-      if(chactive[i] && declip_active){
-	for(j=0;j+blocksize<out.size;j+=blocksize/2){
-	  memcpy(work,temp+j,sizeof(*work)*blocksize);
-	  declip(work,lap[i],out.data[i]+j,blocksize,chtrigger[i]);
-	}
-	memcpy(work,temp+j,sizeof(*work)*blocksize/2);
-	memcpy(work+blocksize/2,in->data[i],sizeof(*work)*blocksize/2);
-	declip(work,lap[i],out.data[i]+j,blocksize,chtrigger[i]);
-      }else{
-	memcpy(out.data[i],temp,out.size*sizeof(*temp));
-	for(j=0;j<blocksize/2;j++)
-	  lap[i][j]=window[j+blocksize/2]*temp[j];
+      int j;
+      total=0;
+      for(j=0;j+blocksize<out.size;j+=blocksize/2){
+	memcpy(work,temp+j,sizeof(*work)*blocksize);
+	declip(work,lap[i],out.data[i]+j,blocksize,
+	       local_trigger[i],local_convergence,local_iterations,
+	       &total,count+i);
       }
+      memcpy(work,temp+j,sizeof(*work)*blocksize/2);
+      memcpy(work+blocksize/2,in->data[i],sizeof(*work)*blocksize/2);
+      declip(work,lap[i],out.data[i]+j,blocksize,
+	     local_trigger[i],local_convergence,local_iterations,
+	     &total,count+i);
       
       in->data[i]=cache[i];
       cache[i]=temp;
@@ -342,5 +402,9 @@
   case 2: /* we've pushed out EOF already */
     return 0;
   }
+
+  /* we're returning data, push feedback */
+  push_declip_feedback(count,total);
+
   return &out;
 }

<p><p>1.2       +2 -1      postfish/declip.h

Index: declip.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/declip.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- declip.h	20 Dec 2003 11:24:17 -0000	1.1
+++ declip.h	24 Dec 2003 09:49:16 -0000	1.2
@@ -23,7 +23,8 @@
 
 extern int declip_load(void);
 extern int declip_setblock(int n);
-extern int declip_setactive(int activep,int ch);
 extern int declip_settrigger(double trigger,int ch);
+extern int declip_setiterations(double x);
+extern int declip_setconvergence(double x);
 extern int declip_reset(void);
 extern time_linkage *declip_read(time_linkage *in);

<p><p>1.12      +51 -64    postfish/input.c

Index: input.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/input.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- input.c	20 Dec 2003 11:24:17 -0000	1.11
+++ input.c	24 Dec 2003 09:49:16 -0000	1.12
@@ -2,7 +2,7 @@
  *
  *  postfish
  *    
- *      Copyright (C) 2002-2003 Monty
+ *      Copyright (C) 2002-2004 Monty
  *
  *  Postfish is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
  */
 
 #include "postfish.h"
+#include "feedback.h"
 #include "input.h"
 
 static off_t        Acursor=0;
@@ -47,16 +48,13 @@
 } file_entry;
 
 typedef struct input_feedback{
+  feedback_generic parent_class;
   off_t   cursor;
   double *rms;
   double *peak;
-
-  struct input_feedback *next;
 } input_feedback;
 
-static input_feedback *feedback_list_head;
-static input_feedback *feedback_list_tail;
-static input_feedback *feedback_pool;
+static feedback_generic_pool feedpool;
 
 static file_entry *file_list=NULL;
 static int file_entries=0;
@@ -163,7 +161,7 @@
 
 int input_load(int n,char *list[]){
   char *fname="stdin";
-  int stdinp=0,i,j,ch,rate;
+  int stdinp=0,i,j,ch=0,rate=0;
   off_t total=0;
 
   if(n==0){
@@ -309,7 +307,38 @@
     }
   }
 
-  input_size=out.size=2048;
+
+  /* 192000: 8192
+
+      96000: 4096
+      88200: 4096
+      64000: 4096
+
+      48000: 2048
+      44100: 2048
+      32000: 1024
+
+      22050: 1024
+      16000: 1024
+
+      11025:  512
+       8000:  512
+
+       4000:  256 */
+
+  if(rate<6000){
+    input_size=out.size=256;
+  }else if(rate<15000){
+    input_size=out.size=512;
+  }else if(rate<25000){
+    input_size=out.size=1024;
+  }else if(rate<50000){
+    input_size=out.size=2048;
+  }else if(rate<100000){
+    input_size=out.size=4096;
+  }else
+    input_size=out.size=8192;
+
   input_ch=out.channels=ch;
   input_rate=out.rate=rate;
   out.data=malloc(sizeof(*out.data)*ch);
@@ -364,73 +393,31 @@
   return ret;
 }
 
-static input_feedback *new_input_feedback(void){
-  input_feedback *ret;
-  
-  pthread_mutex_lock(&master_mutex);
-  if(feedback_pool){
-    ret=feedback_pool;
-    feedback_pool=feedback_pool->next;
-    pthread_mutex_unlock(&master_mutex);
-    return ret;
-  }
-  pthread_mutex_unlock(&master_mutex);
-  ret=malloc(sizeof(*ret));
+static feedback_generic *new_input_feedback(void){
+  input_feedback *ret=malloc(sizeof(*ret));
   ret->rms=malloc((input_ch+2)*sizeof(*ret->rms));
   ret->peak=malloc((input_ch+2)*sizeof(*ret->peak));
-  
-  return ret;
+  return (feedback_generic *)ret;
 }
 
 static void push_input_feedback(double *peak,double *rms, off_t cursor){
   int i,n=input_ch+2;
-  input_feedback *f=new_input_feedback();
-
+  input_feedback *f=(input_feedback *)
+    feedback_new(&feedpool,new_input_feedback);
   f->cursor=cursor;
   memcpy(f->rms,rms,n*sizeof(*rms));
   memcpy(f->peak,peak,n*sizeof(*peak));
-  f->next=NULL;
-
-  pthread_mutex_lock(&master_mutex);
-  if(!feedback_list_tail){
-    feedback_list_tail=f;
-    feedback_list_head=f;
-  }else{
-    feedback_list_head->next=f;
-    feedback_list_head=f;
-  }
-  pthread_mutex_unlock(&master_mutex);
+  feedback_push(&feedpool,(feedback_generic *)f);
 }
 
-int pull_input_feedback(double *peak,double *rms,off_t *cursor,int *nn){
-  input_feedback *f;
+int pull_input_feedback(double *peak,double *rms,off_t *cursor){
+  input_feedback *f=(input_feedback *)feedback_pull(&feedpool);
   int i,j,n=input_ch+2;
-  if(nn)*nn=n;
-
-  pthread_mutex_lock(&master_mutex);
-  if(feedback_list_tail){
-    
-    f=feedback_list_tail;
-    feedback_list_tail=feedback_list_tail->next;
-    if(!feedback_list_tail)feedback_list_head=0;
-
-  }else{
-    pthread_mutex_unlock(&master_mutex);
-    return 0;
-  }
-  pthread_mutex_unlock(&master_mutex);
-
-  if(rms)
-    memcpy(rms,f->rms,sizeof(*rms)*n);
-  if(peak)
-    memcpy(peak,f->peak,sizeof(*peak)*n);
-  if(cursor)
-    *cursor=f->cursor;
-
-  pthread_mutex_lock(&master_mutex);
-  f->next=feedback_pool;
-  feedback_pool=f;
-  pthread_mutex_unlock(&master_mutex);
+  if(!f)return 0;
+  if(rms)memcpy(rms,f->rms,sizeof(*rms)*n);
+  if(peak)memcpy(peak,f->peak,sizeof(*peak)*n);
+  if(cursor)*cursor=f->cursor;
+  feedback_old(&feedpool,(feedback_generic *)f);
   return 1;
 }
 
@@ -567,7 +554,7 @@
 }
 
 void input_reset(void){
-  while(pull_input_feedback(NULL,NULL,NULL,NULL));
+  while(pull_input_feedback(NULL,NULL,NULL));
   return;
 }
 

<p><p>1.7       +1 -1      postfish/input.h

Index: input.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/input.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- input.h	17 Oct 2003 08:40:18 -0000	1.6
+++ input.h	24 Dec 2003 09:49:16 -0000	1.7
@@ -6,6 +6,6 @@
 extern off_t input_seek(off_t pos);
 extern time_linkage *input_read(void);
 extern int input_load(int n,char *list[]);
-extern int pull_input_feedback(double *peak,double *rms,off_t *cursor,int *n);
+extern int pull_input_feedback(double *peak,double *rms,off_t *cursor);
 extern void input_reset(void);
 extern off_t input_time_seek_rel(double s);

<p><p>1.8       +2 -0      postfish/main.c

Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/main.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- main.c	18 Oct 2003 11:10:09 -0000	1.7
+++ main.c	24 Dec 2003 09:49:16 -0000	1.8
@@ -41,6 +41,8 @@
 
   /* parse command line and open all the input files */
   if(input_load(argc-1,argv+1))exit(1);
+  /* set up filter chains */
+  if(declip_load())exit(1);
 
   /* look at stdout... do we have a file or device? */
   if(!isatty(STDOUT_FILENO)){

<p><p>1.24      +65 -40    postfish/mainpanel.c

Index: mainpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- mainpanel.c	20 Dec 2003 11:24:17 -0000	1.23
+++ mainpanel.c	24 Dec 2003 09:49:16 -0000	1.24
@@ -10,14 +10,45 @@
 #include "input.h"
 #include "output.h"
 #include "mainpanel.h"
+#include "windowbutton.h"
 
 
-static void action_clippanel_window(GtkWidget *widget,postfish_mainpanel *p){
-  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){
-    clippanel_show(&p->clippanel);
-  }else{
-    clippanel_hide(&p->clippanel);
+gboolean slider_keymodify(GtkWidget *w,GdkEventKey *event,gpointer in){
+  GtkWidget *toplevel=gtk_widget_get_toplevel(w);
+  GtkAdjustment *adj=gtk_range_get_adjustment(GTK_RANGE(w));
+  if(event->state&GDK_MOD1_MASK) return FALSE;
+  if(event->state&GDK_CONTROL_MASK) return FALSE;
+
+  switch(event->keyval){
+  case GDK_minus:
+    gtk_range_set_value(GTK_RANGE(w),adj->value-adj->step_increment);
+    break;
+  case GDK_underscore:
+    gtk_range_set_value(GTK_RANGE(w),adj->value-adj->page_increment);
+    break;
+  case GDK_equal:
+    gtk_range_set_value(GTK_RANGE(w),adj->value+adj->step_increment);
+    break;
+  case GDK_plus:
+    gtk_range_set_value(GTK_RANGE(w),adj->value+adj->page_increment);
+    break;
+
+  case GDK_Left:
+    gtk_widget_child_focus(toplevel,GTK_DIR_LEFT);
+    break;
+  case GDK_Up:
+    gtk_widget_child_focus(toplevel,GTK_DIR_UP);
+    break;
+  case GDK_Right:
+    gtk_widget_child_focus(toplevel,GTK_DIR_RIGHT);
+    break;
+  case GDK_Down:
+    gtk_widget_child_focus(toplevel,GTK_DIR_DOWN);
+    break;
+  default:
+    return FALSE;
   }
+  return TRUE;
 }
 
 static void action_zero(GtkWidget *widget,postfish_mainpanel *p){
@@ -29,6 +60,7 @@
   readout_set(READOUT(p->cue),(char *)time);
   multibar_reset(MULTIBAR(p->inbar));
   multibar_reset(MULTIBAR(p->outbar));
+  clippanel_reset();
 }
 
 static void action_end(GtkWidget *widget,postfish_mainpanel *p){
@@ -41,6 +73,7 @@
   readout_set(READOUT(p->cue),(char *)buf);
   multibar_reset(MULTIBAR(p->inbar));
   multibar_reset(MULTIBAR(p->outbar));
+  clippanel_reset();
 }
 
 static void action_bb(GtkWidget *widget,postfish_mainpanel *p){
@@ -131,6 +164,7 @@
   char time[14];
   input_cursor_to_time(0,time);
   gtk_entry_set_text(GTK_ENTRY(p->entry_a),time);
+  input_Acursor_set(0);
 }
 
 static void action_resetb(GtkWidget *widget,postfish_mainpanel *p){
@@ -263,7 +297,7 @@
   case GDK_Left:
     if(pos==0){
       /* back up focus */
-      gtk_widget_child_focus(toplevel,GTK_DIR_TAB_BACKWARD);
+      gtk_widget_child_focus(toplevel,GTK_DIR_LEFT);
       return TRUE;
     }
 
@@ -275,7 +309,7 @@
   case GDK_Right:
     if(pos>=12){
       /* advance focus */
-      gtk_widget_child_focus(toplevel,GTK_DIR_TAB_FORWARD);
+      gtk_widget_child_focus(toplevel,GTK_DIR_RIGHT);
       return TRUE;
     }
 
@@ -401,10 +435,6 @@
     gtk_widget_activate(p->deckactive[3]);
     break;
   case GDK_period:
-
-
-
-
     gtk_widget_activate(p->deckactive[4]);
     break;
   case GDK_greater:
@@ -424,23 +454,18 @@
                                  char *label,
                                  char *shortcut,
                                  int i,
-				 GCallback cw,
-				 GCallback ca){
-  GtkWidget *ww=gtk_check_button_new_with_mnemonic(label);
+				 void (*panel_create)
+				 (postfish_mainpanel *,
+				  GtkWidget *, GtkWidget *)){  
+  
+  GtkWidget *ww=windowbutton_new(label);
   GtkWidget *wa=gtk_toggle_button_new_with_label(shortcut);
-
-  p->buttonwindow[i]=ww;
-  p->buttonactive[i]=wa;
   
   gtk_table_attach_defaults(GTK_TABLE(p->wintable),ww,0,1,i+1,i+2);
   gtk_table_attach_defaults(GTK_TABLE(p->wintable),wa,1,2,i+1,i+2);
 
-  if(cw)
-    g_signal_connect (G_OBJECT (ww), "clicked",
-		      G_CALLBACK (cw), p);
-  if(ca)
-    g_signal_connect (G_OBJECT (wa), "clicked",
-		      G_CALLBACK (ca), p);
+  p->buttonactive[i]=wa;
+  if(panel_create)(*panel_create)(p,ww,wa);
 }
 
 void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
@@ -494,8 +519,6 @@
   gtk_container_add (GTK_CONTAINER (panel->toplevel), topplace);
   gtk_container_set_border_width (GTK_CONTAINER (panel->quitbutton), 3);
 
-
-
   g_signal_connect (G_OBJECT (panel->quitbutton), "clicked",
                     G_CALLBACK (shutdown), NULL);
   
@@ -578,14 +601,13 @@
     gtk_table_attach_defaults(GTK_TABLE(panel->wintable),temp,1,2,0,1);
   }
 
-  mainpanel_panelentry(panel,"_Declip ","[d]",0,
-		       (GCallback)action_clippanel_window,0);
-  mainpanel_panelentry(panel,"Cross_Talk ","[t]",1,0,0);
-  mainpanel_panelentry(panel,"_Noise Filter ","[n]",2,0,0);
-  mainpanel_panelentry(panel,"_Equalizer ","[e]",3,0,0);
-  mainpanel_panelentry(panel,"_Compander ","[c]",4,0,0);
-  mainpanel_panelentry(panel,"_Limiter ","[l]",5,0,0);
-  mainpanel_panelentry(panel,"_Output Cal. ","[o]",6,0,0);
+  mainpanel_panelentry(panel,"_Declip ","[d]",0,clippanel_create);
+  mainpanel_panelentry(panel,"Cross_Talk ","[t]",1,0);
+  mainpanel_panelentry(panel,"_Noise Filter ","[n]",2,0);
+  mainpanel_panelentry(panel,"_Equalizer ","[e]",3,0);
+  mainpanel_panelentry(panel,"_Compander ","[c]",4,0);
+  mainpanel_panelentry(panel,"_Limiter ","[l]",5,0);
+  mainpanel_panelentry(panel,"_Output Cal. ","[o]",6,0);
 
 
   g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
@@ -666,6 +688,9 @@
       
       gtk_table_attach_defaults(GTK_TABLE(ttable),box,1,3,3,4);
 
+      g_signal_connect (G_OBJECT (panel->masterdB_s), "key-press-event",
+			G_CALLBACK (slider_keymodify), NULL);
+
       g_signal_connect_after (G_OBJECT(panel->masterdB_s), "value-changed",
                         G_CALLBACK(masterdB_change), (gpointer)panel);
 
@@ -734,7 +759,7 @@
       GtkWidget *framea=gtk_vseparator_new();
       GtkWidget *frameb=gtk_vseparator_new();
 
-      GtkWidget *panelb=gtk_check_button_new_with_mnemonic("c_ue list");
+      GtkWidget *panelb=windowbutton_new("c_ue list");
 
       panel->entry_a=gtk_entry_new();
       panel->entry_b=gtk_entry_new();
@@ -803,7 +828,7 @@
       GtkWidget *confbox=gtk_hbox_new(0,0);
       GtkWidget *conflabel=gtk_label_new("setting:");
       GtkWidget *conf=readout_new("");
-      GtkWidget *panel=gtk_check_button_new_with_mnemonic("_setting list");
+      GtkWidget *panel=windowbutton_new("_setting list");
       gtk_misc_set_alignment(GTK_MISC(conflabel),1,.5);
 
       gtk_table_attach_defaults(GTK_TABLE(ttable),conflabel,0,1,6,7);
@@ -822,8 +847,6 @@
   gtk_widget_show_all(panel->toplevel);
   gtk_window_set_resizable(GTK_WINDOW(panel->toplevel),0);
 
-  clippanel_create(&panel->clippanel,panel);
-
 }
 
 static gboolean feedback_process(postfish_mainpanel *panel){
@@ -839,10 +862,10 @@
      available and not dirtied by a seek */
   if(!playback_seeking){
     off_t   time_cursor;
-    int     n;
+    int     n=input_ch+2;
     double *rms=alloca(sizeof(*rms)*(input_ch+2));
     double *peak=alloca(sizeof(*peak)*(input_ch+2));
-    if(pull_input_feedback(peak,rms,&time_cursor,&n)){
+    if(pull_input_feedback(peak,rms,&time_cursor)){
       char buffer[14];
       int i;
       for(i=0;i<n;i++){
@@ -859,7 +882,9 @@
       input_cursor_to_time(time_cursor,buffer);
       readout_set(READOUT(panel->cue),buffer);
 
-      if(pull_output_feedback(peak,rms,&n)){
+      clippanel_feedback();
+
+      if(pull_output_feedback(peak,rms)){
         for(i=0;i<n;i++){
           if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->channelshow[i]))){
             peak[i]=todB(peak[i]);

<p><p>1.5       +1 -2      postfish/mainpanel.h

Index: mainpanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- mainpanel.h	18 Oct 2003 11:10:09 -0000	1.4
+++ mainpanel.h	24 Dec 2003 09:49:16 -0000	1.5
@@ -33,7 +33,6 @@
   GtkWidget *masterdB_s;
   GtkWidget *masterdB_a;
 
-  GtkWidget *buttonwindow[7];
   GtkWidget *buttonactive[7];
 
   GtkWidget *cue_set[2];
@@ -50,7 +49,6 @@
   GtkWidget *entry_a;
   GtkWidget *entry_b;
 
-  postfish_clippanel clippanel;
 
   /* ui state */
   int fishframe;
@@ -59,3 +57,4 @@
  
 };
 
+extern gboolean slider_keymodify(GtkWidget *w,GdkEventKey *event,gpointer in);

<p><p>1.13      +1 -1      postfish/multibar.c

Index: multibar.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/multibar.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- multibar.c	20 Dec 2003 11:24:17 -0000	1.12
+++ multibar.c	24 Dec 2003 09:49:16 -0000	1.13
@@ -343,7 +343,7 @@
     if(y>maxy)maxy=y;
   }
 
-  requisition->width = (maxx*2)*m->labels;
+  requisition->width = (maxx*1.5+2)*m->labels;
   requisition->height = maxy;
 }
 

<p><p>1.10      +21 -59    postfish/output.c

Index: output.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/output.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- output.c	17 Oct 2003 06:28:15 -0000	1.9
+++ output.c	24 Dec 2003 09:49:16 -0000	1.10
@@ -25,7 +25,10 @@
 #include <linux/soundcard.h>
 #include <sys/ioctl.h>
 #include "postfish.h"
+#include "feedback.h"
 #include "input.h"
+#include "output.h"
+#include "declip.h"
 
 sig_atomic_t playback_active=0;
 sig_atomic_t playback_exit=0;
@@ -33,7 +36,7 @@
 
 void output_reset(void){
   /* empty feedback queues */
-  while(pull_output_feedback(NULL,NULL,NULL));
+  while(pull_output_feedback(NULL,NULL));
   return;
 }
 
@@ -47,84 +50,42 @@
   fcntl(eventpipe[0],F_SETFL,flags);
 
   input_reset();  /* clear any persistent lapping state */
+  declip_reset();  /* clear any persistent lapping state */
   output_reset(); /* clear any persistent lapping state */
 }
 
 typedef struct output_feedback{
+  feedback_generic parent_class;
   double *rms;
   double *peak;
-
-  struct output_feedback *next;
 } output_feedback;
 
-static output_feedback *feedback_list_head;
-static output_feedback *feedback_list_tail;
-static output_feedback *feedback_pool;
+static feedback_generic_pool feedpool;
 
-static output_feedback *new_output_feedback(void){
-  output_feedback *ret;
-  
-  pthread_mutex_lock(&master_mutex);
-  if(feedback_pool){
-    ret=feedback_pool;
-    feedback_pool=feedback_pool->next;
-    pthread_mutex_unlock(&master_mutex);
-    return ret;
-  }
-  pthread_mutex_unlock(&master_mutex);
-  ret=malloc(sizeof(*ret));
+static feedback_generic *new_output_feedback(void){
+  output_feedback *ret=malloc(sizeof(*ret));
   ret->rms=malloc((input_ch+2)*sizeof(*ret->rms));
   ret->peak=malloc((input_ch+2)*sizeof(*ret->peak));
-  
-  return ret;
+  return (feedback_generic *)ret;
 }
 
 static void push_output_feedback(double *peak,double *rms){
   int i,n=input_ch+2;
-  output_feedback *f=new_output_feedback();
-
+  output_feedback *f=(output_feedback *)
+    feedback_new(&feedpool,new_output_feedback);
+  
   memcpy(f->rms,rms,n*sizeof(*rms));
   memcpy(f->peak,peak,n*sizeof(*peak));
-  f->next=NULL;
-
-  pthread_mutex_lock(&master_mutex);
-  if(!feedback_list_tail){
-    feedback_list_tail=f;
-    feedback_list_head=f;
-  }else{
-    feedback_list_head->next=f;
-    feedback_list_head=f;
-  }
-  pthread_mutex_unlock(&master_mutex);
+  feedback_push(&feedpool,(feedback_generic *)f);
 }
 
-int pull_output_feedback(double *peak,double *rms,int *nn){
-  output_feedback *f;
+int pull_output_feedback(double *peak,double *rms){
+  output_feedback *f=(output_feedback *)feedback_pull(&feedpool);
   int i,j,n=input_ch+2;
-  if(nn)*nn=n;
-
-  pthread_mutex_lock(&master_mutex);
-  if(feedback_list_tail){
-    
-    f=feedback_list_tail;
-    feedback_list_tail=feedback_list_tail->next;
-    if(!feedback_list_tail)feedback_list_head=0;
-
-  }else{
-    pthread_mutex_unlock(&master_mutex);
-    return 0;
-  }
-  pthread_mutex_unlock(&master_mutex);
-
-  if(rms)
-    memcpy(rms,f->rms,sizeof(*rms)*n);
-  if(peak)
-    memcpy(peak,f->peak,sizeof(*peak)*n);
-
-  pthread_mutex_lock(&master_mutex);
-  f->next=feedback_pool;
-  feedback_pool=f;
-  pthread_mutex_unlock(&master_mutex);
+  if(!f)return 0;
+  if(rms)memcpy(rms,f->rms,sizeof(*rms)*n);
+  if(peak)memcpy(peak,f->peak,sizeof(*peak)*n);
+  feedback_old(&feedpool,(feedback_generic *)f);
   return 1;
 }
 
@@ -240,6 +201,7 @@
 
     /* get data */
     if(!(ret=input_read()))break;
+    //!(ret=declip_read()))break;
 
     /************/
 

<p><p>1.4       +1 -1      postfish/output.h

Index: output.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/output.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- output.h	17 Oct 2003 06:28:15 -0000	1.3
+++ output.h	24 Dec 2003 09:49:16 -0000	1.4
@@ -1,4 +1,4 @@
-extern int pull_output_feedback(double *peak,double *rms,int *n);
+extern int pull_output_feedback(double *peak,double *rms);
 extern void *playback_thread(void *dummy);
 extern void output_halt_playback(void);
 extern void output_reset(void);

<p><p>1.22      +2 -2      postfish/version.h

Index: version.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/version.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- version.h	20 Dec 2003 11:24:17 -0000	1.21
+++ version.h	24 Dec 2003 09:49:16 -0000	1.22
@@ -1,2 +1,2 @@
-#define VERSION "$Id: version.h,v 1.21 2003/12/20 11:24:17 xiphmont Exp $ "
-/* DO NOT EDIT: Automated versioning hack [Sat Dec 20 05:44:23 EST 2003] */
+#define VERSION "$Id: version.h,v 1.22 2003/12/24 09:49:16 xiphmont Exp $ "
+/* DO NOT EDIT: Automated versioning hack [Wed Dec 24 04:43:27 EST 2003] */

<p><p>1.1                  postfish/feedback.c

Index: feedback.c
===================================================================
/*
 *
 *  postfish
 *    
 *      Copyright (C) 2002-2004 Monty and Xiph.Org
 *
 *  Postfish is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  Postfish is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with Postfish; see the file COPYING.  If not, write to the
 *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * 
 */

#include "postfish.h"
#include "feedback.h"

feedback_generic *feedback_new(feedback_generic_pool *pool,
                               feedback_generic *(*constructor)(void)){
  feedback_generic *ret;
  
  pthread_mutex_lock(&master_mutex);
  if(pool->feedback_pool){
    ret=pool->feedback_pool;
    pool->feedback_pool=pool->feedback_pool->next;
    pthread_mutex_unlock(&master_mutex);
    return ret;
  }
  pthread_mutex_unlock(&master_mutex);

  ret=constructor();
  return ret;
}

void feedback_push(feedback_generic_pool *pool,
                   feedback_generic *f){
  f->next=NULL;

  pthread_mutex_lock(&master_mutex);
  if(!pool->feedback_list_tail){
    pool->feedback_list_tail=f;
    pool->feedback_list_head=f;
  }else{
    pool->feedback_list_head->next=f;
    pool->feedback_list_head=f;
  }
  pthread_mutex_unlock(&master_mutex);
}

feedback_generic *feedback_pull(feedback_generic_pool *pool){
  feedback_generic *f;

  pthread_mutex_lock(&master_mutex);
  if(pool->feedback_list_tail){
    
    f=pool->feedback_list_tail;
    pool->feedback_list_tail=pool->feedback_list_tail->next;
    if(!pool->feedback_list_tail)pool->feedback_list_head=0;

  }else{
    pthread_mutex_unlock(&master_mutex);
    return 0;
  }
  pthread_mutex_unlock(&master_mutex);
  return(f);
}

void feedback_old(feedback_generic_pool *pool,
                  feedback_generic *f){
  
  pthread_mutex_lock(&master_mutex);
  f->next=pool->feedback_pool;
  pool->feedback_pool=f;
  pthread_mutex_unlock(&master_mutex);
}

<p><p><p>1.1                  postfish/feedback.h

Index: feedback.h
===================================================================
/*
 *
 *  postfish
 *    
 *      Copyright (C) 2002-2004 Monty and Xiph.Org
 *
 *  Postfish is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  Postfish is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with Postfish; see the file COPYING.  If not, write to the
 *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * 
 */

typedef struct feedback_generic{
  struct feedback_generic *next;
} feedback_generic;

typedef struct feedback_generic_pool{
  feedback_generic *feedback_list_head;
  feedback_generic *feedback_list_tail;
  feedback_generic *feedback_pool;
} feedback_generic_pool;

extern feedback_generic *feedback_new(feedback_generic_pool *pool,
                                      feedback_generic *(*constructor)(void));
extern void feedback_push(feedback_generic_pool *pool,
                          feedback_generic *f);
extern feedback_generic *feedback_pull(feedback_generic_pool *pool);
extern void feedback_old(feedback_generic_pool *pool,
                         feedback_generic *f);

<p><p><p>1.1                  postfish/subpanel.c

Index: subpanel.c
===================================================================
/*
 *
 *  postfish
 *    
 *      Copyright (C) 2002-2004 Monty
 *
 *  Postfish is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  Postfish is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with Postfish; see the file COPYING.  If not, write to the
 *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * 
 */

#include "postfish.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "mainpanel.h"
#include "windowbutton.h"
#include "subpanel.h"

tatic int clippanel_hide(GtkWidget *widget,
                          GdkEvent *event,
                          gpointer in){
  subpanel_generic *p=in;
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton),0);
  return FALSE;
}
static int windowbutton_action(GtkWidget *widget,
                        gpointer in){
  int active;
  subpanel_generic *p=in;
  if(widget==p->subpanel_windowbutton){
    active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->mainpanel_windowbutton),active);
  }else{
    active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->mainpanel_windowbutton));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton),active);
  }
  
  if(active)
    gtk_widget_show_all(p->subpanel_toplevel);
  else
    gtk_widget_hide_all(p->subpanel_toplevel);

  return FALSE;
}

tatic int activebutton_action(GtkWidget *widget,
                        gpointer in){
  subpanel_generic *p=in;
  int active;

  if(widget==p->subpanel_activebutton){
    active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->subpanel_activebutton));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->mainpanel_activebutton),active);
  }else{
    active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->mainpanel_activebutton));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_activebutton),active);
  }
  
  *p->activevar=active;
  return FALSE;
}

tatic gboolean forward_events(GtkWidget *widget,
                               GdkEvent *event,
                               gpointer in){
  subpanel_generic *p=in;
  GdkEvent copy=*(GdkEvent *)event;
  copy.any.window=p->mainpanel->toplevel->window;
  gtk_main_do_event((GdkEvent *)(&copy));
  return TRUE;
}

ubpanel_generic *subpanel_create(postfish_mainpanel *mp,
                                  GtkWidget *windowbutton,
                                  GtkWidget *activebutton,
                                  sig_atomic_t *activevar,
                                  char *prompt,char *shortcut){

  subpanel_generic *panel=calloc(1,sizeof(*panel));
  GdkWindow *root=gdk_get_default_root_window();
  GtkWidget *topframe=gtk_frame_new (NULL);

  GtkWidget *toplabelbox=gtk_event_box_new();
  GtkWidget *toplabelframe=gtk_frame_new(NULL);
  GtkWidget *toplabel=gtk_hbox_new(0,0);
  GtkWidget *toplabelwb=windowbutton_new(prompt);
  GtkWidget *toplabelab=0;
  
  if(activebutton && activevar)
    toplabelab=gtk_toggle_button_new_with_label(shortcut);
  
  panel->subpanel_windowbutton=toplabelwb;
  panel->subpanel_activebutton=toplabelab;

  panel->mainpanel_windowbutton=windowbutton;
  panel->mainpanel_activebutton=activebutton;
  panel->activevar=activevar;
  
  gtk_box_pack_start(GTK_BOX(toplabel),toplabelwb,0,0,5);
  gtk_box_pack_end(GTK_BOX(toplabel),toplabelab,0,0,5);

  gtk_widget_set_name(toplabelwb,"panelbutton");
  gtk_widget_set_name(toplabelbox,"panelbox");
  gtk_frame_set_shadow_type(GTK_FRAME(toplabelframe),GTK_SHADOW_ETCHED_IN);
  gtk_container_add(GTK_CONTAINER (toplabelbox), toplabelframe);
  gtk_container_add(GTK_CONTAINER (toplabelframe), toplabel);

  panel->subpanel_box=gtk_vbox_new (0,0);

  panel->subpanel_toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
  panel->mainpanel=mp;

  gtk_container_add (GTK_CONTAINER (panel->subpanel_toplevel), topframe);
  gtk_container_add (GTK_CONTAINER (topframe), panel->subpanel_box);
  gtk_container_set_border_width (GTK_CONTAINER (topframe), 3);
  gtk_container_set_border_width (GTK_CONTAINER (panel->subpanel_box), 5);
  gtk_frame_set_shadow_type(GTK_FRAME(topframe),GTK_SHADOW_NONE);
  gtk_frame_set_label_widget(GTK_FRAME(topframe),toplabelbox);

    
  /* forward unhandled events to the main window */
  g_signal_connect_after (G_OBJECT (panel->subpanel_toplevel), "key-press-event",
                          G_CALLBACK (forward_events), 
                          panel);

  /* delete should == hide */
  g_signal_connect (G_OBJECT (panel->mainpanel->toplevel), "delete-event",
                    G_CALLBACK (clippanel_hide), 
                    panel);

  /* link the mainpanel and subpanel buttons */
  g_signal_connect_after (G_OBJECT (panel->mainpanel_windowbutton), "clicked",
                          G_CALLBACK (windowbutton_action), panel);
  g_signal_connect_after (G_OBJECT (panel->subpanel_windowbutton), "clicked",
                          G_CALLBACK (windowbutton_action), panel);
  if(activebutton && activevar){
    g_signal_connect_after (G_OBJECT (panel->mainpanel_activebutton), "clicked",
                            G_CALLBACK (activebutton_action), panel);
    g_signal_connect_after (G_OBJECT (panel->subpanel_activebutton), "clicked",
                            G_CALLBACK (activebutton_action), panel);
  }

  gtk_window_set_resizable(GTK_WINDOW(panel->subpanel_toplevel),0);

  return panel;
}

<p><p><p>1.1                  postfish/subpanel.h

Index: subpanel.h
===================================================================
/*
 *
 *  postfish
 *    
 *      Copyright (C) 2002-2004 Monty
 *
 *  Postfish is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  Postfish is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with Postfish; see the file COPYING.  If not, write to the
 *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * 
 */

typedef struct{
  GtkWidget *mainpanel_windowbutton;
  GtkWidget *mainpanel_activebutton;
  GtkWidget *subpanel_windowbutton;
  GtkWidget *subpanel_activebutton;
  GtkWidget *subpanel_toplevel;
  GtkWidget *subpanel_box;
  sig_atomic_t *activevar;

  postfish_mainpanel *mainpanel;
} subpanel_generic;

extern subpanel_generic *subpanel_create(postfish_mainpanel *mp,
                                         GtkWidget *windowbutton,
                                         GtkWidget *activebutton,
                                         sig_atomic_t *activevar,
                                         char *prompt,char *shortcut);

<p><p>1.1                  postfish/windowbutton.c

Index: windowbutton.c
===================================================================
#include "windowbutton.h"

tatic GtkCheckButtonClass *parent_class = NULL;

tatic void draw_triangle (GtkStyle      *style,
                           GdkWindow     *window,
                           GtkStateType   state_type,
                           GtkShadowType  shadow_type,
                           gint           x,
                           gint           y,
                           gint           size){

  GdkGC *gc=style->bg_gc[state_type];
  GdkGC *light_gc=style->light_gc[state_type];
  GdkGC *dark_gc=style->dark_gc[state_type];
  GdkGC *black_gc=style->black_gc;
  int i;
  
  /* fill the main triangle */
  for(i=0;i<size;i++)
    gdk_draw_line(window,gc,x+i,y+((i)>>1),x+i,y+size-1-((i)>>1));

<p>  /* draw border */
  switch(shadow_type){
  case GTK_SHADOW_ETCHED_IN:
    for(i=0;i<size;i++){
      if(y+size-1-(i>>1) > y+(i>>1)+1){
        gdk_draw_point(window,dark_gc,x+i,y+size-1-(i>>1)-1);
        gdk_draw_point(window,light_gc,x+i,y+(i>>1)+1);
      }
      gdk_draw_point(window,light_gc,x+i,y+size-1-(i>>1));
      gdk_draw_point(window,dark_gc,x+i,y+(i>>1));
    } 
    gdk_draw_line(window,dark_gc,x,y,x,y+size-1);
    gdk_draw_line(window,light_gc,x+1,y+1,x+1,y+size-2);
    break;

  case GTK_SHADOW_IN:
    for(i=0;i<size;i++){
      if(y+size-1-(i>>1) > y+(i>>1)+1)
        gdk_draw_point(window,black_gc,x+i,y+(i>>1)+1);
      gdk_draw_point(window,light_gc,x+i,y+size-1-(i>>1));
      gdk_draw_point(window,dark_gc,x+i,y+(i>>1));    
    } 
    gdk_draw_line(window,dark_gc,x,y,x,y+size-1);
    gdk_draw_line(window,black_gc,x+1,y+1,x+1,y+size-2);
    break;

<p>  case GTK_SHADOW_OUT:
    for(i=0;i<size;i++){
      if(y+size-1-(i>>1)-1 > y+(i>>1))
        gdk_draw_point(window,dark_gc,x+i,y+size-1-(i>>1)-1);
      gdk_draw_point(window,light_gc,x+i,y+(i>>1));    
      gdk_draw_point(window,black_gc,x+i,y+size-1-(i>>1));
    } 
    gdk_draw_line(window,light_gc,x,y,x,y+size-2);
    break;
  }

}

tatic void windowbutton_draw_indicator (GtkCheckButton *check_button,
                                         GdkRectangle   *area){
  GtkWidget *widget;
  GtkWidget *child;
  GtkButton *button;
  GtkToggleButton *toggle_button;
  GtkStateType state_type;
  GtkShadowType shadow_type;
  gint x, y;
  gint indicator_size;
  gint indicator_spacing;
  gint focus_width;
  gint focus_pad;
  gboolean interior_focus;
  
  if (GTK_WIDGET_DRAWABLE (check_button)){
    
    widget = GTK_WIDGET (check_button);
    button = GTK_BUTTON (check_button);
    toggle_button = GTK_TOGGLE_BUTTON (check_button);
    
    gtk_widget_style_get (widget, "interior_focus", &interior_focus,
                          "focus-line-width", &focus_width, 
                          "focus-padding", &focus_pad, NULL);
    
    _gtk_check_button_get_props (check_button, &indicator_size, 
                                 &indicator_spacing);
    
    x = widget->allocation.x + 
      indicator_spacing + GTK_CONTAINER (widget)->border_width;
    y = widget->allocation.y + 
      (widget->allocation.height - indicator_size) / 2;
    
    child = GTK_BIN (check_button)->child;
    if (!interior_focus || !(child && GTK_WIDGET_VISIBLE (child)))
      x += focus_width + focus_pad;      
    
    if (toggle_button->inconsistent)
      shadow_type = GTK_SHADOW_ETCHED_IN;
    else if (toggle_button->active)
      shadow_type = GTK_SHADOW_IN;
    else
      shadow_type = GTK_SHADOW_OUT;
    
    if (button->activate_timeout || (toggle_button->active))
      state_type = GTK_STATE_ACTIVE;
    else if (button->in_button)
      state_type = GTK_STATE_PRELIGHT;
    else if (!GTK_WIDGET_IS_SENSITIVE (widget))
      state_type = GTK_STATE_INSENSITIVE;
    else
      state_type = GTK_STATE_NORMAL;
    
    if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
      x = widget->allocation.x + widget->allocation.width - 
        (indicator_size + x - widget->allocation.x);
    
    draw_triangle (widget->style, widget->window,
                   state_type, shadow_type,
                   x, y, indicator_size);
  }
}

<p>static void windowbutton_class_init (WindowbuttonClass *class){
  GtkCheckButtonClass *cb_class = (GtkCheckButtonClass*) class;
  parent_class = g_type_class_peek_parent (class);
  cb_class->draw_indicator = windowbutton_draw_indicator;
}

tatic void windowbutton_init (Windowbutton *r){
}

GType windowbutton_get_type (void){
  static GType m_type = 0;
  if (!m_type){
    static const GTypeInfo m_info={
      sizeof (WindowbuttonClass),
      NULL, /* base_init */
      NULL, /* base_finalize */
      (GClassInitFunc) windowbutton_class_init,
      NULL, /* class_finalize */
      NULL, /* class_data */
      sizeof (Windowbutton),
      0,
      (GInstanceInitFunc) windowbutton_init,
      0
    };
    
    m_type = g_type_register_static (GTK_TYPE_CHECK_BUTTON, "Windowbutton", &m_info, 0);
  }

  return m_type;
}

GtkWidget* windowbutton_new (char *markup){
  return g_object_new (windowbutton_get_type (), 
                       "label", markup, 
                       "use_underline", TRUE, NULL);
}

<p><p><p><p>1.1                  postfish/windowbutton.h

Index: windowbutton.h
===================================================================
#ifndef __WINDOWBUTTON_H__
#define __WINDOWBUTTON_H__

#include <sys/time.h>
#include <time.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtkcheckbutton.h>

G_BEGIN_DECLS

#define WINDOWBUTTON_TYPE            (windowbutton_get_type ())
#define WINDOWBUTTON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), WINDOWBUTTON_TYPE, Windowbutton))
#define WINDOWBUTTON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), WINDOWBUTTON_TYPE, WindowbuttonClass))
#define IS_WINDOWBUTTON(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WINDOWBUTTON_TYPE))
#define IS_WINDOWBUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WINDOWBUTTON_TYPE))

typedef struct _Windowbutton       Windowbutton;
typedef struct _WindowbuttonClass  WindowbuttonClass;

truct _Windowbutton{

  GtkCheckButton frame;

};

truct _WindowbuttonClass{

  GtkCheckButtonClass parent_class;
  void (* windowbutton) (Windowbutton *m);

};

GType          windowbutton_get_type        (void);
GtkWidget*     windowbutton_new             (char *markup);

G_END_DECLS

#endif

<p><p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list