Esempio n. 1
0
 public virtual void Dispatch(MouseInput e)
 {
 }
Esempio n. 2
0
        private void MouseInputHook_MouseInputReceived(object sender, MouseInput e)
        {
            #region Mouse 'Button State' Tracking

            ButtonState mouseButtonInfo = null;
            if (Mouse_Buttons.TryGetValue(e.WM, out mouseButtonInfo))
            {
                var dateTimeNow = DateTime.Now;
                switch (e.WM)
                {
                    case WinAPI.WM.MOUSEMOVE:
                        if (mouseButtonInfo.IsDown && MuboxConfigSection.Default.Profiles.ActiveProfile.EnableMousePanningFix)
                        {
                            if ((int)e.Point.X != mouseButtonInfo.ClickX || (int)e.Point.Y != mouseButtonInfo.ClickY)
                            {
                                // TODO: screen bounds code may be incorrect for multimon, not properly tested
                                var drawingPoint = new System.Drawing.Point(mouseButtonInfo.ClickX, mouseButtonInfo.ClickY);
                                var screen = System.Windows.Forms.Screen.FromPoint(drawingPoint);
                                var x = (ushort)Math.Ceiling((double)(mouseButtonInfo.ClickX) * (65536.0 / (double)screen.Bounds.Width));
                                var y = (ushort)Math.Ceiling((double)(mouseButtonInfo.ClickY) * (65536.0 / (double)screen.Bounds.Height));
                                var mouseinput = new Mubox.WinAPI.SendInputApi.INPUT
                                {
                                    InputType = WinAPI.SendInputApi.InputType.INPUT_MOUSE,
                                    mi = new WinAPI.SendInputApi.MOUSEINPUT
                                    {
                                        dwExtraInfo = WinAPI.SendInputApi.GetMessageExtraInfo(),
                                        dx = x,
                                        dy = y,
                                        Flags = WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_MOVE | WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_ABSOLUTE,
                                        mouseData = 0,
                                        time = e.Time + 1,
                                    },
                                };
                                WinAPI.SendInputApi.SendInput(1, new Mubox.WinAPI.SendInputApi.INPUT[]
                                {
                                    mouseinput,
                                }, Marshal.SizeOf(mouseinput));
                                e.Handled = true;
                            }
                            else
                            {
                                e.Handled = true;
                            }
                            return;
                        }
                        break;

                    case WinAPI.WM.LBUTTONDOWN:
                    case WinAPI.WM.RBUTTONDOWN:
                    case WinAPI.WM.MBUTTONDOWN:
                    case WinAPI.WM.XBUTTONDOWN:
                        if (!mouseButtonInfo.IsDown)
                        {
                            mouseButtonInfo.ClickX = (int)e.Point.X;
                            mouseButtonInfo.ClickY = (int)e.Point.Y;
                            mouseButtonInfo.IsClick = false;
                            mouseButtonInfo.IsDoubleClick =
                                // within buffer timestamp for a second down/up transition to be interpretted as a double-click
                                (DateTime.Now.Ticks <= mouseButtonInfo.LastClickTimestamp.AddMilliseconds(Mubox.Configuration.MuboxConfigSection.Default.ClickBufferMilliseconds).Ticks)
                                // and last click event was not also a double-click event
                                && mouseButtonInfo.LastDoubleClickTimestamp != mouseButtonInfo.LastClickTimestamp;
                            if (mouseButtonInfo.IsDoubleClick)
                            {
                                // translate message
                                switch (e.WM)
                                {
                                    case WinAPI.WM.LBUTTONDOWN:
                                        e.WM = WinAPI.WM.LBUTTONDBLCLK;
                                        break;

                                    case WinAPI.WM.RBUTTONDOWN:
                                        e.WM = WinAPI.WM.RBUTTONDBLCLK;
                                        break;

                                    case WinAPI.WM.MBUTTONDOWN:
                                        e.WM = WinAPI.WM.MBUTTONDBLCLK;
                                        break;

                                    case WinAPI.WM.XBUTTONDOWN:
                                        e.WM = WinAPI.WM.XBUTTONDBLCLK;
                                        break;
                                }
                            }
                            mouseButtonInfo.LastDownTimestamp = dateTimeNow;
                        }
                        break;

                    case WinAPI.WM.LBUTTONDBLCLK:
                    case WinAPI.WM.MBUTTONDBLCLK:
                    case WinAPI.WM.RBUTTONDBLCLK:
                    case WinAPI.WM.XBUTTONDBLCLK:
                        mouseButtonInfo.IsDoubleClick = true;
                        break;

                    case WinAPI.WM.LBUTTONUP:
                    case WinAPI.WM.RBUTTONUP:
                    case WinAPI.WM.MBUTTONUP:
                    case WinAPI.WM.XBUTTONUP:
                        if (mouseButtonInfo.IsDown)
                        {
                            mouseButtonInfo.IsClick =
                                // within buffer timestamp for down/up transition to be interpretted as a 'click' gesture
                                dateTimeNow.Ticks <= mouseButtonInfo.LastDownTimestamp.AddMilliseconds(Mubox.Configuration.MuboxConfigSection.Default.ClickBufferMilliseconds).Ticks;
                            if (mouseButtonInfo.IsClick)
                            {
                                if (mouseButtonInfo.IsDoubleClick)
                                {
                                    mouseButtonInfo.IsDoubleClick = false;
                                    mouseButtonInfo.LastDoubleClickTimestamp = dateTimeNow;
                                }
                                mouseButtonInfo.IsClick = false;
                                mouseButtonInfo.LastClickTimestamp = dateTimeNow;
                            }
                            mouseButtonInfo.LastUpTimestamp = dateTimeNow;
                        }
                        break;
                }
                e.IsClickEvent = mouseButtonInfo.IsClick;
                e.IsDoubleClickEvent = mouseButtonInfo.IsDoubleClick;
            }

            #endregion Mouse 'Button State' Tracking

            if (!Mubox.Configuration.MuboxConfigSection.Default.EnableMouseCapture)
            {
                e.Handled = false;
                return;
            }

            Mubox.Extensions.ExtensionManager.Instance.OnMouseInputReceived(sender, e);

            ClientBase activeClient = ActiveClient;

            #region Mouse_RelativeMovement

            // one-time init
            if (e.WM == WinAPI.WM.MOUSEMOVE)
            {
                if (this.Mouse_RelativeMovement_LastX == double.MinValue)
                {
                    this.Mouse_RelativeMovement_LastX = e.Point.X;
                    this.Mouse_RelativeMovement_LastY = e.Point.Y;
                    return;
                }

                // update for resolution changes every XX seconds
                if ((DateTime.Now.Ticks - Mouse_AbsoluteMovement_Screen_Resolution_UpdateTimestampTicks) > TimeSpan.FromSeconds(15).Ticks)
                {
                    Mouse_Screen_OnResolutionChanged();
                    return;
                }
            }

            var shouldMulticastMouse = ShouldMulticastMouse(e);

            // track relative movement
            // TODO: except when the mouse moves TO the center of the screen or center of client area, some games do this to implement view pan
            // TODO: except when the mouse moves FROM the center of the screen, somce games do this to implement view pan
            int relX = (int)e.Point.X;
            int relY = (int)e.Point.Y;

            if (e.WM == WinAPI.WM.MOUSEMOVE)
            {
                relX -= (int)this.Mouse_RelativeMovement_LastX;
                relY -= (int)this.Mouse_RelativeMovement_LastY;

                this.Mouse_RelativeMovement_LastX += relX;
                if (this.Mouse_RelativeMovement_LastX <= 0)
                {
                    this.Mouse_RelativeMovement_LastX = 0;
                }
                else if (this.Mouse_RelativeMovement_LastX >= Mouse_AbsoluteMovement_Screen_ResolutionX)
                {
                    this.Mouse_RelativeMovement_LastX = Mouse_AbsoluteMovement_Screen_ResolutionX;
                }

                this.Mouse_RelativeMovement_LastY += relY;
                if (this.Mouse_RelativeMovement_LastY <= 0)
                {
                    this.Mouse_RelativeMovement_LastY = 0;
                }
                else if (this.Mouse_RelativeMovement_LastY >= Mouse_AbsoluteMovement_Screen_ResolutionY)
                {
                    this.Mouse_RelativeMovement_LastY = Mouse_AbsoluteMovement_Screen_ResolutionY;
                }
            }

            #endregion Mouse_RelativeMovement

            // send to client
            if (Mubox.Configuration.MuboxConfigSection.Default.IsCaptureEnabled && (activeClient != null))
            {
                //if (!shouldMulticastMouse)
                //{
                //    e.Handled = !(activeClient.IsLocalAddress && (e.WM == Win32.WM.MOUSEMOVE));
                //    if (!activeClient.IsLocalAddress || e.WM != Win32.WM.MOUSEMOVE)
                //    {
                //        e.Point = new Point(relX, relY);
                //        e.WindowStationHandle = activeClient.WindowStationHandle;
                //        e.WindowHandle = activeClient.WindowHandle;
                //        activeClient.Dispatch(e);
                //    }
                //}
                //else
                {
                    e.Handled = (e.WM != WinAPI.WM.MOUSEMOVE);

                    var clients = shouldMulticastMouse
                        ? GetCachedClients()
                        : new[] { activeClient };

                    if (e.WM == WinAPI.WM.MOUSEMOVE)
                    {
                        // track mouse position
                        TrackMousePositionClientRelative(e, activeClient, clients);

                        // in the case of the 'active, local' client it is presumed that the mouse is correctly interacting with said client and thus is removed from the list of target clients, otherwise the client may be receiving double the number of mousemove events
                        if (clients.Length > 0)
                        {
                            if (mouseButtonInfo.IsDown && MuboxConfigSection.Default.Profiles.ActiveProfile.EnableMousePanningFix)
                            {
                                clients = clients.Where(c => c.ClientId != activeClient.ClientId)
                                .ToArray();
                            }
                        }
                    }

                    foreach (ClientBase client in clients)
                    {
                        ForwardMouseEvent(e, client);
                    }
                }
            }
        }
Esempio n. 3
0
        private void Process(MouseInput mouseInput)
        {
            // denormalize coordinates into client coordinates (we should always expect normalized coordinates, whether coordinates are absolute or relative)
            ushort x = (ushort)Math.Ceiling((double)(mouseInput.Point.X) * ((double)ClientWindowRect.Width / 65536.0));
            ushort y = (ushort)Math.Ceiling((double)(mouseInput.Point.Y) * ((double)ClientWindowRect.Height / 65536.0));

            var clientRelativeCoordinates = WinAPI.MACROS.MAKELPARAM(x, y);

            var wm = WinAPI.WM.USER;

            switch ((mouseInput.Flags | WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_ABSOLUTE) ^ WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_ABSOLUTE)
            {
                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_MOVE:
                    wm = WinAPI.WM.MOUSEMOVE;
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_LEFTDOWN:
                    //WinAPI.Cursor.SetCapture(ClientWindowHandle);
                    wm = WinAPI.WM.LBUTTONDOWN;
                    CurrentMK |= WinAPI.Windows.MK.MK_LBUTTON;
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_LEFTUP:
                    //var priorCapture = WinAPI.Cursor.GetCapture();
                    //if (priorCapture == IntPtr.Zero)
                    //{
                    //    ("GetCapture Fail").LogWarn();
                    //}
                    //else
                    //{
                    //    WinAPI.Cursor.ReleaseCapture();
                    //}
                    wm = WinAPI.WM.LBUTTONUP;
                    CurrentMK = (CurrentMK | WinAPI.Windows.MK.MK_LBUTTON) ^ WinAPI.Windows.MK.MK_LBUTTON;
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_RIGHTDOWN:
                    //WinAPI.Cursor.SetCapture(ClientWindowHandle);
                    wm = WinAPI.WM.RBUTTONDOWN;
                    CurrentMK |= WinAPI.Windows.MK.MK_RBUTTON;
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_RIGHTUP:
                    //var priorCapture = WinAPI.Cursor.GetCapture();
                    //if (priorCapture == IntPtr.Zero)
                    //{
                    //    ("GetCapture Fail").LogWarn();
                    //}
                    //else
                    //{
                    //    WinAPI.Cursor.ReleaseCapture();
                    //}
                    wm = WinAPI.WM.RBUTTONUP;
                    CurrentMK = (CurrentMK | WinAPI.Windows.MK.MK_RBUTTON) ^ WinAPI.Windows.MK.MK_RBUTTON;
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN:
                    wm = WinAPI.WM.MBUTTONDOWN;
                    CurrentMK |= WinAPI.Windows.MK.MK_MBUTTON;
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_MIDDLEUP:
                    wm = WinAPI.WM.MBUTTONUP;
                    CurrentMK = (CurrentMK | WinAPI.Windows.MK.MK_MBUTTON) ^ WinAPI.Windows.MK.MK_MBUTTON;
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_XDOWN:
                    wm = WinAPI.WM.XBUTTONDOWN;
                    switch (WinAPI.MACROS.GET_XBUTTON_WPARAM(mouseInput.MouseData))
                    {
                        case WinAPI.MACROS.XBUTTONS.XBUTTON1:
                            CurrentMK |= WinAPI.Windows.MK.MK_XBUTTON1;
                            break;

                        case WinAPI.MACROS.XBUTTONS.XBUTTON2:
                            CurrentMK |= WinAPI.Windows.MK.MK_XBUTTON2;
                            break;
                    }
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_XUP:
                    wm = WinAPI.WM.XBUTTONUP;
                    switch (WinAPI.MACROS.GET_XBUTTON_WPARAM(mouseInput.MouseData))
                    {
                        case WinAPI.MACROS.XBUTTONS.XBUTTON1:
                            CurrentMK = (CurrentMK | WinAPI.Windows.MK.MK_XBUTTON1) ^ WinAPI.Windows.MK.MK_XBUTTON1;
                            break;

                        case WinAPI.MACROS.XBUTTONS.XBUTTON2:
                            CurrentMK = (CurrentMK | WinAPI.Windows.MK.MK_XBUTTON2) ^ WinAPI.Windows.MK.MK_XBUTTON2;
                            break;
                    }
                    break;

                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_WHEEL:
                case WinAPI.SendInputApi.MouseEventFlags.MOUSEEVENTF_HWHEEL:
                    wm = WinAPI.WM.MOUSEWHEEL;
                    break;

                default:
                    wm = mouseInput.WM;
                    break;
            }

            WinAPI.Windows.PostMessage(ClientWindowHandle, wm, new UIntPtr(mouseInput.MouseData), new UIntPtr(clientRelativeCoordinates));
        }
Esempio n. 4
0
 private void ForwardMouseEvent(MouseInput e, ClientBase clientBase)
 {
     MouseInput L_e = new MouseInput();
     L_e.IsAbsolute = true;
     L_e.MouseData = e.MouseData;
     L_e.Point = L_e_Point;
     L_e.Time = e.Time;
     L_e.WindowDesktopHandle = clientBase.WindowDesktopHandle;
     L_e.WindowStationHandle = clientBase.WindowStationHandle;
     L_e.WindowHandle = clientBase.WindowHandle;
     L_e.WM = e.WM;
     clientBase.Dispatch(L_e);
 }
Esempio n. 5
0
 private static bool ShouldMulticastMouse(MouseInput e)
 {
     return
         (
             ((Mubox.Configuration.MuboxConfigSection.Default.MouseMulticastMode == MouseMulticastModeType.Toggled) && WinAPI.IsToggled(WinAPI.VK.Capital))
             ||
             ((Mubox.Configuration.MuboxConfigSection.Default.MouseMulticastMode == MouseMulticastModeType.Pressed) && WinAPI.IsPressed(WinAPI.VK.Capital))
         );
 }
Esempio n. 6
0
 private static bool IsMouseInClientArea(MouseInput e, WinAPI.Windows.RECT calcRect)
 {
     return (calcRect.Left <= (int)e.Point.X && calcRect.Top <= (int)e.Point.Y) && (calcRect.Right >= (int)e.Point.X && calcRect.Bottom >= (int)e.Point.Y);
 }
Esempio n. 7
0
 private void TrackMousePositionClientRelative(MouseInput e, ClientBase activeClient, ClientBase[] clients)
 {
     ClientBase clientForCoordinateNormalization = activeClient;
     if (clientForCoordinateNormalization == null || !clientForCoordinateNormalization.IsLocalAddress || !IsMouseInClientArea(e, GetScreenRelativeClientRect(clientForCoordinateNormalization)))
     {
         // look for a local client which the mouse coordinates "belong to" and re-assign "clientForCoordinateNormalization"
         clientForCoordinateNormalization = null;
         foreach (var item in clients)
         {
             if (item.IsLocalAddress && IsMouseInClientArea(e, GetScreenRelativeClientRect(item)))
             {
                 clientForCoordinateNormalization = item;
                 break;
             }
         }
     }
     if (clientForCoordinateNormalization != null)
     {
         // track client-relative position
         this.L_e_Point = new Point(
             Math.Ceiling((double)(e.Point.X - clientForCoordinateNormalization.CachedScreenFromClientRect.Left) * (65536.0 / (double)clientForCoordinateNormalization.CachedScreenFromClientRect.Width)),
             Math.Ceiling((double)(e.Point.Y - clientForCoordinateNormalization.CachedScreenFromClientRect.Top) * (65536.0 / (double)clientForCoordinateNormalization.CachedScreenFromClientRect.Height)));
     }
 }
Esempio n. 8
0
 public override void Dispatch(MouseInput e)
 {
     #if DEBUG
     if (e.WM != WinAPI.WM.MOUSEMOVE) // reduce CPU cost of DEBUG logging
     {
         ("Dispatch(" + _displayName + ") " + Convert.ToString(e)).Log();
     }
     #endif
     ServerTxPerformanceIncrement("MOUSE");
     try
     {
         Send(e);
         base.Dispatch(e);
     }
     catch
     {
         Control.Network.Server.RemoveClient(this);
     }
 }