upiwin/src/sysinput.c

85 lines
1.8 KiB
C

#include <stddef.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include "scode.h"
#include "log.h"
#include "msg_queue.h"
#include "gpio.h"
#include "time_func.h"
#define DEBOUNCE_BUTTON_MSEC 100
PMSG_QUEUE Sys_Queue = NULL;
static pthread_t ithread;
static volatile sig_atomic_t running = 1;
static UINT32 last_bstate = 0;
static void *input_thread(void *arg)
{
UINT32 st, down, up, mask;
UINT_PTR attr;
TIMESTAMP now;
TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT];
memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
while (running)
{
/* poll hardware buttons */
st = Gpio_read_buttons();
if (st != last_bstate)
{
now = Time_since_start();
up = last_bstate & ~st;
down = st & ~last_bstate;
for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
{
if (now < button_event_ok[attr - 1])
continue;
if (up & mask)
{
button_event_ok[attr - 1] = now + DEBOUNCE_BUTTON_MSEC;
Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
}
else if (down & mask)
Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr);
}
last_bstate = st;
}
/* additional poll activity here */
}
return NULL;
}
HRESULT Sys_enable_input(void)
{
HRESULT rc = S_OK;
int threadrc;
Sys_Queue = Mq_alloc(64);
if (!Sys_Queue)
{
Log(LFATAL, "Unable to allocate system message queue.");
return E_OUTOFMEMORY;
}
running = 1;
threadrc = pthread_create(&ithread, NULL, input_thread, NULL);
if (threadrc != 0)
{
rc = SCODE_FROM_ERRNO(threadrc);
Log(LFATAL, "Unable to start system input thread (%08X).", rc);
}
return rc;
}
void Sys_disable_input(void)
{
running = 0;
pthread_join(ithread, NULL);
Mq_destroy(Sys_Queue);
Sys_Queue = NULL;
}