Implemented full mouse support for mac client.
authorArmin Novak <armin.novak@thincast.com>
Thu, 10 Jan 2019 10:09:57 +0000 (11:09 +0100)
committerArmin Novak <armin.novak@thincast.com>
Thu, 10 Jan 2019 10:30:36 +0000 (11:30 +0100)
client/Mac/MRDPView.m
client/Mac/mf_client.h
client/Mac/mf_client.m

index 468dd2a..048fef2 100644 (file)
@@ -330,8 +330,7 @@ DWORD WINAPI mac_client_thread(void* param)
        NSPoint loc = [event locationInWindow];
        int x = (int) loc.x;
        int y = (int) loc.y;
-       mf_scale_mouse_event(context, instance->input,
-                            PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y);
+       mf_press_mouse_button(context, instance->input, 0, x, y, TRUE);
 }
 
 - (void) mouseUp:(NSEvent*) event
@@ -344,7 +343,7 @@ DWORD WINAPI mac_client_thread(void* param)
        NSPoint loc = [event locationInWindow];
        int x = (int) loc.x;
        int y = (int) loc.y;
-       mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON1, x, y);
+       mf_press_mouse_button(context, instance->input, 0, x, y, FALSE);
 }
 
 - (void) rightMouseDown:(NSEvent*)event
@@ -357,8 +356,7 @@ DWORD WINAPI mac_client_thread(void* param)
        NSPoint loc = [event locationInWindow];
        int x = (int) loc.x;
        int y = (int) loc.y;
-       mf_scale_mouse_event(context, instance->input,
-                            PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y);
+       mf_press_mouse_button(context, instance->input, 1, x, y, TRUE);
 }
 
 - (void) rightMouseUp:(NSEvent*)event
@@ -371,7 +369,7 @@ DWORD WINAPI mac_client_thread(void* param)
        NSPoint loc = [event locationInWindow];
        int x = (int) loc.x;
        int y = (int) loc.y;
-       mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON2, x, y);
+       mf_press_mouse_button(context, instance->input, 1, x, y, FALSE);
 }
 
 - (void) otherMouseDown:(NSEvent*)event
@@ -384,8 +382,8 @@ DWORD WINAPI mac_client_thread(void* param)
        NSPoint loc = [event locationInWindow];
        int x = (int) loc.x;
        int y = (int) loc.y;
-       mf_scale_mouse_event(context, instance->input,
-                            PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y);
+       int pressed = [event buttonNumber];
+       mf_press_mouse_button(context, instance->input, pressed, x, y, TRUE);
 }
 
 - (void) otherMouseUp:(NSEvent*)event
@@ -398,7 +396,8 @@ DWORD WINAPI mac_client_thread(void* param)
        NSPoint loc = [event locationInWindow];
        int x = (int) loc.x;
        int y = (int) loc.y;
-       mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON3, x, y);
+       int pressed = [event buttonNumber];
+       mf_press_mouse_button(context, instance->input, pressed, x, y, FALSE);
 }
 
 - (void) scrollWheel:(NSEvent*)event
@@ -412,17 +411,37 @@ DWORD WINAPI mac_client_thread(void* param)
        NSPoint loc = [event locationInWindow];
        int x = (int) loc.x;
        int y = (int) loc.y;
-       flags = PTR_FLAGS_WHEEL;
+       float dx = [event deltaX];
+       float dy = [event deltaY];
        /* 1 event = 120 units */
-       int units = [event deltaY] * 120;
+       UINT16 units = 0;
+
+       if (fabsf(dy) > FLT_EPSILON)
+       {
+               flags = PTR_FLAGS_WHEEL;
+               units = fabsf(dy) * 120;
+
+               if (dy < 0)
+                       flags |= PTR_FLAGS_WHEEL_NEGATIVE;
+       }
+       else if (fabsf(dx) > FLT_EPSILON)
+       {
+               flags = PTR_FLAGS_HWHEEL;
+               units = fabsf(dx) * 120;
+
+               if (dx > 0)
+                       flags |= PTR_FLAGS_WHEEL_NEGATIVE;
+       }
+       else
+               return;
 
        /* send out all accumulated rotations */
        while (units != 0)
        {
                /* limit to maximum value in WheelRotationMask (9bit signed value) */
-               int step = MIN(MAX(-256, units), 255);
+               const UINT16 step = units & WheelRotationMask;
                mf_scale_mouse_event(context, instance->input,
-                                    flags | ((UINT16)step & WheelRotationMask), x, y);
+                                    flags | step, 0, 0);
                units -= step;
        }
 }
index 79712cc..4d8b2fa 100644 (file)
 extern "C" {
 #endif
 
-FREERDP_API void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
+FREERDP_API void mf_press_mouse_button(void* context, rdpInput* intput, int button, int x, int y,
+                                       BOOL down);
+FREERDP_API void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags, UINT16 x,
+                                      UINT16 y);
+FREERDP_API void mf_scale_mouse_event_ex(void* context, rdpInput* input, UINT16 flags, UINT16 x,
+        UINT16 y);
 
 /**
  * Client Interface
index 455231b..727345b 100644 (file)
@@ -143,6 +143,80 @@ void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags,
        }
 }
 
+void mf_scale_mouse_event_ex(void* context, rdpInput* input, UINT16 flags,
+                             UINT16 x, UINT16 y)
+{
+       mfContext* mfc = (mfContext*) context;
+       MRDPView* view = (MRDPView*) mfc->view;
+       int ww, wh, dw, dh;
+       ww = mfc->client_width;
+       wh = mfc->client_height;
+       dw = mfc->context.settings->DesktopWidth;
+       dh = mfc->context.settings->DesktopHeight;
+       // Convert to windows coordinates
+       y = [view frame].size.height - y;
+
+       if (!mfc->context.settings->SmartSizing || ((ww == dw) && (wh == dh)))
+       {
+               y = y + mfc->yCurrentScroll;
+
+               if (wh != dh)
+               {
+                       y -= (dh - wh);
+               }
+
+               freerdp_input_send_extended_mouse_event(input, flags, x + mfc->xCurrentScroll, y);
+       }
+       else
+       {
+               y = y * dh / wh + mfc->yCurrentScroll;
+               freerdp_input_send_extended_mouse_event(input, flags, x * dw / ww + mfc->xCurrentScroll, y);
+       }
+}
+
+void mf_press_mouse_button(void* context, rdpInput* input, int button, int x, int y, BOOL down)
+{
+       UINT16 flags = 0;
+       UINT16 xflags = 0;
+
+       if (down)
+       {
+               flags |= PTR_FLAGS_DOWN;
+               xflags |= PTR_XFLAGS_DOWN;
+       }
+
+       switch (button)
+       {
+               case 0:
+                       mf_scale_mouse_event(context, input,
+                                            flags | PTR_FLAGS_BUTTON1, x, y);
+                       break;
+
+               case 1:
+                       mf_scale_mouse_event(context, input,
+                                            flags | PTR_FLAGS_BUTTON2, x, y);
+                       break;
+
+               case 2:
+                       mf_scale_mouse_event(context, input,
+                                            flags | PTR_FLAGS_BUTTON3, x, y);
+                       break;
+
+               case 3:
+                       mf_scale_mouse_event_ex(context, input,
+                                               xflags | PTR_XFLAGS_BUTTON1, x, y);
+                       break;
+
+               case 4:
+                       mf_scale_mouse_event_ex(context, input,
+                                               xflags | PTR_XFLAGS_BUTTON2, x, y);
+                       break;
+
+               default:
+                       break;
+       }
+}
+
 int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
 {
        pEntryPoints->Version = 1;