# evdev (/integration/embedded_linux/drivers/evdev)



Overview [#overview]

The [Linux event device](https://en.wikipedia.org/wiki/Evdev) (evdev) interface exposes input events from a touchscreen,
mouse, keyboard or anything else the kernel recognizes, through device files under `/dev/input/`.

It's the lightest input option on Linux and the natural pairing for the [framebuffer](/integration/embedded_linux/drivers/fbdev)
and [DRM](/integration/embedded_linux/drivers/drm) display drivers, neither of which brings its own input.

Prerequisites [#prerequisites]

An input device under `/dev/input/`, typically `/dev/input/event0`, and permission to read it.

Configuration [#configuration]

Enable <ApiLink name="LV_USE_EVDEV" />.

Building [#building]

The driver always requires `libevdev`.

<Callout type="tip">
  LVGL's CMake integration resolves both.
  Make sure the required libraries  are present on your system or in your sysroot.

  See [Dependency Management](/integration/building/cmake).
</Callout>

Usage [#usage]

Create an input device with <ApiLink name="lv_evdev_create" />, giving it the device type and node path, then
attach it to a display with <ApiLink name="lv_indev_set_display" />.

```c title=" " lineNumbers=1
lv_display_t * disp = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(disp, "/dev/fb0");

lv_indev_t * touch = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");
lv_indev_set_display(touch, disp);
```

The type is <ApiLink name="LV_INDEV_TYPE_POINTER" /> for mice and touchscreens, or
<ApiLink name="LV_INDEV_TYPE_KEYPAD" /> for keyboards. <ApiLink name="lv_evdev_create_fd" /> takes an already
open file descriptor instead of a path, and <ApiLink name="lv_evdev_delete" /> removes a device.

Finding your input device [#finding-your-input-device]

List what the kernel sees:

```sh title="sh" lineNumbers=1
cat /proc/bus/input/devices
```

Entries mention an `event` handler. `event1` corresponds to `/dev/input/event1`. Confirm you picked the
right one by watching its events:

```sh title="sh" lineNumbers=1
evtest /dev/input/event1
```

Calibrating a touchscreen [#calibrating-a-touchscreen]

Raw touchscreens report device coordinates, not screen coordinates. Map them with
<ApiLink name="lv_evdev_set_calibration" />, and correct a transposed panel with
<ApiLink name="lv_evdev_set_swap_axes" />.

```c title=" " lineNumbers=1
lv_evdev_set_swap_axes(touch, true);
lv_evdev_set_calibration(touch, min_x, min_y, max_x, max_y);
```

Automatic device discovery [#automatic-device-discovery]

Rather than naming device nodes, let the driver find them. <ApiLink name="lv_evdev_discovery_start" /> scans
`/dev/input/` and keeps watching it, so devices plugged in later are added automatically.
Passing `NULL` for both arguments is enough to enable it:

```c title=" " lineNumbers=1
lv_evdev_discovery_start(NULL, NULL);
```

Supply a callback when you need to react to a new device — to attach a cursor image to a mouse, for example:

```c title=" " lineNumbers=1
#include "lvgl/src/core/lv_global.h"

static void indev_deleted_cb(lv_event_t * e)
{
    if(LV_GLOBAL_DEFAULT()->deinit_in_progress) return;
    lv_obj_t * cursor_obj = lv_event_get_user_data(e);
    lv_obj_delete(cursor_obj);
}

static void discovery_cb(lv_indev_t * indev, lv_evdev_type_t type, void * user_data)
{
    LV_LOG_USER("new '%s' device discovered", type == LV_EVDEV_TYPE_REL ? "REL" :
                                             type == LV_EVDEV_TYPE_ABS ? "ABS" :
                                             type == LV_EVDEV_TYPE_KEY ? "KEY" :
                                             "unknown");

    if(type == LV_EVDEV_TYPE_REL) {
        LV_IMAGE_DECLARE(mouse_cursor_icon);
        lv_obj_t * cursor_obj = lv_image_create(lv_screen_active());
        lv_image_set_src(cursor_obj, &mouse_cursor_icon);
        lv_indev_set_cursor(indev, cursor_obj);
        lv_indev_add_event_cb(indev, indev_deleted_cb, LV_EVENT_DELETE, cursor_obj);
    }
}

int main(void)
{
    /* ... */
    lv_evdev_discovery_start(discovery_cb, NULL);
    /* ... */
}
```

<ApiLink name="lv_evdev_discovery_stop" /> turns it off again.

<Callout type="info">
  Discovery relies on `inotify` and is not available on BSD. Create devices explicitly there.
</Callout>

Raw key codes [#raw-key-codes]

For keys LVGL does not map to one of its own, <ApiLink name="lv_evdev_is_raw_key" /> tells you an event
carries a raw code and <ApiLink name="lv_evdev_get_raw_key" /> returns it. Use these when you need keys
outside LVGL's navigation set.

Support [#support]

| Capability                         | Value                                                                      |
| ---------------------------------- | -------------------------------------------------------------------------- |
| Device types                       | Pointer (mouse, touchscreen) and keypad                                    |
| Automatic discovery                | Yes — <ApiLink name="lv_evdev_discovery_start" />                          |
| Hotplug                            | Yes — devices connected later are added automatically                      |
| Full keyboard (layouts, modifiers) | No — use [libinput](/integration/embedded_linux/drivers/libinput) with XKB |
| Touch calibration                  | Yes — <ApiLink name="lv_evdev_set_calibration" />                          |
| Axis swap                          | Yes — <ApiLink name="lv_evdev_set_swap_axes" />                            |
| Find device by capability          | No — pass a node path, or use discovery                                    |
| BSD                                | Yes, except discovery and hotplug                                          |

See Also [#see-also]

* [libinput](/integration/embedded_linux/drivers/libinput) - richer input stack, with XKB keyboard support
* [Linux Framebuffer](/integration/embedded_linux/drivers/fbdev) - display driver commonly paired with evdev
* [DRM](/integration/embedded_linux/drivers/drm) - display driver commonly paired with evdev
* [Dependency Management](/integration/building/cmake) - how LVGL resolves the evdev library
