예제 #1
0
파일: xskin_c.c 프로젝트: agangzz/timidity
static void ctl_lyric(int lyricid)
{
    char *lyric;
	static int lyric_col = 2;
	static char lyric_buf[300];

    lyric = event2string(lyricid);
    if(lyric != NULL)
    {
	if(lyric[0] == ME_KARAOKE_LYRIC)
	{
	    if(lyric[1] == '/' || lyric[1] == '\\')
	    {
		lyric_buf[0] = 'L';
		lyric_buf[1] = ' ';
		snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "%s", lyric + 2);
		xskin_pipe_write(lyric_buf);
		lyric_col = strlen(lyric + 2) + 2;
	    }
	    else if(lyric[1] == '@')
	    {
		lyric_buf[0] = 'L';
		lyric_buf[1] = ' ';
		if(lyric[2] == 'L')
		    snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "Language: %s", lyric + 3);
		else if(lyric[2] == 'T')
		    snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "Title: %s", lyric + 3);
		else
		    snprintf(lyric_buf + 2, sizeof (lyric_buf) - 2, "%s", lyric + 1);
		xskin_pipe_write(lyric_buf);
	    }
	    else
	    {
		lyric_buf[0] = 'L';
		lyric_buf[1] = ' ';
		snprintf(lyric_buf + lyric_col, sizeof (lyric_buf) - lyric_col, "%s", lyric + 1);
		xskin_pipe_write(lyric_buf);
		lyric_col += strlen(lyric + 1);
	    }
	}
	else
	{
	    if(lyric[0] == ME_CHORUS_TEXT || lyric[0] == ME_INSERT_TEXT)
		lyric_col = 0;
	    snprintf(lyric_buf + lyric_col, sizeof (lyric_buf) - lyric_col, "%s", lyric + 1);
	    xskin_pipe_write(lyric_buf);
	}
    }
}
예제 #2
0
static void pauseOff()
{
    if(fpause) {
	fpause = 0;
	xskin_pipe_write("U");
    }
}
예제 #3
0
static void pauseOn()
{
    if(!fpause) {
	fpause = 1;
	xskin_pipe_write("U");
    }
}
예제 #4
0
파일: xskin_c.c 프로젝트: agangzz/timidity
static int cmsg(int type, int verbosity_level, char *fmt, ...) {

  va_list ap;
  if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
      ctl.verbosity<verbosity_level)
    return 0;

  va_start(ap, fmt);

#ifdef MSGWINDOW
  if(!xskin_ready)
#endif
  {
    vfprintf(stderr, fmt, ap);
    fprintf(stderr, NLS);
    va_end(ap);
    return 0;
  }

  vsnprintf(local_buf+2,100,fmt,ap);
  if(pipe_out_fd==-1) {
      fputs(local_buf + 2, stderr);
      fputs(NLS, stderr);
  } else {
    local_buf[0]='L';
    local_buf[1]=' ';
    xskin_pipe_write(local_buf);
  }
  va_end(ap);
  return 0;
}
예제 #5
0
파일: xskin_c.c 프로젝트: agangzz/timidity
static void ctl_close(void)
{
  if (ctl.opened) {
    xskin_pipe_write("Q");
    ctl.opened=0;
    pipe_out_fd=-1;
    xskin_ready = 0;
  }
}
예제 #6
0
파일: xskin_c.c 프로젝트: agangzz/timidity
static void ctl_current_time(int sec, int v) {

  static int previous_sec=-1;
  if (sec!=previous_sec) {
    previous_sec=sec;
    sprintf(local_buf,"T %02d:%02d",sec/60,sec%60);
    xskin_pipe_write(local_buf);
  }
}
예제 #7
0
파일: xskin_c.c 프로젝트: agangzz/timidity
static void ctl_speana_data(double *val, int size) {

  /* 0 <= val[n] <= (AMP*NCOLOR) */
  /* AMP and NCOLOR are defined in soundspec.c */
  /* By default, AMP*NCOLOR = 1.0*64 */

  /* size = FFTSIZE/2 = 512 */
  /* FFTSIZE is also defined in soundspec.c */

  /* val[n] is the value of FFTed audio data */

#ifdef SUPPORT_SOUNDSPEC
  int i;
  int tx,x;
  double px;
  double s,a;
  int n;

  if ( isspeanaenabled ) {

    px=0.0;
    speana_buf[0] = (unsigned char)val[0];
    for ( i=1 ; i<SPE_W-1 ; i++ ) {
      s=0.0;
      n=0;
      tx=exp_hz_table[i];
      x=(int)px;

      do {
	a=val[x];
	s += a + (tx-x)*(val[x+1]-a);
	n++;
	x++;
      } while ( x<tx );

      s/=n;
      s*=16;
      if ( s<0 ) s=0;
      if ( s>=NCOLOR ) s=NCOLOR-1;
      speana_buf[i] = (unsigned char)(256*s/NCOLOR);
      px=tx;
    }
    speana_buf[SPE_W-1] = val[FFTSIZE/2-1];

    xskin_pipe_write( "W" );

  }
#endif /* SUPPORT_SOUNDSPEC */

  return;
}
예제 #8
0
파일: xskin_c.c 프로젝트: agangzz/timidity
/*ARGSUSED*/
static void ctl_master_volume(int mv) {

  static int lastvol = CTL_LAST_STATUS;

  if ( mv != lastvol ) {
    if ( mv == CTL_LAST_STATUS ) mv = lastvol;
    else lastvol = mv;
    
    sprintf( local_buf, "V %d", mv );
    xskin_pipe_write(local_buf);
  }

  return;
}
예제 #9
0
파일: xskin_c.c 프로젝트: agangzz/timidity
/*ARGSUSED*/
static void ctl_total_time(int tt) {

  static int previous_total_time=-1;
  int sec,min;

  sec=tt/play_mode->rate;
  min = sec/60;
  sec-= min*60;

  if ( tt!=previous_total_time ) {
    previous_total_time=tt;
    sprintf(local_buf,"A %d",min*60+sec);
    xskin_pipe_write(local_buf);
  }

  return;
}
예제 #10
0
static void xskin_jobs( int pipe_in ) {
  XEvent e;
  int x,y;
  int window_x,window_y;
  int fspe=0;
  int pr=-1;
  int z;
  int p;
  int master_volume=0;
  char file_name[1024], tmp[1024];

  int last_puttext_time;
  int last_window_x=-1, last_window_y=-1;

  int max_files;
  int i;
  fd_set fds;
  static struct timeval tv;

  Window t_w;
  unsigned int t_width, t_height, t_border, t_depth;

  xskin_pipe_write( "READY" );

  shmid = shmget( IPC_PRIVATE, sizeof(char)*SPE_W, IPC_CREAT|0600 );
  if ( shmid<0 ) xskin_pipe_write( "ERROR" );
  else {
    sprintf( local_buf, "%d", shmid );
    xskin_pipe_write( local_buf );
    speana_buf = (unsigned char *)shmat( shmid, 0, 0 );
  }

  xskin_pipe_read( local_buf, sizeof(local_buf) );
  max_files = atoi( local_buf );
  for ( i=0 ; i<max_files ; i++ ) {
    xskin_pipe_read( local_buf, sizeof(local_buf) );
  }

  z=1;
  last_puttext_time=0;
  last_current_time=0;

  XGetGeometry( xskin_d, xskin_w, &t_w,
		&window_x, &window_y,
		&t_width, &t_height, &t_border, &t_depth );

  while( z ) {

    XFlush( xskin_d );

    FD_ZERO( &fds );
    FD_SET( pipe_in, &fds );
    tv.tv_sec=0;
    tv.tv_usec=20000L; /* 20 msec */
    i=select( pipe_in+1, &fds, NULL, NULL, &tv );

    if ( i!=0 ) {
      xskin_pipe_read( local_buf, sizeof(local_buf) );
      switch (local_buf[0]) {

      case 'A': /* total time */
	total_time=atoi( local_buf+2 );
	last_current_time=0;
	last_puttext_time=0;
	break;
	
      case 'T': /* current time */
	{
	  int min,sec;
	  sscanf( local_buf+2, "%02d:%02d", &min, &sec );
	  i=min*60+sec;
	  if ( fremain==1 ) {
	    sec =total_time-i;
	    min =sec/60;
	    sec-=min*60;
	  }
	  if ( i != last_current_time ) {
	    ts_putnum( MIN_H_X, MIN_H_Y, min/10 );
	    ts_putnum( MIN_L_X, MIN_L_Y, min%10 );
	    ts_putnum( SEC_H_X, SEC_H_Y, sec/10 );
	    ts_putnum( SEC_L_X, SEC_L_Y, sec%10 );
	    p=100*i/total_time;
	    play_val=ts_pos( OFF, -p );
	    last_current_time=i;

	    if ( last_current_time - last_puttext_time == 3 ) { /* 3 sec */
	      sprintf( tmp, "%s [%02d:%02d]",
		       file_name, total_time/60, total_time%60 );
	      ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	    }
	  }
	}
      break;

      case 'L': /* lylics/message */
	ts_puttext( MESSAGE_X, MESSAGE_Y, local_buf+2 );
	last_puttext_time=last_current_time;
	break;

      case 'F': /* filename */
	strncpy( file_name, local_buf+2, 1023 );
	file_name[1023]=0;
	break;

      case 'O': /* off the play button */
	fplay=0;
	ts_play(OFF);
	ts_spectrum(fspe, NULL); /* erase spectrums */
	break;

      case 'V': /* master volume */
	master_volume=atoi( local_buf+2 );
	p=100*((master_volume<200)?master_volume:200)/200; /* max:200% */
	vol_val=ts_volume( OFF, -p );
	break;

      case 'Q': /* quit */
	z=1;
	break;

      case 'W': /* wave form */
	ts_spectrum(fspe, speana_buf);
	break;

      default:
	break;
      }
    }

    if ( XPending( xskin_d )==0 ) continue;
    XNextEvent( xskin_d, &e );

    switch ( e.type ) {
      /*
    case KeyPress:
      z=0;
      break;
      */
   
    case Expose:
      repaint();
      break;

    case EnterNotify:
      {
	Cursor cs;
	ts_titlebar(ON);
	cs = XCreateFontCursor( xskin_d, XC_top_left_arrow );
	XDefineCursor( xskin_d, xskin_w, cs );
      }
      break;

    case LeaveNotify:
      ts_titlebar(OFF);
      XUndefineCursor( xskin_d, xskin_w );
      break;

    case MotionNotify:
      while( XCheckMaskEvent( xskin_d, Button1MotionMask, &e ) ) {
	XNextEvent( xskin_d, &e );
      }
      x = e.xbutton.x;
      y = e.xbutton.y;
      switch( pr ) {
	
	/*
      case TS_POS:
	play_val=ts_pos( ON, x );break;
	*/
      case TS_VOLUME:
	vol_val=ts_volume( ON, x );
	i=master_volume;
	master_volume=200*vol_val/100;
	sprintf( local_buf, "V %d", master_volume-i );
	xskin_pipe_write( local_buf );

	sprintf( tmp, " volume: %d%%", vol_val );
	ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	last_puttext_time=last_current_time;
	break;
	/*
      case TS_PAN:
	pan_val=ts_pan( ON, x );break;
	*/
	
      default:
	if ( x != last_window_x || y != last_window_y ) {
	  window_x += x-last_window_x;
	  window_y += y-last_window_y;
	  XMoveWindow( xskin_d, xskin_w,
		       window_x, window_y );
	}
	break;
      }
      break;

    case ButtonPress:
      x = e.xbutton.x;
      y = e.xbutton.y;
      last_window_x=x;
      last_window_y=y;

             if ( ISIN( x, y,EXITBUTTON_DX,EXITBUTTON_DY,
			EXITBUTTON_W,EXITBUTTON_H ) ) {
        ts_exitbutton(ON);pr=TS_EXITBUTTON;

      } else if ( ISIN( x, y, PREV_DX, PREV_DY, PREV_W, PREV_H ) ) {
	ts_prev(ON);pr=TS_PREV;
      } else if ( ISIN( x, y, PLAY_DX, PLAY_DY, PLAY_W, PLAY_H ) ) {
	ts_play(ON);pr=TS_PLAY;
      } else if ( ISIN( x, y, PAUSE_DX, PAUSE_DY, PAUSE_W, PAUSE_H ) ) {
	ts_pause(ON);pr=TS_PAUSE;
      } else if ( ISIN( x, y, STOP_DX, STOP_DY, STOP_W, STOP_H ) ) {
	ts_stop(ON);pr=TS_STOP;
      } else if ( ISIN( x, y, NEXT_DX, NEXT_DY, NEXT_W, NEXT_H ) ) {
	ts_next(ON);pr=TS_NEXT;
      } else if ( ISIN( x, y, EJECT_DX, EJECT_DY, EJECT_W, EJECT_H ) ) {
	ts_eject(ON);pr=TS_EJECT;

      } else if ( ISIN( x, y,164, 89, 47, 15 ) ) {  /* shuffle */
	if ( fshuf==0 ) {
	  ts_shuf(OFFON);pr=TS_SHUFON;
	} else { 
	  ts_shuf(ONOFF);pr=TS_SHUFOFF;
	}
      } else if ( ISIN( x, y,210, 89, 28, 15 ) ) {  /* repeat */
	if ( frep==0 ) {
	  ts_rep(OFFON);pr=TS_REPON;
	} else {
	  ts_rep(ONOFF);pr=TS_REPOFF;
	}
      } else if ( ISIN( x, y,219, 58, 23, 12 ) ) {  /* equalizer */
	if ( fequ==0 ) {
	  ts_equ(OFFON);pr=TS_EQUON;
	} else {
	  ts_equ(ONOFF);pr=TS_EQUOFF;
	}
      } else if ( ISIN( x, y,242, 58, 23, 12 ) ) {  /* playlist */
	if ( fpll==0 ) {
	  ts_plist(OFFON);pr=TS_PLISTON;
	} else {
	  ts_plist(ONOFF);pr=TS_PLISTOFF;
	}

      } else if ( ISIN( x, y, MENUBUTTON_DX, MENUBUTTON_DY,
			MENUBUTTON_W, MENUBUTTON_H ) ) {
	ts_menubutton(ON);pr=TS_MENUBUTTON;
      } else if ( ISIN( x, y, ICONBUTTON_DX, ICONBUTTON_DY,
			ICONBUTTON_W, ICONBUTTON_H ) ) {
	ts_iconbutton(ON);pr=TS_ICONBUTTON;
      } else if ( ISIN( x, y, MINIBUTTON_DX, MINIBUTTON_DY,
			MINIBUTTON_W, MINIBUTTON_H ) ) {
	ts_minibutton(ON);pr=TS_MINIBUTTON;

	/*
      }	else if ( ISIN( x, y,POS_MIN_DX+(POS_MAX_DX-POS_MIN_DX)*play_val/100,
			POS_DY, POS_W, POS_H ) ) {
	ts_pos( ON, -play_val );pr=TS_POS;
	*/
      } else if ( ISIN( x, y,VOL_MIN_DX+(VOL_MAX_DX-VOL_MIN_DX)*vol_val/100,
			VOL_DY, VOL_W, VOL_H ) ) {
	ts_volume( ON, -vol_val );pr=TS_VOLUME;
	sprintf( tmp, " volume: %d%%", vol_val );
	ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	last_puttext_time=last_current_time;

	/*
      } else if ( ISIN( x, y,PAN_MIN_DX+(PAN_MAX_DX-PAN_MIN_DX)*pan_val/100,
			PAN_DY, PAN_W, PAN_H ) ) {
	ts_pan( ON, -pan_val );pr=TS_PAN;
	*/

      } else if ( ISIN( x, y, MIN_H_X, MIN_H_Y,
			SEC_L_X+NUM_W-MIN_H_X, NUM_H ) ) {
	int min,sec;
	fremain=(fremain==0)?1:0;
	sec=(fremain==0)?last_current_time:total_time-last_current_time;
	min =sec/60;
	sec-=min*60;
	ts_putnum( MIN_H_X, MIN_H_Y, min/10 );
	ts_putnum( MIN_L_X, MIN_L_Y, min%10 );
	ts_putnum( SEC_H_X, SEC_H_Y, sec/10 );
	ts_putnum( SEC_L_X, SEC_L_Y, sec%10 );

      } else if ( ISIN( x, y, SPE_SX, SPE_SY, SPE_W, SPE_H ) ) {
	pr=TS_SPECTRUM;
      } else {
	XRaiseWindow( xskin_d, xskin_w );
      }
	     break;  

    case ButtonRelease:

      last_window_x = -1;
      last_window_y = -1;

      switch( pr ) {

      case TS_EXITBUTTON:
	ts_exitbutton(OFF);
	xskin_pipe_write("Q");
	z=0;break;

      case TS_PREV:
	ts_prev(OFF);
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("B");
	break;
      case TS_PLAY:
	xskin_pipe_write("P");
	fplay=1;
	pauseOff();
	ts_play(OFF);ts_pause(OFF);
	ts_pstate( PSTATE_PLAY );
	break;
      case TS_PAUSE:
	ts_pause(OFF);
	if ( fplay ==1 ) {
	  if ( fpause==0 ) {
	    ts_pstate( PSTATE_PAUSE );
	    ts_spectrum( fspe, NULL );
	    pauseOn();
	  } else {
	    ts_pstate( PSTATE_PLAY );
	    pauseOff();
	  }
	}
	break;
      case TS_STOP:
	pauseOff();
	fplay=0;
	ts_pause(OFF);ts_play(OFF);ts_stop(OFF);
	ts_pstate( PSTATE_STOP );
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("S");
	break;
      case TS_NEXT:
	ts_next(OFF);
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("N");
	break;
      case TS_EJECT:
	ts_eject(OFF);break;

      case TS_SHUFON:
	ts_shuf(ON);fshuf=1;
	fplay=1;
	pauseOff();
	ts_pstate( PSTATE_PLAY );
	xskin_pipe_write("D 1");
	break;
      case TS_SHUFOFF:
	ts_shuf(OFF);fshuf=0;
	fplay=0;
	pauseOff();
	ts_pstate( PSTATE_STOP );
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("D 2");
	break;
      case TS_REPON:
	ts_rep(ON);frep=1;
	xskin_pipe_write("R 1");
	break;
      case TS_REPOFF:
	ts_rep(OFF);frep=0;
	xskin_pipe_write("R 0");
	break;

      case TS_EQUON:
	ts_equ(ON);fequ=1;break;
      case TS_EQUOFF:
	ts_equ(OFF);fequ=0;break;

      case TS_PLISTON:
	ts_plist(ON);fpll=1;break;
      case TS_PLISTOFF:
	ts_plist(OFF);fpll=0;break;

      case TS_MENUBUTTON:
	ts_menubutton(OFF);break;
      case TS_ICONBUTTON:
	ts_iconbutton(OFF);break;
      case TS_MINIBUTTON:
	ts_minibutton(OFF);break;

	/*
      case TS_POS:
	ts_pos( OFF, -play_val );break;
	*/
      case TS_VOLUME:
	ts_volume( OFF, -vol_val );break;
	/*
      case TS_PAN:
	ts_pan( OFF, -pan_val );break;
	*/

      case TS_SPECTRUM:
#ifdef SUPPORT_SOUNDSPEC
	fspe = (fspe+1)%3;
	if ( fspe==1 ) xskin_pipe_write("W");      /* on */
	else if ( fspe==0 ) {
	  xskin_pipe_write("W"); /* off */
	  ts_spectrum(0,speana_buf);
	}
#endif /* SUPPORT_SOUNDSPEC */
	break;

      default:
	break;
      }
      pr=-1;
      break;

    default:
      break;
    }
  }

  return;
}
예제 #11
0
파일: xskin_c.c 프로젝트: agangzz/timidity
static int ctl_pass_playing_list(int number_of_files, char *list_of_files[]) {

  int current_no,command,i;
  int32 val;
  int *file_table;
  char **titles;
  char *p;

  /* Wait prepare 'interface' */
  xskin_pipe_read(local_buf,sizeof(local_buf));
  if (strcmp("READY",local_buf))
    return 0;
  xskin_ready = 1;

  /* receive shared memory buffer */
  xskin_pipe_read(local_buf, sizeof(local_buf));
  if (strcmp("ERROR",local_buf)) {
    int shmid;
    isspeanaenabled=1;
    shmid = atoi(local_buf);
    speana_buf = (unsigned char *)shmat(shmid,0,0);
  } else {
    isspeanaenabled=0;
  }

  /* Make title string */
  titles=(char **)safe_malloc(number_of_files*sizeof(char *));
  for (i=0;i<number_of_files;i++) {
    p=strrchr(list_of_files[i],'/');
    if (p==NULL) {
      p=list_of_files[i];
    } else p++;
    sprintf(local_buf,"%d. %s",i+1,p);
    titles[i]=(char *)safe_malloc(strlen(local_buf)+1);
    strcpy(titles[i],local_buf);
  }

  /* Send title string */
  sprintf(local_buf,"%d",number_of_files);
  xskin_pipe_write(local_buf);
  for (i=0;i<number_of_files;i++) xskin_pipe_write(titles[i]);

  /* Make the table of play sequence */
  file_table=(int *)safe_malloc(number_of_files*sizeof(int));
  for (i=0;i<number_of_files;i++) file_table[i]=i;

  /* Draw the title of the first file */
  current_no=0;
  sprintf(local_buf,"F %s",titles[file_table[0]]);
  xskin_pipe_write(local_buf);

  command=ctl_blocking_read(&val);

  /* Main loop */
  for (;;) {
    /* Play file */
    if (command==RC_LOAD_FILE) {
      sprintf(local_buf,"F %s",titles[file_table[current_no]]);
      xskin_pipe_write(local_buf);
      command=play_midi_file(list_of_files[file_table[current_no]]);
    } else {
      /* Quit timidity*/
      if (exitflag) return 0;
      /* Stop playing */
      if (command==RC_QUIT) {
	sprintf(local_buf,"T 00:00");
	xskin_pipe_write(local_buf);
	/* Shuffle the table */
	if (randomflag) {
	  current_no=0;
	  if (randomflag==1) {
	    shuffle(number_of_files,file_table);
	    randomflag=0;
	    command=RC_LOAD_FILE;
	    continue;
	  }
	  randomflag=0;
	  for (i=0;i<number_of_files;i++) file_table[i]=i;
	  sprintf(local_buf,"F %s",titles[file_table[current_no]]);
	  xskin_pipe_write(local_buf);
	}
	/* Play the selected file */
	if (selectflag) {
	  for (i=0;i<number_of_files;i++)
	    if (file_table[i]==selectflag-1) break;
	  if (i!=number_of_files) current_no=i;
	  selectflag=0;
	  command=RC_LOAD_FILE;
	  continue;
	}
      /* After the all file played */
      } else if (command==RC_TUNE_END || command==RC_ERROR) {
	if (current_no+1<number_of_files) {
	  current_no++;
	  command=RC_LOAD_FILE;
	  continue;
	/* Repeat */
	} else if (repeatflag) {
	  current_no=0;
	  command=RC_LOAD_FILE;
	  continue;
	/* Off the play button */
	} else {
	  xskin_pipe_write("O");
	}
      /* Play the next */
      } else if (command==RC_NEXT) {
	if (current_no+1<number_of_files) current_no++;
	command=RC_LOAD_FILE;
	continue;
      /* Play the previous */
      } else if (command==RC_REALLY_PREVIOUS) {
	if (current_no>0) current_no--;
	command=RC_LOAD_FILE;
	continue;
      }

      command=ctl_blocking_read(&val);
    }
  }
  return 0;
}
예제 #12
0
static void xskin_jobs( int pipe_in ) {
  XEvent e;
  int x,y;
  int window_x,window_y;
  int fspe=0;
  int pr=-1;
  int z;
  int p;
  int master_volume=0;
  char file_name[1024], tmp[1024];

  int last_puttext_time;
  int last_window_x=-1, last_window_y=-1;

  int max_files;
  int i;
  fd_set fds;
  static struct timeval tv;

  Window t_w;
  unsigned int t_width, t_height, t_border, t_depth;

  xskin_pipe_write( "READY" );

  shmid = shmget( IPC_PRIVATE, sizeof(char)*SPE_W, IPC_CREAT|0600 );
  if ( shmid<0 ) xskin_pipe_write( "ERROR" );
  else {
    sprintf( local_buf, "%d", shmid );
    xskin_pipe_write( local_buf );
    speana_buf = (unsigned char *)shmat( shmid, 0, 0 );
  }

  xskin_pipe_read( local_buf, sizeof(local_buf) );
  max_files = atoi( local_buf );
  for ( i=0 ; i<max_files ; i++ ) {
    xskin_pipe_read( local_buf, sizeof(local_buf) );
  }

  z=1;
  last_puttext_time=0;
  last_current_time=0;

  XGetGeometry( xskin_d, xskin_w, &t_w,
		&window_x, &window_y,
		&t_width, &t_height, &t_border, &t_depth );

  while( z ) {

    XFlush( xskin_d );

    FD_ZERO( &fds );
    FD_SET( pipe_in, &fds );
    tv.tv_sec=0;
    tv.tv_usec=20000L; /* 20 msec */
    i=select( pipe_in+1, &fds, NULL, NULL, &tv );

    if ( i!=0 ) {
      xskin_pipe_read( local_buf, sizeof(local_buf) );
      switch (local_buf[0]) {

      case 'A': /* total time */
	total_time=atoi( local_buf+2 );
	last_current_time=0;
	last_puttext_time=0;
	break;
	
      case 'T': /* current time */
	{
	  int min,sec;
	  sscanf( local_buf+2, "%02d:%02d", &min, &sec );
	  i=min*60+sec;
	  if ( fremain==1 ) {
	    sec =total_time-i;
	    min =sec/60;
	    sec-=min*60;
	  }
	  if ( i != last_current_time ) {
	    ts_putnum( MIN_H_X, MIN_H_Y, min/10 );
	    ts_putnum( MIN_L_X, MIN_L_Y, min%10 );
	    ts_putnum( SEC_H_X, SEC_H_Y, sec/10 );
	    ts_putnum( SEC_L_X, SEC_L_Y, sec%10 );
	    p=100*i/total_time;
	    play_val=ts_pos( OFF, -p );
	    last_current_time=i;

	    if ( last_current_time - last_puttext_time == 3 ) { /* 3 sec */
	      sprintf( tmp, "%s [%02d:%02d]",
		       file_name, total_time/60, total_time%60 );
	      ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	    }
	  }
	}
      break;

      case 'L': /* lylics/message */
	ts_puttext( MESSAGE_X, MESSAGE_Y, local_buf+2 );
	last_puttext_time=last_current_time;
	break;

      case 'F': /* filename */
	strncpy( file_name, local_buf+2, 1023 );
	file_name[1023]=0;
	break;

      case 'O': /* off the play button */
	fplay=0;
	ts_play(OFF);
	ts_spectrum(fspe, NULL); /* erase spectrums */
	break;

      case 'V': /* master volume */
	master_volume=atoi( local_buf+2 );
	p=100*((master_volume<200)?master_volume:200)/200; /* max:200% */
	vol_val=ts_volume( OFF, -p );
	break;

      case 'Q': /* quit */
	z=1;
	break;

      case 'W': /* wave form */
	ts_spectrum(fspe, speana_buf);
	break;

      default:
	break;
      }
    }

    if ( XPending( xskin_d )==0 ) continue;
    XNextEvent( xskin_d, &e );

    switch ( e.type ) {
      /*
    case KeyPress:
      z=0;
      break;
      */
   
    case Expose:
      repaint();
      break;

    case EnterNotify:
      {
	Cursor cs;
	ts_titlebar(ON);
	cs = XCreateFontCursor( xskin_d, XC_top_left_arrow );
	XDefineCursor( xskin_d, xskin_w, cs );
      }
      break;

    case LeaveNotify:
      ts_titlebar(OFF);
      XUndefineCursor( xskin_d, xskin_w );
      break;

    case MotionNotify:
      while( XCheckMaskEvent( xskin_d, Button1MotionMask, &e ) ) {
	XNextEvent( xskin_d, &e );
      }
      x = e.xbutton.x;
      y = e.xbutton.y;
      switch( pr ) {
	
	/*
      case TS_POS:
	play_val=ts_pos( ON, x );break;
	*/
      case TS_VOLUME:
	vol_val=ts_volume( ON, x );
	i=master_volume;
	master_volume=200*vol_val/100;
	sprintf( local_buf, "V %d", master_volume-i );
	xskin_pipe_write( local_buf );

	sprintf( tmp, " volume: %d%%", vol_val );
	ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	last_puttext_time=last_current_time;
	break;
	/*
      case TS_PAN:
	pan_val=ts_pan( ON, x );break;
	*/
	
      default:
	if ( x != last_window_x || y != last_window_y ) {
	  window_x += x-last_window_x;
	  window_y += y-last_window_y;
	  XMoveWindow( xskin_d, xskin_w,
		       window_x, window_y );
	}
	break;
      }
      break;

    case ButtonPress:
      x = e.xbutton.x;
      y = e.xbutton.y;
      last_window_x=x;
      last_win