input.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,860 行 · 第 1/4 页
C
1,860 行
static intmp_input_default_cmd_func(int fd,char* buf, int l) { while(1) { int r = read(fd,buf,l); // Error ? if(r < 0) { if(errno == EINTR) continue; else if(errno == EAGAIN) return MP_INPUT_NOTHING; return MP_INPUT_ERROR; // EOF ? } return r; }}voidmp_input_add_cmd_filter(mp_input_cmd_filter func, void* ctx) { #if 0 mp_cmd_filter_t* filter = malloc(sizeof(mp_cmd_filter_t))/*, *prev*/; filter->filter = func; filter->ctx = ctx; filter->next = cmd_filters; cmd_filters = filter; #endif} static char*mp_input_find_bind_for_key(mp_cmd_bind_t* binds, int n,int* keys) { int j; if (n <= 0) return NULL; for(j = 0; binds[j].cmd != NULL; j++) { int found = 1,s; for(s = 0; s < n && binds[j].input[s] != 0; s++) { if(binds[j].input[s] != keys[s]) { found = 0; break; } } if(found && binds[j].input[s] == 0 && s == n) break; } 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; if (section==NULL) section="default"; while (bind_section) { if(strcmp(section,bind_section->section)==0) return bind_section; if(bind_section->next==NULL) break; bind_section=bind_section->next; } if(bind_section) { bind_section->next=malloc(sizeof(mp_cmd_bind_section_t)); bind_section=bind_section->next; } else { cmd_binds_section=malloc(sizeof(mp_cmd_bind_section_t)); bind_section=cmd_binds_section; } bind_section->cmd_binds=NULL; bind_section->section=strdup(section); bind_section->next=NULL; return bind_section;}static mp_cmd_t*mp_input_get_cmd_from_keys(int n,int* keys, int paused) { char* cmd = NULL; mp_cmd_t* ret; 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(cmd == NULL) cmd = mp_input_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])); 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," \n"); return NULL; } 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) { 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])); } mp_msg(MSGT_INPUT,MSGL_ERR," : %s \n",cmd); } return ret;}static mp_cmd_t*interpret_key(int code, int paused){ unsigned int j; mp_cmd_t* ret; if(mp_input_key_cb) { if (code & MP_KEY_DOWN) return NULL; code &= ~(MP_KEY_DOWN|MP_NO_REPEAT_KEY); mp_input_key_cb(code); return NULL; } if(code & MP_KEY_DOWN) { if(num_key_down > MP_MAX_KEY_DOWN) { mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_Err2ManyKeyDowns); 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) break; } if(j != num_key_down) return NULL; key_down[num_key_down] = code; num_key_down++; last_key_down = GetTimer(); 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) 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); return NULL; } key_down[num_key_down] = code; num_key_down++; 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; // 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; } return ret;}static mp_cmd_t *check_autorepeat(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)) { 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; return NULL; } ar_state = 1; last_ar = t; return mp_cmd_clone(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); } } return NULL;}static mp_cmd_t *read_events(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++) if (key_fds[i].dead) { mp_input_rm_key_fd(key_fds[i].fd); i--; } for (i = 0; i < num_cmd_fd; i++) if (cmd_fds[i].dead || cmd_fds[i].eof) { mp_input_rm_cmd_fd(cmd_fds[i].fd); i--; } else if (cmd_fds[i].got_cmd) got_cmd = 1;#ifdef HAVE_POSIX_SELECT FD_ZERO(&fds); if (!got_cmd) { int max_fd = 0, num_fd = 0; for (i = 0; i < num_key_fd; i++) { if (key_fds[i].no_select) continue; if (key_fds[i].fd > max_fd) max_fd = key_fds[i].fd; FD_SET(key_fds[i].fd, &fds); num_fd++; } for (i = 0; i < num_cmd_fd; i++) { if (cmd_fds[i].no_select) continue; if (cmd_fds[i].fd > max_fd) max_fd = cmd_fds[i].fd; FD_SET(cmd_fds[i].fd, &fds); num_fd++; } if (num_fd > 0) { struct timeval tv, *time_val; if (time >= 0) { tv.tv_sec = time / 1000; tv.tv_usec = (time % 1000) * 1000; time_val = &tv; } else 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, strerror(errno)); FD_ZERO(&fds); } } }#else if (!got_cmd) usec_sleep(time * 1000);#endif for (i = 0; i < num_key_fd; i++) { int code;#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); if (code >= 0) { mp_cmd_t *ret = interpret_key(code, paused); if (ret) return ret; } else if (code == MP_INPUT_ERROR) mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrOnKeyInFd, key_fds[i].fd); else if (code == MP_INPUT_DEAD) { mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrDeadKeyOnFd, key_fds[i].fd); key_fds[i].dead = 1; } } autorepeat_cmd = check_autorepeat(paused); if (autorepeat_cmd) return autorepeat_cmd; for (i = 0; i < num_cmd_fd; i++) { char *cmd; int r;#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); if (r >= 0) { mp_cmd_t *ret = mp_input_parse_cmd(cmd); free(cmd); if (ret) return ret; } else if (r == MP_INPUT_ERROR) mp_msg(MSGT_INPUT, MSGL_ERR, MSGTR_INPUT_INPUT_ErrOnCmdFd, cmd_fds[i].fd); else if (r == MP_INPUT_DEAD) cmd_fds[i].dead = 1; } return NULL;}intmp_input_queue_cmd(mp_cmd_t* cmd) { #if 0 if(cmd_queue_length >= CMD_QUEUE_SIZE) return 0; cmd_queue[cmd_queue_end] = cmd; cmd_queue_end = (cmd_queue_end + 1) % CMD_QUEUE_SIZE; cmd_queue_length++; #endif return 1;}static mp_cmd_t*mp_input_get_queued_cmd(int peek_only) { mp_cmd_t* ret; if(cmd_queue_length == 0) return NULL; ret = cmd_queue[cmd_queue_start]; if (!peek_only) { cmd_queue_length--; cmd_queue_start = (cmd_queue_start + 1) % CMD_QUEUE_SIZE; } return ret;} /** * \param peek_only when set, the returned command stays in the queue. * Do not free the returned cmd whe you set this! */mp_cmd_t*mp_input_get_cmd(int time, int paused, int peek_only) { #if 0 mp_cmd_t* ret = NULL; mp_cmd_filter_t* cf; int from_queue; while(1) { from_queue = 1; ret = mp_input_get_queued_cmd(peek_only); if(ret) break; from_queue = 0; ret = read_events(time, paused); if (!ret) { from_queue = 1; ret = mp_input_get_queued_cmd(peek_only); } break; } if(!ret) return NULL; for(cf = cmd_filters ; cf ; cf = cf->next) { if(cf->filter(ret,paused,cf->ctx)) return NULL; } if (!from_queue && peek_only) mp_input_queue_cmd(ret); return ret; #endif return NULL;}voidmp_cmd_free(mp_cmd_t* cmd) { #if 0 int i;//#ifdef MP_DEBUG// assert(cmd != NULL);//#endif if ( !cmd ) return; 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 && cmd->args[i].v.s != NULL) free(cmd->args[i].v.s); } free(cmd); #endif}mp_cmd_t*mp_cmd_clone(mp_cmd_t* cmd) { #if 0 mp_cmd_t* ret; int i;#ifdef MP_DEBUG assert(cmd != NULL);#endif ret = malloc(sizeof(mp_cmd_t)); memcpy(ret,cmd,sizeof(mp_cmd_t)); if(cmd->name) ret->name = strdup(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 && cmd->args[i].v.s != NULL) ret->args[i].v.s = strdup(cmd->args[i].v.s); } return ret; #endif return NULL;}static char key_str[12];static char*mp_input_get_key_name(int key) { int i; for(i = 0; key_names[i].name != NULL; i++) { if(key_names[i].key == key) return key_names[i].name; } if(isascii(key)) { snprintf(key_str,12,"%c",(char)key); return key_str; } // Print the hex key code snprintf(key_str,12,"%#-8x",key); return key_str;}static intmp_input_get_key_from_name(char* name) { int i,ret = 0,len = strlen(name); if(len == 1) { // Direct key code ret = (unsigned char)name[0]; return ret;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?