Input device interface
Types of input devices
To create an input device use
/*Register at least one display before you register any input devices*/
lv_indev_t * indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_...);   /*See below.*/
lv_indev_set_read_cb(indev, read_cb);  /*See below.*/
The type member can be:
- LV_INDEV_TYPE_POINTER: touchpad or mouse
- LV_INDEV_TYPE_KEYPAD: keyboard or keypad
- LV_INDEV_TYPE_ENCODER: encoder with left/right turn and push options
- LV_INDEV_TYPE_BUTTON: external buttons virtually pressing the screen
read_cb is a function pointer which will be called periodically to
report the current state of an input device.
Visit Input devices to learn more about input devices in general.
Touchpad, mouse or any pointer
Input devices that can click points on the screen belong to this category.
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
...
void my_input_read(lv_indev_t * indev, lv_indev_data_t*data)
{
  if(touchpad_pressed) {
    data->point.x = touchpad_x;
    data->point.y = touchpad_y;
    data->state = LV_INDEV_STATE_PRESSED;
  } else {
    data->state = LV_INDEV_STATE_RELEASED;
  }
}
To set a mouse cursor use lv_indev_set_cursor(indev, &img_cursor).
Keypad or keyboard
Full keyboards with all the letters or simple keypads with a few navigation buttons belong here.
To use a keyboard/keypad:
- Register a - read_cbfunction and use- LV_INDEV_TYPE_KEYPADtype.
- An object group has to be created: - lv_group_t * g = lv_group_create()and objects have to be added to it with lv_group_add_obj(g, obj)
- The created group has to be assigned to an input device: lv_indev_set_group(indev, g) 
- Use - LV_KEY_...to navigate among the objects in the group. See- lv_core/lv_group.hfor the available keys.
lv_indev_set_type(indev, LV_INDEV_TYPE_KEYPAD);
...
void keyboard_read(lv_indev_t * indev, lv_indev_data_t*data){
  data->key = last_key();            /*Get the last pressed or released key*/
  if(key_pressed()) data->state = LV_INDEV_STATE_PRESSED;
  else data->state = LV_INDEV_STATE_RELEASED;
}
Encoder
With an encoder you can do the following:
- Press its button 
- Long-press its button 
- Turn left 
- Turn right 
In short, the Encoder input devices work like this:
- By turning the encoder you can focus on the next/previous object. 
- When you press the encoder on a simple object (like a button), it will be clicked. 
- If you press the encoder on a complex object (like a list, message box, etc.) the object will go to edit mode whereby you can navigate inside the object by turning the encoder. 
- To leave edit mode, long press the button. 
To use an Encoder (similarly to the Keypads) the objects should be added to groups.
lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER);
...
void encoder_read(lv_indev_t * indev, lv_indev_data_t*data){
  data->enc_diff = enc_get_new_moves();
  if(enc_pressed()) data->state = LV_INDEV_STATE_PRESSED;
  else data->state = LV_INDEV_STATE_RELEASED;
}
Other features
Parameters
The default value of the following parameters can be changed in lv_indev_t:
- scroll_limitNumber of pixels to slide before actually scrolling the object.
- scroll_throwScroll throw (momentum) slow-down in [%]. Greater value means faster slow-down.
- long_press_timePress time to send- LV_EVENT_LONG_PRESSED(in milliseconds)
- long_press_repeat_timeInterval of sending- LV_EVENT_LONG_PRESSED_REPEAT(in milliseconds)
- read_timerpointer to the- lv_timerwhich reads the input device. Its parameters can be changed by- lv_timer_...()functions.- LV_DEF_REFR_PERIODin- lv_conf.hsets the default read period.
Feedback
Besides read_cb a feedback_cb callback can be also specified in
lv_indev_t. feedback_cb is called when any type of event is sent
by the input devices (independently of its type). This allows generating
feedback for the user, e.g. to play a sound on LV_EVENT_CLICKED.
Associating with a display
Every input device is associated with a display. By default, a new input
device is added to the last display created or explicitly selected
(using lv_disp_set_default()). The associated display is stored and
can be changed in disp field of the driver.
Buffered reading
By default, LVGL calls read_cb periodically. Because of this
intermittent polling there is a chance that some user gestures are
missed.
To solve this you can write an event driven driver for your input device
that buffers measured data. In read_cb you can report the buffered
data instead of directly reading the input device. Setting the
data->continue_reading flag will tell LVGL there is more data to
read and it should call read_cb again.
Switching the input device to event-driven mode
Normally the input event is read every LV_DEF_REFR_PERIOD
milliseconds (set in lv_conf.h).  However, in some cases, you might
need more control over when to read the input device. For example, you
might need to read it by polling file descriptor (fd).
You can do this in the following way:
/*Update the input device's running mode to LV_INDEV_MODE_EVENT*/
lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT);
...
/*Call this anywhere you want to read the input device*/
lv_indev_read(indev);
Note
that lv_indev_read(), lv_timer_handler() and _lv_disp_refr_timer() can not run at the same time.
Further reading
- lv_port_indev_template.c for a template for your own driver. 
- INdev features <indev> to learn more about higher level input device features.