首先,嗨,这是我在stackoverflow中的第一个问题:)
硬件设置为2 x nvidia gtx980 GPU,每个GPU连接到3个监视器。视频墙设置为一排6台显示器。我们正在使用专有的nvidia驱动程序。xserver版本为1.15.1(7.7)。
我们创建了一个uinput多点触摸ABS(MT)设备,该设备连接到与核心指针不同的主机上。ABS_X和ABS_MT_POSITION_X的最大值和最小值根据两个X屏幕的大小(0、11520-1)进行设置。这是使用xinput list[设备id]检查的。
由于我们使用两个GPU,我们无法创建一个大的xscreen,但我们安排了两个xscreen(每个GPU一个),每个屏幕上对齐三个监视器。
问题出在第二个xscreen1屏幕上。当我们发出x坐标高于5760(第一个xscreen的大小)的触摸事件时,xserver会在远处的x坐标上报告点(可能在第二个xscreet的末尾或更远的地方)。我们已经从xscreen0开始检查了这一点,然后转到第二个。将正确报告y坐标(因为两个xscreen都是y对齐的)。
虚拟多点触摸设备的校准矩阵是身份矩阵。如果uinput设备被创建为ABS单点设备(我想像wacom平板电脑一样),则x坐标会被正确报告。
我认为问题可能存在于evdev或xserver中(因为我已经在服务器内部而不是evdev中阅读了新版本的校准)。如果是这样的话,任何关于这可能发生在哪里的提示都将是非常好的。如果不是这样的话,我们将非常感谢您的帮助。
对于将来可能遇到这个问题的人,我们的团队很久以前就提出了一个小补丁,现在就放在这里,以防它有用。。。
---
dix/events.c | 21 +++++++++++++++++++--
mi/mieq.c | 26 ++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/dix/events.c b/dix/events.c
index 8efdf18..5155ef5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2999,8 +2999,25 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
/* Motion events entering DIX get translated to Screen 0
coordinates. Replayed events have already been
translated since they've entered DIX before */
- ev->root_x += pSprite->screen->x - screenInfo.screens[0]->x;
- ev->root_y += pSprite->screen->y - screenInfo.screens[0]->y;
+
+ /*Now we take into account inputs comming from MT device that uses absolutes coordinates.*/
+ switch (ev->type) {
+ case ET_Motion:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ ev->root_x += pSprite->screen->x - screenInfo.screens[0]->x;
+ ev->root_y += pSprite->screen->y - screenInfo.screens[0]->y;
+ break;
+ case ET_TouchBegin:
+ case ET_TouchUpdate:
+ case ET_TouchEnd:
+ ev->root_x -= screenInfo.screens[0]->x;
+ ev->root_y -= screenInfo.screens[0]->y;
+ break;
+
+ }
}
else
#endif
diff --git a/mi/mieq.c b/mi/mieq.c
index 05447d6..cc151f6 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -447,6 +447,32 @@ mieqMoveToNewScreen(DeviceIntPtr dev, ScreenPtr screen, DeviceEvent *event)
DequeueScreen(dev) = screen;
x = event->root_x;
y = event->root_y;
+
+
+ /*Now we take into account inputs comming from MT device that uses absolutes coordinates.*/
+ switch (event->type) {
+ case ET_Motion:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ // print
+ break;
+ case ET_TouchBegin:
+ case ET_TouchUpdate:
+ case ET_TouchEnd:
+ {
+ ScreenPtr screenPtr = dev->spriteInfo->sprite->pDequeueScreen;
+ x -= screenPtr->x;
+ y -= screenPtr->y;
+ NewCurrentScreen(dev, screenPtr, x, y);
+ return;
+ // break;
+ }
+ default:
+ break;
+ }
+
NewCurrentScreen(dev, DequeueScreen(dev), x, y);
}
}