1 /**
2 * @file hal_indev.c
3 *
4 * @description Input device HAL interface
5 *
6 */
7
8 /*********************
9 * INCLUDES
10 *********************/
11 #include "../lv_misc/lv_debug.h"
12 #include "../lv_hal/lv_hal_indev.h"
13 #include "../lv_core/lv_indev.h"
14 #include "../lv_misc/lv_mem.h"
15 #include "../lv_misc/lv_gc.h"
16 #include "lv_hal_disp.h"
17
18 #if defined(LV_GC_INCLUDE)
19 #include LV_GC_INCLUDE
20 #endif /* LV_ENABLE_GC */
21
22 /*********************
23 * DEFINES
24 *********************/
25
26 /**********************
27 * TYPEDEFS
28 **********************/
29
30 /**********************
31 * STATIC PROTOTYPES
32 **********************/
33
34 /**********************
35 * STATIC VARIABLES
36 **********************/
37
38 /**********************
39 * MACROS
40 **********************/
41
42 /**********************
43 * GLOBAL FUNCTIONS
44 **********************/
45
46 /**
47 * Initialize an input device driver with default values.
48 * It is used to surly have known values in the fields ant not memory junk.
49 * After it you can set the fields.
50 * @param driver pointer to driver variable to initialize
51 */
lv_indev_drv_init(lv_indev_drv_t * driver)52 void lv_indev_drv_init(lv_indev_drv_t * driver)
53 {
54 _lv_memset_00(driver, sizeof(lv_indev_drv_t));
55
56 driver->type = LV_INDEV_TYPE_NONE;
57 driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT;
58 driver->drag_throw = LV_INDEV_DEF_DRAG_THROW;
59 driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME;
60 driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
61 driver->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT;
62 driver->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY;
63 }
64
65 /**
66 * Register an initialized input device driver.
67 * @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
68 * @return pointer to the new input device or NULL on error
69 */
lv_indev_drv_register(lv_indev_drv_t * driver)70 lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
71 {
72
73 if(driver->disp == NULL) driver->disp = lv_disp_get_default();
74
75 if(driver->disp == NULL) {
76 LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
77 "a display");
78 return NULL;
79 }
80
81 lv_indev_t * indev = _lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
82 if(!indev) {
83 LV_ASSERT_MEM(indev);
84 return NULL;
85 }
86
87 _lv_memset_00(indev, sizeof(lv_indev_t));
88 _lv_memcpy(&indev->driver, driver, sizeof(lv_indev_drv_t));
89
90 indev->proc.reset_query = 1;
91 indev->cursor = NULL;
92 indev->group = NULL;
93 indev->btn_points = NULL;
94
95 indev->driver.read_task = lv_task_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_HIGH, indev);
96
97 return indev;
98 }
99
100 /**
101 * Update the driver in run time.
102 * @param indev pointer to a input device. (return value of `lv_indev_drv_register`)
103 * @param new_drv pointer to the new driver
104 */
lv_indev_drv_update(lv_indev_t * indev,lv_indev_drv_t * new_drv)105 void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv)
106 {
107 memcpy(&indev->driver, new_drv, sizeof(lv_indev_drv_t));
108 }
109
110 /**
111 * Get the next input device.
112 * @param indev pointer to the current input device. NULL to initialize.
113 * @return the next input devise or NULL if no more. Give the first input device when the parameter
114 * is NULL
115 */
lv_indev_get_next(lv_indev_t * indev)116 lv_indev_t * lv_indev_get_next(lv_indev_t * indev)
117 {
118 if(indev == NULL)
119 return _lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
120 else
121 return _lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
122 }
123
124 /**
125 * Read data from an input device.
126 * @param indev pointer to an input device
127 * @param data input device will write its data here
128 * @return false: no more data; true: there more data to read (buffered)
129 */
_lv_indev_read(lv_indev_t * indev,lv_indev_data_t * data)130 bool _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
131 {
132 bool cont = false;
133
134 _lv_memset_00(data, sizeof(lv_indev_data_t));
135
136 /* For touchpad sometimes users don't the last pressed coordinate on release.
137 * So be sure a coordinates are initialized to the last point */
138 if(indev->driver.type == LV_INDEV_TYPE_POINTER) {
139 data->point.x = indev->proc.types.pointer.act_point.x;
140 data->point.y = indev->proc.types.pointer.act_point.y;
141 }
142 /*Similarly set at least the last key in case of the the user doesn't set it on release*/
143 else if(indev->driver.type == LV_INDEV_TYPE_KEYPAD) {
144 data->key = indev->proc.types.keypad.last_key;
145 }
146 /*For compatibility assume that used button was enter (encoder push) */
147 else if(indev->driver.type == LV_INDEV_TYPE_ENCODER) {
148 data->key = LV_KEY_ENTER;
149 data->enc_diff = 0;
150 }
151
152 if(indev->driver.read_cb) {
153 LV_LOG_TRACE("idnev read started");
154 cont = indev->driver.read_cb(&indev->driver, data);
155 LV_LOG_TRACE("idnev read finished");
156 }
157 else {
158 LV_LOG_WARN("indev function registered");
159 }
160
161 return cont;
162 }
163
164 /**********************
165 * STATIC FUNCTIONS
166 **********************/
167