该项目主要作用是模拟驱动来实现对触摸屏的操控。如:滑动,点击操作。
本人使用该代码,尝试在真机上在某社交app执行点赞以及滑动下一个视频动作。
这是在下的项目地址:
https://github.com/2290474055/marlin_touch_set_input/tree/main
该手机使用的是真机piexl 1,系统版本是android10
直接使用synaptics_dsx_core.c替换掉原先的驱动中的该文件,位于/private/msm-google/drivers/input/touchscreeen/synaptics_dsx_htc_2.6/synaptics_dsx_core.c
只需要创建一个android工程的c++版本,然后创建my_dev_user.cpp文件正常写c++代码或者c代码,或者将我的文件直接拷贝放到这里
在cmake中添加代码
add_executable(text_my_dev my_dev_user.cpp)
即可编译为elf可执行文件
至此,所有代码步骤完成。
在Linux输入子系统中报告触摸屏输入事件,通过调用
input_mt_slot(p_inputdev,0);
input_mt_report_slot_state(p_inputdev,MT_TOOL_FINGER, 1);
input_report_key(p_inputdev,BTN_TOUCH, 1);
input_report_key(p_inputdev,BTN_TOOL_FINGER, 1);
input_report_abs(p_inputdev,ABS_MT_POSITION_X, x);
input_report_abs(p_inputdev,ABS_MT_POSITION_Y, y);
input_report_abs(p_inputdev,ABS_MT_TOUCH_MAJOR,
synaptics_sqrt(wxwx + wywy));
input_report_abs(p_inputdev,ABS_MT_TOUCH_MINOR,min(wx, wy));
input_report_abs(p_inputdev,ABS_MT_PRESSURE, 1);
依据此原理,是可以通过构建android动态加载的驱动ko文件可以制作一个通用驱动。但本人并没有深入继续研究该目标。仅供需要的大佬考虑。
整个分为
3
个部分
文件synaptics_dsx_core.c,该驱动为内核原本的驱动,其中添加了函数synaptics_rmi4_f12_abs_report_me为关键代码用来向输入子系统报告触摸屏操作。通过封装synaptics_rmi4_f12_abs_report_me实现
2
个函数,set_input_touch_slide,set_input_touch_click分别实现滑动和点击事件
/
/
该函数为实现触摸关键函数
/
/
stop为控制是触摸还是停止,true为手指离开,false为手指还在屏幕上
/
/
x,y位坐标
static
int
synaptics_rmi4_f12_abs_report_me(
bool
stop,
int
x,
int
y)
{
int
wx;
int
wy;
/
/
判断是手指是否离开触摸屏
if
(stop
=
=
true){
data_me.object_type_and_status
=
20
;
}
else
{
data_me.object_type_and_status
=
F12_FINGER_STATUS;
}
wx
=
0
;
wy
=
0
;
switch (data_me.object_type_and_status) {
case F12_FINGER_STATUS:
case F12_GLOVED_FINGER_STATUS:
/
*
Stylus has priority over fingers
*
/
printk(KERN_ALERT
"zeyu F12_GLOVED_FINGER_STATUS\n"
);
/
/
向输入子系统报告触摸屏触摸信息,p_inputdev为触摸屏设备的指针,该指针我是通过正常驱动函数中拿到的,当然也可以通过其他途径,大家自行考虑
input_mt_slot(p_inputdev,
0
);
input_mt_report_slot_state(p_inputdev,
MT_TOOL_FINGER,
1
);
input_report_key(p_inputdev,
BTN_TOUCH,
1
);
input_report_key(p_inputdev,
BTN_TOOL_FINGER,
1
);
input_report_abs(p_inputdev,
ABS_MT_POSITION_X, x);
input_report_abs(p_inputdev,
ABS_MT_POSITION_Y, y);
input_report_abs(p_inputdev,
ABS_MT_TOUCH_MAJOR,
synaptics_sqrt(wx
*
wx
+
wy
*
wy));
input_report_abs(p_inputdev,
ABS_MT_TOUCH_MINOR,
min
(wx, wy));
input_report_abs(p_inputdev,
ABS_MT_PRESSURE,
1
);
break
;
default:
/
/
当手指离开触摸屏时执行到这里
printk(KERN_ALERT
"zeyu default\n"
);
input_mt_slot(p_inputdev,
0
);
input_mt_report_slot_state(p_inputdev,
MT_TOOL_FINGER,
0
);
break
;
}
/
/
该函数执行立即同步,不然会有延迟
input_sync(p_inputdev);
return
0
;
}
/
/
该函数为实现点击触摸屏
void set_input_touch_click(
int
x,
int
y)
{
/
/
这是为了模拟更像所以多调用几次
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
/
/
手指离开屏幕(如果不设置,则表示为长时间触摸该位置)
synaptics_rmi4_f12_abs_report_me(true,x,y);
return
;
}
/
/
该代码作用为将该符号到处给其他驱动使用
EXPORT_SYMBOL(set_input_touch_click);
/
/
该函数实现滑动触摸屏,为开始的位置到停止的位置,可以看到我都是分为
9
次移动过去,系统会通过判断时间等来判断点击和移动的。其中代码就不仔细分析了。
void set_input_touch_slide(
int
start_x,
int
start_y,
int
end_x,
int
end_y)
{
int
tmp_x
=
0
;
int
tmp_y
=
0
;
int
zeyu_x
=
0
;
int
zeyu_y
=
0
;
size_t i
=
0
;
if
((end_x
=
=
start_x) && (end_y
=
=
start_y)) {
return
;
}
if
((end_x >
=
start_x) && (end_y >
=
start_y)) {
tmp_x
=
end_x
-
start_x;
tmp_y
=
end_y
-
start_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
+
(tmp_x
*
i);
zeyu_y
=
start_y
+
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x >
=
start_x) && (end_y <
=
start_y)) {
tmp_x
=
end_x
-
start_x;
tmp_y
=
start_y
-
end_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
+
(tmp_x
*
i);
zeyu_y
=
start_y
-
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x <
=
start_x) && (end_y >
=
start_y)) {
tmp_x
=
start_x
-
end_x;
tmp_y
=
end_y
-
start_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
-
(tmp_x
*
i);
zeyu_y
=
start_y
+
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x <
=
start_x) && (end_y <
=
start_y)) {
tmp_x
=
start_x
-
end_x;
tmp_y
=
start_y
-
end_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
-
(tmp_x
*
i);
zeyu_y
=
start_y
-
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
return
;
}
EXPORT_SYMBOL(set_input_touch_slide);
文件synaptics_dsx_core.c,该驱动为内核原本的驱动,其中添加了函数synaptics_rmi4_f12_abs_report_me为关键代码用来向输入子系统报告触摸屏操作。通过封装synaptics_rmi4_f12_abs_report_me实现
2
个函数,set_input_touch_slide,set_input_touch_click分别实现滑动和点击事件
/
/
该函数为实现触摸关键函数
/
/
stop为控制是触摸还是停止,true为手指离开,false为手指还在屏幕上
/
/
x,y位坐标
static
int
synaptics_rmi4_f12_abs_report_me(
bool
stop,
int
x,
int
y)
{
int
wx;
int
wy;
/
/
判断是手指是否离开触摸屏
if
(stop
=
=
true){
data_me.object_type_and_status
=
20
;
}
else
{
data_me.object_type_and_status
=
F12_FINGER_STATUS;
}
wx
=
0
;
wy
=
0
;
switch (data_me.object_type_and_status) {
case F12_FINGER_STATUS:
case F12_GLOVED_FINGER_STATUS:
/
*
Stylus has priority over fingers
*
/
printk(KERN_ALERT
"zeyu F12_GLOVED_FINGER_STATUS\n"
);
/
/
向输入子系统报告触摸屏触摸信息,p_inputdev为触摸屏设备的指针,该指针我是通过正常驱动函数中拿到的,当然也可以通过其他途径,大家自行考虑
input_mt_slot(p_inputdev,
0
);
input_mt_report_slot_state(p_inputdev,
MT_TOOL_FINGER,
1
);
input_report_key(p_inputdev,
BTN_TOUCH,
1
);
input_report_key(p_inputdev,
BTN_TOOL_FINGER,
1
);
input_report_abs(p_inputdev,
ABS_MT_POSITION_X, x);
input_report_abs(p_inputdev,
ABS_MT_POSITION_Y, y);
input_report_abs(p_inputdev,
ABS_MT_TOUCH_MAJOR,
synaptics_sqrt(wx
*
wx
+
wy
*
wy));
input_report_abs(p_inputdev,
ABS_MT_TOUCH_MINOR,
min
(wx, wy));
input_report_abs(p_inputdev,
ABS_MT_PRESSURE,
1
);
break
;
default:
/
/
当手指离开触摸屏时执行到这里
printk(KERN_ALERT
"zeyu default\n"
);
input_mt_slot(p_inputdev,
0
);
input_mt_report_slot_state(p_inputdev,
MT_TOOL_FINGER,
0
);
break
;
}
/
/
该函数执行立即同步,不然会有延迟
input_sync(p_inputdev);
return
0
;
}
/
/
该函数为实现点击触摸屏
void set_input_touch_click(
int
x,
int
y)
{
/
/
这是为了模拟更像所以多调用几次
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
/
/
手指离开屏幕(如果不设置,则表示为长时间触摸该位置)
synaptics_rmi4_f12_abs_report_me(true,x,y);
return
;
}
/
/
该代码作用为将该符号到处给其他驱动使用
EXPORT_SYMBOL(set_input_touch_click);
/
/
该函数实现滑动触摸屏,为开始的位置到停止的位置,可以看到我都是分为
9
次移动过去,系统会通过判断时间等来判断点击和移动的。其中代码就不仔细分析了。
void set_input_touch_slide(
int
start_x,
int
start_y,
int
end_x,
int
end_y)
{
int
tmp_x
=
0
;
int
tmp_y
=
0
;
int
zeyu_x
=
0
;
int
zeyu_y
=
0
;
size_t i
=
0
;
if
((end_x
=
=
start_x) && (end_y
=
=
start_y)) {
return
;
}
if
((end_x >
=
start_x) && (end_y >
=
start_y)) {
tmp_x
=
end_x
-
start_x;
tmp_y
=
end_y
-
start_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
+
(tmp_x
*
i);
zeyu_y
=
start_y
+
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x >
=
start_x) && (end_y <
=
start_y)) {
tmp_x
=
end_x
-
start_x;
tmp_y
=
start_y
-
end_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
+
(tmp_x
*
i);
zeyu_y
=
start_y
-
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x <
=
start_x) && (end_y >
=
start_y)) {
tmp_x
=
start_x
-
end_x;
tmp_y
=
end_y
-
start_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
-
(tmp_x
*
i);
zeyu_y
=
start_y
+
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x <
=
start_x) && (end_y <
=
start_y)) {
tmp_x
=
start_x
-
end_x;
tmp_y
=
start_y
-
end_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
-
(tmp_x
*
i);
zeyu_y
=
start_y
-
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-7-16 22:56
被琳宇编辑
,原因: 补充