# # Copyright (C) 2004 Melissa K. Schrumpf # # Licence for this patch shall defer to the licence under which # the mpg123 software is distributed with the following # additional qualifications: # # This patch, or source modified with this patch shall be distributed # with a notice giving credit to the author. # # This software 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. # # # # Patch to add TERM_CONTROL support on Win32 systems. # # 2004.01.21 by M. K. Schrumpf # # Patch adds ConIO support for console control # and stdin raw mode for non-console control (e.g. via pipe) # # Removed support for "stop" on WIN32. There are pause and quit; # that shall suffice for now. # # Requires: mpg123-0.59r-20001023.diff by Takuro Horikawa # # *** mpg123-0.59r/Makefile Wed Jan 21 11:22:06 2004 --- Makefile Wed Jan 21 11:20:28 2004 *************** *** 542,554 **** mpg123.o common.o decode_2to1.o decode_4to1.o \ tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \ getlopt.o httpget.o wav.o readers.o getbits.o decode_i386.o \ dct64_i386.o equalizer.o xfermem.o audio_win32.o decode_ntom.o' \ OBJECTS='decode_i386.o dct64_i386.o equalizer.o xfermem.o \ ! audio_win32.o decode_ntom.o' \ CFLAGS='-O2 -DNDEBUG -DWIN32 -DNOXFERMEM \ ! -D_CONSOLE -D_WIN32 -D_inline=inline' \ LIBS="-lgdi32 -lcomdlg32 -lwinmm" \ mpg123.exe # maybe you need the additonal options LDFLAGS='-lnsl -lsocket' when linking (see solaris:) generic: --- 542,554 ---- mpg123.o common.o decode_2to1.o decode_4to1.o \ tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \ getlopt.o httpget.o wav.o readers.o getbits.o decode_i386.o \ dct64_i386.o equalizer.o xfermem.o audio_win32.o decode_ntom.o' \ OBJECTS='decode_i386.o dct64_i386.o equalizer.o xfermem.o \ ! audio_win32.o decode_ntom.o term.o' \ CFLAGS='-O2 -DNDEBUG -DWIN32 -DNOXFERMEM \ ! -D_CONSOLE -D_WIN32 -DTERM_CONTROL -D_inline=inline' \ LIBS="-lgdi32 -lcomdlg32 -lwinmm" \ mpg123.exe # maybe you need the additonal options LDFLAGS='-lnsl -lsocket' when linking (see solaris:) generic: *** mpg123-0.59r/Makefile.win32 Wed Jan 21 11:22:06 2004 --- Makefile.win32 Tue Jan 20 14:06:35 2004 *************** *** 1,19 **** LINKER=link CC=cl ! CFLAGS=-nologo -G4 -ML -W2 -GX -O2 -DNDEBUG -DWIN32 -DNOXFERMEM -D_CONSOLE -D_WIN32 -YX LIBS=-DEFAULTLIB:user32.lib gdi32.lib comdlg32.lib winmm.lib ! LINKFLAGS=-nologo -subsystem:console -incremental:no -machine:I386 ! ! mpg123.exe: audio.obj mpg123.obj layer3.obj layer2.obj layer1.obj buffer.obj \ ! decode_i386.obj dct64_i386.obj common.obj equalizer.obj control.obj \ tabinit.obj xfermem.obj httpget.obj decode_2to1.obj decode_4to1.obj \ ! getlopt.obj audio_win32.obj $(LINKER) $(LINKFLAGS) -out:mpg123.exe \ ! audio.obj mpg123.obj layer3.obj layer2.obj layer1.obj buffer.obj \ ! decode_i386.obj dct64_i386.obj common.obj equalizer.obj control.obj \ ! tabinit.obj xfermem.obj httpget.obj decode_2to1.obj decode_4to1.obj \ ! getlopt.obj audio_win32.obj \ $(LIBS) ! ! ! --- 1,17 ---- LINKER=link CC=cl ! CFLAGS=-nologo -Zi -G4 -ML -W2 -GX -O2 -DNDEBUG -DWIN32 -DNOXFERMEM -D_CONSOLE -D_WIN32 -DTERM_CONTROL -YX LIBS=-DEFAULTLIB:user32.lib gdi32.lib comdlg32.lib winmm.lib ! LINKFLAGS= -debug -nologo -subsystem:console -incremental:no -machine:I386 ! OBJS=audio.obj mpg123.obj layer3.obj layer2.obj layer1.obj buffer.obj \ ! decode_i386.obj dct64_i386.obj common.obj equalizer.obj \ tabinit.obj xfermem.obj httpget.obj decode_2to1.obj decode_4to1.obj \ ! getlopt.obj audio_win32.obj decode_ntom.obj wav.obj getbits.obj readers.obj \ ! term.obj ! ! mpg123.exe: $(OBJS) $(LINKER) $(LINKFLAGS) -out:mpg123.exe \ ! $(OBJS) \ $(LIBS) ! ! *** mpg123-0.59r/mpg123.c Wed Jan 21 11:22:06 2004 --- mpg123.c Tue Jan 20 18:39:09 2004 *************** *** 11,20 **** --- 11,23 ---- #if !defined(WIN32) && !defined(GENERIC) #include #include #include #endif + #ifdef WIN32 + #include + #endif #include #include #include *************** *** 780,789 **** --- 783,796 ---- #ifdef OS2 _wildcard(&argc,&argv); #endif + #ifdef WIN32 + setvbuf(stdout, NULL, _IONBF, 0); + *stderr = *stdout; + #endif if(sizeof(short) != 2) { fprintf(stderr,"Ouch SHORT has size of %d bytes (required: '2')\n",(int)sizeof(short)); exit(1); } if(sizeof(long) < 4) { *************** *** 973,982 **** --- 980,991 ---- if(!param.term_ctrl) { continue; } else { long offset; if((offset=term_control(&fr))) { + //printf("__00008 %d\n", frameNum); + //fflush(stdout); if(!rd->back_frame(rd, &fr, -offset)) { frameNum+=offset; if (frameNum < 0) frameNum = 0; } *** mpg123-0.59r/term.c Wed Feb 10 16:15:49 1999 --- term.c Wed Jan 21 11:01:36 2004 *************** *** 1,25 **** ! #ifdef TERM_CONTROL #include #include #include #include #include #include "mpg123.h" #include "buffer.h" #include "term.h" #include "common.h" static int term_enable = 0; static struct termios old_tio; /* initialze terminal */ void term_init(void) { struct termios tio; term_enable = 0; if(tcgetattr(0,&tio) < 0) { --- 1,44 ---- ! //#ifdef TERM_CONTROL + #ifndef WIN32 #include #include + #endif #include + #ifndef WIN32 #include + #else + #include + #include + #include + #include + #include + #endif #include #include "mpg123.h" #include "buffer.h" #include "term.h" #include "common.h" static int term_enable = 0; + #ifndef WIN32 static struct termios old_tio; + #else + char c = ""; + HANDLE hThread = NULL; + DWORD threadID; + DWORD dwThrdParam = 1; + BOOL Win32Console = 1; + #endif /* initialze terminal */ void term_init(void) { + #ifndef WIN32 struct termios tio; term_enable = 0; if(tcgetattr(0,&tio) < 0) { *************** *** 33,45 **** if(tcsetattr(0,TCSANOW,&tio) < 0) { fprintf(stderr,"Can't set terminal attributes\n"); return; } term_enable = 1; - } static long term_handle_input(struct frame *,int); static int stopped = 0; --- 52,83 ---- if(tcsetattr(0,TCSANOW,&tio) < 0) { fprintf(stderr,"Can't set terminal attributes\n"); return; } + #else + int records_read; + // use conio for console, because stdin can't be made to non-buffer + // (raw mode). if a pipe input, stdin can be successfully unbuffered. + // however, can't use conio universally, either, because it [obviously] + // doesn't work with pipes. + if (PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), + NULL, 0, &records_read)) { + //printf("Using Windows Console I/O.\n"); + Win32Console = 1; + } else { + //printf("Not using Windows Console I/O\n"); + Win32Console = 0; + } + if (hThread==NULL) { + setvbuf(stdin, NULL, _IONBF, 0); + hThread = CreateThread(NULL, 0, readInp, &dwThrdParam, 0, &threadID); + if (hThread==NULL) { hThread = NULL; } + } + #endif term_enable = 1; } static long term_handle_input(struct frame *,int); static int stopped = 0; *************** *** 48,61 **** long term_control(struct frame *fr) { long offset = 0; ! if(!term_enable) return 0; if(paused) { if(!--pause_cycle) { pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr)); offset-=pause_cycle; --- 86,100 ---- long term_control(struct frame *fr) { long offset = 0; ! if(!term_enable) return 0; + #ifndef WIN32 if(paused) { if(!--pause_cycle) { pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr)); offset-=pause_cycle; *************** *** 69,108 **** if(!paused) offset += pause_cycle; } } } ! do { offset += term_handle_input(fr, stopped); - } while (stopped); ! return offset; } static long term_handle_input(struct frame *fr, int do_delay) { int n = 1; long offset = 0; extern struct audio_info_struct ai; ! while(n > 0) { fd_set r; struct timeval t; char val; t.tv_sec=0; t.tv_usec=(do_delay) ? 1000 : 0; FD_ZERO(&r); FD_SET(0,&r); n = select(1,&r,NULL,NULL,&t); if(n > 0 && FD_ISSET(0,&r)) { if(read(0,&val,1) <= 0) break; switch(tolower(val)) { case BACK_KEY: audio_queueflush(&ai); --- 108,172 ---- if(!paused) offset += pause_cycle; } } } ! #else ! while (paused) { ! offset += term_handle_input(fr, paused); ! Sleep(50); ! } ! #endif do { offset += term_handle_input(fr, stopped); } while (stopped); ! return offset; } + + DWORD WINAPI readInp(LPVOID param) { + while (1) { + if (Win32Console) { + c = getch(); + } else { + fscanf(stdin,"%c",&c); + } + if (ferror(stdin)||feof(stdin)) {break;} + } + hThread = NULL; + return 0; + } + + static long term_handle_input(struct frame *fr, int do_delay) { int n = 1; long offset = 0; extern struct audio_info_struct ai; ! ! #ifndef WIN32 while(n > 0) { fd_set r; struct timeval t; + #endif char val; + #ifndef WIN32 t.tv_sec=0; t.tv_usec=(do_delay) ? 1000 : 0; FD_ZERO(&r); FD_SET(0,&r); n = select(1,&r,NULL,NULL,&t); if(n > 0 && FD_ISSET(0,&r)) { if(read(0,&val,1) <= 0) break; + #else + val = c; + #endif switch(tolower(val)) { case BACK_KEY: audio_queueflush(&ai); *************** *** 124,137 **** --- 188,207 ---- pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr)); rd->rewind(rd); break; case NEXT_KEY: audio_queueflush(&ai); + #ifndef WIN32 kill(0,SIGINT); + #endif break; case QUIT_KEY: + #ifndef WIN32 kill(0,SIGTERM); + #else + exit(0); + #endif break; case PAUSE_KEY: paused=1-paused; if(paused) { pause_cycle=(int)(LOOP_CYCLES/compute_tpf(fr)); *************** *** 142,161 **** --- 212,233 ---- if(param.usebuffer) buffer_start(); } fprintf(stderr, "%s", (paused) ? PAUSED_STRING : EMPTY_STRING); break; + #ifndef WIN32 case STOP_KEY: stopped=1-stopped; if(paused) { paused=0; offset -= pause_cycle; } if(param.usebuffer) (stopped) ? buffer_stop() : buffer_start(); fprintf(stderr, "%s", (stopped) ? STOPPED_STRING : EMPTY_STRING); break; + #endif case FINE_REWIND_KEY: offset--; break; case FINE_FORWARD_KEY: offset++; *************** *** 173,193 **** offset+=50; break; default: ; } } } return offset; } void term_restore(void) { ! if(!term_enable) return; tcsetattr(0,TCSAFLUSH,&old_tio); } ! #endif --- 245,270 ---- offset+=50; break; default: ; } + #ifndef WIN32 } } + #else + c = ""; + #endif return offset; } void term_restore(void) { ! #ifndef WIN32 if(!term_enable) return; tcsetattr(0,TCSAFLUSH,&old_tio); + #endif } ! //#endif *** mpg123-0.59r/term.h Tue Feb 09 05:42:14 1999 --- term.h Tue Jan 20 18:18:58 2004 *************** *** 33,39 **** --- 33,42 ---- #define EMPTY_STRING " \b\b\b\b\b\b\b\b" void term_init(void); long term_control(struct frame *fr); void term_restore(void); + #ifdef WIN32 + DWORD WINAPI readInp(LPVOID); + #endif #endif *** README.orig Wed Jan 21 11:40:36 2004 --- README Wed Jan 21 11:39:41 2004 *************** *** 34,43 **** --- 34,44 ---- Steven Tiger Lang: advanced shuffle Henrik P Johnson: HTTP auth patch Eric B. Mitchell: esd port Ryan R. Prosser esd port for Solaris Daniel Kobras : lot of (DK)-bugfixes + M. K. Schrumpf : win32 TERM_CONTROL support and more .... current distribution site for new test versions is: http://www-ti.informatik.uni-tuebingen.de/~hippm/mpg123.html