diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 0c164106f..1221cec4e 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 65291ac8c..2948693dc 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 d59ae1ebf..b90ac095b 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);