~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to src/term.c

Tags: upstream-0.60
ImportĀ upstreamĀ versionĀ 0.60

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        term: terminal control
 
3
 
 
4
        copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
 
5
        see COPYING and AUTHORS files in distribution or http://mpg123.de
 
6
        initially written by Michael Hipp
 
7
*/
 
8
 
 
9
#include "config.h"
 
10
#ifdef HAVE_TERMIOS
 
11
 
 
12
#include <termios.h>
 
13
#include <unistd.h>
 
14
#include <ctype.h>
 
15
#include <sys/time.h>
 
16
#include <sys/types.h>
 
17
 
 
18
#include "debug.h"
 
19
#include "mpg123.h"
 
20
#include "buffer.h"
 
21
#include "term.h"
 
22
#include "common.h"
 
23
 
 
24
extern int buffer_pid;
 
25
 
 
26
static int term_enable = 0;
 
27
static struct termios old_tio;
 
28
 
 
29
/* initialze terminal */
 
30
void term_init(void)
 
31
{
 
32
  struct termios tio;
 
33
  debug("term_init");
 
34
 
 
35
  term_enable = 0;
 
36
 
 
37
  if(tcgetattr(0,&tio) < 0) {
 
38
    fprintf(stderr,"Can't get terminal attributes\n");
 
39
    return;
 
40
  }
 
41
  old_tio=tio;
 
42
  tio.c_lflag &= ~(ICANON|ECHO); 
 
43
  tio.c_cc[VMIN] = 1;
 
44
  tio.c_cc[VTIME] = 0;
 
45
 
 
46
  if(tcsetattr(0,TCSANOW,&tio) < 0) {
 
47
    fprintf(stderr,"Can't set terminal attributes\n");
 
48
    return;
 
49
  }
 
50
 
 
51
  term_enable = 1;
 
52
 
 
53
}
 
54
 
 
55
static long term_handle_input(struct frame *,int);
 
56
 
 
57
static int stopped = 0;
 
58
static int paused = 0;
 
59
static int pause_cycle;
 
60
 
 
61
long term_control(struct frame *fr)
 
62
{
 
63
 
 
64
  long offset = 0;
 
65
        
 
66
  if(!term_enable)
 
67
    return 0;
 
68
 
 
69
  if(paused) {
 
70
        if(!--pause_cycle) {
 
71
                pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr));
 
72
                offset-=pause_cycle;
 
73
                
 
74
                if(param.usebuffer) {
 
75
 
 
76
                        while(paused && xfermem_get_usedspace(buffermem)) {
 
77
                                
 
78
                                buffer_ignore_lowmem();
 
79
                                offset += term_handle_input(fr, TRUE);
 
80
                        }
 
81
                        if(!paused)
 
82
                                offset += pause_cycle;
 
83
                }
 
84
        }
 
85
  }
 
86
  
 
87
  do {
 
88
          offset += term_handle_input(fr, stopped);
 
89
          
 
90
  } while (stopped);
 
91
 
 
92
  return offset;
 
93
  
 
94
}
 
95
 
 
96
static long term_handle_input(struct frame *fr, int do_delay)
 
97
{
 
98
  int n = 1;
 
99
  long offset = 0;
 
100
  extern struct audio_info_struct ai;
 
101
  
 
102
  while(n > 0) {
 
103
    fd_set r;
 
104
    struct timeval t;
 
105
    char val;
 
106
 
 
107
    t.tv_sec=0;
 
108
    t.tv_usec=(do_delay) ? 1000 : 0;
 
109
    
 
110
    FD_ZERO(&r);
 
111
    FD_SET(0,&r);
 
112
    n = select(1,&r,NULL,NULL,&t);
 
113
    if(n > 0 && FD_ISSET(0,&r)) {
 
114
      if(read(0,&val,1) <= 0)
 
115
        break;
 
116
 
 
117
      switch(tolower(val)) {
 
118
        case BACK_KEY:
 
119
        if(!param.usebuffer) audio_queueflush(&ai);
 
120
          /*
 
121
           * NOTE: rd->rewind() calls buffer_resync() that blocks until
 
122
           * buffer process returns ACK. If buffer process is stopped, we
 
123
           * end up in a deadlock. The only acceptable workaround was to
 
124
           * resume playing as soon as BACK_KEY is pressed. This is not
 
125
           * necessary when running non-buffered but I chose to remain
 
126
           * compatible. [dk]
 
127
           */
 
128
          if(stopped) {
 
129
                  stopped = 0;
 
130
                  if(param.usebuffer)
 
131
                        buffer_start();
 
132
                  fprintf(stderr, "%s", EMPTY_STRING);
 
133
          }
 
134
          if(paused)
 
135
                  pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr));
 
136
          rd->rewind(rd);
 
137
          fr->num=0;
 
138
          break;
 
139
        case NEXT_KEY:
 
140
                if(!param.usebuffer) audio_queueflush(&ai);
 
141
          if (buffer_pid)
 
142
                  kill(buffer_pid, SIGINT);
 
143
          next_track();
 
144
          break;
 
145
        case QUIT_KEY:
 
146
          if (buffer_pid)
 
147
                  kill(buffer_pid, SIGTERM);
 
148
          kill(getpid(), SIGTERM);
 
149
          break;
 
150
        case PAUSE_KEY:
 
151
          paused=1-paused;
 
152
          if(paused) {
 
153
                  pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr));
 
154
                  offset -= pause_cycle;
 
155
          }
 
156
          if(stopped) {
 
157
                stopped=0;
 
158
                if(param.usebuffer)
 
159
                        buffer_start();
 
160
          }
 
161
          fprintf(stderr, "%s", (paused) ? PAUSED_STRING : EMPTY_STRING);
 
162
          break;
 
163
        case STOP_KEY:
 
164
        case ' ':
 
165
          stopped=1-stopped;
 
166
          if(paused) {
 
167
                  paused=0;
 
168
                  offset -= pause_cycle;
 
169
          }
 
170
          if(param.usebuffer) 
 
171
                  (stopped) ? buffer_stop() : buffer_start();
 
172
          fprintf(stderr, "%s", (stopped) ? STOPPED_STRING : EMPTY_STRING);
 
173
          break;
 
174
        case FINE_REWIND_KEY:
 
175
          offset--;
 
176
          break;
 
177
        case FINE_FORWARD_KEY:
 
178
          offset++;
 
179
          break;
 
180
        case REWIND_KEY:
 
181
          offset-=10;
 
182
          break;
 
183
        case FORWARD_KEY:
 
184
          offset+=10;
 
185
          break;
 
186
        case FAST_REWIND_KEY:
 
187
          offset-=50;
 
188
          break;
 
189
        case FAST_FORWARD_KEY:
 
190
          offset+=50;
 
191
          break;
 
192
        case HELP_KEY:
 
193
          fprintf(stderr,"\n\n -= terminal control keys =-\n[%c] or space bar\t interrupt/restart playback (i.e. 'pause')\n[%c]\t next track\n[%c]\t back to beginning of track\n[%c]\t pause while looping current sound chunk\n[%c]\t forward\n[%c]\t rewind\n[%c]\t fast forward\n[%c]\t fast rewind\n[%c]\t fine forward\n[%c]\t fine rewind\n[%c]\t this help\n[%c]\t quit\n\n",
 
194
                        STOP_KEY, NEXT_KEY, BACK_KEY, PAUSE_KEY, FORWARD_KEY, REWIND_KEY, FAST_FORWARD_KEY, FAST_REWIND_KEY, FINE_FORWARD_KEY, FINE_REWIND_KEY, HELP_KEY, QUIT_KEY);
 
195
        break;
 
196
        case FRAME_INDEX_KEY:
 
197
                print_frame_index(stderr);
 
198
        break;
 
199
        default:
 
200
          ;
 
201
      }
 
202
    }
 
203
  }
 
204
  return offset;
 
205
}
 
206
 
 
207
void term_restore(void)
 
208
{
 
209
  
 
210
  if(!term_enable)
 
211
    return;
 
212
 
 
213
  tcsetattr(0,TCSAFLUSH,&old_tio);
 
214
}
 
215
 
 
216
#endif
 
217