1 /**
2 * @file lv_hal_indev.c
3 *
4 * @description Input device HAL interface
5 *
6 */
7
8 /*********************
9 * INCLUDES
10 *********************/
11 #include "../misc/lv_assert.h"
12 #include "../hal/lv_hal_indev.h"
13 #include "../core/lv_indev.h"
14 #include "../misc/lv_mem.h"
15 #include "../misc/lv_gc.h"
16 #include "lv_hal_disp.h"
17
18 /*********************
19 * DEFINES
20 *********************/
21
22 /**********************
23 * TYPEDEFS
24 **********************/
25
26 /**********************
27 * GLOBAL PROTOTYPES
28 **********************/
29
30 /**********************
31 * STATIC PROTOTYPES
32 **********************/
33
34 /**********************
35 * STATIC VARIABLES
36 **********************/
37
38 /**********************
39 * MACROS
40 **********************/
41 #if LV_LOG_TRACE_INDEV
42 #define INDEV_TRACE(...) LV_LOG_TRACE(__VA_ARGS__)
43 #else
44 #define INDEV_TRACE(...)
45 #endif
46
47 /**********************
48 * GLOBAL FUNCTIONS
49 **********************/
50
51 /**
52 * Initialize an input device driver with default values.
53 * It is used to surly have known values in the fields ant not memory junk.
54 * After it you can set the fields.
55 * @param driver pointer to driver variable to initialize
56 */
lv_indev_drv_init(lv_indev_drv_t * driver)57 void lv_indev_drv_init(lv_indev_drv_t * driver)
58 {
59 lv_memset_00(driver, sizeof(lv_indev_drv_t));
60
61 driver->type = LV_INDEV_TYPE_NONE;
62 driver->scroll_limit = LV_INDEV_DEF_SCROLL_LIMIT;
63 driver->scroll_throw = LV_INDEV_DEF_SCROLL_THROW;
64 driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME;
65 driver->long_press_repeat_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
66 driver->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT;
67 driver->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY;
68 }
69
70 /**
71 * Register an initialized input device driver.
72 * @param driver pointer to an initialized 'lv_indev_drv_t' variable.
73 * Only pointer is saved, so the driver should be static or dynamically allocated.
74 * @return pointer to the new input device or NULL on error
75 */
lv_indev_drv_register(lv_indev_drv_t * driver)76 lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
77 {
78
79 if(driver->disp == NULL) driver->disp = lv_disp_get_default();
80
81 if(driver->disp == NULL) {
82 LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
83 "a display");
84 return NULL;
85 }
86
87 lv_indev_t * indev = _lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
88 if(!indev) {
89 LV_ASSERT_MALLOC(indev);
90 return NULL;
91 }
92
93 lv_memset_00(indev, sizeof(lv_indev_t));
94 indev->driver = driver;
95
96 indev->proc.reset_query = 1;
97 indev->driver->read_timer = lv_timer_create(lv_indev_read_timer_cb, LV_INDEV_DEF_READ_PERIOD, indev);
98
99 return indev;
100 }
101
102 /**
103 * Update the driver in run time.
104 * @param indev pointer to a input device. (return value of `lv_indev_drv_register`)
105 * @param new_drv pointer to the new driver
106 */
lv_indev_drv_update(lv_indev_t * indev,lv_indev_drv_t * new_drv)107 void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv)
108 {
109 LV_ASSERT_NULL(indev);
110 LV_ASSERT_NULL(indev->driver);
111 LV_ASSERT_NULL(indev->driver->read_timer);
112 lv_timer_del(indev->driver->read_timer);
113
114 LV_ASSERT_NULL(new_drv);
115 if(new_drv->disp == NULL) {
116 new_drv->disp = lv_disp_get_default();
117 }
118 if(new_drv->disp == NULL) {
119 LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
120 "a display");
121 indev->proc.disabled = true;
122 return;
123 }
124
125 indev->driver = new_drv;
126 indev->driver->read_timer = lv_timer_create(lv_indev_read_timer_cb, LV_INDEV_DEF_READ_PERIOD, indev);
127 indev->proc.reset_query = 1;
128 }
129
130 /**
131 * Remove the provided input device. Make sure not to use the provided input device afterwards anymore.
132 * @param indev pointer to delete
133 */
lv_indev_delete(lv_indev_t * indev)134 void lv_indev_delete(lv_indev_t * indev)
135 {
136 LV_ASSERT_NULL(indev);
137 LV_ASSERT_NULL(indev->driver);
138 LV_ASSERT_NULL(indev->driver->read_timer);
139 /*Clean up the read timer first*/
140 lv_timer_del(indev->driver->read_timer);
141 /*Remove the input device from the list*/
142 _lv_ll_remove(&LV_GC_ROOT(_lv_indev_ll), indev);
143 /*Free the memory of the input device*/
144 lv_mem_free(indev);
145 }
146
147 /**
148 * Get the next input device.
149 * @param indev pointer to the current input device. NULL to initialize.
150 * @return the next input devise or NULL if no more. Give the first input device when the parameter
151 * is NULL
152 */
lv_indev_get_next(lv_indev_t * indev)153 lv_indev_t * lv_indev_get_next(lv_indev_t * indev)
154 {
155 if(indev == NULL)
156 return _lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
157 else
158 return _lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
159 }
160
161 /**
162 * Read data from an input device.
163 * @param indev pointer to an input device
164 * @param data input device will write its data here
165 */
_lv_indev_read(lv_indev_t * indev,lv_indev_data_t * data)166 void _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
167 {
168 lv_memset_00(data, sizeof(lv_indev_data_t));
169
170 /* For touchpad sometimes users don't set the last pressed coordinate on release.
171 * So be sure a coordinates are initialized to the last point */
172 if(indev->driver->type == LV_INDEV_TYPE_POINTER) {
173 data->point.x = indev->proc.types.pointer.last_raw_point.x;
174 data->point.y = indev->proc.types.pointer.last_raw_point.y;
175 }
176 /*Similarly set at least the last key in case of the user doesn't set it on release*/
177 else if(indev->driver->type == LV_INDEV_TYPE_KEYPAD) {
178 data->key = indev->proc.types.keypad.last_key;
179 }
180 /*For compatibility assume that used button was enter (encoder push)*/
181 else if(indev->driver->type == LV_INDEV_TYPE_ENCODER) {
182 data->key = LV_KEY_ENTER;
183 }
184
185 if(indev->driver->read_cb) {
186 INDEV_TRACE("calling indev_read_cb");
187 indev->driver->read_cb(indev->driver, data);
188 }
189 else {
190 LV_LOG_WARN("indev_read_cb is not registered");
191 }
192 }
193
194 /**********************
195 * STATIC FUNCTIONS
196 **********************/
197