⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 input.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  ReactOS W32 Subsystem
 *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/* $Id: input.c 27952 2007-07-28 17:16:51Z weiden $
 *
 * COPYRIGHT:        See COPYING in the top level directory
 * PROJECT:          ReactOS kernel
 * PURPOSE:          Window classes
 * FILE:             subsys/win32k/ntuser/class.c
 * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
 * REVISION HISTORY:
 *       06-06-2001  CSH  Created
 */

/* INCLUDES ******************************************************************/

#include <w32k.h>
#include <ntddkbd.h>

#define NDEBUG
#include <debug.h>

extern BYTE gQueueKeyStateTable[];

/* GLOBALS *******************************************************************/


static HANDLE MouseDeviceHandle;
static HANDLE MouseThreadHandle;
static CLIENT_ID MouseThreadId;
static HANDLE KeyboardThreadHandle;
static CLIENT_ID KeyboardThreadId;
static HANDLE KeyboardDeviceHandle;
static KEVENT InputThreadsStart;
static BOOLEAN InputThreadsRunning = FALSE;

/* FUNCTIONS *****************************************************************/
ULONG FASTCALL
IntSystemParametersInfo(UINT uiAction, UINT uiParam,PVOID pvParam, UINT fWinIni);
DWORD IntLastInputTick(BOOL LastInputTickSetGet);

#define ClearMouseInput(mi) \
  mi.dx = 0; \
  mi.dy = 0; \
  mi.mouseData = 0; \
  mi.dwFlags = 0;

#define SendMouseEvent(mi) \
  if(mi.dx != 0 || mi.dy != 0) \
    mi.dwFlags |= MOUSEEVENTF_MOVE; \
  if(mi.dwFlags) \
    IntMouseInput(&mi); \
  ClearMouseInput(mi);


DWORD IntLastInputTick(BOOL LastInputTickSetGet)
{
	static DWORD LastInputTick = 0;
	if (LastInputTickSetGet == TRUE)
	{
		LARGE_INTEGER TickCount;
        KeQueryTickCount(&TickCount);
        LastInputTick = TickCount.u.LowPart * (KeQueryTimeIncrement() / 10000);
	}
    return LastInputTick;
}

BOOL
STDCALL
NtUserGetLastInputInfo(PLASTINPUTINFO plii)
{
    BOOL ret = TRUE;
    
    UserEnterShared();
    
    _SEH_TRY
    {
        if (ProbeForReadUint(&plii->cbSize) != sizeof(LASTINPUTINFO))
        {
            SetLastWin32Error(ERROR_INVALID_PARAMETER);
            ret = FALSE;
            _SEH_LEAVE; 
        }

        ProbeForWrite(plii, sizeof(LASTINPUTINFO), sizeof(DWORD));
        
        plii->dwTime = IntLastInputTick(FALSE);
    }
    _SEH_HANDLE
    {
        SetLastNtError(_SEH_GetExceptionCode());
        ret = FALSE;
    }
    _SEH_END;
   
    UserLeave(); 
    
    return ret;
}


VOID FASTCALL
ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
{
   PMOUSE_INPUT_DATA mid;
   MOUSEINPUT mi;
   ULONG i;

   ClearMouseInput(mi);
   mi.time = 0;
   mi.dwExtraInfo = 0;
   for(i = 0; i < InputCount; i++)
   {
      mid = (Data + i);
      mi.dx += mid->LastX;
      mi.dy += mid->LastY;

      if(mid->ButtonFlags)
      {
         if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
         {
            mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
         {
            mi.dwFlags |= MOUSEEVENTF_LEFTUP;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
         {
            mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
         {
            mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
         {
            mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
         {
            mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
         {
            mi.mouseData |= XBUTTON1;
            mi.dwFlags |= MOUSEEVENTF_XDOWN;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
         {
            mi.mouseData |= XBUTTON1;
            mi.dwFlags |= MOUSEEVENTF_XUP;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
         {
            mi.mouseData |= XBUTTON2;
            mi.dwFlags |= MOUSEEVENTF_XDOWN;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
         {
            mi.mouseData |= XBUTTON2;
            mi.dwFlags |= MOUSEEVENTF_XUP;
            SendMouseEvent(mi);
         }
         if(mid->ButtonFlags & MOUSE_WHEEL)
         {
            mi.mouseData = mid->ButtonData;
            mi.dwFlags |= MOUSEEVENTF_WHEEL;
            SendMouseEvent(mi);
         }
      }
   }

   SendMouseEvent(mi);
}




VOID STDCALL
MouseThreadMain(PVOID StartContext)
{
   UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
   OBJECT_ATTRIBUTES MouseObjectAttributes;
   IO_STATUS_BLOCK Iosb;
   NTSTATUS Status;

   InitializeObjectAttributes(&MouseObjectAttributes,
                              &MouseDeviceName,
                              0,
                              NULL,
                              NULL);
   do
   {
      LARGE_INTEGER DueTime;
      KEVENT Event;
      DueTime.QuadPart = (LONGLONG)(-10000000);
      KeInitializeEvent(&Event, NotificationEvent, FALSE);
      Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
      Status = NtOpenFile(&MouseDeviceHandle,
                       FILE_ALL_ACCESS,
                       &MouseObjectAttributes,
                       &Iosb,
                       0,
                       FILE_SYNCHRONOUS_IO_ALERT);
   } while (!NT_SUCCESS(Status));

   KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
                       LOW_REALTIME_PRIORITY + 3);

   for(;;)
   {
      /*
       * Wait to start input.
       */
      DPRINT("Mouse Input Thread Waiting for start event\n");
      Status = KeWaitForSingleObject(&InputThreadsStart,
                                     0,
                                     KernelMode,
                                     TRUE,
                                     NULL);
      DPRINT("Mouse Input Thread Starting...\n");

      /*
       * Receive and process mouse input.
       */
      while(InputThreadsRunning)
      {
         MOUSE_INPUT_DATA MouseInput;
         Status = NtReadFile(MouseDeviceHandle,
                             NULL,
                             NULL,
                             NULL,
                             &Iosb,
                             &MouseInput,
                             sizeof(MOUSE_INPUT_DATA),
                             NULL,
                             NULL);
         if(Status == STATUS_ALERTED && !InputThreadsRunning)
         {
            break;
         }
         if(Status == STATUS_PENDING)
         {
            NtWaitForSingleObject(MouseDeviceHandle, FALSE, NULL);
            Status = Iosb.Status;
         }
         if(!NT_SUCCESS(Status))
         {
            DPRINT1("Win32K: Failed to read from mouse.\n");
            return; //(Status);
         }
         DPRINT("MouseEvent\n");         
		 IntLastInputTick(TRUE);

         UserEnterExclusive();

         ProcessMouseInputData(&MouseInput, Iosb.Information / sizeof(MOUSE_INPUT_DATA));

         UserLeave();
      }
      DPRINT("Mouse Input Thread Stopped...\n");
   }
}

/* Returns a value that indicates if the key is a modifier key, and
 * which one.
 */
static UINT STDCALL
IntKeyboardGetModifiers(KEYBOARD_INPUT_DATA *InputData)
{
   if (InputData->Flags & KEY_E1)
      return 0;

   if (!(InputData->Flags & KEY_E0))
   {
      switch (InputData->MakeCode)
      {
         case 0x2a: /* left shift */
         case 0x36: /* right shift */
            return MOD_SHIFT;

         case 0x1d: /* left control */
            return MOD_CONTROL;

         case 0x38: /* left alt */
            return MOD_ALT;

         default:
            return 0;
      }
   }
   else
   {
      switch (InputData->MakeCode)
      {
         case 0x1d: /* right control */
            return MOD_CONTROL;

         case 0x38: /* right alt */
            return MOD_ALT;

         case 0x5b: /* left gui (windows) */
         case 0x5c: /* right gui (windows) */
            return MOD_WIN;

         default:
            return 0;
      }
   }
}

/* Asks the keyboard driver to send a small table that shows which
 * lights should connect with which scancodes
 */
static NTSTATUS STDCALL
IntKeyboardGetIndicatorTrans(HANDLE KeyboardDeviceHandle,
                             PKEYBOARD_INDICATOR_TRANSLATION *IndicatorTrans)
{
   NTSTATUS Status;
   DWORD Size = 0;
   IO_STATUS_BLOCK Block;
   PKEYBOARD_INDICATOR_TRANSLATION Ret;

   Size = sizeof(KEYBOARD_INDICATOR_TRANSLATION);

   Ret = ExAllocatePoolWithTag(PagedPool,
                               Size,
                               TAG_KEYBOARD);

   while (Ret)
   {
      Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
                                     NULL,
                                     NULL,
                                     NULL,
                                     &Block,
                                     IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION,
                                     NULL, 0,
                                     Ret, Size);

      if (Status != STATUS_BUFFER_TOO_SMALL)
         break;

      ExFreePool(Ret);

      Size += sizeof(KEYBOARD_INDICATOR_TRANSLATION);

      Ret = ExAllocatePoolWithTag(PagedPool,
                                  Size,
                                  TAG_KEYBOARD);
   }

   if (!Ret)
      return STATUS_INSUFFICIENT_RESOURCES;

   if (Status != STATUS_SUCCESS)
   {
      ExFreePool(Ret);
      return Status;
   }

   *IndicatorTrans = Ret;
   return Status;
}

/* Sends the keyboard commands to turn on/off the lights.
 */
static NTSTATUS STDCALL
IntKeyboardUpdateLeds(HANDLE KeyboardDeviceHandle,
                      PKEYBOARD_INPUT_DATA KeyInput,
                      PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans)
{
   NTSTATUS Status;
   UINT Count;
   static KEYBOARD_INDICATOR_PARAMETERS Indicators;
   IO_STATUS_BLOCK Block;

   if (!IndicatorTrans)
      return STATUS_NOT_SUPPORTED;

   if (KeyInput->Flags & (KEY_E0 | KEY_E1 | KEY_BREAK))
      return STATUS_SUCCESS;

   for (Count = 0; Count < IndicatorTrans->NumberOfIndicatorKeys; Count++)
   {
      if (KeyInput->MakeCode == IndicatorTrans->IndicatorList[Count].MakeCode)
      {
         Indicators.LedFlags ^=
            IndicatorTrans->IndicatorList[Count].IndicatorFlags;

         /* Update the lights on the hardware */

         Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
                                        NULL,
                                        NULL,
                                        NULL,
                                        &Block,
                                        IOCTL_KEYBOARD_SET_INDICATORS,
                                        &Indicators, sizeof(Indicators),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -