mirror of
https://github.com/MaJerle/lwbtn.git
synced 2026-08-17 09:33:54 +08:00
Update commends and rename structure members
This commit is contained in:
+35
-24
@@ -15,37 +15,40 @@ static lwbtn_btn_t btns[] = {{.arg = (void*)&keys[0]}, {.arg = (void*)&keys[1]},
|
||||
{.arg = (void*)&keys[6]}, {.arg = (void*)&keys[7]}, {.arg = (void*)&keys[8]},
|
||||
{.arg = (void*)&keys[9]}};
|
||||
|
||||
/**
|
||||
* \brief Get input state callback
|
||||
* \param lw: LwBTN instance
|
||||
* \param btn: Button instance
|
||||
* \return `1` if button active, `0` otherwise
|
||||
*/
|
||||
uint8_t
|
||||
prv_btn_get_state(struct lwbtn* lw, struct lwbtn_btn* btn) {
|
||||
(void)lw;
|
||||
return GetAsyncKeyState(*(int*)btn->arg) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Button event
|
||||
*
|
||||
* \param lw: LwBTN instance
|
||||
* \param btn: Button instance
|
||||
* \param evt: Button event
|
||||
*/
|
||||
void
|
||||
prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) {
|
||||
const char* s = "unknown";
|
||||
(void)lw;
|
||||
printf("[%7u] State !!!. CH: %c, evt: ", (unsigned)get_tick(), *(int*)btn->arg);
|
||||
switch (evt) {
|
||||
case LWBTN_EVT_KEEPALIVE: {
|
||||
printf("KEEPALIVE");
|
||||
break;
|
||||
}
|
||||
case LWBTN_EVT_ONPRESS: {
|
||||
printf("ONPRESS");
|
||||
break;
|
||||
}
|
||||
case LWBTN_EVT_ONRELEASE: {
|
||||
printf("ONRELEASE");
|
||||
break;
|
||||
}
|
||||
case LWBTN_EVT_ONCLICK: {
|
||||
printf("ONCLICK");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
/* Get event string */
|
||||
s = ((evt == LWBTN_EVT_KEEPALIVE)
|
||||
? "KEEPALIVE"
|
||||
: ((evt == LWBTN_EVT_ONPRESS)
|
||||
? " ONPRESS"
|
||||
: ((evt == LWBTN_EVT_ONRELEASE) ? "ONRELEASE"
|
||||
: ((evt == LWBTN_EVT_ONCLICK) ? " ONCLICK" : " UNKNOWN"))));
|
||||
|
||||
printf("[%7u] CH: %c, evt: %s, keep-alive cnt: %3u, click cnt: %3u\r\n", (unsigned)get_tick(), *(int*)btn->arg, s,
|
||||
(unsigned)btn->keepalive.cnt, (unsigned)btn->click.cnt);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -54,14 +57,22 @@ main(void) {
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&sys_start_time);
|
||||
|
||||
/* Define buttons */
|
||||
lwbtn_init_ex(NULL, btns, sizeof(btns) / sizeof(btns[0]), prv_btn_get_state, prv_btn_event);
|
||||
|
||||
while (1) {
|
||||
/* Process forever */
|
||||
lwbtn_process_ex(NULL, get_tick());
|
||||
Sleep(10);
|
||||
|
||||
/* Artificial sleep to offload win process */
|
||||
Sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get current tick in ms from start of program
|
||||
* \return uint32_t: Tick in ms
|
||||
*/
|
||||
static uint32_t
|
||||
get_tick(void) {
|
||||
LONGLONG ret;
|
||||
|
||||
@@ -74,44 +74,75 @@ typedef enum {
|
||||
LWBTN_EVT_KEEPALIVE,
|
||||
} lwbtn_evt_t;
|
||||
|
||||
/**
|
||||
* \brief Button event function callback prototype
|
||||
* \param[in] lw: LwBTN instance
|
||||
* \param[in] btn: Button instance from array for which event occured
|
||||
* \param[in] evt: Event type
|
||||
*/
|
||||
typedef void (*lwbtn_evt_fn)(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt);
|
||||
|
||||
/**
|
||||
* \brief Get button/input state callback function
|
||||
* \param[in] lw: LwBTN instance
|
||||
* \param[in] btn: Button instance from array to read state
|
||||
* \return `1` when button is considered `active`, `0` otherwise
|
||||
*/
|
||||
typedef uint8_t (*lwbtn_get_state_fn)(struct lwbtn* lw, struct lwbtn_btn* btn);
|
||||
|
||||
/**
|
||||
* \brief Button/input structure
|
||||
*/
|
||||
typedef struct lwbtn_btn {
|
||||
uint16_t flags;
|
||||
uint8_t old_state;
|
||||
uint32_t time_change;
|
||||
uint16_t flags; /*!< Private button flags management */
|
||||
uint8_t old_state; /*!< Old button state - `1` means active, `0` means inactive */
|
||||
uint32_t time_change; /*!< Time in ms when button state got changed last time */
|
||||
|
||||
struct {
|
||||
uint32_t last_time;
|
||||
uint16_t cnt;
|
||||
} keepalive;
|
||||
uint32_t last_time; /*!< Time in ms of last send keep alive event */
|
||||
uint16_t cnt; /*!< Number of keep alive events sent after successful on-press detection.
|
||||
Value is reset after on-release */
|
||||
} keepalive; /*!< Keep alive structure */
|
||||
|
||||
struct {
|
||||
uint32_t last_time;
|
||||
uint8_t consecutive_cnt;
|
||||
} click;
|
||||
uint32_t last_time; /*!< Time in ms of last successfully detected (not sent!) click event */
|
||||
uint8_t cnt; /*!< Number of consecutive clicks detected, respecting maximum timeout between clicks */
|
||||
} click; /*!< Click event structure */
|
||||
|
||||
void* arg;
|
||||
void* arg; /*!< User defined custom argument for callback function purpose */
|
||||
} lwbtn_btn_t;
|
||||
|
||||
/**
|
||||
* \brief LwBTN group structure
|
||||
*/
|
||||
typedef struct lwbtn {
|
||||
lwbtn_btn_t* btns;
|
||||
uint16_t btns_cnt;
|
||||
lwbtn_evt_fn evt_fn;
|
||||
lwbtn_get_state_fn get_state_fn;
|
||||
lwbtn_btn_t* btns; /*!< Pointer to buttons array */
|
||||
uint16_t btns_cnt; /*!< Number of buttons in array */
|
||||
lwbtn_evt_fn evt_fn; /*!< Pointer to event function */
|
||||
lwbtn_get_state_fn get_state_fn; /*!< Pointer to get state function */
|
||||
} lwbtn_t;
|
||||
|
||||
uint8_t lwbtn_init_ex(lwbtn_t* lw, lwbtn_btn_t* btns, uint16_t btns_cnt, lwbtn_get_state_fn get_state_fn,
|
||||
lwbtn_evt_fn evt_fn);
|
||||
uint8_t lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime);
|
||||
|
||||
/**
|
||||
* \brief Initialize LwBTN library with buttons on default button group
|
||||
* \param[in] btns: Array of buttons to process
|
||||
* \param[in] btns_cnt: Number of buttons to process
|
||||
* \param[in] get_state_fn: Pointer to function providing button state on demand
|
||||
* \param[in] evt_fn: Button event function callback
|
||||
* \sa lwbtn_init_ex
|
||||
*/
|
||||
#define lwbtn_init(btns, btns_cnt, get_state_fn, evt_fn) lwbtn_init_ex(NULL, btns, btns_cnt, get_state_fn, evt_fn)
|
||||
|
||||
/**
|
||||
* \brief Periodically read button states and take appropriate actions
|
||||
* \param[in] mstime: Current system time in milliseconds
|
||||
* \sa lwbtn_process_ex
|
||||
*/
|
||||
#define lwbtn_process(mstime) lwbtn_process_ex(NULL, mstime)
|
||||
|
||||
/**
|
||||
* \}
|
||||
*/
|
||||
|
||||
@@ -112,12 +112,12 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) {
|
||||
* Increase consecutive clicks if max not reached yet
|
||||
* and if time between two clicks is not too long
|
||||
*/
|
||||
if (b->click.consecutive_cnt > 0 && b->click.consecutive_cnt < LWBTN_CLICK_MAX_CONSECUTIVE(b)
|
||||
if (b->click.cnt > 0 && b->click.cnt < LWBTN_CLICK_MAX_CONSECUTIVE(b)
|
||||
&& (mstime - b->click.last_time) < LWBTN_TIME_CLICK_MAX_MULTI(b)) {
|
||||
++b->click.consecutive_cnt;
|
||||
++b->click.cnt;
|
||||
} else {
|
||||
/* Start over - set as first click */
|
||||
b->click.consecutive_cnt = 1;
|
||||
b->click.cnt = 1;
|
||||
}
|
||||
b->click.last_time = mstime;
|
||||
} else {
|
||||
@@ -130,7 +130,7 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) {
|
||||
*
|
||||
* Clear then counter
|
||||
*/
|
||||
b->click.consecutive_cnt = 0;
|
||||
b->click.cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,9 +164,9 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) {
|
||||
*
|
||||
* Handle this on on-press state
|
||||
*/
|
||||
if (b->click.consecutive_cnt > 0 && b->click.consecutive_cnt == LWBTN_CLICK_MAX_CONSECUTIVE(b)) {
|
||||
if (b->click.cnt > 0 && b->click.cnt == LWBTN_CLICK_MAX_CONSECUTIVE(b)) {
|
||||
lw->evt_fn(lw, b, LWBTN_EVT_ONCLICK);
|
||||
b->click.consecutive_cnt = 0;
|
||||
b->click.cnt = 0;
|
||||
}
|
||||
|
||||
/* Now start with new on-press */
|
||||
@@ -202,10 +202,10 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) {
|
||||
* This is sent after last valid click has been detected for OnRelease event
|
||||
* - Reset consecutive clicks counter if time after last click is longer than maximum one
|
||||
*/
|
||||
if (b->click.consecutive_cnt > 0) {
|
||||
if (b->click.cnt > 0) {
|
||||
if ((mstime - b->click.last_time) >= LWBTN_TIME_CLICK_SEND_TIMEOUT(b)) {
|
||||
lw->evt_fn(lw, b, LWBTN_EVT_ONCLICK);
|
||||
b->click.consecutive_cnt = 0;
|
||||
b->click.cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user