Ejemplo n.º 1
0
/*
 * UserProcessMouseInput
 *
 * Process raw mouse input data
 */
VOID NTAPI
UserProcessMouseInput(PMOUSE_INPUT_DATA mid)
{
    MOUSEINPUT mi;

    /* Convert MOUSE_INPUT_DATA to MOUSEINPUT. First init all fields. */
    mi.dx = mid->LastX;
    mi.dy = mid->LastY;
    mi.mouseData = 0;
    mi.dwFlags = 0;
    mi.time = 0;
    mi.dwExtraInfo = mid->ExtraInformation;

    /* Mouse position */
    if (mi.dx != 0 || mi.dy != 0)
        mi.dwFlags |= MOUSEEVENTF_MOVE;

    /* Flags for absolute move */
    if (mid->Flags & MOUSE_MOVE_ABSOLUTE)
        mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
    if (mid->Flags & MOUSE_VIRTUAL_DESKTOP)
        mi.dwFlags |= MOUSEEVENTF_VIRTUALDESK;

    /* Left button */
    if (mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
        mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
    if (mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
        mi.dwFlags |= MOUSEEVENTF_LEFTUP;

    /* Middle button */
    if (mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
        mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
    if (mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
        mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;

    /* Right button */
    if (mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
        mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
    if (mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
        mi.dwFlags |= MOUSEEVENTF_RIGHTUP;

    /* Note: Next buttons use mouseData field so they cannot be sent in one call */

    /* Button 4 */
    if (mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
    {
        mi.dwFlags |= MOUSEEVENTF_XDOWN;
        mi.mouseData |= XBUTTON1;
    }
    if (mid->ButtonFlags & MOUSE_BUTTON_4_UP)
    {
        mi.dwFlags |= MOUSEEVENTF_XUP;
        mi.mouseData |= XBUTTON1;
    }

    /* If mouseData is used by button 4, send input and clear mi */
    if (mi.dwFlags & (MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_4_UP))
    {
        UserSendMouseInput(&mi, FALSE);
        RtlZeroMemory(&mi, sizeof(mi));
    }

    /* Button 5 */
    if (mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
    {
        mi.mouseData |= XBUTTON2;
        mi.dwFlags |= MOUSEEVENTF_XDOWN;
    }
    if (mid->ButtonFlags & MOUSE_BUTTON_5_UP)
    {
        mi.mouseData |= XBUTTON2;
        mi.dwFlags |= MOUSEEVENTF_XUP;
    }

    /* If mouseData is used by button 5, send input and clear mi */
    if (mi.dwFlags & (MOUSE_BUTTON_5_DOWN | MOUSE_BUTTON_5_UP))
    {
        UserSendMouseInput(&mi, FALSE);
        RtlZeroMemory(&mi, sizeof(mi));
    }

    /* Mouse wheel */
    if (mid->ButtonFlags & MOUSE_WHEEL)
    {
        mi.mouseData = mid->ButtonData;
        mi.dwFlags |= MOUSEEVENTF_WHEEL;
    }

    /* If something has changed, send input to user */
    if (mi.dwFlags)
        UserSendMouseInput(&mi, FALSE);
}
Ejemplo n.º 2
0
HWND FASTCALL
co_UserSetCapture(HWND hWnd)
{
   PTHREADINFO pti;
   PUSER_MESSAGE_QUEUE ThreadQueue;
   PWND pWnd, Window = NULL;
   HWND hWndPrev;

   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;

   if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
      return NULL;

   if (hWnd && (Window = UserGetWindowObject(hWnd)))
   {
      if (Window->head.pti->MessageQueue != ThreadQueue)
      {
         return NULL;
      }
   }

   hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);

   if (hWndPrev)
   {
      pWnd = UserGetWindowObject(hWndPrev);
      if (pWnd)
         IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
   }

   if (Window)
      IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);

   if (hWndPrev && hWndPrev != hWnd)
   {
      if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;

      //co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
      co_IntSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);

      ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
   }

   ThreadQueue->spwndCapture = Window;

   if (hWnd == NULL) // Release mode.
   {
      MOUSEINPUT mi;
   /// These are HACKS!
      /* Also remove other windows if not capturing anymore */
      MsqSetStateWindow(pti, MSQ_STATE_MENUOWNER, NULL);
      MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, NULL);
   ///
      /* Somebody may have missed some mouse movements */
      mi.dx = 0;
      mi.dy = 0;
      mi.mouseData = 0;
      mi.dwFlags = MOUSEEVENTF_MOVE;
      mi.time = 0;
      mi.dwExtraInfo = 0;
      UserSendMouseInput(&mi, FALSE);
   }
   return hWndPrev;
}
Ejemplo n.º 3
0
/*
 * NtUserSendInput
 *
 * Generates input events from software
 */
UINT
APIENTRY
NtUserSendInput(
    UINT nInputs,
    LPINPUT pInput,
    INT cbSize)
{
    PTHREADINFO pti;
    UINT uRet = 0;

    TRACE("Enter NtUserSendInput\n");
    UserEnterExclusive();

    pti = PsGetCurrentThreadWin32Thread();
    ASSERT(pti);

    if (!pti->rpdesk)
    {
        goto cleanup;
    }

    if (!nInputs || !pInput || cbSize != sizeof(INPUT))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        goto cleanup;
    }

    /*
     * FIXME: Check access rights of the window station
     *        e.g. services running in the service window station cannot block input
     */
    if (!ThreadHasInputAccess(pti) ||
        !IntIsActiveDesktop(pti->rpdesk))
    {
        EngSetLastError(ERROR_ACCESS_DENIED);
        goto cleanup;
    }

    while (nInputs--)
    {
        INPUT SafeInput;
        NTSTATUS Status;

        Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
        if (!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            goto cleanup;
        }

        switch (SafeInput.type)
        {
            case INPUT_MOUSE:
                if (UserSendMouseInput(&SafeInput.mi, TRUE))
                    uRet++;
                break;
            case INPUT_KEYBOARD:
                if (UserSendKeyboardInput(&SafeInput.ki, TRUE))
                    uRet++;
                break;
            case INPUT_HARDWARE:
                FIXME("INPUT_HARDWARE not supported!");
                break;
            default:
                ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
                break;
        }
    }

cleanup:
    TRACE("Leave NtUserSendInput, ret=%u\n", uRet);
    UserLeave();
    return uRet;
}