-
Notifications
You must be signed in to change notification settings - Fork 6.2k
/
lvgl_pointer_input.c
131 lines (110 loc) · 4.02 KB
/
lvgl_pointer_input.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Copyright 2023 Fabian Blatz <fabianblatz@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT zephyr_lvgl_pointer_input
#include "lvgl_common_input.h"
#include "lvgl_pointer_input.h"
#include <lvgl_display.h>
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL);
struct lvgl_pointer_input_config {
struct lvgl_common_input_config common_config; /* Needs to be first member */
bool swap_xy;
bool invert_x;
bool invert_y;
};
static void lvgl_pointer_process_event(const struct device *dev, struct input_event *evt)
{
const struct lvgl_pointer_input_config *cfg = dev->config;
struct lvgl_common_input_data *data = dev->data;
lv_disp_t *disp = lv_disp_get_default();
struct lvgl_disp_data *disp_data = disp->driver->user_data;
struct display_capabilities *cap = &disp_data->cap;
lv_point_t *point = &data->pending_event.point;
switch (evt->code) {
case INPUT_ABS_X:
point->x = evt->value;
break;
case INPUT_ABS_Y:
point->y = evt->value;
break;
case INPUT_BTN_TOUCH:
data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
break;
}
if (!evt->sync) {
return;
}
/* adjust coordinates */
if (cfg->swap_xy) {
lv_coord_t tmp;
tmp = point->x;
point->x = point->y;
point->y = tmp;
}
if (cfg->invert_x) {
if (cap->current_orientation == DISPLAY_ORIENTATION_NORMAL ||
cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
point->x = cap->x_resolution - point->x;
} else {
point->x = cap->y_resolution - point->x;
}
}
if (cfg->invert_y) {
if (cap->current_orientation == DISPLAY_ORIENTATION_NORMAL ||
cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
point->y = cap->y_resolution - point->y;
} else {
point->y = cap->x_resolution - point->y;
}
}
/* rotate touch point to match display rotation */
if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_90) {
lv_coord_t tmp;
tmp = point->x;
point->x = point->y;
point->y = cap->y_resolution - tmp;
} else if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
point->x = cap->x_resolution - point->x;
point->y = cap->y_resolution - point->y;
} else if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_270) {
lv_coord_t tmp;
tmp = point->x;
point->x = cap->x_resolution - point->y;
point->y = tmp;
}
/* filter readings within display */
if (point->x <= 0) {
point->x = 0;
} else if (point->x >= cap->x_resolution) {
point->x = cap->x_resolution - 1;
}
if (point->y <= 0) {
point->y = 0;
} else if (point->y >= cap->y_resolution) {
point->y = cap->y_resolution - 1;
}
if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) {
LOG_WRN("Could not put input data into queue");
}
}
int lvgl_pointer_input_init(const struct device *dev)
{
return lvgl_input_register_driver(LV_INDEV_TYPE_POINTER, dev);
}
#define LVGL_POINTER_INPUT_DEFINE(inst) \
LVGL_INPUT_DEFINE(inst, pointer, CONFIG_LV_Z_POINTER_INPUT_MSGQ_COUNT, \
lvgl_pointer_process_event); \
static const struct lvgl_pointer_input_config lvgl_pointer_input_config_##inst = { \
.common_config.event_msgq = &LVGL_INPUT_EVENT_MSGQ(inst, pointer), \
.swap_xy = DT_INST_PROP(inst, swap_xy), \
.invert_x = DT_INST_PROP(inst, invert_x), \
.invert_y = DT_INST_PROP(inst, invert_y), \
}; \
static struct lvgl_common_input_data lvgl_common_input_data_##inst; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &lvgl_common_input_data_##inst, \
&lvgl_pointer_input_config_##inst, POST_KERNEL, \
CONFIG_INPUT_INIT_PRIORITY, NULL);
DT_INST_FOREACH_STATUS_OKAY(LVGL_POINTER_INPUT_DEFINE)