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 last_point; /**< Last point of input device.*/
145             lv_point_t last_raw_point; /**< Last point read from read_cb. */
146             lv_point_t vect; /**< Difference between `act_point` and `last_point`.*/
147             lv_point_t scroll_sum; /*Count the dragged pixels to check LV_INDEV_DEF_SCROLL_LIMIT*/
148             lv_point_t scroll_throw_vect;
149             lv_point_t scroll_throw_vect_ori;
150             struct _lv_obj_t * act_obj;      /*The object being pressed*/
151             struct _lv_obj_t * last_obj;     /*The last object which was pressed*/
152             struct _lv_obj_t * scroll_obj;   /*The object being scrolled*/
153             struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
154             lv_area_t scroll_area;
155 
156             lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/
157             /*Flags*/
158             lv_dir_t scroll_dir : 4;
159             lv_dir_t gesture_dir : 4;
160             uint8_t gesture_sent : 1;
161         } pointer;
162         struct {
163             /*Keypad data*/
164             lv_indev_state_t last_state;
165             uint32_t last_key;
166         } keypad;
167     } types;
168 
169     uint32_t pr_timestamp;         /**< Pressed time stamp*/
170     uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/
171 } _lv_indev_proc_t;
172 
173 /** The main input device descriptor with driver, runtime data ('proc') and some additional
174  * information*/
175 typedef struct _lv_indev_t {
176     struct _lv_indev_drv_t * driver;
177     _lv_indev_proc_t proc;
178     struct _lv_obj_t * cursor;     /**< Cursor for LV_INPUT_TYPE_POINTER*/
179     struct _lv_group_t * group;    /**< Keypad destination group*/
180     const lv_point_t * btn_points; /**< Array points assigned to the button ()screen will be pressed
181                                       here by the buttons*/
182 } lv_indev_t;
183 
184 /**********************
185  * GLOBAL PROTOTYPES
186  **********************/
187 
188 /**
189  * Initialize an input device driver with default values.
190  * It is used to surely have known values in the fields and not memory junk.
191  * After it you can set the fields.
192  * @param driver pointer to driver variable to initialize
193  */
194 void lv_indev_drv_init(struct _lv_indev_drv_t * driver);
195 
196 /**
197  * Register an initialized input device driver.
198  * @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
199  * @return pointer to the new input device or NULL on error
200  */
201 lv_indev_t * lv_indev_drv_register(struct _lv_indev_drv_t * driver);
202 
203 /**
204  * Update the driver in run time.
205  * @param indev pointer to an input device. (return value of `lv_indev_drv_register`)
206  * @param new_drv pointer to the new driver
207  */
208 void lv_indev_drv_update(lv_indev_t * indev, struct _lv_indev_drv_t * new_drv);
209 
210 /**
211 * Remove the provided input device. Make sure not to use the provided input device afterwards anymore.
212 * @param indev pointer to delete
213 */
214 void lv_indev_delete(lv_indev_t * indev);
215 
216 /**
217  * Get the next input device.
218  * @param indev pointer to the current input device. NULL to initialize.
219  * @return the next input device or NULL if there are no more. Provide the first input device when
220  * the parameter is NULL
221  */
222 lv_indev_t * lv_indev_get_next(lv_indev_t * indev);
223 
224 /**
225  * Read data from an input device.
226  * @param indev pointer to an input device
227  * @param data input device will write its data here
228  */
229 void _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);
230 
231 /**********************
232  *      MACROS
233  **********************/
234 
235 #ifdef __cplusplus
236 } /*extern "C"*/
237 #endif
238 
239 #endif
240