1 /**
2  * @file lv_hal_indev.h
3  *
4  * @description Input Device HAL interface layer header file
5  *
6  */
7 
8 #ifndef LV_HAL_INDEV_H
9 #define LV_HAL_INDEV_H
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 /*********************
16  *      INCLUDES
17  *********************/
18 #include "../lv_conf_internal.h"
19 
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include "../misc/lv_area.h"
23 #include "../misc/lv_timer.h"
24 
25 /*********************
26  *      DEFINES
27  *********************/
28 
29 /*Drag threshold in pixels*/
30 #define LV_INDEV_DEF_SCROLL_LIMIT         10
31 
32 /*Drag throw slow-down in [%]. Greater value -> faster slow-down*/
33 #define LV_INDEV_DEF_SCROLL_THROW         10
34 
35 /*Long press time in milliseconds.
36  *Time to send `LV_EVENT_LONG_PRESSSED`)*/
37 #define LV_INDEV_DEF_LONG_PRESS_TIME      400
38 
39 /*Repeated trigger period in long press [ms]
40  *Time between `LV_EVENT_LONG_PRESSED_REPEAT*/
41 #define LV_INDEV_DEF_LONG_PRESS_REP_TIME  100
42 
43 
44 /*Gesture threshold in pixels*/
45 #define LV_INDEV_DEF_GESTURE_LIMIT        50
46 
47 /*Gesture min velocity at release before swipe (pixels)*/
48 #define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3
49 
50 
51 /**********************
52  *      TYPEDEFS
53  **********************/
54 
55 struct _lv_obj_t;
56 struct _lv_disp_t;
57 struct _lv_group_t;
58 struct _lv_indev_t;
59 struct _lv_indev_drv_t;
60 
61 /** Possible input device types*/
62 typedef enum {
63     LV_INDEV_TYPE_NONE,    /**< Uninitialized state*/
64     LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/
65     LV_INDEV_TYPE_KEYPAD,  /**< Keypad or keyboard*/
66     LV_INDEV_TYPE_BUTTON,  /**< External (hardware button) which is assigned to a specific point of the screen*/
67     LV_INDEV_TYPE_ENCODER, /**< Encoder with only Left, Right turn and a Button*/
68 } lv_indev_type_t;
69 
70 /** States for input devices*/
71 typedef enum {
72     LV_INDEV_STATE_RELEASED = 0,
73     LV_INDEV_STATE_PRESSED
74 } lv_indev_state_t;
75 
76 /** Data structure passed to an input driver to fill*/
77 typedef struct {
78     lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/
79     uint32_t key;     /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
80     uint32_t btn_id;  /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/
81     int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
82 
83     lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
84     bool continue_reading;  /**< If set to true, the read callback is invoked again*/
85 } lv_indev_data_t;
86 
87 /** Initialized by the user and registered by 'lv_indev_add()'*/
88 typedef struct _lv_indev_drv_t {
89 
90     /**< Input device type*/
91     lv_indev_type_t type;
92 
93     /**< Function pointer to read input device data.*/
94     void (*read_cb)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
95 
96     /** Called when an action happened on the input device.
97      * The second parameter is the event from `lv_event_t`*/
98     void (*feedback_cb)(struct _lv_indev_drv_t *, uint8_t);
99 
100 #if LV_USE_USER_DATA
101     void * user_data;
102 #endif
103 
104     /**< Pointer to the assigned display*/
105     struct _lv_disp_t * disp;
106 
107     /**< Timer to periodically read the input device*/
108     lv_timer_t * read_timer;
109 
110     /**< Number of pixels to slide before actually drag the object*/
111     uint8_t scroll_limit;
112 
113     /**< Drag throw slow-down in [%]. Greater value means faster slow-down*/
114     uint8_t scroll_throw;
115 
116     /**< At least this difference should be between two points to evaluate as gesture*/
117     uint8_t gesture_min_velocity;
118 
119     /**< At least this difference should be to send a gesture*/
120     uint8_t gesture_limit;
121 
122     /**< Long press time in milliseconds*/
123     uint16_t long_press_time;
124 
125     /**< Repeated trigger period in long press [ms]*/
126     uint16_t long_press_repeat_time;
127 } lv_indev_drv_t;
128 
129 /** Run time data of input devices
130  * Internally used by the library, you should not need to touch it.
131  */
132 typedef struct _lv_indev_proc_t {
133     lv_indev_state_t state; /**< Current state of the input device.*/
134     /*Flags*/
135     uint8_t long_pr_sent : 1;
136     uint8_t reset_query : 1;
137     uint8_t disabled : 1;
138     uint8_t wait_until_release : 1;
139 
140     union {
141         struct {
142             /*Pointer and button data*/
143             lv_point_t act_point; /**< Current point of input device.*/
144             lv_point_t indev_point;
145             lv_point_t last_point; /**< Last point of input device.*/
146             lv_point_t last_raw_point; /**< Last point read from read_cb. */
147             lv_point_t vect; /**< Difference between `act_point` and `last_point`.*/
148             lv_point_t scroll_sum; /*Count the dragged pixels to check LV_INDEV_DEF_SCROLL_LIMIT*/
149             lv_point_t scroll_throw_vect;
150             lv_point_t scroll_throw_vect_ori;
151             struct _lv_obj_t * act_obj;      /*The object being pressed*/
152             struct _lv_obj_t * last_obj;     /*The last object which was pressed*/
153             struct _lv_obj_t * scroll_obj;   /*The object being scrolled*/
154             struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
155             lv_area_t scroll_area;
156 
157             lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/
158             /*Flags*/
159             lv_dir_t scroll_dir : 4;
160             lv_dir_t gesture_dir : 4;
161             uint8_t gesture_sent : 1;
162         } pointer;
163         struct {
164             /*Keypad data*/
165             lv_indev_state_t last_state;
166             uint32_t last_key;
167         } keypad;
168     } types;
169 
170     uint32_t pr_timestamp;         /**< Pressed time stamp*/
171     uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/
172 } _lv_indev_proc_t;
173 
174 /** The main input device descriptor with driver, runtime data ('proc') and some additional
175  * information*/
176 typedef struct _lv_indev_t {
177     struct _lv_indev_drv_t * driver;
178     _lv_indev_proc_t proc;
179     struct _lv_obj_t * cursor;     /**< Cursor for LV_INPUT_TYPE_POINTER*/
180     struct _lv_group_t * group;    /**< Keypad destination group*/
181     const lv_point_t * btn_points; /**< Array points assigned to the button ()screen will be pressed
182                                       here by the buttons*/
183 } lv_indev_t;
184 
185 /**********************
186  * GLOBAL PROTOTYPES
187  **********************/
188 
189 /**
190  * Initialize an input device driver with default values.
191  * It is used to surely have known values in the fields and not memory junk.
192  * After it you can set the fields.
193  * @param driver pointer to driver variable to initialize
194  */
195 void lv_indev_drv_init(struct _lv_indev_drv_t * driver);
196 
197 /**
198  * Register an initialized input device driver.
199  * @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
200  * @return pointer to the new input device or NULL on error
201  */
202 lv_indev_t * lv_indev_drv_register(struct _lv_indev_drv_t * driver);
203 
204 /**
205  * Update the driver in run time.
206  * @param indev pointer to an input device. (return value of `lv_indev_drv_register`)
207  * @param new_drv pointer to the new driver
208  */
209 void lv_indev_drv_update(lv_indev_t * indev, struct _lv_indev_drv_t * new_drv);
210 
211 /**
212 * Remove the provided input device. Make sure not to use the provided input device afterwards anymore.
213 * @param indev pointer to delete
214 */
215 void lv_indev_delete(lv_indev_t * indev);
216 
217 /**
218  * Get the next input device.
219  * @param indev pointer to the current input device. NULL to initialize.
220  * @return the next input device or NULL if there are no more. Provide the first input device when
221  * the parameter is NULL
222  */
223 lv_indev_t * lv_indev_get_next(lv_indev_t * indev);
224 
225 /**
226  * Read data from an input device.
227  * @param indev pointer to an input device
228  * @param data input device will write its data here
229  */
230 void _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);
231 
232 /**********************
233  *      MACROS
234  **********************/
235 
236 #ifdef __cplusplus
237 } /*extern "C"*/
238 #endif
239 
240 #endif
241