diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 815aa44..902d767 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -25,6 +25,8 @@ while upiwin.get_message(msg): print("Button {0} was pressed.".format(msg['attrs'][0])) elif msg['message'] == upiwin.WM_HWBUTTONUP: print("Button {0} was released.".format(msg['attrs'][0])) + elif msg['message'] == upiwin.WM_HWBUTTONCLICK: + print("Button {0} was clicked.".format(msg['attrs'][0])) bn = msg['attrs'][0] if bn == 1: print("Backlight ON.") @@ -41,3 +43,5 @@ while upiwin.get_message(msg): log_touch('MOVE', msg['attrs'][0], msg['attrs'][1]) elif msg['message'] == upiwin.WM_TOUCHUP: log_touch('UP', msg['attrs'][0], msg['attrs'][1]) + elif msg['message'] == upiwin.WM_TOUCHCLICK: + log_touch('CLICK', msg['attrs'][0], msg['attrs'][1]) diff --git a/src/config.c b/src/config.c index cc2b67f..7f5dfe7 100644 --- a/src/config.c +++ b/src/config.c @@ -70,6 +70,8 @@ static void init_defaults(void) Gconfig.python_loc = "/usr/bin/python3"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; + Gconfig.click_time = 200; + Gconfig.click_radius = 2; } static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) diff --git a/src/config.h b/src/config.h index 0a514a7..22253ac 100644 --- a/src/config.h +++ b/src/config.h @@ -12,6 +12,8 @@ typedef struct tagGLOBAL_CONFIG { PCSTR python_loc; /* location of the Python3 executable */ UINT32 button_debounce; /* minimum time between button up and next button down (ms) */ UINT32 sys_mq_length; /* length of system message queue */ + UINT32 click_time; /* time between button/touch DOWN and UP to be considered a "click" (ms) */ + UINT32 click_radius; /* maximum number of pixels a touch can "drift" to be considered a "click" */ PCSTR script_name; /* script name to be run */ INT32 script_arg_count; /* number of arguments to pass to the script */ PPCSTR script_args; /* arguments to pass to the script */ diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index a8e33e9..1354d06 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -44,9 +44,11 @@ BEGIN_CONSTANT_TABLE(UPIWINConstants) CONSTANT_INT_MACRO(WM_QUIT) CONSTANT_INT_MACRO(WM_HWBUTTONDOWN) CONSTANT_INT_MACRO(WM_HWBUTTONUP) + CONSTANT_INT_MACRO(WM_HWBUTTONCLICK) CONSTANT_INT_MACRO(WM_TOUCHDOWN) CONSTANT_INT_MACRO(WM_TOUCHMOVE) CONSTANT_INT_MACRO(WM_TOUCHUP) + CONSTANT_INT_MACRO(WM_TOUCHCLICK) /* Raster op constants */ CONSTANT_INT_MACRO(R2_BLACK) CONSTANT_INT_MACRO(R2_NOTMERGEPEN) diff --git a/src/msg.h b/src/msg.h index 7778bde..afff6a9 100644 --- a/src/msg.h +++ b/src/msg.h @@ -17,9 +17,11 @@ typedef struct tagMSG { #define WM_HWBUTTONDOWN 0x0020 #define WM_HWBUTTONUP 0x0021 +#define WM_HWBUTTONCLICK 0x0022 #define WM_TOUCHDOWN 0x0030 #define WM_TOUCHMOVE 0x0031 #define WM_TOUCHUP 0x0032 +#define WM_TOUCHCLICK 0x0033 #endif /* __MSG_H_INCLUDED */ diff --git a/src/sysinput.c b/src/sysinput.c index 44335bd..9419d5d 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -28,11 +28,14 @@ static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER; /* condition for /* Local data for poll_buttons() */ static UINT32 last_bstate = 0; /* previous button state */ static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */ +static TIMESTAMP button_down_time[GPIO_BUTTON_COUNT]; /* timestamps for click detection */ /* Local data for poll_touchscreen() */ static UINT_PTR touch_x = 0; /* X coordinate to send with next message */ static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */ static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */ +static UINT_PTR touch_down_x, touch_down_y; /* location of the touch-down event for click detection */ +static TIMESTAMP touch_down_time; /* timestamp for click detection */ static BOOL poll_buttons(void) { @@ -57,11 +60,14 @@ static BOOL poll_buttons(void) /* reset contact bounce timer - only seems to happen after button releases */ button_event_ok[attr - 1] = now + Gconfig.button_debounce; Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + if ((now - button_down_time[attr - 1]) <= Gconfig.click_time) + Mq_post1(Sys_Queue, 0, WM_HWBUTTONCLICK, attr); posted = TRUE; } else if (down & mask) { Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + button_down_time[attr - 1] = now; posted = TRUE; } } @@ -74,6 +80,7 @@ static BOOL poll_touchscreen(void) { BOOL posted = FALSE; int nb, nev, xerrno, i; + TIMESTAMP now; struct input_event buffer[INPUT_EVENT_BATCH]; nb = read(ts_fd, buffer, INPUT_EVENT_BATCH * sizeof(struct input_event)); @@ -102,7 +109,21 @@ static BOOL poll_touchscreen(void) case EV_SYN: if (buffer[i].code == SYN_REPORT) { + now = Time_since_start(); Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); + if (touch_nextmsg == WM_TOUCHDOWN) + { + touch_down_x = touch_x; + touch_down_y = touch_y; + touch_down_time = now; + } + else if (touch_nextmsg = WM_TOUCHUP) + { + if ( ((now - touch_down_time) <= Gconfig.click_time) + && (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius) + && (ABS((INT32)touch_y - (INT32)touch_down_y) <= Gconfig.click_radius)) + Mq_post2(Sys_Queue, 0, WM_TOUCHCLICK, touch_x, touch_y); + } touch_nextmsg = WM_TOUCHMOVE; posted = TRUE; }