1.背景
手头上有一台电脑,安装了OpenEuler系统+UKUI界面,配了触摸板,但是触摸的位置对不上。
然后按照网上的资料,yum install xinput_calibrator
却无法安装。估计OpenEuler官方没编译好这玩意。
系统(yum install)只能安装xinput,没有xinput_calibrator。
只能自己编译了。
2.下载源码
源码一开始是在github上【tias/xinput_calibrator】。但是好久没维护了,新版本的源码已经转移到gitlab上了【xorg/app/xinput-calibrator】。请使用最新的源码。
新源码
3.编译
假如按照他的说明文档,直接编译的话,会报两个错误
$ ./autogen.sh
Sets up build environment, run ./autogen.sh --help to see the build options
Notable build options:
--with-gui=gtkmm Use gtkmm GUI
--with-gui=x11 Use native x11 GUI
$ make
Builds the software with the configured GUI
autoreconf:未找到命令、Can’t exec “aclocal”
3.1.安装工具
这样的报错是因为缺少几个工具,安装好就行
sudo yum install autoconf
sudo yum install automake
sudo yum install libtool
3.2.修改源码
还要修改一下源码文件夹的src/Makefile.am文件增加一句
AUTOMAKE_OPTIONS = subdir-objects
3.3.执行编译
$ ./autogen.sh --with-gui=x11
$ make
执行完之后,我们期待的xinput_calibrator就出现了
4.执行校准
由于我使用的设备的特殊性,假如直接把运行xinput_calibrator
得到的配置写到99-touchscreen-evdev.conf
,貌似是不行的。
4.1.手动校准
还需要参考这里【触摸屏校正】 ,计算矩阵,手动设置。
但是他那个python脚本,保留的小数位太少了,大屏的话,触摸起来还是有偏移。因此需要修改一下,保留多几位小数
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import sys
def usage():
info = "Usage: " + sys.argv[0]
info += " <screen_width> <screen_height>"
info += " <click_0_x> <click_0_y>"
info += " <click_3_x> <click_3_y>"
print(info)
print("\tScreen width/hight by the command 'xrandr|grep screen' got")
print("\tClick x/y by the command 'xinput_calibrator -v' got")
sys.exit(0)
def convert(screen_x, screen_y, c0_x, c0_y, c3_x, c3_y):
a = (screen_x * 6 / 8) / (c3_x - c0_x)
c = ((screen_x / 8) - (a * c0_x)) / screen_x
e = (screen_y * 6 / 8) / (c3_y - c0_y)
f = ((screen_y / 8) - (e * c0_y)) / screen_y
print("Try set 'libinput Calibration Matrix' to '%.3f, 0.0, %.3f, 0.0, %.3f, %.3f, 0.0, 0.0, 1.0'" % (a,c,e, f))
if __name__ == "__main__":
if len(sys.argv) != 7:
usage()
convert(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]),
int(sys.argv[4]),int(sys.argv[5]),int(sys.argv[6]))
得到结果后,命令行运行一下就可以了,比如我的是:
xinput set-prop 10 'libinput Calibration Matrix' -1.183, 0.0, 1.094, 0.0, 1.152, -0.049, 0.0, 0.0, 1.0
然后就是持久化(关机,再开机之后,所作的设置能够生效)的问题。按照资料的设置,貌似不能生效。可能要自己写个脚本,让其开机启动了。
4.2.自动校准
根据整个操作流程,我弄了个脚本。直接执行就行了。
# 触摸屏的名字,请自行修改
DEVICE_NAME='DIALOGUE INC PenMount USB'
# 获取ID,也可以不获取,因为后面都是直接用设备名的
DEVICE_ID=$(xinput list | grep -i "$DEVICE_NAME" | awk -F'[=\t]' '{print $3}')
echo $DEVICE_ID
# 使用双括号和双等号进行比较
if [[ -z "$DEVICE_ID" ]]; then
notify-send "错误" "无法找到 %$DEVICE_ID 请检查设备名称是否正确。确认后修改本脚本的DEVICE_NAME"
exit -1
fi
# 备份一下原来的矩阵,假如用户在校正的中途取消的话,用回原来备份的矩阵
OLD_MATRIX=$(xinput list-props "$DEVICE_NAME" | grep 'libinput Calibration Matrix (' | awk -F': *' '{print $2}' | tr '\n\t' ' ')
echo "old matrix:" $OLD_MATRIX
# 先将校正矩阵复原
xinput set-prop "$DEVICE_NAME" 'libinput Calibration Matrix' 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0
# 1.获取屏幕分辨率
TEMP_FIL_NAME="_1_2_data.txt"
SCREEN_RESOLUTION=$(xrandr | grep "*" | awk '{print $1}')
echo $SCREEN_RESOLUTION > $TEMP_FIL_NAME
# 2.获取 click0 click3的数据
./xinput_calibrator -v --device "$DEVICE_NAME" | grep -E 'Adding click (0|3)' | tail -n 2 >> $TEMP_FIL_NAME
# 3.计算矩阵的值
{
read -r line1
read -r line2
read -r line3
} < $TEMP_FIL_NAME
echo "line1: $line1"
echo "line2: $line2"
echo "line3: $line3"
# 检查是否中途退出
if [[ -z "$line3" ]]; then
notify-send "中止" "暂停校正,恢复原来的矩阵"
xinput set-prop "$DEVICE_NAME" 'libinput Calibration Matrix' $OLD_MATRIX
echo "xinput set-prop \"$DEVICE_NAME\" 'libinput Calibration Matrix' $OLD_MATRIX"
rm $TEMP_FIL_NAME
exit -1
fi
# 提取分辨率
RESOLUTION=$(echo "$line1" | tr 'x' ' ')
echo "resolution:" "$RESOLUTION"
read -r WIDTH HEIGHT <<< "$RESOLUTION"
# 提取 click 0 的坐标
# 注意 $CLICK_0_COORDS "$CLICK_0_COORDS" 的区别
CLICK_0_COORDS=$(echo "$line2" | grep -oP 'X=\K\d+|Y=\K\d+')
echo "click_0_pos:" $CLICK_0_COORDS "$CLICK_0_COORDS"
read -r X0 Y0 <<< $(echo "$CLICK_0_COORDS" | tr '\n' ' ')
# 提取 click 3 的坐标
CLICK_3_COORDS=$(echo "$line3" | grep -oP 'X=\K\d+|Y=\K\d+')
echo "click_3_pos:" "$CLICK_3_COORDS"
read -r X3 Y3 <<< $(echo "$CLICK_3_COORDS" | tr '\n' ' ')
# 输出变量
echo "WIDTH: $WIDTH"
echo "HEIGHT: $HEIGHT"
echo "X0: $X0"
echo "Y0: $Y0"
echo "X3: $X3"
echo "Y3: $Y3"
# 使用 awk 进行浮点数运算
param_a=$(awk "BEGIN {print ($WIDTH * 6 / 8) / ($X3 -$X0);}")
param_c=$(awk "BEGIN {print (($WIDTH / 8) - ($param_a *$X0)) / $WIDTH;}")
param_e=$(awk "BEGIN {print ($HEIGHT * 6 / 8) / ($Y3 -$Y0);}")
param_f=$(awk "BEGIN {print (($HEIGHT / 8) - ($param_e *$Y0)) / $HEIGHT;}")
# 输出计算结果
echo "param_a: $param_a"
echo "param_c: $param_c"
echo "param_e: $param_e"
echo "param_f: $param_f"
rm $TEMP_FIL_NAME
# 持久化
echo "xinput set-prop '$DEVICE_NAME' 'libinput Calibration Matrix' $param_a, 0.0, $param_c, 0.0, $param_e, $param_f, 0.0, 0.0, 1.0" > /etc/profile.d/cali.sh
chmod 777 /etc/profile.d/cali.sh
/etc/profile.d/cali.sh