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