From 6ca89620452fc36b17cf01ed283d3ccf00594e6b Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Mon, 13 Jul 2015 22:59:18 +0200 Subject: [PATCH] Map logical to physical mouse button events RDP expects to receive an indicator of the physical mouse button that was pressed on the client, whereas X11 deliver a value for which logical mouse button that was pressed. This patch introduces a (reverse) mapping from logical mouse buttons to physical mouse buttons, so that the RDP server can do correct mapping for the event on its end. However, no actual mapping is done here; this patch just introduces the framework to do so. Thus, there should be no behavioural change from this patch alone. There is an implicit assumption that only the first three buttons are mapped to eachother. Enabling more a general mapping would require extensive changes to the event handling as fourth logical button and up is used for special functionality such as wheel. --- client/X11/xf_client.c | 41 +++++++++++++++++++++++++++++++++++++++++ client/X11/xf_event.c | 28 ++++++++-------------------- client/X11/xfreerdp.h | 11 +++++++++++ 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 0c16410..1221cec 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -935,6 +935,46 @@ void xf_check_extensions(xfContext* context) #endif } +/* Assignment of physical (not logical) mouse buttons to wire flags. */ +/* Notice that the middle button is 2 in X11, but 3 in RDP. */ +static const int xf_button_flags[NUM_BUTTONS_MAPPED] = { + PTR_FLAGS_BUTTON1, + PTR_FLAGS_BUTTON3, + PTR_FLAGS_BUTTON2 +}; + +static void xf_button_map_init (xfContext* xfc) +{ + /* loop counter for array initialization */ + int physical; + int logical; + + /* logical mouse button which is used for each physical mouse */ + /* button (indexed from zero). This is the default map. */ + unsigned char x11_map[NUM_BUTTONS_MAPPED] = { + Button1, + Button2, + Button3 + }; + + /* iterate over all (mapped) physical buttons; for each of them */ + /* find the logical button in X11, and assign to this the */ + /* appropriate value to send over the RDP wire. */ + for (physical = 0; physical < NUM_BUTTONS_MAPPED; ++physical) + { + logical = x11_map[physical]; + if (Button1 <= logical && logical <= Button3) + { + xfc->button_map[logical-BUTTON_BASE] = xf_button_flags[physical]; + } + else + { + WLog_ERR(TAG,"Mouse physical button %d is mapped to logical button %d", + physical, logical); + } + } +} + /** * Callback given to freerdp_connect() to process the pre-connect operations. * It will fill the rdp_freerdp structure (instance) with the appropriate options to use for the connection. @@ -1058,6 +1098,7 @@ BOOL xf_pre_connect(freerdp* instance) xfc->decorations = settings->Decorations; xfc->grab_keyboard = settings->GrabKeyboard; xfc->fullscreen_toggle = settings->ToggleFullscreen; + xf_button_map_init (xfc); return TRUE; } diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 65291ac..2948693 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -312,16 +312,10 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win switch (button) { - case 1: - flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1; - break; - - case 2: - flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3; - break; - - case 3: - flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2; + case Button1: + case Button2: + case Button3: + flags = PTR_FLAGS_DOWN | xfc->button_map[button-BUTTON_BASE]; break; case 4: @@ -422,16 +416,10 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w switch (button) { - case 1: - flags = PTR_FLAGS_BUTTON1; - break; - - case 2: - flags = PTR_FLAGS_BUTTON3; - break; - - case 3: - flags = PTR_FLAGS_BUTTON2; + case Button1: + case Button2: + case Button3: + flags = xfc->button_map[button-BUTTON_BASE]; break; case 6: diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index d59ae1e..b90ac09 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -79,6 +79,14 @@ typedef struct xf_glyph xfGlyph; typedef struct xf_clipboard xfClipboard; +/* Value of the first logical button number in X11 which must be */ +/* subtracted to go from a button number in X11 to an index into */ +/* a per-button array. */ +#define BUTTON_BASE Button1 + +/* Number of buttons that are mapped from X11 to RDP button events. */ +#define NUM_BUTTONS_MAPPED 3 + struct xf_context { rdpContext context; @@ -228,6 +236,9 @@ struct xf_context BOOL xkbAvailable; BOOL xrenderAvailable; + + /* value to be sent over wire for each logical client mouse button */ + int button_map[NUM_BUTTONS_MAPPED]; }; BOOL xf_create_window(xfContext* xfc); -- 2.7.4