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 "../lv_misc/lv_area.h"
23 #include "../lv_misc/lv_task.h"
24 
25 /*********************
26  *      DEFINES
27  *********************/
28 
29 /**********************
30  *      TYPEDEFS
31  **********************/
32 
33 struct _lv_obj_t;
34 struct _disp_t;
35 struct _lv_indev_t;
36 struct _lv_indev_drv_t;
37 
38 /** Possible input device types*/
39 enum {
40     LV_INDEV_TYPE_NONE,    /**< Uninitialized state*/
41     LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/
42     LV_INDEV_TYPE_KEYPAD,  /**< Keypad or keyboard*/
43     LV_INDEV_TYPE_BUTTON,  /**< External (hardware button) which is assigned to a specific point of the
44                               screen*/
45     LV_INDEV_TYPE_ENCODER, /**< Encoder with only Left, Right turn and a Button*/
46 };
47 typedef uint8_t lv_indev_type_t;
48 
49 /** States for input devices*/
50 enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };
51 typedef uint8_t lv_indev_state_t;
52 
53 
54 enum {
55     LV_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */
56     LV_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */
57     LV_DRAG_DIR_BOTH = 0x3, /**< Object can be dragged in all directions. */
58     LV_DRAG_DIR_ONE = 0x4, /**< Object can be dragged only one direction (the first move). */
59 };
60 
61 typedef uint8_t lv_drag_dir_t;
62 
63 enum {
64     LV_GESTURE_DIR_TOP,     /**< Gesture dir up. */
65     LV_GESTURE_DIR_BOTTOM,  /**< Gesture dir down. */
66     LV_GESTURE_DIR_LEFT,    /**< Gesture dir left. */
67     LV_GESTURE_DIR_RIGHT,   /**< Gesture dir right. */
68 };
69 typedef uint8_t lv_gesture_dir_t;
70 
71 /** Data structure passed to an input driver to fill */
72 typedef struct {
73     lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/
74     uint32_t key;     /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
75     uint32_t btn_id;  /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/
76     int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
77 
78     lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
79 } lv_indev_data_t;
80 
81 
82 /** Initialized by the user and registered by 'lv_indev_add()'*/
83 typedef struct _lv_indev_drv_t {
84 
85     /**< Input device type*/
86     lv_indev_type_t type;
87 
88     /**< Function pointer to read input device data.
89      * Return 'true' if there is more data to be read (buffered).
90      * Most drivers can safely return 'false' */
91     bool (*read_cb)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
92 
93     /** Called when an action happened on the input device.
94      * The second parameter is the event from `lv_event_t`*/
95     void (*feedback_cb)(struct _lv_indev_drv_t *, uint8_t);
96 
97 #if LV_USE_USER_DATA
98     lv_indev_drv_user_data_t user_data;
99 #endif
100 
101     /**< Pointer to the assigned display*/
102     struct _disp_t * disp;
103 
104     /**< Task to read the periodically read the input device*/
105     lv_task_t * read_task;
106 
107     /**< Number of pixels to slide before actually drag the object*/
108     uint8_t drag_limit;
109 
110     /**< Drag throw slow-down in [%]. Greater value means faster slow-down */
111     uint8_t drag_throw;
112 
113     /**< At least this difference should between two points to evaluate as gesture */
114     uint8_t gesture_min_velocity;
115 
116     /**< At least this difference should be to send a gesture */
117     uint8_t gesture_limit;
118 
119     /**< Long press time in milliseconds*/
120     uint16_t long_press_time;
121 
122     /**< Repeated trigger period in long press [ms] */
123     uint16_t long_press_rep_time;
124 } lv_indev_drv_t;
125 
126 /** Run time data of input devices
127  * Internally used by the library, you should not need to touch it.
128  */
129 typedef struct _lv_indev_proc_t {
130     lv_indev_state_t state; /**< Current state of the input device. */
131     union {
132         struct {
133             /*Pointer and button data*/
134             lv_point_t act_point; /**< Current point of input device. */
135             lv_point_t last_point; /**< Last point of input device. */
136             lv_point_t vect; /**< Difference between `act_point` and `last_point`. */
137             lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/
138             lv_point_t drag_throw_vect;
139             struct _lv_obj_t * act_obj;      /*The object being pressed*/
140             struct _lv_obj_t * last_obj;     /*The last object which was pressed (used by drag_throw and
141                                                 other post-release event)*/
142             struct _lv_obj_t * last_pressed; /*The lastly pressed object*/
143 
144             lv_gesture_dir_t gesture_dir;
145             lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/
146             /*Flags*/
147             uint8_t drag_limit_out : 1;
148             uint8_t drag_in_prog : 1;
149             lv_drag_dir_t drag_dir  : 3;
150             uint8_t gesture_sent : 1;
151         } pointer;
152         struct {
153             /*Keypad data*/
154             lv_indev_state_t last_state;
155             uint32_t last_key;
156         } keypad;
157     } types;
158 
159     uint32_t pr_timestamp;         /**< Pressed time stamp*/
160     uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/
161 
162     /*Flags*/
163     uint8_t long_pr_sent : 1;
164     uint8_t reset_query : 1;
165     uint8_t disabled : 1;
166     uint8_t wait_until_release : 1;
167 } lv_indev_proc_t;
168 
169 struct _lv_obj_t;
170 struct _lv_group_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     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 surly have known values in the fields ant 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(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(lv_indev_drv_t * driver);
201 
202 /**
203  * Update the driver in run time.
204  * @param indev pointer to a 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, lv_indev_drv_t * new_drv);
208 
209 /**
210  * Get the next input device.
211  * @param indev pointer to the current input device. NULL to initialize.
212  * @return the next input devise or NULL if no more. Give the first input device when the parameter
213  * is NULL
214  */
215 lv_indev_t * lv_indev_get_next(lv_indev_t * indev);
216 
217 /**
218  * Read data from an input device.
219  * @param indev pointer to an input device
220  * @param data input device will write its data here
221  * @return false: no more data; true: there more data to read (buffered)
222  */
223 bool _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);
224 
225 /**********************
226  *      MACROS
227  **********************/
228 
229 #ifdef __cplusplus
230 } /* extern "C" */
231 #endif
232 
233 #endif
234