主题 : 小分析->minigui+tslib的触摸屏输入引擎毛病 复制链接 | 浏览器收藏 | 打印
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
贡献值: 2 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
楼主  发表于: 2010-10-23 23:04

 小分析->minigui+tslib的触摸屏输入引擎毛病

管理提醒: 本帖被 kasim 设置为精华(2010-10-24)
       因为MiniGUI的轻巧,灵活,而且还是我们国产的嵌入式GUI,我弃QT的强大首选了它来学习。由于minigui的文档挺详细的而且是汉语编写的,学习起来挺容易的。
  可是学习了这么久还是用鼠标和键盘进行操作,感觉触摸屏挺委屈的,于是从网上搜罗了一大堆的IAL移植资料,大部分都是 minigui+tslib,而且内容都基本上相同。
  
按照这些方法很快的就移植好了(我没有修改tslib的源代码),可是问题也就来了:按下去不能抬起,直到下一次按下才抬起下:
难道是我漏掉了那一节?前辈们认为tslib与mingui的压力感应相反,minigui是1为按下,而tslib为0;所以要将tslib的源代码的压力输出部分修改,可是我用程序测试tslib输出没问题啊?按下为1啊;
这是测试代码:
复制代码
  1. #include<tslib.h>
  2. #include<stdio.h>
  3. #include <stdlib.h>
  4. int main()
  5. {
  6. int i,x,y,re;
  7. char *ts_device,input;
  8. static struct tsdev *ts;
  9. static struct ts_sample spl;
  10. if((ts_device = getenv("TSLIB_TSDEVICE")) != NULL)
  11.     {
  12.             ts = ts_open(ts_device, 0);
  13.             if(ts!=NULL)
  14.                     printf("tslib opened!\n");
  15.             re=ts_config(ts);
  16.             if(re==0)
  17.             printf("ts config ok\n");
  18.       }
  19. while(1)
  20.        {
  21.         re=-1;
  22.         printf("continue or cancel?\n");
  23.         input=getchar();
  24.         if(input=='n')
  25.           {
  26.            ts_close(ts);
  27.             return 0;
  28.            }
  29.       //  for(i=0;i<10;i++)
  30.         //  {
  31.            re=ts_read(ts,&spl,1);
  32.            if(re<0) printf("erro\n");
  33.            printf("x=%d y=%d pressure=%d \n",spl.x,spl.y,spl.pressure);
  34.        //   }
  35.        }    
  36. return 0;
  37. }


从这个测试程序我发现
tslib会缓存最近的数据,一松开设备将处于阻塞状态,当ts_open以阻塞方式打开时将0读完后,ts_read将进入阻塞状态。!

  我再分析IAL的核心函数wait_event
我贴上前辈的函数:
复制代码
  1. static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except, struct timeval *timeout)
  2. {
  3.         struct ts_sample sample;
  4.         int ret = 0;
  5.         int fd;
  6.         fd_set rfds;
  7.         int e;
  8.            if (!in)
  9.            {
  10.              in = &rfds;
  11.              FD_ZERO (in);
  12.            }
  13.        fd = ts_fd(ts);
  14.        if ((which & IAL_MOUSEEVENT) && fd >= 0)
  15.        {
  16.            printf("which is %d ",which);
  17.               FD_SET (fd, in);
  18.         }
  19.       e = select (FD_SETSIZE, in, out, except, timeout) ;
  20.        if (e > 0)
  21.        {        
  22.              if (fd > 0 && FD_ISSET (fd, in))
  23.                {
  24.                    FD_CLR (fd, in);
  25.                    ts_event.x=0;
  26.                   ts_event.y=0;
  27.                   ret = ts_read(ts, &sample, 1);
  28.                   if (ret < 0)
  29.                   {
  30.                         perror("ts_read()");
  31.                         exit(-1);
  32.                   }
  33.                   ts_event.x = sample.x;
  34.                   ts_event.y = sample.y;
  35.                   ts_event.pressure = (sample.pressure > 0 ? 4:0);
  36.                   if((ts_event.x >= 0 && ts_event.x <= 239) &&
  37.                         (ts_event.y >= 0 && ts_event.y <= 319))
  38.                         {
  39.                         mousex = ts_event.x;
  40.                          mousey = ts_event.y;
  41.                          }
  42.                    ret |= IAL_MOUSEEVENT;
  43.                   return (ret);
  44.              }
  45.       }
  46.        else if (e < 0)
  47.        {
  48.              return -1;
  49.       }
  50.        return (ret);
  51. }

当你按下去的时候可以顺利的读取数据,即wait_event返回4(鼠标左击事件)
当你松开时,设备阻塞,select将会超时,e将会等于零,导致不能用ts_read读取松开时的值即sample.pressure,所以你要是不按下去将会永远保持上次按下的状态,直到你下次的按下才会读取上次缓存松开的值即sample.pressure=0;所以导致了按下去抬起依旧保持按下去得状态。

解决的办法是:去掉select函数!直接用ts_read读取判断!
去掉select后的代码为:
复制代码
  1. static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except,struct timeval *timeout)
  2. {
  3.         struct ts_sample sample;
  4.         int ret = 0;
  5.         ts_event.x=0;
  6.         ts_event.y=0;
  7.         ret = ts_read(ts, &sample, 1);
  8.          if (ret < 0)
  9.              {
  10.                perror("ts_read()");
  11.                exit(-1);
  12.               }
  13.          ts_event.x = sample.x;
  14.          ts_event.y = sample.y;
  15.          ts_event.pressure = (sample.pressure > 0 ? 4:0);
  16.          if((ts_event.x >= 0 && ts_event.x <= 239) &&(ts_event.y >= 0 && ts_event.y <= 319))
  17.             {
  18.              mousex = ts_event.x;
  19.              mousey = ts_event.y;
  20.             }
  21.          ret |= IAL_MOUSEEVENT;
  22.          return (ret);
  23. }


注意:用这种方式ts_open的第二个参数要为0!
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2010-10-24 08:40
好,能够从源代码分析并解决问题,是成为高手的第一步。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."