主题 : 小分析->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."
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
贡献值: 2 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
2楼  发表于: 2010-10-24 15:56

 回 1楼(kasim) 的帖子

呵呵,斑竹盛赞了,倒是挖掘源代码真的有趣
级别: 新手上路
UID: 29129
精华: 0
发帖: 6
金钱: 30 两
威望: 6 点
贡献值: 0 点
综合积分: 12 分
注册时间: 2010-09-23
最后登录: 2014-02-10
3楼  发表于: 2010-12-19 22:39
thanks
级别: 新手上路
UID: 15551
精华: 0
发帖: 23
金钱: 115 两
威望: 23 点
贡献值: 0 点
综合积分: 46 分
注册时间: 2010-03-06
最后登录: 2017-09-13
4楼  发表于: 2011-01-09 21:15
多谢楼主,问题解决!
mini2440+minigui+tslib1.4
tslib1.4源码不需改动,按网上的修改getxy()函数反而无法校正屏幕。
minigui中修改dummy.c如下:
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include "common.h"

#include "tslib.h"

#ifdef _DUMMY_IAL

#include <sys/ioctl.h>

#include <sys/poll.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <linux/kd.h>

#include "ial.h"

#include "dummy.h"

#ifndef _DEBUG

#define _DEBUG                    // for debugging

#endif

/* for storing data reading from /dev/touchScreen/0raw */

typedef struct {

       unsigned short pressure;

       unsigned short x;

       unsigned short y;

       unsigned short pad;

} TS_EVENT;

static unsigned char state [NR_KEYS];

static int mousex = 0;

static int mousey = 0;

static TS_EVENT ts_event;

static struct tsdev *ts;

/************************ Low Level Input Operations **********************/

/*

* Mouse operations -- Event

*/

static int mouse_update(void)

{

        return 1;

}

static void mouse_getxy(int *x, int* y)

{

        if (mousex < 0) mousex = 0;

        if (mousey < 0) mousey = 0;

        if (mousex > 239) mousex = 239;

        if (mousey > 319) mousey = 319;

#ifdef _DEBUG

       // printf ("mousex = %d, mousey = %d\n", mousex, mousey);

#endif

       *x = mousex;

       *y = mousey;

}

static int mouse_getbutton(void)

{

        return ts_event.pressure;

}


static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except,struct timeval *timeout)
{

        struct ts_sample sample;
        int ret = 0;
        ts_event.x=0;
        ts_event.y=0;
        ret = ts_read(ts, &sample, 1);
         if (ret < 0)
             {
               perror("ts_read()");
               exit(-1);
              }
         ts_event.x = sample.x;
         ts_event.y = sample.y;
         ts_event.pressure = (sample.pressure > 0 ? 4:0);
         if((ts_event.x >= 0 && ts_event.x <= 239) &&(ts_event.y >= 0 && ts_event.y <= 319))
            {
             mousex = ts_event.x;
             mousey = ts_event.y;
            }
         ret |= IAL_MOUSEEVENT;
         return (ret);
}



BOOL InitDummyInput(INPUT* input, const char* mdev, const char* mtype)

{

      char *ts_device = NULL;

       if ((ts_device = getenv("TSLIB_TSDEVICE")) != NULL) {

            // open touch screen event device in blocking mode

            ts = ts_open(ts_device, 0);
        printf("ts_device != NULL is done!!!!!!hkkkk\n");

      } else {

#ifdef USE_INPUT_API

             ts = ts_open("/dev/input/0raw", 0);

#else

             ts = ts_open("/dev/touchscreen/ucb1x00", 0);

#endif

      }

#ifdef _DEBUG

        printf ("TSLIB_TSDEVICE is open!!!!!!!!!!!\n");

#endif

       if (!ts) {

           perror("ts_open()");

             exit(-1);

       }

      if (ts_config(ts)) {

            perror("ts_config()");

            exit(-1);

       }

      input->update_mouse = mouse_update;

      input->get_mouse_xy = mouse_getxy;

      input->set_mouse_xy = NULL;

      input->get_mouse_button = mouse_getbutton;

      input->set_mouse_range = NULL;

      input->wait_event = wait_event;

      mousex = 0;

      mousey = 0;

      ts_event.x = ts_event.y = ts_event.pressure = 0;

       return TRUE;

}

void TermDummyInput(void)

{

      if (ts)

            ts_close(ts);

}

#endif /* _DUMMY_IAL */