term.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #ifdef TERM_CONTROL
  2. #include <termios.h>
  3. #include <unistd.h>
  4. #include <ctype.h>
  5. #include <sys/time.h>
  6. #include <sys/types.h>
  7. #include "mpg123.h"
  8. #include "buffer.h"
  9. #include "term.h"
  10. #include "common.h"
  11. static int term_enable = 0;
  12. static struct termios old_tio;
  13. /* initialze terminal */
  14. void term_init(void)
  15. {
  16. struct termios tio;
  17. term_enable = 0;
  18. if(tcgetattr(0,&tio) < 0) {
  19. fprintf(stderr,"Can't get terminal attributes\n");
  20. return;
  21. }
  22. old_tio=tio;
  23. tio.c_lflag &= ~(ICANON|ECHO);
  24. tio.c_cc[VMIN] = 1;
  25. tio.c_cc[VTIME] = 0;
  26. if(tcsetattr(0,TCSANOW,&tio) < 0) {
  27. fprintf(stderr,"Can't set terminal attributes\n");
  28. return;
  29. }
  30. term_enable = 1;
  31. }
  32. static long term_handle_input(struct frame *,int);
  33. static int stopped = 0;
  34. static int paused = 0;
  35. static int pause_cycle;
  36. long term_control(struct frame *fr)
  37. {
  38. long offset = 0;
  39. if(!term_enable)
  40. return 0;
  41. if(paused) {
  42. if(!--pause_cycle) {
  43. pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr));
  44. offset-=pause_cycle;
  45. if(param.usebuffer) {
  46. while(paused && xfermem_get_usedspace(buffermem)) {
  47. buffer_ignore_lowmem();
  48. offset += term_handle_input(fr, TRUE);
  49. }
  50. if(!paused)
  51. offset += pause_cycle;
  52. }
  53. }
  54. }
  55. do {
  56. offset += term_handle_input(fr, stopped);
  57. } while (stopped);
  58. return offset;
  59. }
  60. static long term_handle_input(struct frame *fr, int do_delay)
  61. {
  62. int n = 1;
  63. long offset = 0;
  64. extern struct audio_info_struct ai;
  65. while(n > 0) {
  66. fd_set r;
  67. struct timeval t;
  68. char val;
  69. t.tv_sec=0;
  70. t.tv_usec=(do_delay) ? 1000 : 0;
  71. FD_ZERO(&r);
  72. FD_SET(0,&r);
  73. n = select(1,&r,NULL,NULL,&t);
  74. if(n > 0 && FD_ISSET(0,&r)) {
  75. if(read(0,&val,1) <= 0)
  76. break;
  77. switch(tolower(val)) {
  78. case BACK_KEY:
  79. audio_queueflush(&ai);
  80. /*
  81. * NOTE: rd->rewind() calls buffer_resync() that blocks until
  82. * buffer process returns ACK. If buffer process is stopped, we
  83. * end up in a deadlock. The only acceptable workaround was to
  84. * resume playing as soon as BACK_KEY is pressed. This is not
  85. * necessary when running non-buffered but I chose to remain
  86. * compatible. [dk]
  87. */
  88. if(stopped) {
  89. stopped = 0;
  90. if(param.usebuffer)
  91. buffer_start();
  92. fprintf(stderr, "%s", EMPTY_STRING);
  93. }
  94. if(paused)
  95. pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr));
  96. rd->rewind(rd);
  97. break;
  98. case NEXT_KEY:
  99. audio_queueflush(&ai);
  100. kill(0,SIGINT);
  101. break;
  102. case QUIT_KEY:
  103. kill(0,SIGTERM);
  104. break;
  105. case PAUSE_KEY:
  106. paused=1-paused;
  107. if(paused) {
  108. pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr));
  109. offset -= pause_cycle;
  110. }
  111. if(stopped) {
  112. stopped=0;
  113. if(param.usebuffer)
  114. buffer_start();
  115. }
  116. fprintf(stderr, "%s", (paused) ? PAUSED_STRING : EMPTY_STRING);
  117. break;
  118. case STOP_KEY:
  119. stopped=1-stopped;
  120. if(paused) {
  121. paused=0;
  122. offset -= pause_cycle;
  123. }
  124. if(param.usebuffer)
  125. (stopped) ? buffer_stop() : buffer_start();
  126. fprintf(stderr, "%s", (stopped) ? STOPPED_STRING : EMPTY_STRING);
  127. break;
  128. case FINE_REWIND_KEY:
  129. offset--;
  130. break;
  131. case FINE_FORWARD_KEY:
  132. offset++;
  133. break;
  134. case REWIND_KEY:
  135. offset-=10;
  136. break;
  137. case FORWARD_KEY:
  138. offset+=10;
  139. break;
  140. case FAST_REWIND_KEY:
  141. offset-=50;
  142. break;
  143. case FAST_FORWARD_KEY:
  144. offset+=50;
  145. break;
  146. default:
  147. ;
  148. }
  149. }
  150. }
  151. return offset;
  152. }
  153. void term_restore(void)
  154. {
  155. if(!term_enable)
  156. return;
  157. tcsetattr(0,TCSAFLUSH,&old_tio);
  158. }
  159. #endif