197 lines
5.7 KiB
C
197 lines
5.7 KiB
C
|
/**
|
||
|
* @file lv_hal_indev.c
|
||
|
*
|
||
|
* @description Input device HAL interface
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/*********************
|
||
|
* INCLUDES
|
||
|
*********************/
|
||
|
#include "../misc/lv_assert.h"
|
||
|
#include "../hal/lv_hal_indev.h"
|
||
|
#include "../core/lv_indev.h"
|
||
|
#include "../misc/lv_mem.h"
|
||
|
#include "../misc/lv_gc.h"
|
||
|
#include "lv_hal_disp.h"
|
||
|
|
||
|
/*********************
|
||
|
* DEFINES
|
||
|
*********************/
|
||
|
|
||
|
/**********************
|
||
|
* TYPEDEFS
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* GLOBAL PROTOTYPES
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* STATIC PROTOTYPES
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* STATIC VARIABLES
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* MACROS
|
||
|
**********************/
|
||
|
#if LV_LOG_TRACE_INDEV
|
||
|
#define INDEV_TRACE(...) LV_LOG_TRACE(__VA_ARGS__)
|
||
|
#else
|
||
|
#define INDEV_TRACE(...)
|
||
|
#endif
|
||
|
|
||
|
/**********************
|
||
|
* GLOBAL FUNCTIONS
|
||
|
**********************/
|
||
|
|
||
|
/**
|
||
|
* Initialize an input device driver with default values.
|
||
|
* It is used to surly have known values in the fields ant not memory junk.
|
||
|
* After it you can set the fields.
|
||
|
* @param driver pointer to driver variable to initialize
|
||
|
*/
|
||
|
void lv_indev_drv_init(lv_indev_drv_t * driver)
|
||
|
{
|
||
|
lv_memset_00(driver, sizeof(lv_indev_drv_t));
|
||
|
|
||
|
driver->type = LV_INDEV_TYPE_NONE;
|
||
|
driver->scroll_limit = LV_INDEV_DEF_SCROLL_LIMIT;
|
||
|
driver->scroll_throw = LV_INDEV_DEF_SCROLL_THROW;
|
||
|
driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME;
|
||
|
driver->long_press_repeat_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
|
||
|
driver->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT;
|
||
|
driver->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Register an initialized input device driver.
|
||
|
* @param driver pointer to an initialized 'lv_indev_drv_t' variable.
|
||
|
* Only pointer is saved, so the driver should be static or dynamically allocated.
|
||
|
* @return pointer to the new input device or NULL on error
|
||
|
*/
|
||
|
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
|
||
|
{
|
||
|
|
||
|
if(driver->disp == NULL) driver->disp = lv_disp_get_default();
|
||
|
|
||
|
if(driver->disp == NULL) {
|
||
|
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
|
||
|
"a display");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
lv_indev_t * indev = _lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
|
||
|
if(!indev) {
|
||
|
LV_ASSERT_MALLOC(indev);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
lv_memset_00(indev, sizeof(lv_indev_t));
|
||
|
indev->driver = driver;
|
||
|
|
||
|
indev->proc.reset_query = 1;
|
||
|
indev->driver->read_timer = lv_timer_create(lv_indev_read_timer_cb, LV_INDEV_DEF_READ_PERIOD, indev);
|
||
|
|
||
|
return indev;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update the driver in run time.
|
||
|
* @param indev pointer to a input device. (return value of `lv_indev_drv_register`)
|
||
|
* @param new_drv pointer to the new driver
|
||
|
*/
|
||
|
void lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv)
|
||
|
{
|
||
|
LV_ASSERT_NULL(indev);
|
||
|
LV_ASSERT_NULL(indev->driver);
|
||
|
LV_ASSERT_NULL(indev->driver->read_timer);
|
||
|
lv_timer_del(indev->driver->read_timer);
|
||
|
|
||
|
LV_ASSERT_NULL(new_drv);
|
||
|
if(new_drv->disp == NULL) {
|
||
|
new_drv->disp = lv_disp_get_default();
|
||
|
}
|
||
|
if(new_drv->disp == NULL) {
|
||
|
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
|
||
|
"a display");
|
||
|
indev->proc.disabled = true;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
indev->driver = new_drv;
|
||
|
indev->driver->read_timer = lv_timer_create(lv_indev_read_timer_cb, LV_INDEV_DEF_READ_PERIOD, indev);
|
||
|
indev->proc.reset_query = 1;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Remove the provided input device. Make sure not to use the provided input device afterwards anymore.
|
||
|
* @param indev pointer to delete
|
||
|
*/
|
||
|
void lv_indev_delete(lv_indev_t * indev)
|
||
|
{
|
||
|
LV_ASSERT_NULL(indev);
|
||
|
LV_ASSERT_NULL(indev->driver);
|
||
|
LV_ASSERT_NULL(indev->driver->read_timer);
|
||
|
/*Clean up the read timer first*/
|
||
|
lv_timer_del(indev->driver->read_timer);
|
||
|
/*Remove the input device from the list*/
|
||
|
_lv_ll_remove(&LV_GC_ROOT(_lv_indev_ll), indev);
|
||
|
/*Free the memory of the input device*/
|
||
|
lv_mem_free(indev);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the next input device.
|
||
|
* @param indev pointer to the current input device. NULL to initialize.
|
||
|
* @return the next input devise or NULL if no more. Give the first input device when the parameter
|
||
|
* is NULL
|
||
|
*/
|
||
|
lv_indev_t * lv_indev_get_next(lv_indev_t * indev)
|
||
|
{
|
||
|
if(indev == NULL)
|
||
|
return _lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));
|
||
|
else
|
||
|
return _lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Read data from an input device.
|
||
|
* @param indev pointer to an input device
|
||
|
* @param data input device will write its data here
|
||
|
*/
|
||
|
void _lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||
|
{
|
||
|
lv_memset_00(data, sizeof(lv_indev_data_t));
|
||
|
|
||
|
/* For touchpad sometimes users don't set the last pressed coordinate on release.
|
||
|
* So be sure a coordinates are initialized to the last point */
|
||
|
if(indev->driver->type == LV_INDEV_TYPE_POINTER) {
|
||
|
data->point.x = indev->proc.types.pointer.last_raw_point.x;
|
||
|
data->point.y = indev->proc.types.pointer.last_raw_point.y;
|
||
|
}
|
||
|
/*Similarly set at least the last key in case of the user doesn't set it on release*/
|
||
|
else if(indev->driver->type == LV_INDEV_TYPE_KEYPAD) {
|
||
|
data->key = indev->proc.types.keypad.last_key;
|
||
|
}
|
||
|
/*For compatibility assume that used button was enter (encoder push)*/
|
||
|
else if(indev->driver->type == LV_INDEV_TYPE_ENCODER) {
|
||
|
data->key = LV_KEY_ENTER;
|
||
|
}
|
||
|
|
||
|
if(indev->driver->read_cb) {
|
||
|
INDEV_TRACE("calling indev_read_cb");
|
||
|
indev->driver->read_cb(indev->driver, data);
|
||
|
}
|
||
|
else {
|
||
|
LV_LOG_WARN("indev_read_cb is not registered");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**********************
|
||
|
* STATIC FUNCTIONS
|
||
|
**********************/
|