问题描述
我需要在 westton (wayland) 下发送一个虚拟触摸事件。我有一个 1280x800 的屏幕,它在 weston.ini 中旋转了 180 度。
我使用 c++ 的 uinput 实现了成功的触摸事件仿真:
int fd;
struct uinput_user_dev uidev;
fd = open("/dev/uinput",O_WRONLY | O_NONBLOCK);
if(fd < 0)
die("error: open");
if(ioctl(fd,UI_SET_EVBIT,EV_KEY) < 0)
die("error: ioctl");
if(ioctl(fd,EV_SYN) < 0)
die("error: ioctl");
if(ioctl(fd,EV_ABS) < 0)
die("error: ioctl");
if(ioctl(fd,UI_SET_ABSBIT,ABS_X) < 0)
die("error: ioctl");
if(ioctl(fd,ABS_Y) < 0)
die("error: ioctl");
if(ioctl(fd,UI_SET_KEYBIT,BTN_TOUCH) < 0)
die("error: ioctl");
memset(&uidev,sizeof(uidev));
snprintf(uidev.name,UINPUT_MAX_NAME_SIZE,"TestTouch");
uidev.id.bustype = BUS_USB;
uidev.id.vendor = 0x1234;
uidev.id.product = 0x4321;
uidev.id.version = 1;
uidev.absmin[ABS_X] = 0;
uidev.absmax[ABS_X] = 1280;
uidev.absmin[ABS_Y] = 0;
uidev.absmax[ABS_Y] = 800;
ioctl(fd,UI_SET_PROPBIT,INPUT_PROP_DIRECT);
if(write(fd,&uidev,sizeof(uidev)) < 0)
die("error: write");
if(ioctl(fd,UI_DEV_CREATE) < 0)
die("error: ioctl");
sleep(1);
emitEvent(fd,EV_KEY,BTN_TOUCH,1);
emitEvent(fd,EV_ABS,ABS_X,100);
emitEvent(fd,ABS_Y,EV_SYN,SYN_REPORT,0);
usleep(300);
emitEvent(fd,0);
emitEvent(fd,0);
sleep(1);
if(ioctl(fd,UI_DEV_DESTROY) < 0)
die("error: ioctl");
我在 X:100,Y:100 发送触摸事件。该事件在韦斯顿正确注册(我正在使用一个简单的网站来跟踪屏幕上的鼠标事件),但它不是在左上角,而是在右下角。就在屏幕的原始 (100,100) 坐标所在的位置 - 因为它旋转了 180 度(这是我无法更改的硬件限制,需要旋转屏幕以适应外壳)。
我尝试了 INPUT_PROP_DIRECT
或 INPUT_PROP_POINTER
的各种组合,但没有任何变化。
为了在正确的坐标上制作事件,我需要转换它们:
x = (1280 - x); y = (800 - y);
但我很想让它适用于任何类型的屏幕或旋转。我很惊讶,因为我确信是合成器扮演了转换输入事件的角色。我在寻找类似问题时偶然发现了这样的信息:
wlr_cursor probably needs to transform input events. This is already done in the Wayland and X11 backends,we might want to move it in wlr_cursor.
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)