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