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 + -
显示快捷键?