From f60af655fb185975a92373e4263f2a862dbcc8da Mon Sep 17 00:00:00 2001 From: albeu Date: Wed, 30 Jan 2002 12:46:03 +0000 Subject: A new configurable input system and joystick support for this system git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4419 b3059339-0415-0410-9bf9-f77b7e298cf2 --- Makefile | 9 +- input/Makefile | 38 +++ input/input.c | 798 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ input/input.h | 84 ++++++ input/joystick.c | 163 ++++++++++++ input/joystick.h | 23 ++ mplayer.c | 253 +++++++++++++++++- 7 files changed, 1364 insertions(+), 4 deletions(-) create mode 100644 input/Makefile create mode 100644 input/input.c create mode 100644 input/input.h create mode 100644 input/joystick.c create mode 100644 input/joystick.h diff --git a/Makefile b/Makefile index f3c0d95e1d..8e1aa34560 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ MISC_LIBS += -Llibdha -ldha -Lvidix -lvidix endif CFLAGS = $(OPTFLAGS) -Ilibmpdemux -Iloader $(VO_INC) $(EXTRA_INC) # -Wall -PARTS = g72x libmpdemux mp3lib libac3 liba52 libmp1e libmpeg2 opendivx libavcodec libao2 drivers drivers/syncfb linux postproc xa +PARTS = g72x libmpdemux mp3lib libac3 liba52 libmp1e libmpeg2 opendivx libavcodec libao2 drivers drivers/syncfb linux postproc xa input ifeq ($(VIDIX),yes) PARTS += libdha vidix endif @@ -172,7 +172,10 @@ xa/libxa.a: g72x/libg72x.a: $(MAKE) -C g72x -MPLAYER_DEP = $(OBJS_MPLAYER) $(LOADER_DEP) $(MP1E_DEP) $(AV_DEP) $(COMMON_DEPS) +input/libinput.a: + $(MAKE) -C input + +MPLAYER_DEP = $(OBJS_MPLAYER) $(LOADER_DEP) $(MP1E_DEP) $(AV_DEP) $(COMMON_DEPS) input/libinput.a MENCODER_DEP = $(OBJS_MENCODER) $(LOADER_DEP) $(MP1E_DEP) $(AV_DEP) $(COMMON_DEPS) ifeq ($(GUI),yes) @@ -187,7 +190,7 @@ VIDIX_LIBS += -Lvidix -lvidix endif $(PRG): $(MPLAYER_DEP) - $(CC) $(CFLAGS) -o $(PRG) $(OBJS_MPLAYER) $(CODEC_LIBS) -Llibmpdemux -lmpdemux $(GUI_LIBS) $(VO_LIBS) $(AO_LIBS) $(LIB_LOADER) $(COMMON_LIBS) $(EXTRA_LIB) $(A_LIBS) $(V_LIBS) $(LIRC_LIB) $(CSS_LIB) $(ARCH_LIB) $(DECORE_LIB) $(TERMCAP_LIB) $(STATIC_LIB) $(GTK_LIBS) $(PNG_LIB) $(Z_LIB) $(STREAMING_LIB) $(VIDIX_LIBS) -lm + $(CC) $(CFLAGS) -o $(PRG) $(OBJS_MPLAYER) $(CODEC_LIBS) -Llibmpdemux -lmpdemux $(GUI_LIBS) $(VO_LIBS) $(AO_LIBS) $(LIB_LOADER) $(COMMON_LIBS) $(EXTRA_LIB) $(A_LIBS) $(V_LIBS) $(LIRC_LIB) $(CSS_LIB) $(ARCH_LIB) $(DECORE_LIB) $(TERMCAP_LIB) $(STATIC_LIB) $(GTK_LIBS) $(PNG_LIB) $(Z_LIB) $(STREAMING_LIB) $(VIDIX_LIBS) -Linput -linput -lm $(PRG_FIBMAP): fibmap_mplayer.o $(CC) -o $(PRG_FIBMAP) fibmap_mplayer.o diff --git a/input/Makefile b/input/Makefile new file mode 100644 index 0000000000..fd3d5b0555 --- /dev/null +++ b/input/Makefile @@ -0,0 +1,38 @@ + +include ../config.mak + +LIBNAME = libinput.a + +SRCS=input.c joystick.c +OBJS=$(SRCS:.c=.o) + +CFLAGS = $(OPTFLAGS) -I. -I.. -Wall + +.SUFFIXES: .c .o + + +.c.o: + $(CC) -c $(CFLAGS) -o $@ $< + +$(LIBNAME): $(OBJS) + $(AR) r $(LIBNAME) $(OBJS) + +all: $(LIBNAME) + +clean: + rm -f *.o *.a *~ + +distclean: + rm -f Makefile.bak *.o *.a *~ .depend + +dep: depend + +depend: + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +# +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/input/input.c b/input/input.c new file mode 100644 index 0000000000..1ddfc25f7e --- /dev/null +++ b/input/input.c @@ -0,0 +1,798 @@ +#include "../config.h" + +#ifdef HAVE_NEW_INPUT + +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "input.h" +#ifdef MP_DEBUG +#include +#endif +#include "../linux/getch2.h" +#include "../linux/keycodes.h" +#include "../linux/timer.h" + +#ifdef HAVE_JOYSTICK +#include "joystick.h" +#endif + +// If the args field is not NULL, the command will only be passed if +// an argument exist. + +static mp_cmd_t mp_cmds[] = { + { MP_CMD_SEEK, "seek", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_AUDIO_DELAY, "audio_delay", 1, { {MP_CMD_ARG_FLOAT,{0}}, {-1,{0}} } }, + { MP_CMD_QUIT, "quit", 0, { {-1,{0}} } }, + { MP_CMD_PAUSE, "pause", 0, { {-1,{0}} } }, + { MP_CMD_GRAB_FRAMES, "grap_frames",0, { {-1,{0}} } }, + { MP_CMD_PLAY_TREE_STEP, "pt_step",1, { { MP_CMD_ARG_INT ,{0}}, {-1,{0}} } }, + { MP_CMD_PLAY_TREE_UP_STEP, "pt_up_step",1, { { MP_CMD_ARG_INT,{0} }, {-1,{0}} } }, + { MP_CMD_PLAY_ALT_SRC_STEP, "alt_src_step",1, { { MP_CMD_ARG_INT,{0} }, {-1,{0}} } }, + { MP_CMD_SUB_DELAY, "sub_delay",1, { {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_OSD, "osd",0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } }, + { MP_CMD_VOLUME, "volume", 1, { { MP_CMD_ARG_INT,{0} }, {-1,{0}} } }, + { MP_CMD_MIXER_USEMASTER, "use_master", 0, { {-1,{0}} } }, + { MP_CMD_CONTRAST, "contrast",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_BRIGHTNESS, "brightness",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_HUE, "hue",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_SATURATION, "saturation",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_FRAMEDROPPING, "frame_drop",0, { { MP_CMD_ARG_INT,{-1} }, {-1,{0}} } }, +#ifdef USE_TV + { MP_CMD_TV_STEP_CHANNEL, "tv_step_channel", 1, { { MP_CMD_ARG_INT ,{0}}, {-1,{0}} }}, + { MP_CMD_TV_STEP_NORM, "tv_step_norm",0, { {-1,{0}} } }, + { MP_CMD_TV_STEP_CHANNEL_LIST, "tv_step_chanlist", 0, { {-1,{0}} } }, +#endif + { 0, NULL, 0, {} } +}; + +static mp_cmd_bind_t key_names[] = { + { ' ', "SPACE" }, + { KEY_ENTER, "ENTER" }, + { KEY_TAB, "TAB" }, + { KEY_CTRL, "CTRL" }, + { KEY_BACKSPACE, "BS" }, + { KEY_DELETE, "DEL" }, + { KEY_INSERT, "INS" }, + { KEY_HOME, "HOME" }, + { KEY_END, "END" }, + { KEY_PAGE_UP, "PGUP" }, + { KEY_PAGE_DOWN, "PGDWN" }, + { KEY_ESC, "ESC" }, + { KEY_RIGHT, "RIGHT" }, + { KEY_LEFT, "LEFT" }, + { KEY_DOWN, "DOWN" }, + { KEY_UP, "UP" }, +#ifdef HAVE_JOYSTICK + { JOY_UP, "JOY_UP" }, + { JOY_DOWN, "JOY_DOWN" }, + { JOY_LEFT, "JOY_LEFT" }, + { JOY_RIGHT, "JOY_RIGHT" }, + { JOY_BTN0, "JOY_BTN0" }, + { JOY_BTN1, "JOY_BTN1" }, + { JOY_BTN2, "JOY_BTN2" }, + { JOY_BTN3, "JOY_BTN3" }, + { JOY_BTN4, "JOY_BTN4" }, + { JOY_BTN5, "JOY_BTN5" }, + { JOY_BTN6, "JOY_BTN6" }, + { JOY_BTN7, "JOY_BTN7" }, + { JOY_BTN8, "JOY_BTN8" }, + { JOY_BTN9, "JOY_BTN9" }, +#endif + { 0, NULL } +}; + +// This is the default binding we use when no config file is here + +static mp_cmd_bind_t def_cmd_binds[] = { + { KEY_RIGHT, "seek 10" }, + { KEY_LEFT, "seek -10" }, + { KEY_UP, "seek 60" }, + { KEY_DOWN, "seek -60" }, + { KEY_PAGE_UP, "seek 600" }, + { KEY_PAGE_DOWN, "seek -600" }, + { '+', "audio_delay 0.100" }, + { '-', "audio_delay -0.100" }, + { 'q', "quit" }, + { KEY_ESC, "quit" }, + { 'p', "pause" }, + { ' ', "pause" }, + { KEY_HOME, "pt_up_step 1" }, + { KEY_END, "pt_up_step -1" }, + { '>', "pt_step 1" }, + { '<', "pt_step -1" }, + { KEY_INS, "alt_src_step 1" }, + { KEY_DEL, "alt_src_step -1" }, + { 'o', "osd" }, + { 'z', "sub_delay -0.1" }, + { 'x', "sub_delay +0.1" }, + { '9', "volume -1" }, + { '/', "volume -1" }, + { '0', "volume 1" }, + { '*', "volume 1" }, + { 'm', "use_master" }, + { '1', "contrast -1" }, + { '2', "contrast 1" }, + { '3', "brightness -1" }, + { '4', "brightness 1" }, + { '5', "hue -1" }, + { '6', "hue 1" }, + { '7', "saturation -1" }, + { '8', "saturation 1" }, + { 'd', "frame_drop" }, +#ifdef USE_TV + { 'h', "tv_step_channel 1" }, + { 'l', "tv_step_channel -1" }, + { 'n', "tv_step_norm" }, + { 'b', "tv_step_chanlist" }, +#endif + { 0, NULL } +}; + +#ifndef MP_MAX_KEY_FD +#define MP_MAX_KEY_FD 10 +#endif + +#ifndef MP_MAX_CMD_FD +#define MP_MAX_CMD_FD 10 +#endif + +#define MP_FD_EOF (1<<0) +#define MP_FD_DROP (1<<1) +#define MP_FD_DEAD (1<<2) +#define MP_FD_GOT_CMD (1<<3) +#define MP_FD_NO_SELECT (1<<4) + +typedef struct mp_input_fd { + int fd; + void* read_func; + mp_close_func_t close_func; + int flags; + // This fields are for the cmd fds + char* buffer; + int pos,size; +} mp_input_fd_t; + + +static mp_cmd_bind_t* cmd_binds = def_cmd_binds; + +static mp_input_fd_t key_fds[MP_MAX_KEY_FD]; +static unsigned int num_key_fd = 0; +static mp_input_fd_t cmd_fds[MP_MAX_CMD_FD]; +static unsigned int num_cmd_fd = 0; + +static int key_max_fd = -1, cmd_max_fd = -1; + +static int +mp_input_default_key_func(int fd); + + +int +mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t close_func) { + if(num_cmd_fd == MP_MAX_CMD_FD) { + printf("Too much command fd, unable to register fd %d\n",fd); + return 0; + } + + memset(&cmd_fds[num_cmd_fd],0,sizeof(mp_input_fd_t)); + cmd_fds[num_cmd_fd].fd = fd; + cmd_fds[num_cmd_fd].read_func = read_func ? read_func : (mp_cmd_func_t)read; + cmd_fds[num_cmd_fd].close_func = close_func; + if(!select) + cmd_fds[num_cmd_fd].flags = MP_FD_NO_SELECT; + num_cmd_fd++; + if(fd > cmd_max_fd) + cmd_max_fd = fd; + + return 1; +} + +void +mp_input_rm_cmd_fd(int fd) { + unsigned int i; + + for(i = 0; i < num_cmd_fd; i++) { + if(cmd_fds[i].fd == fd) + break; + } + if(i == num_cmd_fd) + return; + if(cmd_fds[i].close_func) + cmd_fds[i].close_func(cmd_fds[i].fd); + + if(i + 1 < num_cmd_fd) + memmove(&cmd_fds[i],&cmd_fds[i+1],(num_cmd_fd - i - 1)*sizeof(mp_input_fd_t)); + num_cmd_fd--; +} + +void +mp_input_rm_key_fd(int fd) { + unsigned int i; + + for(i = 0; i < num_key_fd; i++) { + if(key_fds[i].fd == fd) + break; + } + if(i == num_key_fd) + return; + if(key_fds[i].close_func) + key_fds[i].close_func(key_fds[i].fd); + + if(i + 1 < num_key_fd) + memmove(&key_fds[i],&key_fds[i+1],(num_key_fd - i - 1)*sizeof(mp_input_fd_t)); + num_key_fd--; +} + +int +mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t close_func) { + if(num_key_fd == MP_MAX_KEY_FD) { + printf("Too much key fd, unable to register fd %d\n",fd); + return 0; + } + + memset(&key_fds[num_key_fd],0,sizeof(mp_input_fd_t)); + key_fds[num_key_fd].fd = fd; + key_fds[num_key_fd].read_func = read_func ? read_func : mp_input_default_key_func; + key_fds[num_key_fd].close_func = close_func; + if(!select) + key_fds[num_key_fd].flags |= MP_FD_NO_SELECT; + num_key_fd++; + if(fd > key_max_fd) + key_max_fd = fd; + + return 1; +} + + + +static mp_cmd_t* +mp_input_parse_cmd(char* str) { + int i,l; + char *ptr,*e; + mp_cmd_t *cmd, *cmd_def; + +#ifdef MP_DEBUG + assert(str != NULL); +#endif + + ptr = strchr(str,' '); + if(ptr) + l = ptr-str; + else + l = strlen(str); + + if(l == 0) + return NULL; + + for(i=0; mp_cmds[i].name != NULL; i++) { + if(strncasecmp(mp_cmds[i].name,str,l) == 0) + break; + } + + if(mp_cmds[i].name == NULL) + return NULL; + + cmd_def = &mp_cmds[i]; + + cmd = (mp_cmd_t*)malloc(sizeof(mp_cmd_t)); + cmd->id = cmd_def->id; + cmd->name = strdup(cmd_def->name); + + ptr = str; + + for(i=0; ptr && i < MP_CMD_MAX_ARGS; i++) { + ptr = strchr(ptr,' '); + if(!ptr) break; + while(ptr[0] == ' ') ptr++; + if(ptr[0] == '\0') break; + switch(cmd_def->args[i].type) { + case MP_CMD_ARG_INT: + errno = 0; + cmd->args[i].v.i = atoi(ptr); + if(errno != 0) { + printf("Command %s : argument %d isn't an integer\n",cmd_def->name,i+1); + ptr = NULL; + } + break; + case MP_CMD_ARG_FLOAT: + errno = 0; + cmd->args[i].v.f = atof(ptr); + if(errno != 0) { + printf("Command %s : argument %d isn't a float\n",cmd_def->name,i+1); + ptr = NULL; + } + break; + case MP_CMD_ARG_STRING: + e = strchr(ptr,' '); + if(!e) e = ptr+strlen(ptr); + l = e-ptr; + cmd->args[i].v.s = (char*)malloc((l+1)*sizeof(char)); + strncpy(cmd->args[i].v.s,ptr,l); + cmd->args[i].v.s[l] = '\0'; + break; + case -1: + ptr = NULL; + default : + printf("Unknow argument %d\n",i); + } + } + cmd->nargs = i; + + if(cmd_def->nargs > cmd->nargs) { + printf("Got [%s] but\n",str); + printf("Command %s require at least %d arguments, we found only %d so far\n",cmd_def->name,cmd_def->nargs,cmd->nargs); + mp_cmd_free(cmd); + return NULL; + } + + for( ; i < MP_CMD_MAX_ARGS && cmd_def->args[i].type != -1 ; i++) + memcpy(&cmd->args[i].v,&cmd_def->args[i].v,sizeof(mp_cmd_arg_value_t)); + + return cmd; +} + +static int +mp_input_default_key_func(int fd) { + int r,code=0; + unsigned int l; + l = 0; + while(l < sizeof(int)) { + r = read(fd,(&code)+l,sizeof(int)-l); + if(r <= 0) + break; + l +=r; + } + return code; +} + +#define MP_CMD_MAX_SIZE 256 + +static int +mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { + char* end; + (*ret) = NULL; + + if(!mp_fd->buffer) { + mp_fd->buffer = (char*)malloc(MP_CMD_MAX_SIZE*sizeof(char)); + mp_fd->pos = 0; + mp_fd->size = MP_CMD_MAX_SIZE; + } + + if(mp_fd->size - mp_fd->pos == 0) { + printf("Cmd buffer of fd %d is full : dropping content\n",mp_fd->fd); + mp_fd->pos = 0; + mp_fd->flags |= MP_FD_DROP; + } + + while( !(mp_fd->flags & MP_FD_EOF) && (mp_fd->size - mp_fd->pos > 1) ) { + int r = ((mp_cmd_func_t)mp_fd->read_func)(mp_fd->fd,mp_fd->buffer+mp_fd->pos,mp_fd->size - 1 - mp_fd->pos); + if(r < 0) { + if(errno == EINTR) + continue; + else if(errno == EAGAIN) + break; + printf("Error while reading cmd fd %d : %s\n",mp_fd->fd,strerror(errno)); + return MP_INPUT_ERROR; + } else if(r == 0) { + mp_fd->flags |= MP_FD_EOF; + break; + } + mp_fd->pos += r; + break; + } + + + while(1) { + int l = 0; + mp_fd->buffer[mp_fd->pos] = '\0'; + end = strchr(mp_fd->buffer,'\n'); + if(!end) + break; + else if((*ret)) { + mp_fd->flags |= MP_FD_GOT_CMD; + break; + } + + l = end - mp_fd->buffer; + + if( ! (mp_fd->flags & MP_FD_DROP)) { + (*ret) = (char*)malloc((l+1)*sizeof(char)); + strncpy((*ret),mp_fd->buffer,l); + (*ret)[l] = '\0'; + } else { + mp_fd->flags &= ~MP_FD_DROP; + } + if( mp_fd->pos - (l+1) > 0) + memmove(mp_fd->buffer,end,mp_fd->pos-(l+1)); + mp_fd->pos -= l+1; + } + + if(*ret) + return 1; + else + return MP_INPUT_NOTHING; +} + +static mp_cmd_t* +mp_input_read_keys(int time,int paused) { + fd_set fds; + struct timeval tv; + int i,n=0; + static int last_loop = 0; + + if(num_key_fd == 0) + return NULL; + + FD_ZERO(&fds); + for(i = 0; (unsigned int)i < num_key_fd; i++) { + if( (key_fds[i].flags & MP_FD_DEAD) ) { + mp_input_rm_key_fd(key_fds[i].fd); + i--; + continue; + } else if(key_fds[i].flags & MP_FD_NO_SELECT) + continue; + + FD_SET(key_fds[i].fd,&fds); + n++; + } + + if(n > 0 ) { + + tv.tv_sec=time/1000; + tv.tv_usec = (time%1000)*1000; + + while(1) { + if(select(key_max_fd+1,&fds,NULL,NULL,&tv) < 0) { + if(errno == EINTR) + continue; + printf("Select error : %s\n",strerror(errno)); + } + break; + } + } else { + FD_ZERO(&fds); + } + + for(i = last_loop + 1 ; i != last_loop ; i++) { + int code = -1,j; + + if((unsigned int)i >= num_key_fd) { + i = -1; + last_loop++; + continue; + } + if(! (key_fds[i].flags & MP_FD_NO_SELECT) && ! FD_ISSET(key_fds[i].fd,&fds)) + continue; + if(key_fds[i].fd == 0) { // stdin is handled by getch2 + code = getch2(time); + if(code < 0) + code = MP_INPUT_NOTHING; + } + else + code = ((mp_key_func_t)key_fds[i].read_func)(key_fds[i].fd); + + if(code < 0) { + if(code == MP_INPUT_ERROR) + printf("Error on key input fd %d\n",key_fds[i].fd); + else if(code == MP_INPUT_DEAD) { + printf("Dead key input on fd %d\n",key_fds[i].fd); + key_fds[i].flags |= MP_FD_DEAD; + } + continue; + } + if(paused) + return mp_input_parse_cmd("pause"); + for(j = 0; cmd_binds[j].cmd != NULL; j++) { + if(cmd_binds[j].input == code) + break; + } + if(cmd_binds[j].cmd == NULL) + continue; + last_loop = i; + return mp_input_parse_cmd(cmd_binds[j].cmd); + } + + last_loop = 0; + return NULL; +} + +static mp_cmd_t* +mp_input_read_cmds(int time) { + fd_set fds; + struct timeval tv; + int i,n = 0; + mp_cmd_t* ret; + static int last_loop = 0; + + if(num_cmd_fd == 0) + return NULL; + + FD_ZERO(&fds); + for(i = 0; (unsigned int)i < num_cmd_fd ; i++) { + if( (cmd_fds[i].flags & MP_FD_DEAD) || (cmd_fds[i].flags & MP_FD_EOF) ) { + mp_input_rm_cmd_fd(cmd_fds[i].fd); + i--; + continue; + } else if(cmd_fds[i].flags & MP_FD_NO_SELECT) + continue; + FD_SET(cmd_fds[i].fd,&fds); + n++; + } + + if(n > 0) { + + tv.tv_sec=time/1000; + tv.tv_usec = (time%1000)*1000; + + while(1) { + if((i = select(cmd_max_fd+1,&fds,NULL,NULL,&tv)) <= 0) { + if(i < 0) { + if(errno == EINTR) + continue; + printf("Select error : %s\n",strerror(errno)); + } + return NULL; + } + break; + } + } else { + FD_ZERO(&fds); + } + + for(i = last_loop + 1; i != last_loop ; i++) { + int r = 0; + char* cmd; + if((unsigned int)i >= num_cmd_fd) { + i = -1; + last_loop++; + continue; + } + if( ! (cmd_fds[i].flags & MP_FD_NO_SELECT) && ! FD_ISSET(cmd_fds[i].fd,&fds) && ! (cmd_fds[i].flags & MP_FD_GOT_CMD) ) + continue; + + r = mp_input_read_cmd(&cmd_fds[i],&cmd); + if(r < 0) { + if(r == MP_INPUT_ERROR) + printf("Error on cmd fd %d\n",cmd_fds[i].fd); + else if(r == MP_INPUT_DEAD) + cmd_fds[i].flags |= MP_FD_DEAD; + continue; + } + ret = mp_input_parse_cmd(cmd); + free(cmd); + if(!ret) + continue; + last_loop = i; + return ret; + } + + last_loop = 0; + return NULL; +} + +mp_cmd_t* +mp_input_get_cmd(int time, int paused) { + mp_cmd_t* ret; + + ret = mp_input_read_keys(time,paused); + if(ret) + return ret; + + return mp_input_read_cmds(time); +} + +void +mp_cmd_free(mp_cmd_t* cmd) { + int i; +#ifdef MP_DEBUG + assert(cmd != NULL); +#endif + + if(cmd->name) + free(cmd->name); + + for(i=0; i < MP_CMD_MAX_ARGS && cmd->args[i].type != -1; i++) { + if(cmd->args[i].type == MP_CMD_ARG_STRING) + free(cmd->args[i].v.s); + } + free(cmd); +} + +static int +mp_input_get_key_from_name(char* name) { + int i,ret = 0; + + if(strlen(name) == 1) { // Direct key code + (char)ret = name[0]; + return ret; + } + + for(i = 0; key_names[i].cmd != NULL; i++) { + if(strcasecmp(key_names[i].cmd,name) == 0) + return key_names[i].input; + } + + return -1; +} + +static void +mp_input_free_binds(mp_cmd_bind_t* binds) { + int i; + + if(!binds) + return; + + for(i = 0; binds[i].cmd != NULL; i++) + free(binds[i].cmd); + + free(binds); + +} + + +#define BS_MAX 256 +#define SPACE_CHAR " \n\r\t" + +static void +mp_input_parse_config(char *file) { + int fd,code=-1; + int bs = 0,r,eof = 0; + char *iter,*end; + char buffer[BS_MAX]; + int n_binds = 0; + mp_cmd_bind_t* binds = NULL; + + fd = open(file,O_RDONLY); + + if(fd < 0) { + printf("Can't open input config file %s : %s\n",file,strerror(errno)); + return; + } + + printf("Parsing input config file %s\n",file); + + while(1) { + if(! eof && bs < BS_MAX-1) { + if(bs > 0) bs--; + r = read(fd,buffer+bs,BS_MAX-1-bs); + if(r < 0) { + if(errno == EINTR) + continue; + printf("Error while reading input config file %s : %s\n",file,strerror(errno)); + mp_input_free_binds(binds); + return; + } else if(r == 0) + eof = 1; + else { + bs += r+1; + buffer[bs-1] = '\0'; + } + } + // Empty buffer : return + if(bs <= 1) { + printf("Input config file %s parsed : %d binds\n",file,n_binds); + if(binds) + cmd_binds = binds; + return; + } + + iter = buffer; + + // Find the wanted key + if(code < 0) { + // Jump beginnig space + for( ; iter[0] != '\0' && strchr(SPACE_CHAR,iter[0]) != NULL ; iter++) + /* NOTHING */; + if(iter[0] == '\0') { // Buffer was full of space char + bs = 0; + continue; + } + // Find the end of the key code name + for(end = iter; end[0] != '\0' && strchr(SPACE_CHAR,end[0]) == NULL ; end++) + /*NOTHING */; + if(end[0] == '\0') { // Key name don't fit in the buffer + if(buffer == iter) { + if(eof && (buffer-iter) == bs) + printf("Unfinished binding %s\n",iter); + else + printf("Buffer is too small for this key name : %s\n",iter); + mp_input_free_binds(binds); + return; + } + memmove(buffer,iter,end-iter); + bs = end-iter; + continue; + } + { + char name[end-iter+1]; + strncpy(name,iter,end-iter); + name[end-iter] = '\0'; + code = mp_input_get_key_from_name(name); + if(code < 0) { + printf("Unknow key %s\n",name); + mp_input_free_binds(binds); + return; + } + } + if( bs > (end-buffer)) + memmove(buffer,end,bs - (end-buffer)); + bs -= end-buffer; + continue; + } else { // Get the command + while(iter[0] == ' ' || iter[0] == '\t') iter++; + // Found new line + if(iter[0] == '\n' || iter[0] == '\r') { + printf("No command found for key (TODO)\n" /*mp_input_get_key_name(code)*/); + code = -1; + if(iter > buffer) { + memmove(buffer,iter,bs- (iter-buffer)); + bs -= (iter-buffer); + } + continue; + } + for(end = iter ; end[0] != '\n' && end[0] != '\r' && end[0] != '\0' ; end++) + /* NOTHING */; + if(end[0] == '\0' && ! (eof && (end - buffer) == bs)) { + if(iter == buffer) { + printf("Buffer is too small for command %s\n",buffer); + mp_input_free_binds(binds); + return; + } + memmove(buffer,iter,end - iter); + bs = end - iter; + continue; + } + { + char cmd[end-iter+1]; + strncpy(cmd,iter,end-iter); + cmd[end-iter] = '\0'; + //printf("Set bind %d => %s\n",code,cmd); + binds = (mp_cmd_bind_t*)realloc(binds,(n_binds+2)*sizeof(mp_cmd_bind_t)); + binds[n_binds].input = code; + binds[n_binds].cmd = strdup(cmd); + n_binds++; + memset(&binds[n_binds],0,sizeof(mp_cmd_bind_t)); + } + code = -1; + if(bs > (end-buffer)) + memmove(buffer,end,bs-(end-buffer)); + bs -= (end-buffer); + continue; + } + } + printf("What are we doing here ?\n"); +} + +extern char *get_path(char *filename); + +void +mp_input_init(void) { + char* file; + + file = get_path("input.conf"); + if(!file) + return; + + mp_input_parse_config(file); + +#ifdef HAVE_JOYSTICK + { + int fd = mp_input_joystick_init(NULL); + if(fd < 0) + printf("Can't init input joystick\n"); + else + mp_input_add_key_fd(fd,1,mp_input_joystick_read,(mp_close_func_t)close); + } +#endif + +} + +#endif /* HAVE_NEW_INPUT */ diff --git a/input/input.h b/input/input.h new file mode 100644 index 0000000000..b6d69b7d4b --- /dev/null +++ b/input/input.h @@ -0,0 +1,84 @@ + +#ifdef HAVE_NEW_INPUT + +#define MP_CMD_SEEK 0 +#define MP_CMD_AUDIO_DELAY 1 +#define MP_CMD_QUIT 2 +#define MP_CMD_PAUSE 3 +#define MP_CMD_GRAB_FRAMES 4 +#define MP_CMD_PLAY_TREE_STEP 5 +#define MP_CMD_PLAY_TREE_UP_STEP 6 +#define MP_CMD_PLAY_ALT_SRC_STEP 7 +#define MP_CMD_SUB_DELAY 8 +#define MP_CMD_OSD 9 +#define MP_CMD_VOLUME 10 +#define MP_CMD_MIXER_USEMASTER 11 +#define MP_CMD_CONTRAST 12 +#define MP_CMD_BRIGHTNESS 13 +#define MP_CMD_HUE 14 +#define MP_CMD_SATURATION 15 +#define MP_CMD_FRAMEDROPPING 16 +#define MP_CMD_TV_STEP_CHANNEL 17 +#define MP_CMD_TV_STEP_NORM 18 +#define MP_CMD_TV_STEP_CHANNEL_LIST 19 + +#define MP_CMD_ARG_INT 0 +#define MP_CMD_ARG_FLOAT 1 +#define MP_CMD_ARG_STRING 2 + +#define MP_CMD_MAX_ARGS 10 + +#define MP_INPUT_ERROR -1 +#define MP_INPUT_DEAD -2 +#define MP_INPUT_NOTHING -3 + +typedef union mp_cmd_arg_value { + int i; + float f; + char* s; +} mp_cmd_arg_value_t; + +typedef struct mp_cmd_arg { + int type; + mp_cmd_arg_value_t v; +} mp_cmd_arg_t; + +typedef struct mp_cmd { + int id; + char* name; + int nargs; + mp_cmd_arg_t args[MP_CMD_MAX_ARGS]; +} mp_cmd_t; + + +typedef struct mp_cmd_bind { + int input; + char* cmd; +} mp_cmd_bind_t; + +typedef int (*mp_key_func_t)(int fd); +typedef int (*mp_cmd_func_t)(int fd,char* dest,int size); +typedef void (*mp_close_func_t)(int fd); + +int +mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t close_func); + +void +mp_input_rm_cmd_fd(int fd); + +int +mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t close_func); + +void +mp_input_rm_key_fd(int fd); + +mp_cmd_t* +mp_input_get_cmd(int time, int paused); + +void +mp_cmd_free(mp_cmd_t* cmd); + +void +mp_input_init(void); + +#endif /* HAVE_NEW_INPUT */ diff --git a/input/joystick.c b/input/joystick.c new file mode 100644 index 0000000000..7bb7f0d86b --- /dev/null +++ b/input/joystick.c @@ -0,0 +1,163 @@ + +#include "../config.h" + +#ifdef HAVE_JOYSTICK + +#include "joystick.h" +#include "input.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef JOY_AXIS_DELTA +#define JOY_AXIS_DELTA 500 +#endif + +#ifndef JS_DEV +#define JS_DEV "/dev/input/js0" +#endif + +#ifdef TARGET_LINUX + +#include + +static int buttons = 0; +static int* axis; + +int mp_input_joystick_init(char* dev) { + int fd,l=0; + int inited = 0; + struct js_event ev; + char n_axis; + + printf("Opening joystick device %s\n",dev ? dev : JS_DEV); + + fd = open( dev ? dev : JS_DEV , O_RDONLY | O_NONBLOCK ); + if(fd < 0) { + printf("Can't open joystick device %s : %s\n",dev ? dev : JS_DEV,strerror(errno)); + return -1; + } + + if(ioctl(fd, JSIOCGAXES, &n_axis) < 0) { + printf("Joystick : can't get number of axis, %s\n",strerror(errno)); + close(fd); + return -1; + } + + axis = (int*)malloc(n_axis*sizeof(int)); + + + while(! inited) { + l = 0; + while((unsigned int)l < sizeof(struct js_event)) { + int r = read(fd,&ev+l,sizeof(struct js_event)-l); + if(r < 0) { + if(errno == EINTR) + continue; + else if(errno == EAGAIN) { + inited = 1; + break; + } + printf("Error while reading joystick device : %s\n",strerror(errno)); + close(fd); + return -1; + } + l += r; + } + if((unsigned int)l < sizeof(struct js_event)) { + if(l > 0) + printf("Joystick : we loose %d bytes of data\n",l); + return fd; + } + if(ev.type & JS_EVENT_INIT) { + ev.type &= ~JS_EVENT_INIT; + if(ev.type & JS_EVENT_BUTTON) + buttons |= (ev.value << ev.number); + else if(ev.type & JS_EVENT_AXIS) + axis[ev.number] = ev.value; + } else + printf("Joystick : Warning non-init event during init :-o\n"); + } + + return fd; +} + +int mp_input_joystick_read(int fd) { + struct js_event ev; + int l=0; + + while((unsigned int)l < sizeof(struct js_event)) { + int r = read(fd,&ev+l,sizeof(struct js_event)-l); + if(r <= 0) { + if(errno == EINTR) + continue; + else if(errno == EAGAIN) + return MP_INPUT_NOTHING; + if( r < 0) + printf("Joystick error while reading joystick device : %s\n",strerror(errno)); + else + printf("Joystick error while reading joystick device : EOF\n"); + return MP_INPUT_DEAD; + } + l += r; + } + + if((unsigned int)l < sizeof(struct js_event)) { + if(l > 0) + printf("Joystick : we loose %d bytes of data\n",l); + return MP_INPUT_NOTHING; + } + + if(ev.type & JS_EVENT_INIT) { + printf("Joystick : warning reinit (Can happend more than on time)\n"); + ev.type &= ~JS_EVENT_INIT; + if(ev.type & JS_EVENT_BUTTON) + buttons |= (ev.value << ev.number); + else if(ev.type & JS_EVENT_AXIS) + axis[ev.number] = ev.value; + else + printf("Joystick warning unknow event type %d\n",ev.type); + return mp_input_joystick_read(fd); + } + + ev.type &= ~JS_EVENT_INIT; + + if(ev.type & JS_EVENT_BUTTON) { + int b = buttons | (ev.value << ev.number); + if(b != buttons) + return JOY_BTN0+ev.number; + } else if(ev.type & JS_EVENT_AXIS) { + if(ev.value - axis[ev.number] > JOY_AXIS_DELTA) + return ev.number == 0 ? JOY_UP : JOY_LEFT; + else if(axis[ev.number] - ev.value > JOY_AXIS_DELTA) + return ev.number == 0 ? JOY_DOWN : JOY_RIGHT; + } else { + printf("Joystick warning unknow event type %d\n",ev.type); + return MP_INPUT_ERROR; + } + + return MP_INPUT_NOTHING; +} + +#else + +// dummy function + +int mp_input_joystick_init(char* dev) { + return -1; +} + +int mp_input_joystick_read(int fd) { + + return MP_INPUT_NOTHING; +} + +#endif + +#endif diff --git a/input/joystick.h b/input/joystick.h new file mode 100644 index 0000000000..537c333f03 --- /dev/null +++ b/input/joystick.h @@ -0,0 +1,23 @@ + +#define JOY_BASE (0x100+128) +#define JOY_UP (JOY_BASE+0) +#define JOY_DOWN (JOY_BASE+1) +#define JOY_LEFT (JOY_BASE+2) +#define JOY_RIGHT (JOY_BASE+3) + +#define JOY_BTN0 (JOY_BASE+4) +#define JOY_BTN1 (JOY_BASE+5) +#define JOY_BTN2 (JOY_BASE+6) +#define JOY_BTN3 (JOY_BASE+7) +#define JOY_BTN4 (JOY_BASE+8) +#define JOY_BTN5 (JOY_BASE+9) +#define JOY_BTN6 (JOY_BASE+10) +#define JOY_BTN7 (JOY_BASE+11) +#define JOY_BTN8 (JOY_BASE+12) +#define JOY_BTN9 (JOY_BASE+13) + +int mp_input_joystick_init(char* dev); + +int mp_input_joystick_read(int fd); + + diff --git a/mplayer.c b/mplayer.c index 1c23603eed..c388ab3327 100644 --- a/mplayer.c +++ b/mplayer.c @@ -73,6 +73,10 @@ extern void* mDisplay; // Display* mDisplay; #include "Gui/mplayer/play.h" #endif +#ifdef HAVE_NEW_INPUT +#include "input/input.h" +#endif + int slave_mode=0; int verbose=0; int quiet=0; @@ -670,6 +674,20 @@ if(!parse_codec_cfg(get_path("codecs.conf"))){ // ========== Init keyboard FIFO (connection to libvo) ============ make_pipe(&keyb_fifo_get,&keyb_fifo_put); +// Init input system +#ifdef HAVE_NEW_INPUT +current_module = "init_input"; +mp_input_init(); +if(keyb_fifo_get > 0) + mp_input_add_key_fd(keyb_fifo_get,1,NULL,NULL); +if(slave_mode) + mp_input_add_cmd_fd(0,1,NULL,NULL); +else + mp_input_add_key_fd(0,1,NULL,NULL); +current_module = NULL; +#endif + + //========= Catch terminate signals: ================ // terminate requests: signal(SIGTERM,exit_sighandler); // kill @@ -912,7 +930,18 @@ current_module=NULL; // initial prefill: 20% later: 5% (should be set by -cacheopts) if(stream_cache_size) stream_enable_cache(stream,stream_cache_size*1024,stream_cache_size*1024/5,stream_cache_size*1024/20); +#ifdef HAVE_NEW_INPUT + if(!slave_mode && filename && !use_stdin && !strcmp(filename,"-")) { + mp_input_rm_key_fd(0); + use_stdin = 1; + } + else if(!slave_mode && use_stdin && (!filename || strcmp(filename,"-"))) { + mp_input_add_key_fd(0,1,NULL,NULL); + use_stdin = 0; + } +#else use_stdin=filename && (!strcmp(filename,"-")); +#endif #ifdef HAVE_LIBCSS current_module="libcss"; @@ -1854,6 +1883,9 @@ if(auto_quality>0){ #endif if(osd_function==OSD_PAUSE){ +#ifdef HAVE_NEW_INPUT + mp_cmd_t* cmd; +#endif #ifdef HAVE_NEW_GUI int gui_pause_flag=0; // gany! #endif @@ -1864,6 +1896,9 @@ if(auto_quality>0){ if (audio_out && sh_audio) audio_out->pause(); // pause audio, keep data if possible +#ifdef HAVE_NEW_INPUT + while( (cmd = mp_input_get_cmd(20,1)) == NULL) { +#else /* HAVE_NEW_INPUT */ if(slave_mode) { fd_set set; struct timeval timeout; @@ -1884,9 +1919,10 @@ if(auto_quality>0){ lirc_mp_getinput()<=0 && #endif (use_stdin || getch2(20)<=0) && mplayer_get_key()<=0){ +#endif #ifndef USE_LIBVO2 video_out->check_events(); -#endif +#endif /* HAVE_NEW_INPUT */ #ifdef HAVE_NEW_GUI if(use_gui){ EventHandling(); @@ -1894,9 +1930,14 @@ if(auto_quality>0){ { gui_pause_flag=1; break; } // end of pause or seek } #endif +#ifdef HAVE_NEW_INPUT + } + mp_cmd_free(cmd); +#else if(use_stdin) usec_sleep(1000); // do not eat the CPU } } +#endif /* HAVE_NEW_INPUT */ osd_function=OSD_PLAY; if (audio_out && sh_audio) audio_out->resume(); // resume audio @@ -1919,6 +1960,7 @@ if(step_sec>0) { //================= Keyboard events, SEEKing ==================== +#ifndef HAVE_NEW_INPUT /* slave mode */ if(slave_mode) { char buffer[1024]; @@ -2229,6 +2271,215 @@ if(step_sec>0) { } } // keyboard event handler +#else /* HAVE_NEW_INPUT */ +{ + mp_cmd_t* cmd; + while( (cmd = mp_input_get_cmd(0,0)) != NULL) { + switch(cmd->id) { + case MP_CMD_SEEK : { + int v,abs; + v = cmd->args[0].v.i; + abs = (cmd->nargs > 1) ? cmd->args[1].v.i : 0; + if(abs) { + abs_seek_pos = 3; + osd_function= (v > sh_video->timer) ? OSD_FFW : OSD_REW; + rel_seek_secs = v; + } + else { + rel_seek_secs+= v; + osd_function= (v > 0) ? OSD_FFW : OSD_REW; + } + } break; + case MP_CMD_AUDIO_DELAY : { + float v = cmd->args[0].v.f; + audio_delay += v; + osd_show_av_delay = 9; + if(sh_audio) sh_audio->timer+= v; + } break; + case MP_CMD_PAUSE : { + osd_function=OSD_PAUSE; + } break; + case MP_CMD_QUIT : { + exit_player(MSGTR_Exit_quit); + } + case MP_CMD_GRAB_FRAMES : { + grab_frames=2; + } break; + case MP_CMD_PLAY_TREE_STEP : { + int n = cmd->args[0].v.i > 0 ? 1 : -1; + play_tree_iter_t* i = play_tree_iter_new_copy(playtree_iter); + + if(play_tree_iter_step(i,n,0) == PLAY_TREE_ITER_ENTRY) + eof = (n > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY; + play_tree_iter_free(i); + } break; + case MP_CMD_PLAY_TREE_UP_STEP : { + int n = cmd->args[0].v.i > 0 ? 1 : -1; + play_tree_iter_t* i = play_tree_iter_new_copy(playtree_iter); + if(play_tree_iter_up_step(i,n,0) == PLAY_TREE_ITER_ENTRY) + eof = (n > 0) ? PT_UP_NEXT : PT_UP_PREV; + play_tree_iter_free(i); + } break; + case MP_CMD_PLAY_ALT_SRC_STEP : { + if(playtree_iter->num_files > 1) { + int v = cmd->args[0].v.i; + if(v > 0 && playtree_iter->file < playtree_iter->num_files) + eof = PT_NEXT_SRC; + else if(v < 0 && playtree_iter->file > 1) + eof = PT_PREV_SRC; + } + } break; + case MP_CMD_SUB_DELAY : { + int abs= cmd->args[1].v.i; + float v = cmd->args[0].v.f; + if(abs) + sub_delay = v; + else + sub_delay += v; + osd_show_sub_delay = 9; // show the subdelay in OSD + } break; + case MP_CMD_OSD : { + int v = cmd->args[0].v.i; + if(v < 0) + osd_level=(osd_level+1)%3; + else + osd_level= v > 2 ? 2 : v; + } break; + case MP_CMD_VOLUME : { + int v = cmd->args[0].v.i; + if(v > 0) + mixer_incvolume(); + else + mixer_decvolume(); +#ifdef USE_OSD + if(osd_level){ + osd_visible=sh_video->fps; // 1 sec + vo_osd_progbar_type=OSD_VOLUME; + vo_osd_progbar_value=(mixer_getbothvolume()*256.0)/100.0; + } +#endif + } break; + case MP_CMD_MIXER_USEMASTER : { + mixer_usemaster=!mixer_usemaster; + } break; + case MP_CMD_CONTRAST : { + int v = cmd->args[0].v.i, abs = cmd->args[1].v.i; + if(abs) + v_cont = v > 100 ? 100 : v; + else { + if ( (v_cont += v) > 100 ) v_cont = 100; + } + if(v_cont < 0) v_cont = 0; + + if(set_video_colors(sh_video,"Contrast",v_cont)){ +#ifdef USE_OSD + if(osd_level){ + osd_visible=sh_video->fps; // 1 sec + vo_osd_progbar_type=OSD_CONTRAST; + vo_osd_progbar_value=((v_cont)<<8)/100; + } +#endif + } + } break; + case MP_CMD_BRIGHTNESS : { + int v = cmd->args[0].v.i, abs = cmd->args[1].v.i; + if(abs) + v_bright = v > 100 ? 100 : v; + else { + if ( (v_bright += v) > 100 ) v_cont = 100; + } + if(v_hw_equ_cap & VEQ_CAP_BRIGHTNESS) { + if(v_bright < -100) v_bright = -100; + } else { + if ( v_bright < 0 ) v_bright = 0; + } + if(set_video_colors(sh_video,"Brightness",v_bright)){ +#ifdef USE_OSD + if(osd_level){ + osd_visible=sh_video->fps; // 1 sec + vo_osd_progbar_type=OSD_BRIGHTNESS; + vo_osd_progbar_value=((v_bright)<<8)/100; + } +#endif + } + } break; + case MP_CMD_HUE : { + int v = cmd->args[0].v.i, abs = cmd->args[1].v.i; + if(abs) + v_hue = v > 100 ? 100 : v; + else { + if ( (v_hue += v) > 100 ) v_hue = 100; + } + if(v_hw_equ_cap & VEQ_CAP_HUE) { + if(v_hue < -100) v_hue = -100; + } else { + if ( v_hue < 0 ) v_hue = 0; + } + if(set_video_colors(sh_video,"Hue",v_hue)){ +#ifdef USE_OSD + if(osd_level){ + osd_visible=sh_video->fps; // 1 sec + vo_osd_progbar_type=OSD_HUE; + vo_osd_progbar_value=((v_hue)<<8)/100; + } +#endif + } + } break; + case MP_CMD_SATURATION : { + int v = cmd->args[0].v.i, abs = cmd->args[1].v.i; + if(abs) + v_saturation = v > 100 ? 100 : v; + else { + if ( (v_saturation += v) > 100 ) v_saturation = 100; + } + if(v_hw_equ_cap & VEQ_CAP_SATURATION) { + if(v_saturation < -100) v_saturation = -100; + } else { + if ( v_saturation < 0 ) v_saturation = 0; + } + if(set_video_colors(sh_video,"Saturation",v_saturation)){ +#ifdef USE_OSD + if(osd_level){ + osd_visible=sh_video->fps; // 1 sec + vo_osd_progbar_type=OSD_SATURATION; + vo_osd_progbar_value=((v_saturation)<<8)/100; + } +#endif + } + } break; + case MP_CMD_FRAMEDROPPING : { + int v = cmd->args[0].v.i; + if(v < 0) + frame_dropping = (frame_dropping+1)%3; + else + frame_dropping = v > 2 ? 2 : v; + } break; +#ifdef USE_TV + case MP_CMD_TV_STEP_CHANNEL : { + if (tv_param_on == 1) { + int v = cmd->args[0].v.i; + if(v > 0) + tv_step_channel(tv_handler, TV_CHANNEL_HIGHER); + else + tv_step_channel(tv_handler, TV_CHANNEL_LOWER); + } + } break; + case MP_CMD_TV_STEP_NORM : { + if (tv_param_on == 1) + tv_step_norm(tv_handler); + } break; + case MP_CMD_TV_STEP_CHANNEL_LIST : { + if (tv_param_on == 1) + tv_step_chanlist(tv_handler); + } break; +#endif + default : + printf("Received unknow cmd %s\n",cmd->name); + } + mp_cmd_free(cmd); + } +} +#endif if (seek_to_sec) { int a,b; float d; -- cgit v1.2.3