diff options
Diffstat (limited to 'input/input.c')
-rw-r--r-- | input/input.c | 859 |
1 files changed, 400 insertions, 459 deletions
diff --git a/input/input.c b/input/input.c index b8ccca308d..c5d93a5f17 100644 --- a/input/input.c +++ b/input/input.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include <string.h> #include <stdio.h> +#include <stdbool.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> @@ -35,7 +36,6 @@ #include <assert.h> #endif #include "mp_fifo.h" -#include "osdep/getch2.h" #include "osdep/keycodes.h" #include "osdep/timer.h" #include "libavutil/avstring.h" @@ -44,6 +44,8 @@ #include "m_config.h" #include "m_option.h" #include "get_path.h" +#include "talloc.h" +#include "options.h" #include "joystick.h" @@ -57,6 +59,16 @@ #include "ar.h" +typedef struct mp_cmd_bind { + int input[MP_MAX_KEY_DOWN+1]; + char* cmd; +} mp_cmd_bind_t; + +typedef struct mp_key_name { + int key; + char* name; +} mp_key_name_t; + /// This array defines all known commands. /// The first field is an id used to recognize the command without too many strcmp. /// The second is obviously the command name. @@ -175,17 +187,6 @@ static const mp_cmd_t mp_cmds[] = { { MP_CMD_TV_TELETEXT_ADD_DEC, "teletext_add_dec", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } }, { MP_CMD_TV_TELETEXT_GO_LINK, "teletext_go_link", 1, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, -#ifdef CONFIG_GUI - { MP_CMD_GUI_LOADFILE, "gui_loadfile", 0, { {-1,{0}} } }, - { MP_CMD_GUI_LOADSUBTITLE, "gui_loadsubtitle", 0, { {-1,{0}} } }, - { MP_CMD_GUI_ABOUT, "gui_about", 0, { {-1,{0}} } }, - { MP_CMD_GUI_PLAY, "gui_play", 0, { {-1,{0}} } }, - { MP_CMD_GUI_STOP, "gui_stop", 0, { {-1,{0}} } }, - { MP_CMD_GUI_PLAYLIST, "gui_playlist", 0, { {-1,{0}} } }, - { MP_CMD_GUI_PREFERENCES, "gui_preferences", 0, { {-1,{0}} } }, - { MP_CMD_GUI_SKINBROWSER, "gui_skinbrowser", 0, { {-1,{0}} } }, -#endif - #ifdef CONFIG_DVDNAV { MP_CMD_DVDNAV, "dvdnav", 1, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } }, #endif @@ -202,8 +203,10 @@ static const mp_cmd_t mp_cmds[] = { { MP_CMD_GET_SUB_VISIBILITY, "get_sub_visibility", 0, { {-1,{0}} } }, { MP_CMD_KEYDOWN_EVENTS, "key_down_event", 1, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, { MP_CMD_SET_PROPERTY, "set_property", 2, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } }, + { MP_CMD_SET_PROPERTY_OSD, "set_property_osd", 2, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } }, { MP_CMD_GET_PROPERTY, "get_property", 1, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } }, { MP_CMD_STEP_PROPERTY, "step_property", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_STEP_PROPERTY_OSD, "step_property_osd", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, { MP_CMD_SEEK_CHAPTER, "seek_chapter", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, { MP_CMD_SET_MOUSE_POS, "set_mouse_pos", 2, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, @@ -420,7 +423,8 @@ static const mp_cmd_bind_t def_cmd_binds[] = { { { '7', 0 }, "saturation -1" }, { { '8', 0 }, "saturation 1" }, { { 'd', 0 }, "frame_drop" }, - { { 'D', 0 }, "step_property deinterlace" }, + { { 'D', 0 }, "step_property_osd deinterlace" }, + { { 'c', 0 }, "step_property_osd yuv_colorspace" }, { { 'r', 0 }, "sub_pos -1" }, { { 't', 0 }, "sub_pos +1" }, { { 'a', 0 }, "sub_alignment" }, @@ -494,21 +498,6 @@ static const mp_cmd_bind_t def_cmd_binds[] = { }; -#ifdef CONFIG_GUI -static const mp_cmd_bind_t gui_def_cmd_binds[] = { - - { { 'l', 0 }, "gui_loadfile" }, - { { 't', 0 }, "gui_loadsubtitle" }, - { { KEY_ENTER, 0 }, "gui_play" }, - { { KEY_ESC, 0 }, "gui_stop" }, - { { 'p', 0 }, "gui_playlist" }, - { { 'r', 0 }, "gui_preferences" }, - { { 'c', 0 }, "gui_skinbrowser" }, - - { { 0 }, NULL } -}; -#endif - #ifndef MP_MAX_KEY_FD #define MP_MAX_KEY_FD 10 #endif @@ -521,40 +510,72 @@ static const mp_cmd_bind_t gui_def_cmd_binds[] = { typedef struct mp_input_fd { int fd; - void* read_func; + union { + mp_key_func_t key; + mp_cmd_func_t cmd; + } read_func; mp_close_func_t close_func; + void *ctx; unsigned eof : 1; unsigned drop : 1; unsigned dead : 1; unsigned got_cmd : 1; unsigned no_select : 1; - unsigned no_readfunc_retval : 1; // These fields are for the cmd fds. char* buffer; int pos,size; } mp_input_fd_t; -typedef struct mp_cmd_filter_st mp_cmd_filter_t; +typedef struct mp_cmd_filter mp_cmd_filter_t; -struct mp_cmd_filter_st { +struct mp_cmd_filter { mp_input_cmd_filter filter; void* ctx; mp_cmd_filter_t* next; }; -typedef struct mp_cmd_bind_section_st mp_cmd_bind_section_t; +typedef struct mp_cmd_bind_section mp_cmd_bind_section_t; -struct mp_cmd_bind_section_st { +struct mp_cmd_bind_section { mp_cmd_bind_t* cmd_binds; char* section; mp_cmd_bind_section_t* next; }; -// These are the user defined binds -static mp_cmd_bind_section_t* cmd_binds_section = NULL; -static char* section = NULL; -static mp_cmd_bind_t* cmd_binds = NULL; -static mp_cmd_bind_t* cmd_binds_default = NULL; +struct input_ctx { + // Autorepeat stuff + short ar_state; + mp_cmd_t *ar_cmd; + unsigned int last_ar; + // Autorepeat config + unsigned int ar_delay; + unsigned int ar_rate; + + // these are the keys currently down + int key_down[MP_MAX_KEY_DOWN]; + unsigned int num_key_down; + unsigned int last_key_down; + + bool default_bindings; + // List of command binding sections + mp_cmd_bind_section_t *cmd_bind_sections; + // Name of currently used command section + char *section; + // The command binds of current section + mp_cmd_bind_t *cmd_binds; + mp_cmd_bind_t *cmd_binds_default; + + mp_input_fd_t key_fds[MP_MAX_KEY_FD]; + unsigned int num_key_fd; + + mp_input_fd_t cmd_fds[MP_MAX_CMD_FD]; + unsigned int num_cmd_fd; + + mp_cmd_t *cmd_queue[CMD_QUEUE_SIZE]; + unsigned int cmd_queue_length, cmd_queue_start, cmd_queue_end; +}; + + static mp_cmd_filter_t* cmd_filters = NULL; // Callback to allow the menu filter to grab the incoming keys @@ -562,81 +583,47 @@ int (*mp_input_key_cb)(int code) = NULL; int async_quit_request; -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 mp_cmd_t* cmd_queue[CMD_QUEUE_SIZE]; -static unsigned int cmd_queue_length = 0,cmd_queue_start = 0, cmd_queue_end = 0; - -// this is the key currently down -static int key_down[MP_MAX_KEY_DOWN]; -static unsigned int num_key_down = 0, last_key_down = 0; - -// Autorepeat stuff -static short ar_state = -1; -static mp_cmd_t* ar_cmd = NULL; -static unsigned int ar_delay = 100, ar_rate = 8, last_ar = 0; - -static int use_joystick = 1, use_lirc = 1, use_lircc = 1; -static int default_bindings = 1; -static char* config_file = "input.conf"; - -/* Apple Remote */ -#ifdef CONFIG_APPLE_REMOTE -static int use_ar = 1; -#else -static int use_ar = 0; -#endif - -static char* js_dev = NULL; -static char* ar_dev = NULL; - -static char* in_file = NULL; -static int in_file_fd = -1; - -static int mp_input_print_key_list(m_option_t* cfg); -static int mp_input_print_cmd_list(m_option_t* cfg); +static int print_key_list(m_option_t* cfg); +static int print_cmd_list(m_option_t* cfg); // Our command line options -static m_option_t input_conf[] = { - { "conf", &config_file, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, - { "ar-dev", &ar_dev, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, - { "ar-delay", &ar_delay, CONF_TYPE_INT, CONF_GLOBAL, 0, 0, NULL }, - { "ar-rate", &ar_rate, CONF_TYPE_INT, CONF_GLOBAL, 0, 0, NULL }, - { "keylist", mp_input_print_key_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, - { "cmdlist", mp_input_print_cmd_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, - { "js-dev", &js_dev, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, - { "file", &in_file, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, - { "default-bindings", &default_bindings, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, - { "nodefault-bindings", &default_bindings, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, +static const m_option_t input_conf[] = { + OPT_STRING("conf", input.config_file, CONF_GLOBAL), + OPT_INT("ar-delay",input.ar_delay, CONF_GLOBAL), + OPT_INT("ar-rate", input.ar_rate, CONF_GLOBAL), + { "keylist", print_key_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, + { "cmdlist", print_cmd_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, + OPT_STRING("js-dev", input.js_dev, CONF_GLOBAL), + OPT_STRING("ar-dev", input.ar_dev, CONF_GLOBAL), + OPT_STRING("file", input.in_file, CONF_GLOBAL), + OPT_FLAG_ON("default-bindings", input.default_bindings, CONF_GLOBAL), + OPT_FLAG_OFF("nodefault-bindings", input.default_bindings, CONF_GLOBAL), { NULL, NULL, 0, 0, 0, 0, NULL} }; -static m_option_t mp_input_opts[] = { +static const m_option_t mp_input_opts[] = { { "input", &input_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, - { "nojoystick", &use_joystick, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "joystick", &use_joystick, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, - { "nolirc", &use_lirc, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "lirc", &use_lirc, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, - { "nolircc", &use_lircc, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "lircc", &use_lircc, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, - { "noar", &use_ar, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL }, - { "ar", &use_ar, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL }, + OPT_FLAG_OFF("nojoystick", input.use_joystick, CONF_GLOBAL), + OPT_FLAG_ON("joystick", input.use_joystick, CONF_GLOBAL), + OPT_FLAG_OFF("nolirc", input.use_lirc, CONF_GLOBAL), + OPT_FLAG_ON("lirc", input.use_lirc, CONF_GLOBAL), + OPT_FLAG_OFF("nolircc", input.use_lircc, CONF_GLOBAL), + OPT_FLAG_ON("lircc", input.use_lircc, CONF_GLOBAL), + OPT_FLAG_OFF("noar", input.use_ar, CONF_GLOBAL), + OPT_FLAG_ON("ar", input.use_ar, CONF_GLOBAL), { NULL, NULL, 0, 0, 0, 0, NULL} }; -static int -mp_input_default_cmd_func(int fd,char* buf, int l); +static int default_cmd_func(int fd,char* buf, int l); -static char* -mp_input_get_key_name(int key); +static char *get_key_name(int key, char buffer[12]); -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) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantRegister2ManyCmdFds,fd); +int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select, + mp_cmd_func_t read_func, mp_close_func_t close_func) +{ + if (ictx->num_cmd_fd == MP_MAX_CMD_FD) { + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Too many command file descriptors, cannot register file descriptor %d.\n",fd); return 0; } if (select && fd < 0) { @@ -644,58 +631,65 @@ mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t 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_input_default_cmd_func; - cmd_fds[num_cmd_fd].close_func = close_func; - cmd_fds[num_cmd_fd].no_select = !select; - num_cmd_fd++; + ictx->cmd_fds[ictx->num_cmd_fd] = (struct mp_input_fd){ + .fd = fd, + .read_func.cmd = read_func ? read_func : default_cmd_func, + .close_func = close_func, + .no_select = !select + }; + ictx->num_cmd_fd++; return 1; } -void -mp_input_rm_cmd_fd(int fd) { +void mp_input_rm_cmd_fd(struct input_ctx *ictx, int fd) +{ + struct mp_input_fd *cmd_fds = ictx->cmd_fds; unsigned int i; - for(i = 0; i < num_cmd_fd; i++) { + for (i = 0; i < ictx->num_cmd_fd; i++) { if(cmd_fds[i].fd == fd) break; } - if(i == num_cmd_fd) + if (i == ictx->num_cmd_fd) return; if(cmd_fds[i].close_func) cmd_fds[i].close_func(cmd_fds[i].fd); if(cmd_fds[i].buffer) - free(cmd_fds[i].buffer); + talloc_free(cmd_fds[i].buffer); - 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--; + if (i + 1 < ictx->num_cmd_fd) + memmove(&cmd_fds[i], &cmd_fds[i+1], + (ictx->num_cmd_fd - i - 1) * sizeof(mp_input_fd_t)); + ictx->num_cmd_fd--; } -void -mp_input_rm_key_fd(int fd) { +void mp_input_rm_key_fd(struct input_ctx *ictx, int fd) +{ + struct mp_input_fd *key_fds = ictx->key_fds; unsigned int i; - for(i = 0; i < num_key_fd; i++) { + for (i = 0; i < ictx->num_key_fd; i++) { if(key_fds[i].fd == fd) break; } - if(i == num_key_fd) + if (i == ictx->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--; + if(i + 1 < ictx->num_key_fd) + memmove(&key_fds[i], &key_fds[i+1], + (ictx->num_key_fd - i - 1) * sizeof(mp_input_fd_t)); + ictx->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) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantRegister2ManyKeyFds,fd); +int mp_input_add_key_fd(struct input_ctx *ictx, int fd, int select, + mp_key_func_t read_func, mp_close_func_t close_func, + void *ctx) +{ + if (ictx->num_key_fd == MP_MAX_KEY_FD) { + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Too many key file descriptors, cannot register file descriptor %d.\n",fd); return 0; } if (select && fd < 0) { @@ -703,44 +697,20 @@ mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t 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; - key_fds[num_key_fd].close_func = close_func; - key_fds[num_key_fd].no_select = !select; - num_key_fd++; - - return 1; -} - -int -mp_input_add_event_fd(int fd, void (*read_func)(void)) -{ - if(num_key_fd == MP_MAX_KEY_FD) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantRegister2ManyKeyFds,fd); - return 0; - } - if (fd < 0) { - mp_msg(MSGT_INPUT, MSGL_ERR, "Invalid fd %i in mp_input_add_event_fd", 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; - key_fds[num_key_fd].close_func = NULL; - key_fds[num_key_fd].no_readfunc_retval = 1; - num_key_fd++; + ictx->key_fds[ictx->num_key_fd] = (struct mp_input_fd){ + .fd = fd, + .read_func.key = read_func, + .close_func = close_func, + .no_select = !select, + .ctx = ctx, + }; + ictx->num_key_fd++; return 1; } -void mp_input_rm_event_fd(int fd) +int mp_input_parse_and_queue_cmds(struct input_ctx *ictx, const char *str) { - mp_input_rm_key_fd(fd); -} - -int mp_input_parse_and_queue_cmds(const char *str) { int cmd_num = 0; while (*str == '\n' || *str == '\r' || *str == ' ') @@ -748,17 +718,17 @@ int mp_input_parse_and_queue_cmds(const char *str) { while (*str) { mp_cmd_t *cmd; size_t len = strcspn(str, "\r\n"); - char *cmdbuf = malloc(len+1); + char *cmdbuf = talloc_size(NULL, len+1); av_strlcpy(cmdbuf, str, len+1); cmd = mp_input_parse_cmd(cmdbuf); if (cmd) { - mp_input_queue_cmd(cmd); + mp_input_queue_cmd(ictx, cmd); ++cmd_num; } str += len; while (*str == '\n' || *str == '\r' || *str == ' ') ++str; - free(cmdbuf); + talloc_free(cmdbuf); } return cmd_num; } @@ -766,9 +736,8 @@ int mp_input_parse_and_queue_cmds(const char *str) { mp_cmd_t* mp_input_parse_cmd(char* str) { int i,l; - int pausing = -1; + int pausing = 0; char *ptr,*e; - mp_cmd_t *cmd; const mp_cmd_t *cmd_def; #ifdef MP_DEBUG @@ -813,19 +782,12 @@ mp_input_parse_cmd(char* str) { cmd_def = &mp_cmds[i]; - cmd = calloc(1, sizeof(mp_cmd_t)); - cmd->id = cmd_def->id; - cmd->name = strdup(cmd_def->name); - if (pausing == -1) { - switch (cmd->id) { - case MP_CMD_KEYDOWN_EVENTS: - case MP_CMD_SET_MOUSE_POS: - pausing = 4; break; - default: - pausing = 0; break; - } - } - cmd->pausing = pausing; + mp_cmd_t *cmd = talloc_ptrtype(NULL, cmd); + *cmd = (mp_cmd_t){ + .id = cmd_def->id, + .name = talloc_strdup(cmd, cmd_def->name), + .pausing = pausing, + }; ptr = str; @@ -840,7 +802,7 @@ mp_input_parse_cmd(char* str) { errno = 0; cmd->args[i].v.i = atoi(ptr); if(errno != 0) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrArgMustBeInt,cmd_def->name,i+1); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Command %s: argument %d isn't an integer.\n",cmd_def->name,i+1); ptr = NULL; } break; @@ -848,7 +810,7 @@ mp_input_parse_cmd(char* str) { errno = 0; cmd->args[i].v.f = atof(ptr); if(errno != 0) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrArgMustBeFloat,cmd_def->name,i+1); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Command %s: argument %d isn't a float.\n",cmd_def->name,i+1); ptr = NULL; } break; @@ -870,7 +832,7 @@ mp_input_parse_cmd(char* str) { } if(term != ' ' && (!e || e[0] == '\0')) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrUnterminatedArg,cmd_def->name,i+1); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Command %s: argument %d is unterminated.\n",cmd_def->name,i+1); ptr = NULL; break; } else if(!e) e = ptr+strlen(ptr); @@ -881,23 +843,21 @@ mp_input_parse_cmd(char* str) { ptr2 = e + 1; l--; } - cmd->args[i].v.s = malloc(l+1); - strncpy(cmd->args[i].v.s,start,l); - cmd->args[i].v.s[l] = '\0'; + cmd->args[i].v.s = talloc_strndup(cmd, start, l); if(term != ' ') ptr += l+2; } break; case -1: ptr = NULL; break; default : - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrUnknownArg,i); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Unknown argument %d\n",i); } } cmd->nargs = i; if(cmd_def->nargs > cmd->nargs) { /* mp_msg(MSGT_INPUT,MSGL_ERR,"Got command '%s' but\n",str); */ - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_Err2FewArgs,cmd_def->name,cmd_def->nargs,cmd->nargs); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Command %s requires 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; } @@ -905,7 +865,7 @@ mp_input_parse_cmd(char* str) { for( ; i < MP_CMD_MAX_ARGS && cmd_def->args[i].type != -1 ; i++) { memcpy(&cmd->args[i],&cmd_def->args[i],sizeof(mp_cmd_arg_t)); if(cmd_def->args[i].type == MP_CMD_ARG_STRING && cmd_def->args[i].v.s != NULL) - cmd->args[i].v.s = strdup(cmd_def->args[i].v.s); + cmd->args[i].v.s = talloc_strdup(cmd, cmd_def->args[i].v.s); } if(i < MP_CMD_MAX_ARGS) @@ -916,27 +876,28 @@ mp_input_parse_cmd(char* str) { #define MP_CMD_MAX_SIZE 4096 -static int -mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { +static int read_cmd(mp_input_fd_t* mp_fd, char** ret) +{ char* end; (*ret) = NULL; // Allocate the buffer if it doesn't exist if(!mp_fd->buffer) { - mp_fd->buffer = malloc(MP_CMD_MAX_SIZE); + mp_fd->buffer = talloc_size(NULL, MP_CMD_MAX_SIZE); mp_fd->pos = 0; mp_fd->size = MP_CMD_MAX_SIZE; } // Get some data if needed/possible while (!mp_fd->got_cmd && !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); + int r = mp_fd->read_func.cmd(mp_fd->fd, mp_fd->buffer+mp_fd->pos, + mp_fd->size - 1 - mp_fd->pos); // Error ? if(r < 0) { switch(r) { case MP_INPUT_ERROR: case MP_INPUT_DEAD: - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrReadingCmdFd,mp_fd->fd,strerror(errno)); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Error while reading command file descriptor %d: %s\n",mp_fd->fd,strerror(errno)); case MP_INPUT_NOTHING: return r; case MP_INPUT_RETRY: @@ -962,7 +923,7 @@ mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { if(!end) { // If buffer is full we must drop all until the next \n if(mp_fd->size - mp_fd->pos <= 1) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCmdBufferFullDroppingContent,mp_fd->fd); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Command buffer of file descriptor %d is full: dropping content.\n",mp_fd->fd); mp_fd->pos = 0; mp_fd->drop = 1; } @@ -977,16 +938,12 @@ mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { l = end - mp_fd->buffer; // Not dropping : put the cmd in ret - if (!mp_fd->drop) { - (*ret) = malloc(l+1); - strncpy((*ret),mp_fd->buffer,l); - (*ret)[l] = '\0'; - } else { // Remove the dropping flag + if (!mp_fd->drop) + *ret = talloc_strndup(NULL, mp_fd->buffer, l); + else mp_fd->drop = 0; - } - if( mp_fd->pos - (l+1) > 0) - memmove(mp_fd->buffer,end+1,mp_fd->pos-(l+1)); mp_fd->pos -= l+1; + memmove(mp_fd->buffer, end+1, mp_fd->pos); } if(*ret) @@ -995,9 +952,8 @@ mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) { return MP_INPUT_NOTHING; } -static int -mp_input_default_cmd_func(int fd,char* buf, int l) { - +static int default_cmd_func(int fd,char* buf, int l) +{ while(1) { int r = read(fd,buf,l); // Error ? @@ -1017,7 +973,7 @@ mp_input_default_cmd_func(int fd,char* buf, int l) { void mp_input_add_cmd_filter(mp_input_cmd_filter func, void* ctx) { - mp_cmd_filter_t* filter = malloc(sizeof(mp_cmd_filter_t))/*, *prev*/; + mp_cmd_filter_t *filter = talloc_ptrtype(NULL, filter); filter->filter = func; filter->ctx = ctx; @@ -1026,8 +982,8 @@ mp_input_add_cmd_filter(mp_input_cmd_filter func, void* ctx) { } -static char* -mp_input_find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) { +static char *find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) +{ int j; if (n <= 0) return NULL; @@ -1045,9 +1001,10 @@ mp_input_find_bind_for_key(const mp_cmd_bind_t* binds, int n,int* keys) { return binds[j].cmd; } -static mp_cmd_bind_section_t* -mp_input_get_bind_section(char *section) { - mp_cmd_bind_section_t* bind_section = cmd_binds_section; +static mp_cmd_bind_section_t *get_bind_section(struct input_ctx *ictx, + char *section) +{ + mp_cmd_bind_section_t *bind_section = ictx->cmd_bind_sections; if (section==NULL) section="default"; while (bind_section) { @@ -1056,36 +1013,39 @@ mp_input_get_bind_section(char *section) { bind_section=bind_section->next; } if(bind_section) { - bind_section->next=malloc(sizeof(mp_cmd_bind_section_t)); + bind_section->next = talloc_ptrtype(ictx, bind_section->next); bind_section=bind_section->next; } else { - cmd_binds_section=malloc(sizeof(mp_cmd_bind_section_t)); - bind_section=cmd_binds_section; + ictx->cmd_bind_sections = talloc_ptrtype(ictx, ictx->cmd_bind_sections); + bind_section = ictx->cmd_bind_sections; } bind_section->cmd_binds=NULL; - bind_section->section=strdup(section); + bind_section->section = talloc_strdup(bind_section, section); bind_section->next=NULL; return bind_section; } -static mp_cmd_t* -mp_input_get_cmd_from_keys(int n,int* keys, int paused) { +static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys, + int paused) +{ char* cmd = NULL; mp_cmd_t* ret; + char key_buf[12]; - if(cmd_binds) - cmd = mp_input_find_bind_for_key(cmd_binds,n,keys); - if(cmd_binds_default && cmd == NULL) - cmd = mp_input_find_bind_for_key(cmd_binds_default,n,keys); - if(default_bindings && cmd == NULL) - cmd = mp_input_find_bind_for_key(def_cmd_binds,n,keys); + if (ictx->cmd_binds) + cmd = find_bind_for_key(ictx->cmd_binds, n, keys); + if (ictx->cmd_binds_default && cmd == NULL) + cmd = find_bind_for_key(ictx->cmd_binds_default, n, keys); + if (ictx->default_bindings && cmd == NULL) + cmd = find_bind_for_key(def_cmd_binds,n,keys); if(cmd == NULL) { - mp_msg(MSGT_INPUT,MSGL_WARN,MSGTR_NoBindFound,mp_input_get_key_name(keys[0])); + mp_tmsg(MSGT_INPUT,MSGL_WARN,"No bind found for key '%s'.", get_key_name(keys[0], + key_buf)); if(n > 1) { int s; for(s=1; s < n; s++) - mp_msg(MSGT_INPUT,MSGL_WARN,"-%s",mp_input_get_key_name(keys[s])); + mp_msg(MSGT_INPUT,MSGL_WARN,"-%s", get_key_name(keys[s], key_buf)); } mp_msg(MSGT_INPUT,MSGL_WARN," \n"); return NULL; @@ -1093,11 +1053,13 @@ mp_input_get_cmd_from_keys(int n,int* keys, int paused) { if (strcmp(cmd, "ignore") == 0) return NULL; ret = mp_input_parse_cmd(cmd); if(!ret) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrInvalidCommandForKey,mp_input_get_key_name(key_down[0])); - if( num_key_down > 1) { + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Invalid command for bound key %s", + get_key_name(ictx->key_down[0], key_buf)); + if (ictx->num_key_down > 1) { unsigned int s; - for(s=1; s < num_key_down; s++) - mp_msg(MSGT_INPUT,MSGL_ERR,"-%s",mp_input_get_key_name(key_down[s])); + for(s=1; s < ictx->num_key_down; s++) + mp_msg(MSGT_INPUT,MSGL_ERR,"-%s", get_key_name(ictx->key_down[s], + key_buf)); } mp_msg(MSGT_INPUT,MSGL_ERR," : %s \n",cmd); } @@ -1105,8 +1067,7 @@ mp_input_get_cmd_from_keys(int n,int* keys, int paused) { } -static mp_cmd_t* -interpret_key(int code, int paused) +static mp_cmd_t* interpret_key(struct input_ctx *ictx, int code, int paused) { unsigned int j; mp_cmd_t* ret; @@ -1120,105 +1081,111 @@ interpret_key(int code, int paused) } if(code & MP_KEY_DOWN) { - if(num_key_down > MP_MAX_KEY_DOWN) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_Err2ManyKeyDowns); + if (ictx->num_key_down > MP_MAX_KEY_DOWN) { + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Too many key down events at the same time\n"); return NULL; } code &= ~MP_KEY_DOWN; // Check if we don't already have this key as pushed - for(j = 0; j < num_key_down; j++) { - if(key_down[j] == code) + for (j = 0; j < ictx->num_key_down; j++) { + if (ictx->key_down[j] == code) break; } - if(j != num_key_down) + if (j != ictx->num_key_down) return NULL; - key_down[num_key_down] = code; - num_key_down++; - last_key_down = GetTimer(); - ar_state = 0; + ictx->key_down[ictx->num_key_down] = code; + ictx->num_key_down++; + ictx->last_key_down = GetTimer(); + ictx->ar_state = 0; return NULL; } // key released // Check if the key is in the down key, driver which can't send push event // send only release event - for(j = 0; j < num_key_down; j++) { - if(key_down[j] == code) + for (j = 0; j < ictx->num_key_down; j++) { + if (ictx->key_down[j] == code) break; } - if(j == num_key_down) { // key was not in the down keys : add it - if(num_key_down > MP_MAX_KEY_DOWN) { - mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_Err2ManyKeyDowns); + if (j == ictx->num_key_down) { // key was not in the down keys : add it + if (ictx->num_key_down > MP_MAX_KEY_DOWN) { + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Too many key down events at the same time\n"); return NULL; } - key_down[num_key_down] = code; - num_key_down++; - last_key_down = 1; + ictx->key_down[ictx->num_key_down] = code; + ictx->num_key_down++; + ictx->last_key_down = 1; } // We ignore key from last combination - ret = last_key_down ? mp_input_get_cmd_from_keys(num_key_down,key_down,paused) : NULL; + ret = ictx->last_key_down ? + get_cmd_from_keys(ictx, ictx->num_key_down, ictx->key_down, paused) + : NULL; // Remove the key - if(j+1 < num_key_down) - memmove(&key_down[j],&key_down[j+1],(num_key_down-(j+1))*sizeof(int)); - num_key_down--; - last_key_down = 0; - ar_state = -1; - if(ar_cmd) { - mp_cmd_free(ar_cmd); - ar_cmd = NULL; + if (j+1 < ictx->num_key_down) + memmove(&ictx->key_down[j], &ictx->key_down[j+1], + (ictx->num_key_down-(j+1))*sizeof(int)); + ictx->num_key_down--; + ictx->last_key_down = 0; + ictx->ar_state = -1; + if (ictx->ar_cmd) { + mp_cmd_free(ictx->ar_cmd); + ictx->ar_cmd = NULL; } return ret; } -static mp_cmd_t *check_autorepeat(int paused) +static mp_cmd_t *check_autorepeat(struct input_ctx *ictx, int paused) { // No input : autorepeat ? - if(ar_rate > 0 && ar_state >=0 && num_key_down > 0 && ! (key_down[num_key_down-1] & MP_NO_REPEAT_KEY)) { + if (ictx->ar_rate > 0 && ictx->ar_state >=0 && ictx->num_key_down > 0 + && !(ictx->key_down[ictx->num_key_down-1] & MP_NO_REPEAT_KEY)) { unsigned int t = GetTimer(); // First time : wait delay - if(ar_state == 0 && (t - last_key_down) >= ar_delay*1000) { - ar_cmd = mp_input_get_cmd_from_keys(num_key_down,key_down,paused); - if(!ar_cmd) { - ar_state = -1; + if (ictx->ar_state == 0 + && (t - ictx->last_key_down) >= ictx->ar_delay*1000) { + ictx->ar_cmd = get_cmd_from_keys(ictx, ictx->num_key_down, + ictx->key_down, paused); + if (!ictx->ar_cmd) { + ictx->ar_state = -1; return NULL; } - ar_state = 1; - last_ar = t; - return mp_cmd_clone(ar_cmd); + ictx->ar_state = 1; + ictx->last_ar = t; + return mp_cmd_clone(ictx->ar_cmd); // Then send rate / sec event - } else if(ar_state == 1 && (t -last_ar) >= 1000000/ar_rate) { - last_ar = t; - return mp_cmd_clone(ar_cmd); + } else if (ictx->ar_state == 1 + && (t -ictx->last_ar) >= 1000000 / ictx->ar_rate) { + ictx->last_ar = t; + return mp_cmd_clone(ictx->ar_cmd); } } return NULL; } -static mp_cmd_t *read_events(int time, int paused) +static mp_cmd_t *read_events(struct input_ctx *ictx, int time, int paused) { int i; int got_cmd = 0; - mp_cmd_t *autorepeat_cmd; -#ifdef HAVE_POSIX_SELECT - fd_set fds; -#endif - for (i = 0; i < num_key_fd; i++) + struct mp_input_fd *key_fds = ictx->key_fds; + struct mp_input_fd *cmd_fds = ictx->cmd_fds; + for (i = 0; i < ictx->num_key_fd; i++) if (key_fds[i].dead) { - mp_input_rm_key_fd(key_fds[i].fd); + mp_input_rm_key_fd(ictx, key_fds[i].fd); i--; } - for (i = 0; i < num_cmd_fd; i++) + for (i = 0; i < ictx->num_cmd_fd; i++) if (cmd_fds[i].dead || cmd_fds[i].eof) { - mp_input_rm_cmd_fd(cmd_fds[i].fd); + mp_input_rm_cmd_fd(ictx, cmd_fds[i].fd); i--; } else if (cmd_fds[i].got_cmd) got_cmd = 1; #ifdef HAVE_POSIX_SELECT + fd_set fds; FD_ZERO(&fds); if (!got_cmd) { int max_fd = 0, num_fd = 0; - for (i = 0; i < num_key_fd; i++) { + for (i = 0; i < ictx->num_key_fd; i++) { if (key_fds[i].no_select) continue; if (key_fds[i].fd > max_fd) @@ -1226,7 +1193,7 @@ static mp_cmd_t *read_events(int time, int paused) FD_SET(key_fds[i].fd, &fds); num_fd++; } - for (i = 0; i < num_cmd_fd; i++) { + for (i = 0; i < ictx->num_cmd_fd; i++) { if (cmd_fds[i].no_select) continue; if (cmd_fds[i].fd > max_fd) @@ -1245,7 +1212,7 @@ static mp_cmd_t *read_events(int time, int paused) time_val = NULL; if (select(max_fd + 1, &fds, NULL, NULL, time_val) < 0) { if (errno != EINTR) - mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrSelect, + mp_tmsg(MSGT_INPUT, MSGL_ERR, "Select error: %s\n", strerror(errno)); FD_ZERO(&fds); } @@ -1257,58 +1224,47 @@ static mp_cmd_t *read_events(int time, int paused) #endif - for (i = 0; i < num_key_fd; i++) { - int code; + for (i = 0; i < ictx->num_key_fd; i++) { #ifdef HAVE_POSIX_SELECT if (!key_fds[i].no_select && !FD_ISSET(key_fds[i].fd, &fds)) continue; #endif - if (key_fds[i].no_readfunc_retval) { // getch2 handler special-cased for now - ((void (*)(void))key_fds[i].read_func)(); - if (cmd_queue_length) - return NULL; - code = mplayer_get_key(0); - if (code < 0) - code = MP_INPUT_NOTHING; - } - else - code = ((mp_key_func_t)key_fds[i].read_func)(key_fds[i].fd); + int code = key_fds[i].read_func.key(key_fds[i].ctx, key_fds[i].fd); if (code >= 0) { - mp_cmd_t *ret = interpret_key(code, paused); + mp_cmd_t *ret = interpret_key(ictx, code, paused); if (ret) return ret; } else if (code == MP_INPUT_ERROR) - mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrOnKeyInFd, + mp_tmsg(MSGT_INPUT, MSGL_ERR, "Error on key input file descriptor %d\n", key_fds[i].fd); else if (code == MP_INPUT_DEAD) { - mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrDeadKeyOnFd, + mp_tmsg(MSGT_INPUT, MSGL_ERR, "Dead key input on file descriptor %d\n", key_fds[i].fd); key_fds[i].dead = 1; } } - autorepeat_cmd = check_autorepeat(paused); + mp_cmd_t *autorepeat_cmd = check_autorepeat(ictx, paused); if (autorepeat_cmd) return autorepeat_cmd; - for (i = 0; i < num_cmd_fd; i++) { - char *cmd; - int r; + for (i = 0; i < ictx->num_cmd_fd; i++) { #ifdef HAVE_POSIX_SELECT if (!cmd_fds[i].no_select && !FD_ISSET(cmd_fds[i].fd, &fds) && !cmd_fds[i].got_cmd) continue; #endif - r = mp_input_read_cmd(&cmd_fds[i], &cmd); + char *cmd; + int r = read_cmd(&cmd_fds[i], &cmd); if (r >= 0) { mp_cmd_t *ret = mp_input_parse_cmd(cmd); - free(cmd); + talloc_free(cmd); if (ret) return ret; } else if (r == MP_INPUT_ERROR) - mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrOnCmdFd, + mp_tmsg(MSGT_INPUT, MSGL_ERR, "Error on command file descriptor %d\n", cmd_fds[i].fd); else if (r == MP_INPUT_DEAD) cmd_fds[i].dead = 1; @@ -1318,28 +1274,28 @@ static |