hadisiman
驱动牛犊
驱动牛犊
  • 注册日期2003-03-28
  • 最后登录2003-08-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1927回复:6

鼠标编程一问

楼主#
更多 发布于:2003-07-25 13:53
我想编个程序,用键盘模拟鼠标做一些简单的动作,譬如使用方向键来移动鼠标(都是ps2的)。我看了一下mousedev.c,但是并不是很明白。究竟是怎样放松一个鼠标移动的消息给系统的呢?请大家指点一下我该怎么做啊!谢谢了!
escape
驱动老牛
驱动老牛
  • 注册日期2002-02-01
  • 最后登录2004-08-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-07-25 15:30
为什么要这么做?有没有现成的例子,发给我一个?
alexyi@kinposh.com.cn
hadisiman
驱动牛犊
驱动牛犊
  • 注册日期2003-03-28
  • 最后登录2003-08-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-07-28 09:31
只是想看看系统是如何接收键盘鼠标信息。请各位帮忙。
stonepine
驱动牛犊
驱动牛犊
  • 注册日期2002-12-09
  • 最后登录2009-03-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-07-31 01:39
GUI的鼠标事件的原理大致是这样的:
当鼠标有中断发生时,驱动程序将事件按发生的先后次序将鼠标按键、鼠标相对于上一次产生的偏移dx,dy组成数据投递到鼠

标设备文件中(ps/2是/dev/psaux,/dev/mouse一般都是建立的软链接),
按键的数据格式如下:
#ifdef MMOUSE_SUPPORT
#ifdef EMULATE_3_BUTTONS
static char button[8] = { 0, 1, 2, 4, 4, 0, 0,0};
#else
static char button[8] = { 0, 1, 2, 3, 4, 0, 0,0};
#endif
#else
static char button[8] = {0, 1, 2, 3, 0, 0, 0, 0};
#endif

我们要做的是打开和初始化鼠标设备,再从设备文件里每次循环读取3个字节进行处理,注意,鼠标的事件是三维的,但目前

我们的鼠标z轴衡为0:
static int PS2_Read(int *dx, int *dy, int *dz, char *bp)
{
static unsigned char buf[3] = {0, 0, 0};
static int nbytes =0;
int n;
int temp;

//int buttons[4] = { 0, 1, 2, 4};
/* 0 没有键(但移动) 4 左键1 右键5 左右键同时 */
while((n = read(mouse_fd, &buf[nbytes], 3 - nbytes))) {/*n 为所读的字节数*/

if(n < 0) {
       if (errno == EINTR || errno == EAGAIN)
               return 0;
            else
                return -1;
        }

nbytes += n;
/*保证读了3 个字节*/
if(nbytes == 3) {
/* Check header byte. */  
/*buf[0]头两位为头信息标识,第六位dx符号,第七位dy符号*/
if ((buf[0] & 0xc0) != 0) {  /*11000000*/
buf[0] = buf[1];
buf[1] = buf[2];
nbytes = 2;
return -1;
}

//得到bp,dx,dy,dz  
  temp = buf[0] & 0x07;  
//     temp = buf[0] & 0x03;
 
*bp =button[temp];
*dx = (buf[0] & 0x10) ? buf[1] - 256 : buf[1];
*dy = (buf[0] & 0x20) ? -(buf[2] - 256) : -buf[2];

*dz = 0;
nbytes = 0;
return 1;
}
}
return 0;
}
接着,GUI会产生鼠标键盘事件,他们都是在一起处理的,在这一层上,鼠标,键盘都是一样的,你可以在这一层进行键盘对

鼠标事件进行模拟,接着,GUI会根据鼠标键盘事件产生出相应的消息,这个过程鼠标移动的偏移经过缩放因子(我们在GUI

设置中调节的鼠标灵敏度就是调节缩放因子),以及和你原来记录的鼠标位置叠加处理成鼠标在屏幕上的位置,即屏幕坐标

,经过消息循环的处理,投递到相应的GUI窗口上去(屏幕坐标也相宜转换为窗口坐标),你可以到http://www.minigui.com
上下载MINIGUI source code,对照里面的程序,应该就清楚了,当然你完全可以在消息处理这一层做,截获系统的左右按键,将他

们生产鼠标移动的小心,但由于鼠标消息涉及到一个加速的概念,处理起来有点麻烦,最好的就是在产生事件那一层上去做

,那样会很好做
hadisiman
驱动牛犊
驱动牛犊
  • 注册日期2003-03-28
  • 最后登录2003-08-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-07-31 09:57
to stonepine:
十分感谢你的回答!
但是还有两点不太清楚:
1。这个程序可以不在驱动程序的那一层来做,是吗?如果是截获鼠标键盘的事件,那么请问,这些事件是什么呢?譬如在Windows上就有键盘按键或鼠标移动的事件,所以在Windows上实现起来是比较简单的。
2。如果我是想往设备文件中填写数据,请问该怎样做?就是说,其实鼠标并没有移动,但是填了这些数据后,就好像鼠标已经被移动了一样。 因为我想这样做,不知道行不行得通。鼠标并未移动,但是我按了某一个键,就往鼠标的设备文件中填写一些数据,这样我不管上层是如何去读取这些数据的,只要他读到了,就知道是鼠标移动了,然后屏幕上的光标理所当然的就会移动。(不知道说清楚了没,^_^表述得不是很好)。
好像光是这样想想觉得挺容易的,但是,就是不知道怎么去实现。
请大家帮帮忙讨论一下好吗?我很弱,对那些太底层的东西并不太懂。谢了!
stonepine
驱动牛犊
驱动牛犊
  • 注册日期2002-12-09
  • 最后登录2009-03-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-07-31 12:18
1、ok,我们就以windows为例,如果你只是想在你建立的窗口中用键盘模拟鼠标玩玩,你应该去截获键盘KEYDOWN和KEYUP消息,另外你需要将重复按键(在windows的CHAR消息中会有域带出重复按键的个数来)处理成鼠标加速,再转换为鼠标消息投递到消息循环中(以上消息名称我记得不清楚,特别是那个CHAR消息,windows不是这么叫的,可我就是想不起来,手头又没有MSDN,你可以查MSDN的SDK编程帮助,很清楚的),如果你要使按键对所有窗口都起模拟作用,我觉得以上办法还是行不通,估计要用消息钩子,把按键消息勾过来,处理之后再送到系统消息循环中。
2、这个想法是好,可惜行不通,也违背了驱动程序的本来含义,呵呵。行不通的道理简单,其一就是你这样做相当于模拟了一个设备,也就是说是两个设备往一个设备文件里写数据,结果自然会乱,起码鼠标会乱飞,也就不是鼠标了,而是飞标,呵呵。
hadisiman
驱动牛犊
驱动牛犊
  • 注册日期2003-03-28
  • 最后登录2003-08-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-07-31 16:03
to stonepine:
1.nod。可是我不知道在linux中的那些事件啊。你的意思是不是所用的GUI的不同,消息处理事件也不同? 譬如MiniGUI和X Window。如果我要做下去的话,就得先确定好一个GUI?是这样吗?
2.哦,好像有点明白了。还想弱弱的再问一下。触摸屏的驱动原理又是什么呢?应该和鼠标有点像吧。虽然他和鼠标是往两个设备文件里写数据,但他们两个控制的是同一个屏幕上的同一个光标,为什么光标不会乱飞呢?
很感谢你,这两天我想这些问题都有点头发晕了。  :)
游客

返回顶部