2008年10月8日星期三

nanox GsSelect函数记一下

GsSelect 获得nanox事件
|----select 同时select 2个文件描述符(鼠标,按键)
|----if((e > 0) 如果select有数据
|----|----GsCheckMouseEvent 获得鼠标事件
|----|----|----devmouse.c GdReadMouse 配置了鼠标或触摸屏
|----|----|----|----mousedev.Read 调用鼠标驱动读函数读数据,如果是transform模式则转换为lcd点再返回,如果是raw模式则直接返回数据
|----|----|----devnomouse.c GdReadMouse 未配置鼠标,直接返回x y为0的数据
|----|----GsCheckKeyboardEvent 获得键盘事件
|----|----|----GdReadKeyboard 调用devkbd.c读取键盘消息
|----|----|----|----kbddev.Read 读取键盘消息
|----|----GsDeliverKeyboardEvent 根据键值发送pen down/up事件
|----else if (e == 0) 如果select无数据
|----|----GdTimeout timeout返回
|----else if ( e < 0 ) 如果select出错,打印错误返回


说一下GsSelect的fd与select
/* Set up the FDs for use in the main select(): */
FD_ZERO(&rfds);
if(mouse_fd >= 0) {
FD_SET(mouse_fd, &rfds);
if (mouse_fd > setsize)
setsize = mouse_fd;
}
if(keyb_fd >= 0) {
FD_SET(keyb_fd, &rfds);
if (keyb_fd > setsize)
setsize = keyb_fd;

先将rfds清零,把mouse_fd和keyb_fd设置到rfds的某一位上,原本我不知道file descriptor怎样分配了,看了一下,结果fd是一个文件描述符表的索引,所以是个很小的正整数。这样FD_SET某一位时也不会重复

select(setsize+1, &rfds, NULL, NULL, to)

select同时作用到2个fd上,setsize是mouse_fd和keyb_fd中最大的一个加1,rfds里又有mouse和key的2位置1,这样内核sys_select里实现是有个for循环,会把mouse和key的poll都调用到,而不是我以前所理解的,一个select对应一个poll,而是一对多的关系。setsize加1是因为do_select 循环里用的是i < n,所以要执行到n传进去的数要加1

要看fd可以看sys_close(unsigned int fd)
struct fdtable *fdt;
fdt->fd[fd],数组下标就是fd

struct fdtable {
unsigned int max_fds;
int max_fdset;
int next_fd;
struct file ** fd; /* current fd array */
fd_set *close_on_exec;
fd_set *open_fds;
struct rcu_head rcu;
struct files_struct *free_files;
struct fdtable *next;
};

没有评论: