diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 9f1ccdb5..a7fb59c3 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -979,6 +979,33 @@ dump_mouseinput(RdpPeerContext *peerContext, UINT16 flags, UINT16 x, UINT16 y, b rdp_debug_verbose_continue(b, "\n"); } +static void +rdp_validate_button_state(RdpPeerContext *peerContext, bool pressed, uint32_t *button) +{ + struct rdp_backend *b = peerContext->rdpBackend; + uint32_t index; + + if (*button < BTN_LEFT || *button > BTN_EXTRA) { + weston_log("RDP client posted invalid button event\n"); + goto ignore; + } + + index = *button - BTN_LEFT; + assert(index < ARRAY_LENGTH(peerContext->button_state)); + + if (pressed == peerContext->button_state[index]) { + rdp_debug_verbose(b, "%s: inconsistent button state button:%d (index:%d) pressed:%d\n", + __func__, *button, index, pressed); + goto ignore; + } else { + peerContext->button_state[index] = pressed; + } + return; +ignore: + /* ignore button input */ + *button = 0; +} + static BOOL xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) { @@ -1007,6 +1034,12 @@ xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) else if (flags & PTR_FLAGS_BUTTON3) button = BTN_MIDDLE; + if (button) { + rdp_validate_button_state(peerContext, + flags & PTR_FLAGS_DOWN ? true : false, + &button); + } + if (button) { weston_compositor_get_time(&time); notify_button(peerContext->item.seat, &time, button, @@ -1062,6 +1095,12 @@ xf_extendedMouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) else if (flags & PTR_XFLAGS_BUTTON2) button = BTN_EXTRA; + if (button) { + rdp_validate_button_state(peerContext, + flags & PTR_XFLAGS_DOWN ? true : false, + &button); + } + if (button) { weston_compositor_get_time(&time); notify_button(peerContext->item.seat, &time, button, diff --git a/libweston/backend-rdp/rdp.h b/libweston/backend-rdp/rdp.h index 2ebf50f6..31e56d96 100644 --- a/libweston/backend-rdp/rdp.h +++ b/libweston/backend-rdp/rdp.h @@ -109,6 +109,8 @@ struct rdp_peer_context { NSC_CONTEXT *nsc_context; struct rdp_peers_item item; + + bool button_state[5]; }; typedef struct rdp_peer_context RdpPeerContext;