Commit c196b9d4 authored by Monty Montgomery's avatar Monty Montgomery

So... this is a big patch from about a month ago, but I was afraid to

commit it because Jack would be angry and come steal me Lucky Charms.

Jack likes me again and me Lucky Charms are ssafely hidden, thus the
patch can now safely go into SVN.



git-svn-id: https://svn.xiph.org/trunk/postfish@6914 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 165ceb33
......@@ -3,6 +3,7 @@
# and Fuck its little dog Libtool too
# Use the below line to build for PowerPC
# The PPC build *must* use -maltivec, even if the target is a non-altivec machine
#ADD_DEF= -DUGLY_IEEE754_FLOAT32_HACK=1 -maltivec
......@@ -36,8 +37,7 @@ OBJ = main.o mainpanel.o multibar.o readout.o input.o output.o clippanel.o \
bessel.o suppresspanel.o suppress.o singlecomp.o singlepanel.o \
limit.o limitpanel.o mute.o mixpanel.o mix.o reverb.o reverbpanel.o \
outpanel.o config.o
#GCF = -DETCDIR=\\\"$(ETCDIR)\\\" `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
GCF = -DETCDIR=\\\"$(ETCDIR)\\\" `pkg-config --cflags gtk+-2.0`
GCF = -DETCDIR=\\\"$(ETCDIR)\\\" `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
all:
$(MAKE) target CFLAGS="-O3 -ffast-math -fomit-frame-pointer $(GCF) $(ADD_DEF)"
......@@ -76,7 +76,7 @@ endif
target: $(OBJ) postfish-wisdomrc
./touch-version
$(LD) $(OBJ) $(CFLAGS) -o postfish $(LIBS) `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm
$(LD) $(OBJ) $(CFLAGS) -o postfish $(LIBS) `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm
install: target
$(INSTALL) -d -m 0755 $(BINDIR)
......
......@@ -196,6 +196,10 @@ void compute_iir_fast_attack2(float *x, int n, iir_state *is,
int state=is->state;
int i=0;
if(zerome(y0) && zerome(y1)){
y0=y1=0.;
}
if(x[0]>y0)state=0;
while(i<n){
......@@ -253,6 +257,10 @@ void compute_iir_freefall1(float *x, int n, iir_state *is,
double y0=is->y[0];
int i=0;
if(zerome(y0)){
y0=0.;
}
while(i<n){
double yd;
......@@ -281,6 +289,10 @@ void compute_iir_freefall2(float *x, int n, iir_state *is,
double y1=is->y[1];
int i=0;
if(zerome(y0) && zerome(y1)){
y0=y1=0.;
}
while(i<n){
double yd;
if(y1<y0)y1=y0; // slope fixup
......@@ -314,6 +326,10 @@ void compute_iir_decayonly2(float *x, int n, iir_state *is,
double y1=is->y[1];
int i=0;
if(zerome(y0) && zerome(y1)){
y0=y1=0.;
}
while(i<n){
double yd;
......@@ -346,6 +362,10 @@ void compute_iir_freefall3(float *x, int n, iir_state *is,
double x2=is->x[2],y2=is->y[2];
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2)){
y0=y1=y2=0.;
}
while(i<n){
double yd;
if(y1<y0)y1=y0; // slope fixup
......@@ -381,6 +401,10 @@ void compute_iir_freefall4(float *x, int n, iir_state *is,
double x3=is->x[3],y3=is->y[3];
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2) && zerome(y3)){
y0=y1=y2=y3=0.;
}
while(i<n){
double yd;
if(y1<y0)y1=y0; // slope fixup
......@@ -419,6 +443,10 @@ void compute_iir_symmetric2(float *x, int n, iir_state *is,
int i=0;
if(zerome(y0) && zerome(y1)){
y0=y1=0.;
}
while(i<n){
double yd= (x[i]+x0*2.+x1)/g + y0*c0+y1*c1;
x1=x0;x0=x[i];
......@@ -446,6 +474,10 @@ void compute_iir_symmetric3(float *x, int n, iir_state *is,
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2)){
y0=y1=y2=0.;
}
while(i<n){
double yd= (x[i]+(x0+x1)*3.+x2)/g + y0*c0+y1*c1+y2*c2;
x2=x1;x1=x0;x0=x[i];
......@@ -474,6 +506,10 @@ void compute_iir_symmetric4(float *x, int n, iir_state *is,
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2) && zerome(y3)){
y0=y1=y2=y3=0.;
}
while(i<n){
double yd= (x[i]+(x0+x2)*4.+x1*6.+x3)/g +
y0*c0+y1*c1+y2*c2+y3*c3;
......
......@@ -201,10 +201,11 @@ int declip_reset(void){
return 0;
}
int noisy=0;
static void sliding_bark_average(float *f,int n,float width){
int i=0;
float acc=0.,del=0.;
float sec[hipad+1];
double acc=0.,del=0.;
double sec[hipad+1];
memset(sec,0,sizeof(sec));
......@@ -233,7 +234,6 @@ static void sliding_bark_average(float *f,int n,float width){
f[(i<<1)+1]=f[i<<1]=1./(acc*acc);
del+=sec[i+lopad];
acc+=del;
}
f[n+1]=f[n]=f[n-1];
}
......@@ -244,7 +244,15 @@ static void declip(int blocksize,float trigger,
int *runningtotal, int *runningcount){
float flag[blocksize*2];
int iterbound,i,count=0;
/* too many apps screw up proper output scaling, so previously
clipped audio ends up getting rounded to just short of the rail
upon export. To avoid users accidentally shooting themselves in
the foot, trigger clipping at -.05dB rather than 0dB even if 0dB
is selected. This corresponds to mis-rounding 8 bit audio by 1.5
steps.*/
if(trigger>.99426)trigger=.99426;
for(i=blocksize/2;i<blocksize*3/2;i++){
flag[i]=0.;
if(work[i]>=trigger || work[i]<=-trigger){
......@@ -252,6 +260,7 @@ static void declip(int blocksize,float trigger,
count++;
}
}
*runningtotal+=blocksize;
*runningcount+=count;
......@@ -259,7 +268,6 @@ static void declip(int blocksize,float trigger,
if(count){
for(i=0;i<blocksize/2;i++)flag[i]=0.;
for(i=blocksize*3/2;i<blocksize*2;i++)flag[i]=0.;
for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i];
fftwf_execute(fftwf_weight);
......@@ -268,10 +276,11 @@ static void declip(int blocksize,float trigger,
if(iterbound<10)iterbound=10;
reconstruct(work,freq,flag,epsilon,iterbound);
for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i];
}else
for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i]*window[i];
}
/* called only by playback thread */
......@@ -596,6 +605,5 @@ time_linkage *declip_read(time_linkage *in){
}
out.active=active;
return &out;
}
......@@ -599,7 +599,7 @@ int input_load(void){
return 0;
}
off_t input_seek_i(off_t pos,int ps){
static off_t input_seek_i(off_t pos,int ps){
int i,k;
int flag=0;
off_t maxpos=0;
......@@ -692,7 +692,6 @@ static void LEconvert(float **data,
unsigned char *readbuf, int dataoff,
int ch,int bytes, int signp, int n){
int i,j,k=0;
int32_t val;
int32_t xor=(signp?0:0x80000000UL);
float scale=1./2147483648.;
......@@ -702,8 +701,7 @@ static void LEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=(readbuf[k]<<24)^xor;
data[j][i]=(val==0x7f000000?1.:val*scale);
data[j][i]=((readbuf[k]<<24)^xor)*scale;
k++;
}
break;
......@@ -712,8 +710,7 @@ static void LEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=((readbuf[k]<<16)|(readbuf[k+1]<<24))^xor;
data[j][i]=(val==0x7fff0000?1.:val*scale);
data[j][i]=(((readbuf[k]<<16)|(readbuf[k+1]<<24))^xor)*scale;
k+=2;
}
break;
......@@ -722,8 +719,7 @@ static void LEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=((readbuf[k]<<8)|(readbuf[k+1]<<16)|(readbuf[k+2]<<24))^xor;
data[j][i]=(val==0x7fffff00?1.:val*scale);
data[j][i]=(((readbuf[k]<<8)|(readbuf[k+1]<<16)|(readbuf[k+2]<<24))^xor)*scale;
k+=3;
}
break;
......@@ -732,8 +728,7 @@ static void LEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=((readbuf[k])|(readbuf[k+1]<<8)|(readbuf[k+2]<<16)|(readbuf[k+3]<<24))^xor;
data[j][i]=(val==0x7fffffff?1.:val*scale);
data[j][i]=(((readbuf[k])|(readbuf[k+1]<<8)|(readbuf[k+2]<<16)|(readbuf[k+3]<<24))^xor)*scale;
k+=4;
}
break;
......@@ -744,7 +739,6 @@ static void BEconvert(float **data,
unsigned char *readbuf, int dataoff,
int ch,int bytes, int signp, int n){
int i,j,k=0;
int32_t val;
int32_t xor=(signp?0:0x80000000UL);
float scale=1./2147483648.;
......@@ -754,8 +748,7 @@ static void BEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=(readbuf[k]<<24)^xor;
data[j][i]=(val==0x7f000000?1.:val*scale);
data[j][i]=((readbuf[k]<<24)^xor)*scale;
k++;
}
break;
......@@ -764,8 +757,7 @@ static void BEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=((readbuf[k+1]<<16)|(readbuf[k]<<24))^xor;
data[j][i]=(val==0x7fff0000?1.:val*scale);
data[j][i]=(((readbuf[k+1]<<16)|(readbuf[k]<<24))^xor)*scale;
k+=2;
}
break;
......@@ -774,8 +766,7 @@ static void BEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=((readbuf[k+2]<<8)|(readbuf[k+1]<<16)|(readbuf[k]<<24))^xor;
data[j][i]=(val==0x7fffff00?1.:val*scale);
data[j][i]=(((readbuf[k+2]<<8)|(readbuf[k+1]<<16)|(readbuf[k]<<24))^xor)*scale;
k+=3;
}
break;
......@@ -784,8 +775,7 @@ static void BEconvert(float **data,
for(i=dataoff;i<dataoff+n;i++)
for(j=0;j<ch;j++){
val=((readbuf[k+3])|(readbuf[k+2]<<8)|(readbuf[k+1]<<16)|(readbuf[k]<<24))^xor;
data[j][i]=(val==0x7fffffff?1.:val*scale);
data[j][i]=(((readbuf[k+3])|(readbuf[k+2]<<8)|(readbuf[k+1]<<16)|(readbuf[k]<<24))^xor)*scale;
k+=4;
}
break;
......
......@@ -53,10 +53,6 @@ sig_atomic_t main_looping;
char *configfile="postfish-staterc";
char *version;
static void cleanup(void){
save_state();
}
void clean_exit(int sig){
signal(sig,SIG_IGN);
if(sig!=SIGINT){
......@@ -72,18 +68,17 @@ void clean_exit(int sig){
"bug as quickly as possible.\n\n"
"-- monty@xiph.org, Postfish revision %s\n\n",sig,version);
configfile="postfish-staterc-crashsave";
cleanup();
exit(0);
}else{
output_halt_playback();
}
/* otherwise we want a clean SIGINT exit */
if(main_looping)
save_state();
if(main_looping){
main_looping=0;
gtk_main_quit();
else{
cleanup();
exit(0);
}
exit(0);
}
const char *optstring = "-c:gh";
......@@ -243,9 +238,18 @@ int main(int argc, char **argv){
/* We do not care about FPEs; rather, underflow is nominal case, and
its better to ignore other traps in production than to crash the
app. Please inform the FPU of this. */
#ifndef DEBUG
fedisableexcept(FE_INVALID);
fedisableexcept(FE_INEXACT);
fedisableexcept(FE_UNDERFLOW);
fedisableexcept(FE_OVERFLOW);
#else
feenableexcept(FE_INVALID);
feenableexcept(FE_INEXACT);
feenableexcept(FE_UNDERFLOW);
feenableexcept(FE_OVERFLOW);
#endif
/* Linux Altivec support has a very annoying problem; by default,
math on denormalized floats will simply crash the program. FFTW3
......@@ -317,6 +321,9 @@ int main(int argc, char **argv){
}
/* probe outputs */
if(setvbuf(stdout, NULL, _IONBF , 0))
fprintf(stderr,"Unable to remove block buffering on stdout; continuing\n");
output_probe_stdout(STDOUT_FILENO);
output_probe_monitor();
......@@ -355,9 +362,6 @@ int main(int argc, char **argv){
mainpanel_go(argc,argv,input_ch);
output_halt_playback();
cleanup();
return(0);
}
......@@ -365,3 +369,4 @@ int main(int argc, char **argv){
......@@ -36,6 +36,7 @@
static postfish_mainpanel p;
extern char *configfile;
extern sig_atomic_t main_looping;
static void action_setb_to(postfish_mainpanel *p,const char *time);
static void action_seta_to(postfish_mainpanel *p,const char *time);
......@@ -204,7 +205,7 @@ static int reanimate_fish(postfish_mainpanel *p){
if(p->fishframe==0 && !playback_active){
/* reschedule to blink */
p->fishframe_timer=
gtk_timeout_add(rand()%1000*30,(GtkFunction)reanimate_fish,p);
g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,p);
return FALSE;
}
}else{
......@@ -220,13 +221,13 @@ static int reanimate_fish(postfish_mainpanel *p){
if(p->fishframe==12){
/* reschedule to animate */
p->fishframe_timer=
gtk_timeout_add(10,(GtkFunction)reanimate_fish,p);
g_timeout_add(10,(GSourceFunc)reanimate_fish,p);
return FALSE;
}
if(p->fishframe==0){
/* reschedule to blink */
p->fishframe_timer=
gtk_timeout_add(rand()%1000*30,(GtkFunction)reanimate_fish,p);
g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,p);
return FALSE;
}
}
......@@ -235,13 +236,13 @@ static int reanimate_fish(postfish_mainpanel *p){
static void animate_fish(postfish_mainpanel *p){
if(p->fishframe_init){
gtk_timeout_remove(p->fishframe_timer);
g_source_remove(p->fishframe_timer);
p->fishframe_timer=
gtk_timeout_add(80,(GtkFunction)reanimate_fish,p);
g_timeout_add(80,(GSourceFunc)reanimate_fish,p);
}else{
p->fishframe_init=1;
p->fishframe_timer=
gtk_timeout_add(rand()%1000*30,(GtkFunction)reanimate_fish,p);
g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,p);
}
}
......@@ -338,14 +339,17 @@ static void action_setb(GtkWidget *widget,postfish_mainpanel *p){
}
static void shutdown(void){
gtk_main_quit ();
output_halt_playback();
save_state();
main_looping=0;
gtk_main_quit();
}
static void masterdB_change(GtkWidget *dummy, gpointer in){
postfish_mainpanel *p=in;
char buf[80];
float val=multibar_get_value(MULTIBAR(p->masterdB_s),0);
sprintf(buf,"%.1fdB",val);
sprintf(buf,"%+5.1fdB",val);
readout_set(READOUT(p->masterdB_r),buf);
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->masterdB_a)))
......@@ -1056,9 +1060,9 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
}
mainpanel_chentry(panel,channeltable,"_Declip ",0,clippanel_create,0);
mainpanel_chentry(panel,channeltable,"_Multicomp ",1,0,compandpanel_create_channel);
mainpanel_chentry(panel,channeltable,"_Singlecomp ",2,0,singlepanel_create_channel);
mainpanel_chentry(panel,channeltable,"De_verb ",3,suppresspanel_create_channel,0);
mainpanel_chentry(panel,channeltable,"De_verb ",1,suppresspanel_create_channel,0);
mainpanel_chentry(panel,channeltable,"_Multicomp ",2,0,compandpanel_create_channel);
mainpanel_chentry(panel,channeltable,"_Singlecomp ",3,0,singlepanel_create_channel);
mainpanel_chentry(panel,channeltable,"_EQ ",4,0,eqpanel_create_channel);
mainpanel_chentry(panel,channeltable,"_Reverb ",5,0,reverbpanel_create_channel);
mainpanel_chentry(panel,channeltable,"Atten/Mi_x ",6,attenpanel_create,
......@@ -1130,9 +1134,6 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
G_CALLBACK (shutdown), NULL);
g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
G_CALLBACK (shutdown), NULL);
gtk_widget_show_all(panel->toplevel);
gtk_window_set_resizable(GTK_WINDOW(panel->toplevel),0);
......@@ -1181,7 +1182,7 @@ static void feedback_process(postfish_mainpanel *panel){
}
multibar_set(MULTIBAR(panel->outbar),rms,peak,input_ch,current_p);
multibar_set(MULTIBAR(panel->outbar),rms,peak,OUTPUT_CHANNELS,current_p);
if(pull_input_feedback(peak,rms,&time_cursor)){
for(i=0;i<input_ch;i++){
......@@ -1237,7 +1238,6 @@ static int look_for_gtkrc(char *filename){
}
#include <stdlib.h>
extern sig_atomic_t main_looping;
void mainpanel_go(int argc,char *argv[], int ch){
char *homedir=getenv("HOME");
char *labels[33];
......
......@@ -268,9 +268,13 @@ time_linkage *mix_read(time_linkage *in,
/* fillstate here is only used for lazy initialization/reset */
if(ms.fillstate==0){
/* zero the cache */
for(i=0;i<input_ch;i++){
for(i=0;i<input_ch;i++){
memset(ms.cacheP[i],0,sizeof(**ms.cacheP)*input_size);
memset(ms.cachePP[i],0,sizeof(**ms.cachePP)*input_size);
memset(ms.cachePA[i],0,sizeof(**ms.cachePA)*input_size);
memset(ms.cachePPA[i],0,sizeof(**ms.cachePPA)*input_size);
memset(ms.cachePB[i],0,sizeof(**ms.cachePB)*input_size);
memset(ms.cachePPB[i],0,sizeof(**ms.cachePPB)*input_size);
}
memcpy(ms.prev,ms.curr,sizeof(*mix_set)*input_ch);
ms.fillstate=1;
......
......@@ -552,7 +552,7 @@ static void draw(GtkWidget *widget,int n){
gdk_draw_polygon(m->backing,gc,TRUE,p,7);
gdk_draw_lines(m->backing,dark_gc,d,3);
if(m->thumbfocus==j){
if(m->thumbfocus==j && m->widgetfocus){
if(x&1)
gdk_gc_set_stipple(black_gc,stipple);
else
......@@ -632,6 +632,7 @@ static gboolean multibar_focus (GtkWidget *widget,
int ret=TRUE;
if(m->thumbs==0)return FALSE;
if(!m->widgetfocus)m->thumbfocus=-1;
switch(direction){
case GTK_DIR_TAB_FORWARD:
......@@ -666,15 +667,16 @@ static gboolean multibar_focus (GtkWidget *widget,
ret=TRUE;
}else{
transition_thumbfocus=m->thumbfocus;
m->thumbfocus=-1;
ret=FALSE;
}
break;
default:
m->thumbfocus=-1;
ret=FALSE;
}
m->prev_thumbfocus=m->thumbfocus;
if(ret==TRUE) gtk_widget_grab_focus(widget);
draw_and_expose(widget);
......@@ -683,40 +685,38 @@ static gboolean multibar_focus (GtkWidget *widget,
static gint determine_thumb(Multibar *m,int ix, int iy){
GtkWidget *widget=GTK_WIDGET(m);
int height=widget->allocation.height;
int max=widget->allocation.height;
float distances[3]={-1,-1,-1};
int thumb=-1;
/* lower thumb */
/* center thumb */
if(m->thumbs==1 || m->thumbs>2){
int num=(m->thumbs==1?0:1);
int x= ix-m->thumbpixel[num];
int y= iy-(height*4/5-2);
distances[num]=sqrt(x*x + y*y);
int x= m->thumbpixel[num]-ix;
distances[num]=fabs(x);
}
/* left thumb */
if(m->thumbs>1){
int x= ix-(m->thumbpixel[0]-(height/2));
int y= iy-(height/2-3);
distances[0]=sqrt(x*x + y*y);
int x= m->thumbpixel[0]-ix;
distances[0]=fabs(x-.1);
}
/* right thumb */
if(m->thumbs>1){
int num=(m->thumbs==2?1:2);
int x= ix-(m->thumbpixel[num]+(height/2));
int y= iy-(height/2-3);
distances[num]=sqrt(x*x + y*y);
}
int x= m->thumbpixel[num]-ix;
distances[num]=fabs(x+.1);
}
if(m->thumbs && distances[0]<height)thumb=0;
if(m->thumbs>1 && distances[1]<height)
if(m->thumbs && distances[0]<max)thumb=0;
if(m->thumbs>1 && distances[1]<max)
if(thumb == -1 || distances[1]<distances[0])thumb=1;
if(m->thumbs>2 && distances[2]<height)
if(m->thumbs>2 && distances[2]<max)
if(thumb == -1 || (distances[2]<distances[0] &&
distances[2]<distances[1]))thumb=2;
if(m->thumbs>2 && distances[1]<max/2)thumb=1;
return thumb;
}
......@@ -844,47 +844,60 @@ static void vals_bound(Multibar *m){
}
}
}
}
static gint lightme(GtkWidget *w,gint x,gint y){
Multibar *m=MULTIBAR(w);
int thumb=determine_thumb(m,x,y);
GtkStateType thumbstate[3];
thumbstate[0]=GTK_STATE_NORMAL;
thumbstate[1]=GTK_STATE_NORMAL;
thumbstate[2]=GTK_STATE_NORMAL;
if(thumb>=0)thumbstate[thumb]=GTK_STATE_PRELIGHT;
if(thumbstate[0]!=m->thumbstate[0] ||
thumbstate[1]!=m->thumbstate[1] ||
thumbstate[2]!=m->thumbstate[2]){
m->thumbstate[0]=thumbstate[0];
m->thumbstate[1]=thumbstate[1];
m->thumbstate[2]=thumbstate[2];
draw_and_expose(w);
}
return TRUE;
}
static gint multibar_motion(GtkWidget *w,
GdkEventMotion *event){
Multibar *m=MULTIBAR(w);
/* is a thumb already grabbed? */
if(m->thumbgrab>=0){
int x=event->x+m->thumbx;
float v;
x=pixel_bound(m,x);
m->thumbval[m->thumbgrab]=pixel_to_val(m,x);
vals_bound(m);
v=m->thumbval[m->thumbgrab];
x=m->thumbpixel[m->thumbgrab]=val_to_pixel(m,v);
if(m->callback)m->callback(GTK_WIDGET(m),m->callbackp);
draw_and_expose(w);
}else{
/* nothing grabbed right now; determine if we're in a a thumb's area */
int thumb=determine_thumb(m,event->x-m->xpad,event->y);
GtkStateType thumbstate[3];
thumbstate[0]=GTK_STATE_NORMAL;
thumbstate[1]=GTK_STATE_NORMAL;
thumbstate[2]=GTK_STATE_NORMAL;
if(thumb>=0)thumbstate[thumb]=GTK_STATE_PRELIGHT;
if(thumbstate[0]!=m->thumbstate[0] ||
thumbstate[1]!=m->thumbstate[1] ||
thumbstate[2]!=m->thumbstate[2]){
m->thumbstate[0]=thumbstate[0];
m->thumbstate[1]=thumbstate[1];
m->thumbstate[2]=thumbstate[2];
draw_and_expose(w);
}
lightme(w,event->x-m->xpad,event->y);
}
return TRUE;
}
static gint multibar_enter(GtkWidget *w,
GdkEventCrossing *event){
Multibar *m=MULTIBAR(w);
lightme(w,event->x-m->xpad,event->y);
return TRUE;
}
......@@ -893,9 +906,9 @@ static gint multibar_leave(GtkWidget *widget,
Multibar *m=MULTIBAR(widget);
if(m->thumbgrab<0){
if(0!=m->thumbstate[0] ||
0!=m->thumbstate[1] ||
0!=m->thumbstate[2]){
if(m->thumbstate[0] ||
m->thumbstate[1] ||
m->thumbstate[2]){
m->thumbstate[0]=0;
m->thumbstate[1]=0;
m->thumbstate[2]=0;
......@@ -909,17 +922,19 @@ static gint multibar_leave(GtkWidget *widget,
static gboolean button_press (GtkWidget *widget,
GdkEventButton *event){
Multibar *m=MULTIBAR(widget);
if(m->thumbstate[0]){
int thumb=determine_thumb(m,event->x-m->xpad,event->y);