Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ntinput.c File Reference

#include "precomp.h"
#include <ntddmou.h>

Go to the source code of this file.

Classes

struct  _RIT_INIT

Defines

#define UPDATE_KBD_TYPEMATIC   1
#define UPDATE_KBD_LEDS   2
#define MOUSE_BUTTON_LEFT   0x0001
#define MOUSE_BUTTON_RIGHT   0x0002
#define MOUSE_BUTTON_MIDDLE   0x0004
#define MOUSE_BUTTON_X1   0x0008
#define MOUSE_BUTTON_X2   0x0010
#define ID_INPUT   0
#define ID_MOUSE   1
#define ID_TIMER   2
#define ID_HIDCHANGE   3
#define ID_NUMBER_NON_HYDRA_HANDLES   4
#define ID_SHUTDOWN   4
#define ID_WDTIMER   5
#define fAbsoluteMouse(pmei)   (((pmei)->Flags & MOUSE_MOVE_ABSOLUTE) != 0)
#define ConvertToMouseDriverFlags(Flags)
#define VKTOMODIFIERS(Vk)

Typedefs

typedef _RIT_INIT RIT_INIT
typedef _RIT_INITPRIT_INIT

Functions

void ProcessQueuedMouseEvents (void)
VOID RawInputThread (PVOID pVoid)
LONG DoMouseAccel (LONG delta)
VOID GetMouseCoord (LONG dx, LONG dy, DWORD dwFlags, LONG time, ULONG_PTR ExtraInfo, PPOINT ppt)
VOID xxxMoveEventAbsolute (LONG x, LONG y, ULONG_PTR dwExtraInfo, DWORD time, BOOL bInjected)
ULONG MonotonicTick ()
BOOL xxxInitInput (PTERMINAL pTerm)
PSCANCODEMAP InitScancodeMap ()
BOOL MapScancode (PBYTE pbScanCode, PBYTE pbPrefix)
VOID InitMice ()
PDEVICEINFO FreeDeviceInfo (PDEVICEINFO pDeviceInfo)
void UpdateMouseInfo (void)
NTSTATUS DeviceNotify (IN PPLUGPLAY_NOTIFY_HDR, IN PDEVICEINFO)
VOID InitKeyboard (VOID)
HKL GetActiveHKL ()
VOID xxxButtonEvent (DWORD ButtonNumber, POINT ptPointer, BOOL fBreak, DWORD time, ULONG_PTR ExtraInfo, BOOL bInjected, BOOL fDblClk)
VOID QueueMouseEvent (USHORT ButtonFlags, USHORT ButtonData, ULONG_PTR ExtraInfo, POINT ptMouse, LONG time, BOOL bInjected, BOOL bWakeRIT)
BOOL UnqueueMouseEvent (PMOUSEEVENT pme)
VOID xxxDoButtonEvent (PMOUSEEVENT pme)
VOID NTAPI InputApc (IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
VOID ProcessMouseInput (PDEVICEINFO pMouseInfo)
__inline IsHexNumpadKeys (BYTE Vk, WORD wScanCode)
VOID xxxKeyEvent (USHORT usFlaggedVk, WORD wScanCode, DWORD time, ULONG_PTR ExtraInfo, BOOL bInjected)
VOID xxxMoveEvent (LONG dx, LONG dy, DWORD dwFlags, ULONG_PTR dwExtraInfo, DWORD time, BOOL bInjected)
void UpdateRawKeyState (BYTE Vk, BOOL fBreak)
VOID CleanupResources (VOID)
BOOL InitiateWin32kCleanup (VOID)
void RemoteSyncToggleKeys (ULONG toggleKeys)
VOID ProcessKeyboardInput (PDEVICEINFO pDeviceInfo)
VOID xxxProcessKeyEvent (PKE pke, ULONG_PTR ExtraInformation, BOOL bInjected)
PWND PwndForegroundCapture (VOID)
VOID SetKeyboardRate (UINT nKeySpeedAndDelay)
VOID UpdateKeyLights (BOOL bInjected)
int _GetKeyboardType (int nTypeFlag)
VOID xxxMouseEventDirect (DWORD dx, DWORD dy, DWORD mouseData, DWORD dwMEFlags, DWORD dwTime, ULONG_PTR dwExtraInfo)
VOID xxxInternalKeyEventDirect (BYTE bVk, WORD wScan, DWORD dwFlags, DWORD dwTime, ULONG_PTR dwExtraInfo)
BOOL _BlockInput (BOOL fBlockIt)
UINT xxxSendInput (UINT nInputs, LPINPUT pInputs)
BOOL _SetConsoleReserveKeys (PWND pwnd, DWORD fsReserveKeys)
int _GetMouseMovePointsEx (CONST MOUSEMOVEPOINT *ppt, MOUSEMOVEPOINT *ccxpptBuf, UINT nPoints, DWORD resolution)
VOID RawInputThread (PRIT_INIT pInitData)

Variables

PKWAIT_BLOCK gWaitBlockArray
KEYBOARD_UNIT_ID_PARAMETER kuid
MOUSE_UNIT_ID_PARAMETER muid
INT idxRemainder
INT idyRemainder
ULONG gMouseProcessMiceInputTime = 0
ULONG gMouseQueueMouseEventTime = 0
ULONG gMouseUnqueueMouseEventTime = 0
PKTIMER gptmrWD
PVOID * apObjects


Define Documentation

#define ConvertToMouseDriverFlags Flags   ) 
 

Value:

(((Flags) & MOUSEEVENTF_ABSOLUTE) >> 15 | \ ((Flags) & MOUSEEVENTF_VIRTUALDESK) >> 13)

Definition at line 118 of file ntinput.c.

Referenced by xxxMoveEvent().

#define fAbsoluteMouse pmei   )     (((pmei)->Flags & MOUSE_MOVE_ABSOLUTE) != 0)
 

Definition at line 100 of file ntinput.c.

Referenced by ProcessMouseInput().

#define ID_HIDCHANGE   3
 

Definition at line 77 of file ntinput.c.

Referenced by RawInputThread().

#define ID_INPUT   0
 

Definition at line 73 of file ntinput.c.

Referenced by RawInputThread().

#define ID_MOUSE   1
 

Definition at line 74 of file ntinput.c.

Referenced by RawInputThread().

#define ID_NUMBER_NON_HYDRA_HANDLES   4
 

Definition at line 78 of file ntinput.c.

Referenced by RawInputThread().

#define ID_SHUTDOWN   4
 

Definition at line 80 of file ntinput.c.

Referenced by RawInputThread().

#define ID_TIMER   2
 

Definition at line 76 of file ntinput.c.

Referenced by RawInputThread().

#define ID_WDTIMER   5
 

Definition at line 81 of file ntinput.c.

Referenced by RawInputThread().

#define MOUSE_BUTTON_LEFT   0x0001
 

Definition at line 67 of file ntinput.c.

#define MOUSE_BUTTON_MIDDLE   0x0004
 

Definition at line 69 of file ntinput.c.

Referenced by xxxButtonEvent().

#define MOUSE_BUTTON_RIGHT   0x0002
 

Definition at line 68 of file ntinput.c.

#define MOUSE_BUTTON_X1   0x0008
 

Definition at line 70 of file ntinput.c.

Referenced by xxxButtonEvent().

#define MOUSE_BUTTON_X2   0x0010
 

Definition at line 71 of file ntinput.c.

Referenced by xxxButtonEvent().

#define UPDATE_KBD_LEDS   2
 

Definition at line 24 of file ntinput.c.

Referenced by RawInputThread(), and UpdateKeyLights().

#define UPDATE_KBD_TYPEMATIC   1
 

Definition at line 23 of file ntinput.c.

Referenced by RawInputThread(), and SetKeyboardRate().

#define VKTOMODIFIERS Vk   ) 
 

Value:

((((Vk) >= VK_SHIFT) && ((Vk) <= VK_MENU)) ? \ (MOD_SHIFT >> ((Vk) - VK_SHIFT)) : \ 0)

Definition at line 122 of file ntinput.c.

Referenced by xxxKeyEvent().


Typedef Documentation

typedef struct _RIT_INIT * PRIT_INIT
 

typedef struct _RIT_INIT RIT_INIT
 


Function Documentation

BOOL _BlockInput BOOL  fBlockIt  ) 
 

Definition at line 3498 of file ntinput.c.

References tagTHREADINFO::amdesk, tagWINDOWSTATION::dwWSF_Flags, FALSE, gptiBlockInput, grpdeskRitInput, NULL, PtiCurrent, tagTHREADINFO::rpdesk, tagDESKTOP::rpwinstaParent, RtlAreAllAccessesGranted(), tagTHREADINFO::TIF_flags, TIF_INCLEANUP, TRUE, and WSF_NOIO.

Referenced by NtUserBlockInput().

03499 { 03500 PTHREADINFO ptiCurrent; 03501 03502 ptiCurrent = PtiCurrent(); 03503 03504 /* 03505 * The calling thread must be on the active desktop and have journal 03506 * playback access to that desktop if it wants to block input. 03507 * (Unblocking is less restricted) 03508 */ 03509 if (fBlockIt && 03510 (ptiCurrent->rpdesk != grpdeskRitInput || 03511 !RtlAreAllAccessesGranted(ptiCurrent->amdesk, DESKTOP_JOURNALPLAYBACK))) { 03512 03513 RIPNTERR0(STATUS_ACCESS_DENIED, RIP_WARNING, 03514 "BlockInput failed: Non active desktop or access denied"); 03515 return FALSE; 03516 } 03517 UserAssert(!(ptiCurrent->rpdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO)); 03518 03519 /* 03520 * If we are enabling input 03521 * * Is it disabled? No, then fail the call 03522 * * Is it disabled but we aren't the dude in control? Yes, then 03523 * fail the call. 03524 * If we are disabling input 03525 * * Is it enabled? No, then fail the call 03526 * * Set us up as the dude in control 03527 */ 03528 03529 if (fBlockIt) { 03530 /* 03531 * Is input blocked right now? 03532 */ 03533 if (gptiBlockInput != NULL) { 03534 return FALSE; 03535 } 03536 03537 /* 03538 * Is this thread exiting? If so, fail the call now. User's 03539 * cleanup code won't get a chance to whack this back if so. 03540 */ 03541 if (ptiCurrent->TIF_flags & TIF_INCLEANUP) { 03542 return FALSE; 03543 } 03544 03545 /* 03546 * Set blocking on. 03547 */ 03548 gptiBlockInput = ptiCurrent; 03549 } else { 03550 /* 03551 * Fail if input is not blocked, or blocked by another thread 03552 */ 03553 if (gptiBlockInput != ptiCurrent) { 03554 return FALSE; 03555 } 03556 03557 /* 03558 * This thread was blocking input, so now clear the block. 03559 */ 03560 gptiBlockInput = NULL; 03561 } 03562 03563 return TRUE; 03564 }

int _GetKeyboardType int  nTypeFlag  ) 
 

Definition at line 3070 of file ntinput.c.

References gKeyboardInfo, gpKbdNlsTbl, and NULL.

03071 { 03072 03073 switch (nTypeFlag) { 03074 case 0: 03075 return gKeyboardInfo.KeyboardIdentifier.Type; 03076 03077 case 1: 03078 // FE_SB 03079 { 03080 int OEMId = 0; 03081 // 03082 // If this keyboard layout is compatible with 101 or 106 03083 // Japanese keyboard, we just return 101 or 106's keyboard 03084 // id, not this keyboard's one to let application handle 03085 // this keyboard as 101 or 106 Japanese keyboard. 03086 // 03087 if (gpKbdNlsTbl != NULL) { 03088 if (gpKbdNlsTbl->LayoutInformation & NLSKBD_INFO_EMURATE_101_KEYBOARD) { 03089 return (MICROSOFT_KBD_101_TYPE); 03090 } 03091 if (gpKbdNlsTbl->LayoutInformation & NLSKBD_INFO_EMURATE_106_KEYBOARD) { 03092 return (MICROSOFT_KBD_106_TYPE); 03093 } 03094 } 03095 03096 // 03097 // PSS ID Number: Q130054 03098 // Article last modified on 05-16-1995 03099 // 03100 // 3.10 1.20 | 3.50 1.20 03101 // WINDOWS | WINDOWS NT 03102 // 03103 // --------------------------------------------------------------------- 03104 // The information in this article applies to: 03105 // - Microsoft Windows Software Development Kit (SDK) for Windows 03106 // version 3.1 03107 // - Microsoft Win32 Software Development Kit (SDK) version 3.5 03108 // - Microsoft Win32s version 1.2 03109 // --------------------------------------------------------------------- 03110 // SUMMARY 03111 // ======= 03112 // Because of the variety of computer manufacturers (NEC, Fujitsu, IBMJ, and 03113 // so on) in Japan, sometimes Windows-based applications need to know which 03114 // OEM (original equipment manufacturer) manufactured the computer that is 03115 // running the application. This article explains how. 03116 // 03117 // MORE INFORMATION 03118 // ================ 03119 // There is no documented way to detect the manufacturer of the computer that 03120 // is currently running an application. However, a Windows-based application 03121 // can detect the type of OEM Windows by using the return value of the 03122 // GetKeyboardType() function. 03123 // 03124 // If an application uses the GetKeyboardType API, it can get OEM ID by 03125 // specifying "1" (keyboard subtype) as argument of the function. Each OEM ID 03126 // is listed here: 03127 // 03128 // OEM Windows OEM ID 03129 // ------------------------------ 03130 // Microsoft 00H (DOS/V) 03131 // all AX 01H 03132 // EPSON 04H 03133 // Fujitsu 05H 03134 // IBMJ 07H 03135 // Matsushita 0AH 03136 // NEC 0DH 03137 // Toshiba 12H 03138 // 03139 // Application programs can use these OEM IDs to distinguish the type of OEM 03140 // Windows. Note, however, that this method is not documented, so Microsoft 03141 // may not support it in the future version of Windows. 03142 // 03143 // As a rule, application developers should write hardware-independent code, 03144 // especially when making Windows-based applications. If they need to make a 03145 // hardware-dependent application, they must prepare the separated program 03146 // file for each different hardware architecture. 03147 // 03148 // Additional reference words: 3.10 1.20 3.50 1.20 kbinf 03149 // KBCategory: kbhw 03150 // KBSubcategory: wintldev 03151 // ============================================================================= 03152 // Copyright Microsoft Corporation 1995. 03153 03154 if (gpKbdNlsTbl != NULL) { 03155 // 03156 // Get OEM (Windows) ID. 03157 // 03158 OEMId = ((int)gpKbdNlsTbl->OEMIdentifier) << 8; 03159 } 03160 // 03161 // The format of KeyboardIdentifier.Subtype : 03162 // 03163 // 0 - 3 bits = keyboard subtype 03164 // 4 - 7 bits = kernel mode kerboard driver provider id. 03165 // 03166 // Kernel mode keyboard dirver provier | ID 03167 // ------------------------------------+----- 03168 // Microsoft | 00H 03169 // all AX | 01H 03170 // Toshiba | 02H 03171 // EPSON | 04H 03172 // Fujitsu | 05H 03173 // IBMJ | 07H 03174 // Matsushita | 0AH 03175 // NEC | 0DH 03176 // 03177 03178 // 03179 // And here is the format of return value. 03180 // 03181 // 0 - 7 bits = Keyboard Subtype. 03182 // 8 - 15 bits = OEM (Windows) Id. 03183 // 16 - 31 bits = not used. 03184 // 03185 return (int)(OEMId | (gKeyboardInfo.KeyboardIdentifier.Subtype & 0x0F)); 03186 } 03187 03188 case 2: 03189 return gKeyboardInfo.NumberOfFunctionKeys; 03190 } 03191 return 0; 03192 }

int _GetMouseMovePointsEx CONST MOUSEMOVEPOINT *  ppt,
MOUSEMOVEPOINT *  ccxpptBuf,
UINT  nPoints,
DWORD  resolution
 

Definition at line 3652 of file ntinput.c.

References BOOL, DWORD, FALSE, gaptMouse, gptInd, MAX_MOUSEPOINTS, min, PREVPOINT, SYSMET, TRUE, and UINT.

Referenced by NtUserGetMouseMovePointsEx().

03657 { 03658 UINT uInd, uStart, nPointsRetrieved, i; 03659 BOOL bFound = FALSE; 03660 int x, y; 03661 DWORD resX, resY; 03662 03663 uStart = PREVPOINT(gptInd); 03664 03665 /* 03666 * Search the point in the global buffer and get the first occurance. 03667 */ 03668 uInd = uStart; 03669 03670 do { 03671 /* 03672 * The resolutions can be zero only if the buffer is still not full 03673 */ 03674 if (HIWORD(gaptMouse[uInd].x) == 0 || HIWORD(gaptMouse[uInd].y) == 0) { 03675 break; 03676 } 03677 03678 resX = (DWORD)HIWORD(gaptMouse[uInd].x) + 1; 03679 resY = (DWORD)HIWORD(gaptMouse[uInd].y) + 1; 03680 03681 if ((int)resX != SYSMET(CXVIRTUALSCREEN)) { 03682 UserAssert(resX == 0x10000); 03683 x = (LOWORD(gaptMouse[uInd].x) * SYSMET(CXVIRTUALSCREEN)) / resX; 03684 } else { 03685 x = LOWORD(gaptMouse[uInd].x); 03686 } 03687 03688 if ((int)resY != SYSMET(CYVIRTUALSCREEN)) { 03689 UserAssert(resY == 0x10000); 03690 y = (LOWORD(gaptMouse[uInd].y) * SYSMET(CYVIRTUALSCREEN)) / resY; 03691 } else { 03692 y = LOWORD(gaptMouse[uInd].y); 03693 } 03694 03695 if (x == ppt->x && y == ppt->y) { 03696 03697 /* 03698 * If the timestamp was provided check to see if it's the right 03699 * timestamp. 03700 */ 03701 if (ppt->time != 0 && ppt->time != gaptMouse[uInd].time) { 03702 uInd = PREVPOINT(uInd); 03703 RIPMSG4(RIP_VERBOSE, 03704 "GetMouseMovePointsEx: Found point (%x, %y) but timestamp %x diff from %x", 03705 x, y, ppt->time, gaptMouse[uInd].time); 03706 continue; 03707 } 03708 03709 bFound = TRUE; 03710 break; 03711 } 03712 uInd = PREVPOINT(uInd); 03713 03714 } while (uInd != uStart); 03715 03716 /* 03717 * The point might not be in the buffer anymore. 03718 */ 03719 if (!bFound) { 03720 RIPERR2(ERROR_POINT_NOT_FOUND, RIP_VERBOSE, 03721 "GetMouseMovePointsEx: point not found (%x, %y)", ppt->x, ppt->y); 03722 return -1; 03723 } 03724 03725 /* 03726 * See how many points we can retrieve. 03727 */ 03728 nPointsRetrieved = (uInd <= uStart ? uInd + MAX_MOUSEPOINTS - uStart : uInd - uStart); 03729 03730 nPointsRetrieved = min(nPointsRetrieved, nPoints); 03731 03732 /* 03733 * Copy the points to the app buffer 03734 */ 03735 try { 03736 for (i = 0; i < nPointsRetrieved; i++) { 03737 03738 resX = (DWORD)HIWORD(gaptMouse[uInd].x) + 1; 03739 resY = (DWORD)HIWORD(gaptMouse[uInd].y) + 1; 03740 03741 /* 03742 * If one of the resolution is 0 then we're done 03743 */ 03744 if (HIWORD(gaptMouse[uInd].x) == 0 || HIWORD(gaptMouse[uInd].y) == 0) { 03745 break; 03746 } 03747 03748 /* 03749 * LOWORD(gaptMouse[uInd].x) contains the x point on the 03750 * scale specified by HIWORD(gaptMouse[uInd].x) 03751 */ 03752 if (resolution == GMMP_USE_HIGH_RESOLUTION_POINTS) { 03753 ccxpptBuf[i].x = ((DWORD)LOWORD(gaptMouse[uInd].x) * 0xFFFF) / (resX - 1); 03754 03755 ccxpptBuf[i].y = ((DWORD)LOWORD(gaptMouse[uInd].y) * 0xFFFF) / (resY - 1); 03756 03757 } else { 03758 UserAssert(resolution == GMMP_USE_DISPLAY_POINTS); 03759 03760 ccxpptBuf[i].x = (LOWORD(gaptMouse[uInd].x) * SYSMET(CXVIRTUALSCREEN)) / resX; 03761 03762 ccxpptBuf[i].y = (LOWORD(gaptMouse[uInd].y) * SYSMET(CYVIRTUALSCREEN)) / resY; 03763 } 03764 ccxpptBuf[i].time = gaptMouse[uInd].time; 03765 ccxpptBuf[i].dwExtraInfo = gaptMouse[uInd].dwExtraInfo; 03766 03767 03768 uInd = PREVPOINT(uInd); 03769 } 03770 } except(W32ExceptionHandler(FALSE, RIP_WARNING)) { 03771 } 03772 return i; 03773 }

BOOL _SetConsoleReserveKeys PWND  pwnd,
DWORD  fsReserveKeys
 

Definition at line 3634 of file ntinput.c.

References BOOL, GETPTI, and TRUE.

Referenced by NtUserSetConsoleReserveKeys().

03637 { 03638 GETPTI(pwnd)->fsReserveKeys = fsReserveKeys; 03639 return TRUE; 03640 }

VOID CleanupResources VOID   ) 
 

Definition at line 2087 of file ntinput.c.

References CleanupGDI(), CleanupPowerRequestList(), DestroyClass(), gbCleanedUpResources, gpclsList, HH_CLEANUPRESOURCES, HYDRA_HINT, LockQCursor, NULL, PpiCurrent, tagTHREADINFO::pq, tagTHREADINFO::ptiSibling, TRUE, UnloadCursorsAndIcons(), and VOID().

Referenced by xxxDestroyThreadInfo().

02089 { 02090 PPCLS ppcls; 02091 PTHREADINFO pti; 02092 02093 UserAssert(!gbCleanedUpResources); 02094 02095 gbCleanedUpResources = TRUE; 02096 02097 HYDRA_HINT(HH_CLEANUPRESOURCES); 02098 02099 /* 02100 * Prevent power callouts. 02101 */ 02102 CleanupPowerRequestList(); 02103 02104 /* 02105 * Destroy the system classes also 02106 */ 02107 ppcls = &gpclsList; 02108 while (*ppcls != NULL) { 02109 DestroyClass(ppcls); 02110 } 02111 02112 /* 02113 * Unlock the cursor from all the CSRSS's threads. 02114 * We do this here because RIT might not be the only 02115 * CSRSS process running at this time and we want 02116 * to prevent the change of thread ownership 02117 * after RIT is gone. 02118 */ 02119 pti = PpiCurrent()->ptiList; 02120 02121 while (pti != NULL) { 02122 02123 if (pti->pq != NULL) { 02124 LockQCursor(pti->pq, NULL); 02125 } 02126 pti = pti->ptiSibling; 02127 } 02128 02129 UnloadCursorsAndIcons(); 02130 02131 /* 02132 * Cleanup the GDI globals in USERK 02133 */ 02134 CleanupGDI(); 02135 }

NTSTATUS DeviceNotify IN  PPLUGPLAY_NOTIFY_HDR,
IN  PDEVICEINFO
 

Definition at line 1025 of file w32/ntuser/kernel/pnp.c.

Referenced by RegisterForDeviceChangeNotifications().

01028 { 01029 USHORT usAction; 01030 01031 #if DBG 01032 { 01033 PDEVICEINFO pDeviceInfoDbg; 01034 for (pDeviceInfoDbg = gpDeviceInfoList; pDeviceInfoDbg; pDeviceInfoDbg = pDeviceInfoDbg->pNext) { 01035 if (pDeviceInfoDbg == pDeviceInfo) { 01036 break; 01037 } 01038 } 01039 UserAssertMsg1(pDeviceInfoDbg != NULL, "Notification for unlisted DEVICEINFO %lx", pDeviceInfo); 01040 } 01041 #endif 01042 01043 CheckCritOut(); 01044 01045 UserAssert(!gbRemoteSession); 01046 01047 TAGMSG1(DBGTAG_PNP | RIP_THERESMORE, "DeviceNotify >>> %lx", pDeviceInfo); 01048 01049 UserAssert(pDeviceInfo->OpenerProcess != PsGetCurrentThread()->Cid.UniqueProcess); 01050 UserAssert(pDeviceInfo->usActions == 0); 01051 01052 if (IsEqualGUID(&pNotification->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE)) { 01053 TAGMSG0(DBGTAG_PNP | RIP_NONAME, "QueryRemove"); 01054 usAction = GDIAF_QUERYREMOVE; 01055 01056 } else if (IsEqualGUID(&pNotification->Event, &GUID_TARGET_DEVICE_REMOVE_CANCELLED)) { 01057 TAGMSG0(DBGTAG_PNP | RIP_NONAME, "RemoveCancelled"); 01058 usAction = GDIAF_REMOVECANCELLED; 01059 01060 } else if (IsEqualGUID(&pNotification->Event, &GUID_TARGET_DEVICE_REMOVE_COMPLETE)) { 01061 TAGMSG1(DBGTAG_PNP | RIP_NONAME, "RemoveComplete (process %#x)", PsGetCurrentThread()->Cid.UniqueProcess); 01062 usAction = GDIAF_DEPARTED; 01063 01064 } else { 01065 TAGMSG4(DBGTAG_PNP | RIP_NONAME, "GUID Unknown: %lx:%lx:%lx:%x...", 01066 pNotification->Event.Data1, pNotification->Event.Data2, 01067 pNotification->Event.Data3, pNotification->Event.Data4[0]); 01068 return STATUS_UNSUCCESSFUL; 01069 } 01070 01071 /* 01072 * Signal the RIT to ProcessDeviceChanges() 01073 * Wait for completion according to the GDIAF_PNPWAITING bit 01074 */ 01075 CheckCritOut(); 01076 CheckDeviceInfoListCritOut(); 01077 RequestDeviceChange(pDeviceInfo, (USHORT)(usAction | GDIAF_PNPWAITING), FALSE); 01078 01079 return STATUS_SUCCESS; 01080 }

LONG DoMouseAccel LONG  delta  ) 
 

Definition at line 2888 of file ntinput.c.

References abs, gMouseSpeed, gMouseThresh1, and gMouseThresh2.

Referenced by GetMouseCoord().

02890 { 02891 LONG newDelta = Delta; 02892 02893 if (abs(Delta) > gMouseThresh1) { 02894 newDelta *= 2; 02895 02896 if ((abs(Delta) > gMouseThresh2) && (gMouseSpeed == 2)) { 02897 newDelta *= 2; 02898 } 02899 } 02900 02901 return newDelta; 02902 }

PDEVICEINFO FreeDeviceInfo PDEVICEINFO  pDeviceInfo  ) 
 

Definition at line 313 of file ntinput.c.

References CheckDeviceInfoListCritIn, EVENT_INCREMENT, FALSE, FreeKernelEvent(), GDIAF_FREEME, GDIAF_PNPWAITING, GDIF_PNPMUSTFREE, GDIF_READERMUSTFREE, GDIF_READING, gpDeviceInfoList, KeSetEvent(), and NULL.

Referenced by InputApc(), ProcessDeviceChanges(), RequestDeviceChange(), StartDeviceRead(), and Win32kNtUserCleanup().

00314 { 00315 PDEVICEINFO *ppDeviceInfo; 00316 00317 CheckDeviceInfoListCritIn(); 00318 00319 TAGMSG1(DBGTAG_PNP, "FreeDeviceInfo(%#p)", pDeviceInfo); 00320 00321 /* 00322 * We cannot free the device since we still have a read pending. 00323 * Mark it GDIAF_FREEME so that it will be freed when the APC is made 00324 * (see InputApc), or when the next read request is about to be issued 00325 * (see StartDeviceRead). 00326 */ 00327 if (pDeviceInfo->bFlags & GDIF_READING) { 00328 #if DIAGNOSE_IO 00329 pDeviceInfo->bFlags |= GDIF_READERMUSTFREE; 00330 #endif 00331 TAGMSG1(DBGTAG_PNP, "** FreeDeviceInfo(%#p) DEFERRED : reader must free", pDeviceInfo); 00332 pDeviceInfo->usActions |= GDIAF_FREEME; 00333 return pDeviceInfo->pNext; 00334 } 00335 00336 /* 00337 * If a PnP thread is waiting in RequestDeviceChange for some action to be 00338 * performed on this device, just mark it for freeing and signal that PnP 00339 * thread with the pkeHidChangeCompleted so that it will free it 00340 */ 00341 if (pDeviceInfo->usActions & GDIAF_PNPWAITING) { 00342 #if DIAGNOSE_IO 00343 pDeviceInfo->bFlags |= GDIF_PNPMUSTFREE; 00344 #endif 00345 TAGMSG1(DBGTAG_PNP, "** FreeDeviceInfo(%#p) DEFERRED : PnP must free", pDeviceInfo); 00346 pDeviceInfo->usActions |= GDIAF_FREEME; 00347 KeSetEvent(pDeviceInfo->pkeHidChangeCompleted, EVENT_INCREMENT, FALSE); 00348 return pDeviceInfo->pNext; 00349 } 00350 00351 ppDeviceInfo = &gpDeviceInfoList; 00352 00353 while (*ppDeviceInfo) { 00354 if (*ppDeviceInfo == pDeviceInfo) { 00355 /* 00356 * Found the DEVICEINFO struct, so free it and its members. 00357 */ 00358 if (pDeviceInfo->pkeHidChangeCompleted != NULL) { 00359 FreeKernelEvent(&pDeviceInfo->pkeHidChangeCompleted); // BUG BUG 00360 } 00361 if (pDeviceInfo->ustrName.Buffer != NULL) { 00362 UserFreePool(pDeviceInfo->ustrName.Buffer); 00363 } 00364 *ppDeviceInfo = pDeviceInfo->pNext; 00365 UserFreePool(pDeviceInfo); 00366 00367 return *ppDeviceInfo; 00368 } 00369 ppDeviceInfo = &(*ppDeviceInfo)->pNext; 00370 } 00371 RIPMSG1(RIP_ERROR, "pDeviceInfo %#p not found in gpDeviceInfoList", pDeviceInfo); 00372 00373 return NULL; 00374 }

HKL GetActiveHKL  ) 
 

Definition at line 439 of file ntinput.c.

References _GetKeyboardLayout(), CheckCritIn, GETPTI, gpqForeground, tagKL::hkl, L, tagTHREADINFO::spklActive, and tagQ::spwndActive.

Referenced by FindImeHotKeyByKey(), RemoteSyncToggleKeys(), VKFromVSC(), xxxButtonEvent(), xxxKeyEvent(), and xxxProcessKeyEvent().

00440 { 00441 CheckCritIn(); 00442 if (gpqForeground && gpqForeground->spwndActive) { 00443 PTHREADINFO ptiForeground = GETPTI(gpqForeground->spwndActive); 00444 if (ptiForeground && ptiForeground->spklActive) { 00445 return ptiForeground->spklActive->hkl; 00446 } 00447 } 00448 return _GetKeyboardLayout(0L); 00449 }

VOID GetMouseCoord LONG  dx,
LONG  dy,
DWORD  dwFlags,
LONG  time,
ULONG_PTR  ExtraInfo,
PPOINT  ppt
 

Definition at line 1794 of file ntinput.c.

References DoMouseAccel(), dwFlags, gMouseSensitivity, gMouseSensitivityFactor, gMouseSpeed, idxRemainder, idyRemainder, MOUSE_SENSITIVITY_DEFAULT, SAVEPOINT, SYSMET, and VOID().

Referenced by ProcessMouseInput(), and xxxMoveEvent().

01801 { 01802 if (dwFlags & MOUSE_MOVE_ABSOLUTE) { 01803 01804 LONG cxMetric, cyMetric; 01805 01806 /* 01807 * If MOUSE_VIRTUAL_DESKTOP was specified, map to entire virtual screen 01808 */ 01809 if (dwFlags & MOUSE_VIRTUAL_DESKTOP) { 01810 cxMetric = SYSMET(CXVIRTUALSCREEN); 01811 cyMetric = SYSMET(CYVIRTUALSCREEN); 01812 } else { 01813 cxMetric = SYSMET(CXSCREEN); 01814 cyMetric = SYSMET(CYSCREEN); 01815 } 01816 01817 /* 01818 * Absolute pointing device used: deltas are actually the current 01819 * position. Update the global mouse position. 01820 * 01821 * Note that the position is always reported in units of 01822 * (0,0)-(0xFFFF,0xFFFF) which corresponds to 01823 * (0,0)-(SYSMET(CXSCREEN), SYSMET(CYSCREEN)) in pixels. 01824 * We must first scale it to fit on the screen using the formula: 01825 * ptScreen = ptMouse * resPrimaryMonitor / 64K 01826 * 01827 * The straightforward algorithm coding of this algorithm is: 01828 * 01829 * ppt->x = (dx * SYSMET(CXSCREEN)) / (long)0x0000FFFF; 01830 * ppt->y = (dy * SYSMET(CYSCREEN)) / (long)0x0000FFFF; 01831 * 01832 * On x86, with 14 more bytes we can avoid the division function with 01833 * the following code. 01834 */ 01835 01836 ppt->x = dx * cxMetric; 01837 if (ppt->x >= 0) { 01838 ppt->x = HIWORD(ppt->x); 01839 } else { 01840 ppt->x = - (long) HIWORD(-ppt->x); 01841 } 01842 01843 ppt->y = dy * cyMetric; 01844 if (ppt->y >= 0) { 01845 ppt->y = HIWORD(ppt->y); 01846 } else { 01847 ppt->y = - (long) HIWORD(-ppt->y); 01848 } 01849 01850 /* 01851 * (0, 0) must map to the leftmost point on the desktop 01852 */ 01853 if (dwFlags & MOUSE_VIRTUAL_DESKTOP) { 01854 ppt->x += SYSMET(XVIRTUALSCREEN); 01855 ppt->y += SYSMET(YVIRTUALSCREEN); 01856 } 01857 01858 /* 01859 * Reset the mouse sensitivity remainder. 01860 */ 01861 idxRemainder = idyRemainder = 0; 01862 01863 /* 01864 * Save the absolute coordinates in the global array 01865 * for GetMouseMovePointsEx. 01866 */ 01867 SAVEPOINT(dx, dy, 0xFFFF, 0xFFFF, time, ExtraInfo); 01868 } else { 01869 /* 01870 * Is there any mouse acceleration to do? 01871 */ 01872 if (gMouseSpeed != 0) { 01873 dx = DoMouseAccel(dx); 01874 dy = DoMouseAccel(dy); 01875 } 01876 01877 /* 01878 * Does the mouse sensitivity need to be adjusted? 01879 */ 01880 if (gMouseSensitivity != MOUSE_SENSITIVITY_DEFAULT) { 01881 int iNumerator; 01882 01883 if (dx) { 01884 iNumerator = dx * gMouseSensitivityFactor + idxRemainder; 01885 dx = iNumerator / 256 ; 01886 idxRemainder = iNumerator % 256 ; 01887 if ((iNumerator < 0) && (idxRemainder > 0)) { 01888 dx++ ; 01889 idxRemainder -= 256 ; 01890 } 01891 } 01892 if (dy) { 01893 iNumerator = dy * gMouseSensitivityFactor + idyRemainder ; 01894 dy = iNumerator / 256 ; 01895 idyRemainder = iNumerator % 256 ; 01896 if ((iNumerator < 0) && (idyRemainder > 0)) { 01897 dy++ ; 01898 idyRemainder -= 256 ; 01899 } 01900 } 01901 } 01902 01903 ppt->x += dx; 01904 ppt->y += dy; 01905 01906 /* 01907 * Save the absolute coordinates in the global array 01908 * for GetMouseMovePointsEx. 01909 */ 01910 SAVEPOINT(ppt->x, ppt->y, 01911 SYSMET(CXVIRTUALSCREEN) - 1, SYSMET(CYVIRTUALSCREEN) - 1, 01912 time, ExtraInfo); 01913 } 01914 }

BOOL InitiateWin32kCleanup VOID   ) 
 

Definition at line 2146 of file ntinput.c.

References _PostThreadMessage(), BOOL, CleanupPowerRequestList(), CloseProtectedHandle(), CsrApiPort, tagPROCESSINFO::cThreads, tagTHREADINFO::cWindows, EnterCrit, FALSE, FreeAllSpbs(), FreeTimer(), gbConnected, gbExitInProgress, gbRemoteSession, ghDisconnectDesk, ghDisconnectWinSta, ghRemoteThinwireChannel, gpDispInfo, gpevtDesktopDestroyed, gppiList, gpsmsList, gptiRit, gptmrFirst, grpdeskLogon, grpdeskRitInput, gSessionId, gspdeskDisconnect, gspdeskShouldBeForeground, gspwndCursor, gspwndInternalCapture, gspwndLogonNotify, gspwndMouseOwner, gspwndScreenCapture, gTermIO, gTermNOIO, gThinwireFileObject, tagDISPLAYINFO::hDev, HH_ALLDTGONE, HH_DTQUITPOSTED, HH_INITIATEWIN32KCLEANUP, HH_RITGONE, HYDRA_HINT, KernelMode, KeWaitForMultipleObjects(), KeWaitForSingleObject(), L, LeaveCrit, MAX_SESSION_PATH, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, tagPROCESSINFO::ppiNextRunning, PSMS, tagWINDOWSTATION::pTerm, PtiCurrent, tagTERMINAL::ptiDesktop, tagPROCESSINFO::ptiList, tagTHREADINFO::ptiSibling, tagTHREADINFO::pwinsta, tagTERMINAL::rpdeskDestroy, tagWINDOWSTATION::rpdeskList, tagDESKTOP::rpdeskNext, RtlInitUnicodeString(), Status, szName, tagTHREADINFO::TIF_flags, TIF_PALETTEAWARE, TRACE_HYDAPI, TRACE_RIT, TRUE, Unlock, UnlockDesktop, and WrUserRequest.

Referenced by RawInputThread().

02148 { 02149 PTHREADINFO ptiCurrent; 02150 PWINDOWSTATION pwinsta; 02151 BOOLEAN fWait = TRUE; 02152 PDESKTOP pdesk; 02153 UNICODE_STRING ustrName; 02154 WCHAR szName[MAX_SESSION_PATH]; 02155 HANDLE hevtRitExited; 02156 OBJECT_ATTRIBUTES obja; 02157 NTSTATUS Status; 02158 LARGE_INTEGER timeout; 02159 NTSTATUS Reason; 02160 BOOL fFirstTimeout = TRUE; 02161 02162 if (!gbRemoteSession) { 02163 return FALSE; 02164 } 02165 02166 TRACE_HYDAPI(("InitiateWin32kCleanup\n")); 02167 02168 TRACE_RIT(("Exiting Win32k ...\n")); 02169 02170 /* 02171 * Prevent power callouts. 02172 */ 02173 CleanupPowerRequestList(); 02174 02175 EnterCrit(); 02176 02177 HYDRA_HINT(HH_INITIATEWIN32KCLEANUP); 02178 02179 ptiCurrent = PtiCurrent(); 02180 02181 UserAssert(ptiCurrent != NULL); 02182 02183 pwinsta = ptiCurrent->pwinsta; 02184 02185 /* 02186 * Give DTs 5 minutes to go away 02187 */ 02188 timeout.QuadPart = Int32x32To64(-10000, 300000); 02189 02190 /* 02191 * Wait for all desktops to exit other than the disconnected desktop. 02192 */ 02193 while (fWait) { 02194 02195 /* 02196 * If things are left on the destroy list or the disconnected desktop is 02197 * not the current desktop (at the end we should always switch to the 02198 * disconnected desktop), then wait. 02199 */ 02200 pdesk = pwinsta->rpdeskList; 02201 02202 if (pdesk == NULL) { 02203 break; 02204 } 02205 02206 fWait = pdesk != gspdeskDisconnect 02207 || pdesk->rpdeskNext != NULL 02208 || pwinsta->pTerm->rpdeskDestroy != NULL; 02209 02210 if (fWait) { 02211 02212 LeaveCrit(); 02213 02214 Reason = KeWaitForSingleObject(gpevtDesktopDestroyed, WrUserRequest, 02215 KernelMode, FALSE, &timeout); 02216 02217 if (Reason == STATUS_TIMEOUT) { 02218 02219 /* 02220 * The first time we timeout might be because winlogon died 02221 * before calling ExitWindowsEx. In that case there may be processes 02222 * w/ GUI threads running and those threads will have an hdesk 02223 * in the THREADINFO structure. Thus the desktop threads will not exit. 02224 * In this situation we signal the event 'EventRitStuck' so that 02225 * csrss can tell termsrv to start killing the remaining processes 02226 * calling NtTerminateProcess on them. csrss signals that to termsrv 02227 * by closing the LPC port in ntuser\server\api.c (W32WinStationTerminate) 02228 */ 02229 02230 if (fFirstTimeout) { 02231 02232 HANDLE hevtRitStuck; 02233 02234 RIPMSG0(RIP_WARNING, 02235 "Timeout in RIT waiting for gpevtDesktopDestroyed. Signal EventRitStuck..."); 02236 02237 swprintf(szName, L"\\Sessions\\%ld\\BaseNamedObjects\\EventRitStuck", 02238 gSessionId); 02239 02240 RtlInitUnicodeString(&ustrName, szName); 02241 02242 InitializeObjectAttributes(&obja, 02243 &ustrName, 02244 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, 02245 NULL, 02246 NULL); 02247 02248 Status = ZwCreateEvent(&hevtRitStuck, 02249 EVENT_ALL_ACCESS, 02250 &obja, 02251 SynchronizationEvent, 02252 FALSE); 02253 02254 UserAssert(NT_SUCCESS(Status)); 02255 02256 if (NT_SUCCESS(Status)) { 02257 ZwSetEvent(hevtRitStuck, NULL); 02258 ZwClose(hevtRitStuck); 02259 02260 fFirstTimeout = FALSE; 02261 } 02262 02263 } else { 02264 RIPMSG0(RIP_ERROR, 02265 "Timeout in RIT waiting for gpevtDesktopDestroyed.\n" 02266 "There are still GUI threads (assigned to a desktop) running !"); 02267 } 02268 } 02269 02270 EnterCrit(); 02271 } 02272 } 02273 TRACE_RIT(("All other desktops exited...\n")); 02274 02275 Unlock(&gspwndLogonNotify); 02276 02277 gbExitInProgress = TRUE; 02278 02279 TRACE_RIT(("Shutting down ptiCurrent %lx cWindows %d\n", 02280 ptiCurrent, ptiCurrent->cWindows)); 02281 02282 /* 02283 * Clear out some values so some operations won't be possible 02284 */ 02285 UserAssert(gspwndScreenCapture == NULL); 02286 UserAssert(gspwndMouseOwner == NULL); 02287 UserAssert(gspwndInternalCapture == NULL); 02288 02289 /* 02290 * Free any SPB's (Taken from wallpaper change code) 02291 */ 02292 02293 if (gpDispInfo) // If this wasn't allocated, never mind 02294 FreeAllSpbs(); 02295 02296 /* 02297 * Close the disconnected desktop. 02298 */ 02299 if (ghDisconnectWinSta) { 02300 UserVerify(NT_SUCCESS(ZwClose(ghDisconnectWinSta))); 02301 ghDisconnectWinSta = NULL; 02302 } 02303 02304 if (ghDisconnectDesk) { 02305 CloseProtectedHandle(ghDisconnectDesk); 02306 ghDisconnectDesk = NULL; 02307 } 02308 02309 UserAssert(pwinsta->rpdeskList == NULL); 02310 02311 /* 02312 * Unlock the logon desktop from the global variable 02313 */ 02314 UnlockDesktop(&grpdeskLogon, LDU_DESKLOGON, 0); 02315 02316 /* 02317 * Unlock the disconnect logon 02318 * 02319 * This was referenced when we created it, so free it now. 02320 * This is also a flag since the disconnect code checks to see if 02321 * the disconnected desktop is still around. 02322 */ 02323 UnlockDesktop(&gspdeskDisconnect, LDU_DESKDISCONNECT, 0); 02324 02325 /* 02326 * Unlock any windows still locked in the SMS list. We need to do 02327 * this here because if we don't, we end up with zombie windows in the 02328 * desktop thread that we'll try to assign to RIT but RIT will be gone. 02329 */ 02330 { 02331 PSMS psms = gpsmsList; 02332 02333 while (psms != NULL) { 02334 if (psms->spwnd != NULL) { 02335 UserAssert(psms->message == WM_CLIENTSHUTDOWN); 02336 02337 RIPMSG1(RIP_WARNING, "Window %x locked in the SMS list", 02338 psms->spwnd); 02339 02340 Unlock(&psms->spwnd); 02341 } 02342 psms = psms->psmsNext; 02343 } 02344 } 02345 02346 TRACE_RIT(("posting WM_QUIT to the IO DT\n")); 02347 02348 UserAssert(pwinsta->pTerm->ptiDesktop != NULL); 02349 02350 UserVerify(_PostThreadMessage(pwinsta->pTerm->ptiDesktop, WM_QUIT, 0, 0)); 02351 02352 HYDRA_HINT(HH_DTQUITPOSTED); 02353 02354 /* 02355 * Wait for desktop thread(s) to exit. 02356 * This thread (RIT) is used to assign 02357 * objects if the orginal thread leaves. So it should be 02358 * the last one to go. Hopefully, if the desktop thread 02359 * exits, there shouldn't be any objects in use. 02360 */ 02361 { 02362 PVOID aDT[2]; 02363 ULONG objects = 1; 02364 02365 aDT[0] = gTermIO.ptiDesktop->pEThread; 02366 02367 ObReferenceObject(aDT[0]); 02368 02369 if (gTermNOIO.ptiDesktop != NULL) { 02370 aDT[1] = gTermNOIO.ptiDesktop->pEThread; 02371 ObReferenceObject(aDT[1]); 02372 objects++; 02373 } 02374 02375 TRACE_RIT(("waiting on desktop thread(s) destruction ...\n")); 02376 02377 LeaveCrit(); 02378 02379 /* 02380 * Give DTs 5 minutes to go away 02381 */ 02382 timeout.QuadPart = Int32x32To64(-10000, 300000); 02383 WaitAgain: 02384 02385 Reason = 02386 02387 KeWaitForMultipleObjects(objects, 02388 aDT, 02389 WaitAll, 02390 WrUserRequest, 02391 KernelMode, 02392 TRUE, 02393 &timeout, 02394 NULL); 02395 02396 if (Reason == STATUS_TIMEOUT) { 02397 RIPMSG0(RIP_ERROR, 02398 "Timeout in RIT waiting for desktop threads to go away."); 02399 goto WaitAgain; 02400 } 02401 02402 TRACE_RIT(("desktop thread(s) destroyed\n")); 02403 02404 ObDereferenceObject(aDT[0]); 02405 02406 if (objects > 1) { 02407 ObDereferenceObject(aDT[1]); 02408 } 02409 02410 EnterCrit(); 02411 } 02412 02413 HYDRA_HINT(HH_ALLDTGONE); 02414 02415 /* 02416 * If still connected, tell the miniport driver to disconnect 02417 */ 02418 if (gbConnected) { 02419 bDrvDisconnect(gpDispInfo->hDev, ghRemoteThinwireChannel, 02420 gThinwireFileObject); 02421 } 02422 02423 UnlockDesktop(&grpdeskRitInput, LDU_DESKRITINPUT, 0); 02424 UnlockDesktop(&gspdeskShouldBeForeground, LDU_DESKSHOULDBEFOREGROUND, 0); 02425 02426 /* 02427 * Free outstanding timers 02428 */ 02429 while (gptmrFirst != NULL) { 02430 FreeTimer(gptmrFirst); 02431 } 02432 02433 /* 02434 * Kill the csr port so no hard errors are services after this point 02435 */ 02436 if (CsrApiPort != NULL) { 02437 ObDereferenceObject(CsrApiPort); 02438 CsrApiPort = NULL; 02439 } 02440 02441 Unlock(&gspwndCursor); 02442 02443 /* 02444 * set this to NULL 02445 */ 02446 gptiRit = NULL; 02447 02448 TRACE_RIT(("TERMINATING !!!\n")); 02449 02450 #if DBG 02451 { 02452 PPROCESSINFO ppi = gppiList; 02453 02454 KdPrint(("Processes still running:\n")); 02455 KdPrint(("-------------------------\n")); 02456 02457 while (ppi) { 02458 02459 PTHREADINFO pti; 02460 02461 KdPrint(("ppi '%s' 0x%x threads: %d\n", 02462 ppi->Process->ImageFileName, 02463 ppi, 02464 ppi->cThreads)); 02465 02466 KdPrint(("\tGUI threads\n")); 02467 02468 pti = ppi->ptiList; 02469 02470 while (pti) { 02471 KdPrint(("\t%#p\n", pti)); 02472 pti = pti->ptiSibling; 02473 } 02474 02475 ppi = ppi->ppiNextRunning; 02476 } 02477 KdPrint(("-------------------------\n")); 02478 } 02479 #endif // DBG 02480 02481 LeaveCrit(); 02482 02483 swprintf(szName, L"\\Sessions\\%ld\\BaseNamedObjects\\EventRitExited", 02484 gSessionId); 02485 02486 RtlInitUnicodeString(&ustrName, szName); 02487 02488 InitializeObjectAttributes(&obja, 02489 &ustrName, 02490 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, 02491 NULL, 02492 NULL); 02493 02494 Status = ZwCreateEvent(&hevtRitExited, 02495 EVENT_ALL_ACCESS, 02496 &obja, 02497 SynchronizationEvent, 02498 FALSE); 02499 02500 UserAssert(NT_SUCCESS(Status)); 02501 02502 ZwSetEvent(hevtRitExited, NULL); 02503 02504 ZwClose(hevtRitExited); 02505 /* 02506 * Clear TIF_PALETTEAWARE or else we will AV in xxxDestroyThreadInfo 02507 * MCostea #412136 02508 */ 02509 ptiCurrent->TIF_flags &= ~TIF_PALETTEAWARE; 02510 02511 HYDRA_HINT(HH_RITGONE); 02512 02513 return TRUE; 02514 }

VOID InitKeyboard VOID   ) 
 

Definition at line 428 of file ntinput.c.

References gbRemoteSession, gpScancodeMap, InitScancodeMap(), and VOID().

00429 { 00430 if (!gbRemoteSession) { 00431 /* 00432 * Get the Scancode Mapping, if any. 00433 */ 00434 gpScancodeMap = InitScancodeMap(); 00435 } 00436 }

VOID InitMice  ) 
 

Definition at line 289 of file ntinput.c.

References ACCF_MKVIRTUALMOUSE, CLEAR_ACCF, CLEAR_GTERMF, FALSE, GTERMF_MOUSE, SYSMET, and VOID().

Referenced by RawInputThread().

00290 { 00291 CLEAR_ACCF(ACCF_MKVIRTUALMOUSE); 00292 CLEAR_GTERMF(GTERMF_MOUSE); 00293 SYSMET(MOUSEPRESENT) = FALSE; 00294 SYSMET(CMOUSEBUTTONS) = 0; 00295 SYSMET(MOUSEWHEELPRESENT) = FALSE; 00296 }

PSCANCODEMAP InitScancodeMap  ) 
 

Definition at line 194 of file ntinput.c.

References DWORD, FastGetProfileValue(), gbRemoteSession, ghRemoteKeyboardChannel, giosbKbdControl, L, NULL, PMAP_KBDLAYOUT, and PSCANCODEMAP.

Referenced by InitKeyboard().

00195 { 00196 LPBYTE pb = NULL; 00197 DWORD dwBytes; 00198 00199 /* 00200 * Find the size of the scancode map 00201 */ 00202 dwBytes = FastGetProfileValue(NULL, PMAP_KBDLAYOUT, L"Scancode Map", NULL, NULL, 0); 00203 00204 /* 00205 * Allocate space for the scancode map, and fetch it from the registry 00206 */ 00207 if (dwBytes > sizeof(SCANCODEMAP)) { 00208 if ((pb = UserAllocPoolZInit(dwBytes, TAG_SCANCODEMAP)) != 0) { 00209 dwBytes = FastGetProfileValue(NULL, PMAP_KBDLAYOUT, L"Scancode Map", 00210 NULL, pb, dwBytes); 00211 } 00212 } 00213 00214 #ifdef LATER 00215 /* 00216 * For shadow the WD has it's own keyboard scan code interpreter. 00217 * It needs to know the keyboard type. 00218 * 00219 * The keyboard comments say these are asynchronous commands so only 00220 * use globals. 00221 */ 00222 if (gbRemoteSession && dwBytes) { 00223 00224 ZwDeviceIoControlFile(ghRemoteKeyboardChannel, NULL, NULL, NULL, 00225 &giosbKbdControl, IOCTL_KEYBOARD_ICA_SCANMAP, pb, dwBytes, 00226 NULL, 0); 00227 00228 } 00229 #endif // LATER 00230 00231 return (PSCANCODEMAP)pb; 00232 }

VOID NTAPI InputApc IN PVOID  ApcContext,
IN PIO_STATUS_BLOCK  IoStatusBlock,
IN ULONG  Reserved
 

Definition at line 1090 of file ntinput.c.

References aDeviceTemplate, tagDEVICE_TEMPLATE::DeviceRead, EnterDeviceInfoListCrit(), FreeDeviceInfo(), GDIAF_FREEME, GDIF_READING, LeaveDeviceInfoListCrit(), NT_SUCCESS, PDEVICE_TEMPLATE, StartDeviceRead(), and VOID().

Referenced by StartDeviceRead().

01095 { 01096 PDEVICEINFO pDeviceInfo = (PDEVICEINFO)ApcContext; 01097 UNREFERENCED_PARAMETER(Reserved); 01098 01099 #ifdef DIAGNOSE_IO 01100 pDeviceInfo->nReadsOutstanding--; 01101 #endif 01102 01103 /* 01104 * If this device needs freeing, abandon reading now and request the free. 01105 * (Don't even process the input that we received in this APC) 01106 */ 01107 if (pDeviceInfo->usActions & GDIAF_FREEME) { 01108 EnterDeviceInfoListCrit(); 01109 pDeviceInfo->bFlags &= ~GDIF_READING; 01110 FreeDeviceInfo(pDeviceInfo); 01111 LeaveDeviceInfoListCrit(); 01112 return; 01113 } 01114 01115 if (NT_SUCCESS(IoStatusBlock->Status)) { 01116 PDEVICE_TEMPLATE pDevTpl = &aDeviceTemplate[pDeviceInfo->type]; 01117 pDevTpl->DeviceRead(pDeviceInfo); 01118 } 01119 StartDeviceRead(pDeviceInfo); 01120 }

__inline IsHexNumpadKeys BYTE  Vk,
WORD  wScanCode
 

Definition at line 1311 of file ntinput.c.

References aVkNumpad, and L.

Referenced by xxxKeyEvent().

01312 { 01313 return (wScanCode >= SCANCODE_NUMPAD_FIRST && wScanCode <= SCANCODE_NUMPAD_LAST && aVkNumpad[wScanCode - SCANCODE_NUMPAD_FIRST] != 0xff) || 01314 (Vk >= L'A' && Vk <= L'F') || 01315 (Vk >= L'0' && Vk <= L'9'); 01316 }

BOOL MapScancode PBYTE  pbScanCode,
PBYTE  pbPrefix
 

Definition at line 256 of file ntinput.c.

References CheckCritIn, DWORD, FALSE, gpScancodeMap, HIBYTE, LOBYTE, NULL, and TRUE.

Referenced by ProcessKeyboardInput().

00260 { 00261 DWORD *pdw; 00262 WORD wT = MAKEWORD(*pbScanCode, *pbPrefix); 00263 00264 CheckCritIn(); 00265 UserAssert(gpScancodeMap != NULL); 00266 00267 for (pdw = &(gpScancodeMap->dwMap[0]); *pdw; pdw++) { 00268 if (HIWORD(*pdw) == wT) { 00269 wT = LOWORD(*pdw); 00270 *pbScanCode = LOBYTE(wT); 00271 *pbPrefix = HIBYTE(wT); 00272 return TRUE; 00273 } 00274 } 00275 return FALSE; 00276 }

ULONG MonotonicTick  ) 
 

Definition at line 48 of file ntinput.c.

References NtGetTickCount().

00049 { 00050 static ULONG lasttick = 0; 00051 ULONG newtick; 00052 00053 newtick = NtGetTickCount(); 00054 if (newtick > lasttick) { 00055 lasttick = newtick; // use the new tick since it is larger 00056 } else { 00057 lasttick++; // artificially bump the tick up one. 00058 } 00059 return lasttick; 00060 }

VOID ProcessKeyboardInput PDEVICEINFO  pDeviceInfo  ) 
 

Definition at line 2615 of file ntinput.c.

References AccessProceduresStream(), ACCF_ACCESSENABLED, BYTE, tagKEYBOARD_DEVICE_INFO::Data, DEVICE_TYPE_KEYBOARD, EnterCrit, FALSE, gAccessTimeOut, gafRawKeyState, gbRemoteSession, gCurrentModifierBit, gfEnableWindowsKey, gPhysModifierState, gpScancodeMap, gSetLedReceived, gtmridAccessTimeOut, InternalSetTimer(), tagDEVICEINFO::keyboard, LeaveCrit, MapScancode(), NULL, PBYTE, RemoteSyncToggleKeys(), TEST_ACCESSFLAG, TEST_ACCF, UINT, UserBeep(), VKFromVSC(), VOID(), xxxAccessTimeOutTimer(), and xxxProcessKeyEvent().

02616 { 02617 BYTE Vk; 02618 BYTE bPrefix; 02619 KE ke; 02620 PKEYBOARD_INPUT_DATA pkei; 02621 PKEYBOARD_INPUT_DATA pkeiStart, pkeiEnd; 02622 02623 EnterCrit(); 02624 UserAssert(pDeviceInfo->type == DEVICE_TYPE_KEYBOARD); 02625 02626 pkeiStart = pDeviceInfo->keyboard.Data; 02627 pkeiEnd = (PKEYBOARD_INPUT_DATA)((PBYTE)pkeiStart + pDeviceInfo->iosb.Information); 02628 for (pkei = pkeiStart; pkei < pkeiEnd; pkei++) { 02629 02630 /* 02631 * Remote terminal server clients occationally need to be able to set 02632 * the server's toggle key state to match the client. All other 02633 * standard keyboard inputs are processed below since this is the most 02634 * frequent code path. 02635 */ 02636 if (!(pkei->Flags & KEY_TERMSRV_SET_LED)) { 02637 02638 // Process any deferred remote key sync requests 02639 if (!(gSetLedReceived & KEYBOARD_LED_INJECTED)) 02640 goto ProcessKeys; 02641 else 02642 RemoteSyncToggleKeys(gSetLedReceived); 02643 02644 ProcessKeys: 02645 if (pkei->Flags & KEY_E0) { 02646 bPrefix = 0xE0; 02647 } else if (pkei->Flags & KEY_E1) { 02648 bPrefix = 0xE1; 02649 } else { 02650 bPrefix = 0; 02651 } 02652 02653 if (pkei->MakeCode == 0xFF) { 02654 /* 02655 * Kbd overrun (kbd hardware and/or keyboard driver) : Beep! 02656 * (some DELL keyboards send 0xFF if keys are hit hard enough, 02657 * presumably due to keybounce) 02658 */ 02659 LeaveCrit(); 02660 UserBeep(440, 125); 02661 EnterCrit(); 02662 continue; 02663 } 02664 02665 ke.bScanCode = (BYTE)(pkei->MakeCode & 0x7F); 02666 if (gpScancodeMap) { 02667 MapScancode(&ke.bScanCode, &bPrefix); 02668 } 02669 02670 Vk = VKFromVSC(&ke, bPrefix, gafRawKeyState); 02671 02672 if (Vk == 0) { 02673 continue; 02674 } 02675 02676 if (pkei->Flags & KEY_BREAK) { 02677 ke.usFlaggedVk |= KBDBREAK; 02678 } 02679 02680 02681 /* 02682 * We don't know if the client system or the host should get the 02683 * windows key, so the choice is to not support it on the host. 02684 * (The windows key is a local key.) 02685 * 02686 * The other practical problem is that the local shell intercepts 02687 * the "break" of the windows key and switches to the start menu. 02688 * The client never sees the "break" so the host thinks the 02689 * windows key is always depressed. 02690 * 02691 * Newer clients may indicate they support the windows key. 02692 * If the client has indicated this through the gfEnableWindowsKey, 02693 * then we allow it to be processed here on the host. 02694 */ 02695 if (gbRemoteSession) { 02696 BYTE CheckVk = (BYTE)ke.usFlaggedVk; 02697 02698 if (CheckVk == VK_LWIN || CheckVk == VK_RWIN) 02699 if ( !gfEnableWindowsKey ) 02700 continue; 02701 } 02702 02703 // 02704 // Keep track of real modifier key state. Conveniently, the values for 02705 // VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU and 02706 // VK_RMENU are contiguous. We'll construct a bit field to keep track 02707 // of the current modifier key state. If a bit is set, the corresponding 02708 // modifier key is down. The bit field has the following format: 02709 // 02710 // +---------------------------------------------------+ 02711 // | Right | Left | Right | Left | Right | Left | 02712 // | Alt | Alt | Control | Control | Shift | Shift | 02713 // +---------------------------------------------------+ 02714 // 5 4 3 2 1 0 Bit 02715 // 02716 // Add bit 7 -- VK_RWIN 02717 // bit 6 -- VK_LWIN 02718 02719 switch (Vk) { 02720 case VK_LSHIFT: 02721 case VK_RSHIFT: 02722 case VK_LCONTROL: 02723 case VK_RCONTROL: 02724 case VK_LMENU: 02725 case VK_RMENU: 02726 gCurrentModifierBit = 1 << (Vk & 0xf); 02727 break; 02728 case VK_LWIN: 02729 gCurrentModifierBit = 0x40; 02730 break; 02731 case VK_RWIN: 02732 gCurrentModifierBit = 0x80; 02733 break; 02734 default: 02735 gCurrentModifierBit = 0; 02736 } 02737 if (gCurrentModifierBit) { 02738 /* 02739 * If this is a break of a modifier key then clear the bit value. 02740 * Otherwise, set it. 02741 */ 02742 if (pkei->Flags & KEY_BREAK) { 02743 gPhysModifierState &= ~gCurrentModifierBit; 02744 } else { 02745 gPhysModifierState |= gCurrentModifierBit; 02746 } 02747 } 02748 02749 if (!TEST_ACCF(ACCF_ACCESSENABLED)) { 02750 xxxProcessKeyEvent(&ke, (ULONG_PTR)pkei->ExtraInformation, FALSE); 02751 } else { 02752 if ((gtmridAccessTimeOut != 0) && TEST_ACCESSFLAG(AccessTimeOut, ATF_TIMEOUTON)) { 02753 gtmridAccessTimeOut = InternalSetTimer( 02754 NULL, 02755 gtmridAccessTimeOut, 02756 (UINT)gAccessTimeOut.iTimeOutMSec, 02757 xxxAccessTimeOutTimer, 02758 TMRF_RIT | TMRF_ONESHOT 02759 ); 02760 } 02761 if (AccessProceduresStream(&ke, pkei->ExtraInformation, 0)) { 02762 xxxProcessKeyEvent(&ke, (ULONG_PTR)pkei->ExtraInformation, FALSE); 02763 } 02764 } 02765 } 02766 02767 // Special toggle key synchronization for Terminal Server 02768 else { 02769 RemoteSyncToggleKeys(pkei->ExtraInformation); 02770 } 02771 } 02772 02773 LeaveCrit(); 02774 }

VOID ProcessMouseInput PDEVICEINFO  pMouseInfo  ) 
 

Definition at line 1137 of file ntinput.c.

References ACCF_ACCESSENABLED, tagMOUSE_DEVICE_INFO::Attr, CheckCritOut, CheckDeviceInfoListCritOut, tagMOUSE_DEVICE_INFO::Data, EnterCrit, fAbsoluteMouse, FALSE, FKMOUSEMOVE, gbRemoteSession, GDIAF_REFRESH_MOUSE, GetMouseCoord(), gFilterKeysState, gMouseProcessMiceInputTime, gptCursorAsync, gptiBlockInput, gStickyKeysLeftShiftCount, gStickyKeysRightShiftCount, gTermIO, gTermNOIO, gtmridFKActivation, KILLRITTIMER, LeaveCrit, LOGTIME, tagDEVICEINFO::mouse, NT_SUCCESS, NtGetTickCount(), NULL, PtiCurrentShared, tagTERMINAL::ptiDesktop, QueueMouseEvent(), RequestDeviceChange(), TEST_ACCF, VOID(), and xxxMoveEventAbsolute().

01139 { 01140 PMOUSE_INPUT_DATA pmei, pmeiNext; 01141 LONG time; 01142 POINT ptLastMove; 01143 01144 /* 01145 * This is an APC, so we don't need the DeviceInfoList Critical Section 01146 * In fact, we don't want it either. We will not remove the device until 01147 * ProcessMouseInput has signalled that it is OK to do so. (TBD) 01148 */ 01149 CheckCritOut(); 01150 CheckDeviceInfoListCritOut(); 01151 01152 UserAssert(pMouseInfo); 01153 UserAssert((PtiCurrentShared() == gTermIO.ptiDesktop) || 01154 (PtiCurrentShared() == gTermNOIO.ptiDesktop)); 01155 01156 LOGTIME(gMouseProcessMiceInputTime); 01157 01158 if (gptiBlockInput != NULL) { 01159 return; 01160 } 01161 01162 if (TEST_ACCF(ACCF_ACCESSENABLED)) { 01163 /* 01164 * Any mouse movement resets the count of consecutive shift key 01165 * presses. The shift key is used to enable & disable the 01166 * stickykeys accessibility functionality. 01167 */ 01168 gStickyKeysLeftShiftCount = 0; 01169 gStickyKeysRightShiftCount = 0; 01170 01171 /* 01172 * Any mouse movement also cancels the FilterKeys activation timer. 01173 * Entering critsect here breaks non-jerky mouse movement 01174 */ 01175 if (gtmridFKActivation != 0) { 01176 EnterCrit(); 01177 KILLRITTIMER(NULL, gtmridFKActivation); 01178 gtmridFKActivation = 0; 01179 gFilterKeysState = FKMOUSEMOVE; 01180 LeaveCrit(); 01181 return; 01182 } 01183 } 01184 01185 if (!NT_SUCCESS(pMouseInfo->iosb.Status)) { 01186 /* 01187 * If we get a bad status, we abandon reading this mouse. 01188 */ 01189 if (!gbRemoteSession) 01190 if (pMouseInfo->iosb.Status != STATUS_DELETE_PENDING) { 01191 RIPMSG3(RIP_ERROR, "iosb.Status %lx for mouse %#p (id %x) tell IanJa x63321", 01192 pMouseInfo->iosb.Status, 01193 pMouseInfo, pMouseInfo->mouse.Attr.MouseIdentifier); 01194 } 01195 return; 01196 } 01197 01198 /* 01199 * get the last move point from ptCursorAsync 01200 */ 01201 ptLastMove = gptCursorAsync; 01202 01203 pmei = pMouseInfo->mouse.Data; 01204 while (pmei != NULL) { 01205 01206 time = NtGetTickCount(); 01207 01208 /* 01209 * Figure out where the next event is. 01210 */ 01211 pmeiNext = pmei + 1; 01212 if ((PUCHAR)pmeiNext >= 01213 (PUCHAR)(((PUCHAR)pMouseInfo->mouse.Data) + pMouseInfo->iosb.Information)) { 01214 01215 /* 01216 * If there isn't another event set pmeiNext to 01217 * NULL so we exit the loop and don't get confused. 01218 */ 01219 pmeiNext = NULL; 01220 } 01221 01222 /* 01223 * If a PS/2 mouse was plugged in, evaluate the (new) mouse and 01224 * the skip the input record. 01225 */ 01226 if (pmei->Flags & MOUSE_ATTRIBUTES_CHANGED) { 01227 RequestDeviceChange(pMouseInfo, GDIAF_REFRESH_MOUSE, FALSE); 01228 goto NextMouseInputRecord; 01229 } 01230 01231 /* 01232 * First process any mouse movement that occured. 01233 * It is important to process movement before button events, otherwise 01234 * absolute coordinate pointing devices like touch-screens and tablets 01235 * will produce button clicks at old coordinates. 01236 */ 01237 if (pmei->LastX || pmei->LastY) { 01238 01239 /* 01240 * Get the actual point that will be injected. 01241 */ 01242 GetMouseCoord(pmei->LastX, 01243 pmei->LastY, 01244 pmei->Flags, 01245 time, 01246 pmei->ExtraInformation, 01247 &ptLastMove); 01248 01249 /* 01250 * If this is a move-only event, and the next one is also a 01251 * move-only event, skip/coalesce it. 01252 */ 01253 if ( (pmeiNext != NULL) && 01254 (pmei->ButtonFlags == 0) && 01255 (pmeiNext->ButtonFlags == 0) && 01256 (fAbsoluteMouse(pmei) == fAbsoluteMouse(pmeiNext))) { 01257 01258 pmei = pmeiNext; 01259 01260 continue; 01261 } 01262 01263 /* 01264 * Moves the cursor on the screen and updates gptCursorAsync 01265 * Call directly xxxMoveEventAbsolute because we already did the 01266 * acceleration sensitivity and clipping. 01267 */ 01268 xxxMoveEventAbsolute( 01269 ptLastMove.x, 01270 ptLastMove.y, 01271 pmei->ExtraInformation, 01272 time, 01273 FALSE 01274 ); 01275 01276 /* 01277 * Now update ptLastMove with ptCursorAsync because ptLastMove 01278 * doesn't reflect the clipping. 01279 */ 01280 ptLastMove = gptCursorAsync; 01281 } 01282 01283 /* 01284 * Queue mouse event for the other thread to pick up when it finishes 01285 * with the USER critical section. 01286 * If pmeiNext == NULL, there is no more mouse input yet, so wake RIT. 01287 */ 01288 QueueMouseEvent( 01289 pmei->ButtonFlags, 01290 pmei->ButtonData, 01291 pmei->ExtraInformation, 01292 gptCursorAsync, 01293 time, 01294 FALSE, 01295 (pmeiNext == NULL)); 01296 01297 NextMouseInputRecord: 01298 pmei = pmeiNext; 01299 } 01300 01301 return; 01302 }

void ProcessQueuedMouseEvents void   ) 
 

Definition at line 3784 of file ntinput.c.

References tagMOUSEEVENT::ButtonFlags, tagLASTINPUT::dwFlags, EnterCrit, tagMOUSEEVENT::ExtraInfo, FALSE, gdwMouseMoveExtraInfo, glinp, gpDispInfo, gpsi, LeaveCrit, LINP_INPUTTIMEOUTS, LINP_KEYBOARD, LINP_POWERTIMEOUTS, tagDISPLAYINFO::pmdev, tagMOUSEEVENT::ptPointer, tagMOUSEEVENT::time, tagLASTINPUT::timeLastInputMessage, UnqueueMouseEvent(), xxxDoButtonEvent(), and zzzSetFMouseMoved().

Referenced by RawInputThread(), and xxxMouseEventDirect().

03786 { 03787 MOUSEEVENT MouseEvent; 03788 static POINT ptCursorLast = {0,0}; 03789 03790 while (UnqueueMouseEvent(&MouseEvent)) { 03791 03792 EnterCrit(); 03793 03794 // Setup to shutdown screen saver and exit video power down mode. 03795 if (glinp.dwFlags & LINP_POWERTIMEOUTS) { 03796 // Call video driver here to exit power down mode. 03797 KdPrint(("Exit video power down mode\n")); 03798 DrvSetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD0); 03799 } 03800 glinp.dwFlags &= ~(LINP_INPUTTIMEOUTS | LINP_KEYBOARD); 03801 glinp.timeLastInputMessage = gpsi->dwLastRITEventTickCount = MouseEvent.time; 03802 gpsi->bLastRITWasKeyboard = FALSE; 03803 03804 gpsi->ptCursor = MouseEvent.ptPointer; 03805 03806 if ((ptCursorLast.x != gpsi->ptCursor.x) || 03807 (ptCursorLast.y != gpsi->ptCursor.y)) { 03808 03809 /* 03810 * This mouse move ExtraInfo is global (as ptCursor 03811 * was) and is associated with the current ptCursor 03812 * position. ExtraInfo is sent from the driver - pen 03813 * win people use it. 03814 */ 03815 gdwMouseMoveExtraInfo = MouseEvent.ExtraInfo; 03816 03817 ptCursorLast = gpsi->ptCursor; 03818 03819 /* 03820 * Wake up someone. xxxSetFMouseMoved() clears 03821 * dwMouseMoveExtraInfo, so we must then restore it. 03822 */ 03823 zzzSetFMouseMoved(); 03824 03825 gdwMouseMoveExtraInfo = MouseEvent.ExtraInfo; 03826 } 03827 03828 if (MouseEvent.ButtonFlags != 0) { 03829 xxxDoButtonEvent(&MouseEvent); 03830 } 03831 03832 LeaveCrit(); 03833 } 03834 }

PWND PwndForegroundCapture VOID   ) 
 

Definition at line 2912 of file ntinput.c.

References gpqForeground, NULL, and tagQ::spwndCapture.

Referenced by xxxButtonEvent().

02913 { 02914 if (gpqForeground != NULL) { 02915 return gpqForeground->spwndCapture; 02916 } 02917 02918 return NULL; 02919 }

VOID QueueMouseEvent USHORT  ButtonFlags,
USHORT  ButtonData,
ULONG_PTR  ExtraInfo,
POINT  ptMouse,
LONG  time,
BOOL  bInjected,
BOOL  bWakeRIT
 

Definition at line 925 of file ntinput.c.

References tagMOUSEEVENT::bInjected, tagMOUSEEVENT::ButtonData, tagMOUSEEVENT::ButtonFlags, CheckCritOut, EnterMouseCrit(), EVENT_INCREMENT, tagMOUSEEVENT::ExtraInfo, FALSE, gdwMouseEvents, gdwMouseQueueHead, gMouseEventQueue, gMouseQueueMouseEventTime, gpkeMouseData, KeSetEvent(), LeaveMouseCrit(), LOGTIME, NELEM_BUTTONQUEUE, tagMOUSEEVENT::ptPointer, tagMOUSEEVENT::time, UserBeep(), and VOID().

Referenced by ProcessMouseInput(), xxxMKMouseMove(), xxxMKMoveAccelCursorTimer(), xxxMKMoveConstCursorTimer(), and xxxMouseEventDirect().

00934 { 00935 CheckCritOut(); 00936 00937 EnterMouseCrit(); 00938 00939 LOGTIME(gMouseQueueMouseEventTime); 00940 00941 /* 00942 * Button data must always be accompanied by a flag to interpret it. 00943 */ 00944 UserAssert(ButtonData == 0 || ButtonFlags != 0); 00945 00946 /* 00947 * We can coalesce this mouse event with the previous event if there is a 00948 * previous event, and if the previous event and this event involve no 00949 * key transitions. 00950 */ 00951 if ((gdwMouseEvents == 0) || 00952 (ButtonFlags != 0) || 00953 (gMouseEventQueue[gdwMouseQueueHead].ButtonFlags != 0)) { 00954 /* 00955 * Can't coalesce: must add a new mouse event 00956 */ 00957 if (gdwMouseEvents >= NELEM_BUTTONQUEUE) { 00958 /* 00959 * But no more room! 00960 */ 00961 LeaveMouseCrit(); 00962 UserBeep(440, 125); 00963 return; 00964 } 00965 00966 gdwMouseQueueHead = (gdwMouseQueueHead + 1) % NELEM_BUTTONQUEUE; 00967 gMouseEventQueue[gdwMouseQueueHead].ButtonFlags = ButtonFlags; 00968 gMouseEventQueue[gdwMouseQueueHead].ButtonData = ButtonData; 00969 gdwMouseEvents++; 00970 } 00971 00972 gMouseEventQueue[gdwMouseQueueHead].ExtraInfo = ExtraInfo; 00973 gMouseEventQueue[gdwMouseQueueHead].ptPointer = ptMouse; 00974 gMouseEventQueue[gdwMouseQueueHead].time = time; 00975 gMouseEventQueue[gdwMouseQueueHead].bInjected = bInjected; 00976 00977 LeaveMouseCrit(); 00978 00979 if (bWakeRIT) { 00980 /* 00981 * Signal RIT to complete the mouse input processing 00982 */ 00983 KeSetEvent(gpkeMouseData, EVENT_INCREMENT, FALSE); 00984 } 00985 }

VOID RawInputThread PRIT_INIT  pInitData  ) 
 

Definition at line 3858 of file ntinput.c.

References _RegisterHotKey(), aDeviceTemplate, apObjects, BOOL, CheckCritOut, CreateDeviceInfo(), CreateKernelEvent(), DEVICE_TYPE_KEYBOARD, DEVICE_TYPE_MOUSE, DWORD, EnterCrit, EnterDeviceInfoListCrit(), EVENT_INCREMENT, ExEventObjectType, FALSE, gbRemoteSession, gdwUpdateKeyboard, GetPrimaryMonitor(), giosbKbdControl, gklp, gktp, gnRetryReadInput, gpDeviceInfoList, gpDispInfo, gpepCSRSS, gpkeMouseData, gpsi, gptCursorAsync, gptiRit, gptmrMaster, gptmrWD, gpvwplHungRedraw, grcCursorClip, gSessionId, gspwndAltTab, gWaitBlockArray, tagDISPLAYINFO::hDev, HH_RITCREATED, HYDRA_HINT, ID_HIDCHANGE, ID_INPUT, ID_MOUSE, ID_NUMBER_NON_HYDRA_HANDLES, ID_SHUTDOWN, ID_TIMER, ID_WDTIMER, IDHOT_WINDOWS, InitiateWin32kCleanup(), InitKeyboard(), InitMice(), InitSystemThread(), KeInitializeTimer(), KeInitializeTimerEx(), KernelMode, KeSetEvent(), KeWaitForMultipleObjects(), KeWaitForSingleObject(), KTIMER, L, LeaveCrit, LeaveDeviceInfoListCrit(), MAX_SESSION_PATH, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), ObReferenceObjectByPointer(), tagTERMINAL::pEventInputReady, tagTHREADINFO::pEventQueueServer, tagDEVICE_TEMPLATE::pkeHidChange, _RIT_INIT::pRitReadyEvent, ProcessDeviceChanges(), ProcessQueuedMouseEvents(), _RIT_INIT::pTerm, PtiCurrentShared, tagTHREADINFO::pwinsta, PWND_INPUTOWNER, tagMONITOR::rcMonitor, tagDISPLAYINFO::rcScreen, tagTHREADINFO::rpdesk, tagWINDOWSTATION::rpdeskList, RtlInitUnicodeString(), SetDebugHotKeys(), StartTimers(), Status, szName, TIF_DONTJOURNALATTACH, tagTHREADINFO::TIF_flags, TimersProc(), TRUE, UINT, UPDATE_KBD_LEDS, UPDATE_KBD_TYPEMATIC, UserSleep(), VOID(), _EPROCESS::Win32Process, WrUserRequest, xxxReceiveMessages, xxxRegisterForDeviceClassNotifications(), and xxxSwitchDesktop().

03860 { 03861 KPRIORITY Priority; 03862 NTSTATUS Status; 03863 UNICODE_STRING strRIT; 03864 PKEVENT pEvent; 03865 UINT NumberOfHandles = ID_NUMBER_NON_HYDRA_HANDLES; 03866 PTERMINAL pTerm; 03867 PMONITOR pMonitorPrimary; 03868 HANDLE hevtShutDown; 03869 static DWORD nLastRetryReadInput = 0; 03870 03871 if (gbRemoteSession) { 03872 NumberOfHandles += 2; 03873 } 03874 03875 pTerm = pInitData->pTerm; 03876 03877 /* 03878 * Initialize GDI accelerators. Identify this thread as a server thread. 03879 */ 03880 apObjects = UserAllocPoolNonPaged(NumberOfHandles * sizeof(PVOID), TAG_SYSTEM); 03881 03882 gWaitBlockArray = UserAllocPoolNonPaged(NumberOfHandles * sizeof(KWAIT_BLOCK), 03883 TAG_SYSTEM); 03884 03885 if (apObjects == NULL || gWaitBlockArray == NULL) { 03886 RIPMSG0(RIP_WARNING, "RIT failed to allocate memory"); 03887 goto Exit; 03888 } 03889 03890 /* 03891 * Set the priority of the RIT to 19. 03892 */ 03893 Priority = LOW_REALTIME_PRIORITY + 3; 03894 03895 ZwSetInformationThread(NtCurrentThread(), 03896 ThreadPriority, 03897 &Priority, 03898 sizeof(KPRIORITY)); 03899 03900 RtlInitUnicodeString(&strRIT, L"WinSta0_RIT"); 03901 03902 /* 03903 * Create an event for signalling mouse/kbd attach/detach and device-change 03904 * notifications such as QueryRemove, RemoveCancelled etc. 03905 */ 03906 aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange = 03907 apObjects[ID_HIDCHANGE] = 03908 CreateKernelEvent(SynchronizationEvent, FALSE); 03909 aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange = 03910 CreateKernelEvent(SynchronizationEvent, FALSE); 03911 03912 /* 03913 * Create an event for desktop threads to pass mouse input to RIT 03914 */ 03915 apObjects[ID_MOUSE] = CreateKernelEvent(SynchronizationEvent, FALSE); 03916 gpkeMouseData = apObjects[ID_MOUSE]; 03917 03918 if (aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange == NULL || 03919 apObjects[ID_HIDCHANGE] == NULL || 03920 gpkeMouseData == NULL) { 03921 RIPMSG0(RIP_WARNING, "RIT failed to create a required input event"); 03922 goto Exit; 03923 } 03924 03925 /* 03926 * Initialize keyboard device driver. 03927 */ 03928 EnterCrit(); 03929 InitKeyboard(); 03930 InitMice(); 03931 LeaveCrit(); 03932 03933 Status = InitSystemThread(&strRIT); 03934 03935 if (!NT_SUCCESS(Status)) { 03936 RIPMSG0(RIP_WARNING, "RIT failed InitSystemThread"); 03937 goto Exit; 03938 } 03939 03940 UserAssert(gpepCSRSS != NULL); 03941 03942 /* 03943 * Allow the system to read the screen 03944 */ 03945 ((PW32PROCESS)gpepCSRSS->Win32Process)->W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED|W32PF_IOWINSTA); 03946 03947 /* 03948 * Initialize the cursor clipping rectangle to the screen rectangle. 03949 */ 03950 UserAssert(gpDispInfo != NULL); 03951 grcCursorClip = gpDispInfo->rcScreen; 03952 03953 /* 03954 * Initialize gpsi->ptCursor and gptCursorAsync 03955 */ 03956 pMonitorPrimary = GetPrimaryMonitor(); 03957 03958 UserAssert(gpsi != NULL); 03959 03960 gpsi->ptCursor.x = pMonitorPrimary->rcMonitor.right / 2; 03961 gpsi->ptCursor.y = pMonitorPrimary->rcMonitor.bottom / 2; 03962 gptCursorAsync = gpsi->ptCursor; 03963 03964 /* 03965 * The hung redraw list should already be set to NULL by the compiler, 03966 * linker & loader since it is an uninitialized global variable. Memory will 03967 * be allocated the first time a pwnd is added to this list (hungapp.c) 03968 */ 03969 UserAssert(gpvwplHungRedraw == NULL); 03970 03971 /* 03972 * Initialize the pre-defined hotkeys 03973 */ 03974 EnterCrit(); 03975 _RegisterHotKey(PWND_INPUTOWNER, IDHOT_WINDOWS, MOD_WIN, VK_NONE); 03976 SetDebugHotKeys(); 03977 LeaveCrit(); 03978 03979 /* 03980 * Create a timer for timers. 03981 */ 03982 gptmrMaster = UserAllocPoolNonPaged(sizeof(KTIMER), 03983 TAG_SYSTEM); 03984 if (gptmrMaster == NULL) { 03985 RIPMSG0(RIP_WARNING, "RIT failed to create gptmrMaster"); 03986 goto Exit; 03987 } 03988 03989 KeInitializeTimer(gptmrMaster); 03990 apObjects[ID_TIMER] = gptmrMaster; 03991 03992 /* 03993 * Create an event for mouse device reads to signal the desktop thread to 03994 * move the pointer and QueueMouseEvent(). 03995 * We should do this *before* we have any devices. 03996 */ 03997 UserAssert(gpDeviceInfoList == NULL); 03998 03999 if (gbRemoteSession) { 04000 04001 OBJECT_ATTRIBUTES obja; 04002 UNICODE_STRING ustrName; 04003 BOOL fSuccess = TRUE; 04004 WCHAR szName[MAX_SESSION_PATH]; 04005 04006 /* 04007 * Create and initialize a timer object 04008 * and pass a pointer to this object via the display driver to the WD. 04009 * The RIT will do a KeWaitForObject() on this timer object. 04010 * When the WD calls KeSetTimer() it will NOT specify a DPC routine. 04011 * When the timer goes off the RIT will get signaled and will make the 04012 * appropriate call to the display driver to flush the frame buffer. 04013 */ 04014 gptmrWD = UserAllocPoolNonPaged(sizeof(KTIMER), TAG_SYSTEM); 04015 04016 if (gptmrWD == NULL) { 04017 RIPMSG0(RIP_WARNING, "RIT failed to create gptmrWD"); 04018 goto Exit; 04019 } 04020 04021 KeInitializeTimerEx(gptmrWD, SynchronizationTimer); 04022 apObjects[ID_WDTIMER] = gptmrWD; 04023 04024 RtlInitUnicodeString(&ustrName, NULL); 04025 04026 /* 04027 * Pass a pointer to the timer to the WD via the display driver 04028 */ 04029 EnterCrit(); 04030 fSuccess &= !!HDXDrvEscape(gpDispInfo->hDev, 04031 ESC_SET_WD_TIMEROBJ, 04032 (PVOID)gptmrWD, 04033 sizeof(gptmrWD)); 04034 04035 fSuccess &= !!CreateDeviceInfo(DEVICE_TYPE_MOUSE, &ustrName, 0); 04036 fSuccess &= !!CreateDeviceInfo(DEVICE_TYPE_KEYBOARD, &ustrName, 0); 04037 04038 LeaveCrit(); 04039 04040 if (!fSuccess) { 04041 RIPMSG0(RIP_WARNING, 04042 "RIT failed HDXDrvEscape or the creation of input devices"); 04043 goto Exit; 04044 } 04045 04046 /* 04047 * Create the shutdown event. This event will be signaled 04048 * from W32WinStationTerminate. 04049 * This is a named event opend by CSR to signal that win32k should 04050 * go away. It's used in ntuser\server\api.c 04051 */ 04052 swprintf(szName, L"\\Sessions\\%ld\\BaseNamedObjects\\EventShutDownCSRSS", 04053 gSessionId); 04054 RtlInitUnicodeString(&ustrName, szName); 04055 04056 InitializeObjectAttributes(&obja, 04057 &ustrName, 04058 OBJ_CASE_INSENSITIVE, 04059 NULL, 04060 NULL); 04061 04062 Status = ZwCreateEvent(&hevtShutDown, 04063 EVENT_ALL_ACCESS, 04064 &obja, 04065 SynchronizationEvent, 04066 FALSE); 04067 04068 if (!NT_SUCCESS(Status)) { 04069 RIPMSG0(RIP_WARNING, "RIT failed to create EventShutDownCSRSS"); 04070 goto Exit; 04071 } 04072 04073 ObReferenceObjectByHandle(hevtShutDown, 04074 EVENT_ALL_ACCESS, 04075 *ExEventObjectType, 04076 KernelMode, 04077 &apObjects[ID_SHUTDOWN], 04078 NULL); 04079 } else { 04080 EnterCrit(); 04081 04082 /* 04083 * Register for Plug and Play devices. 04084 * If any PnP devices are already attached, these will be opened and 04085 * we will start reading them at this time. 04086 */ 04087 xxxRegisterForDeviceClassNotifications(); 04088 04089 LeaveCrit(); 04090 } 04091 04092 /* 04093 * Get the rit-thread. 04094 */ 04095 gptiRit = PtiCurrentShared(); 04096 04097 HYDRA_HINT(HH_RITCREATED); 04098 04099 /* 04100 * Don't allow this thread to get involved with journal synchronization. 04101 */ 04102 gptiRit->TIF_flags |= TIF_DONTJOURNALATTACH; 04103 04104 /* 04105 * Also wait on our input event so the cool switch window can 04106 * receive messages. 04107 */ 04108 apObjects[ID_INPUT] = gptiRit->pEventQueueServer; 04109 04110 /* 04111 * Signal that the rit has been initialized 04112 */ 04113 KeSetEvent(pInitData->pRitReadyEvent, EVENT_INCREMENT, FALSE); 04114 04115 /* 04116 * Since this is a SYSTEM-THREAD, we should set the pwinsta 04117 * pointer in the SystemInfoThread to assure that if any 04118 * paints occur from the input-thread, we can process them 04119 * in DoPaint(). 04120 * 04121 * Set the winsta after the first desktop is created. 04122 */ 04123 gptiRit->pwinsta = NULL; 04124 04125 pEvent = pTerm->pEventInputReady; 04126 04127 /* 04128 * Wait until the first desktop is created. 04129 */ 04130 ObReferenceObjectByPointer(pEvent, 04131 EVENT_ALL_ACCESS, 04132 *ExEventObjectType, 04133 KernelMode); 04134 04135 KeWaitForSingleObject(pEvent, WrUserRequest, KernelMode, FALSE, NULL); 04136 ObDereferenceObject(pEvent); 04137 04138 /* 04139 * Switch to the first desktop if no switch has been 04140 * performed. 04141 */ 04142 EnterCrit(); 04143 04144 if (gptiRit->rpdesk == NULL) { 04145 UserVerify(xxxSwitchDesktop(gptiRit->pwinsta, gptiRit->pwinsta->rpdeskList, FALSE)); 04146 } 04147 04148 /* 04149 * Create a timer for hung app detection/redrawing. 04150 */ 04151 StartTimers(); 04152 04153 LeaveCrit(); 04154 04155 /* 04156 * Go into a wait loop so we can process input events and APCs as 04157 * they occur. 04158 */ 04159 while (TRUE) { 04160 04161 CheckCritOut(); 04162 04163 Status = KeWaitForMultipleObjects(NumberOfHandles, 04164 apObjects, 04165 WaitAny, 04166 WrUserRequest, 04167 KernelMode, 04168 TRUE, 04169 NULL, 04170 gWaitBlockArray); 04171 04172 UserAssert(NT_SUCCESS(Status)); 04173 04174 if (gdwUpdateKeyboard != 0) { 04175 /* 04176 * Here's our opportunity to process pending IOCTLs for the kbds: 04177 * These are asynchronous IOCTLS, so be sure any buffers passed 04178 * in to ZwDeviceIoControlFile are not in the stack! 04179 * Using gdwUpdateKeyboard to tell the RIT to issue these IOCTLS 04180 * renders the action asynchronous (delayed until next apObjects 04181 * event), but the IOCTL was asynch anyway 04182 */ 04183 PDEVICEINFO pDeviceInfo; 04184 EnterDeviceInfoListCrit(); 04185 for (pDeviceInfo = gpDeviceInfoList; pDeviceInfo; pDeviceInfo = pDeviceInfo->pNext) { 04186 if ((pDeviceInfo->type == DEVICE_TYPE_KEYBOARD) && (pDeviceInfo->handle)) { 04187 if (gdwUpdateKeyboard & UPDATE_KBD_TYPEMATIC) { 04188 ZwDeviceIoControlFile(pDeviceInfo->handle, NULL, NULL, NULL, 04189 &giosbKbdControl, IOCTL_KEYBOARD_SET_TYPEMATIC, 04190 (PVOID)&gktp, sizeof(gktp), NULL, 0); 04191 } 04192 if (gdwUpdateKeyboard & UPDATE_KBD_LEDS) { 04193 ZwDeviceIoControlFile(pDeviceInfo->handle, NULL, NULL, NULL, 04194 &giosbKbdControl, IOCTL_KEYBOARD_SET_INDICATORS, 04195 (PVOID)&gklp, sizeof(gklp), NULL, 0); 04196 } 04197 } 04198 } 04199 LeaveDeviceInfoListCrit(); 04200 gdwUpdateKeyboard &= ~(UPDATE_KBD_TYPEMATIC | UPDATE_KBD_LEDS); 04201 } 04202 04203 if (Status == ID_MOUSE) { 04204 /* 04205 * A desktop thread got some Mouse input for us. Process it. 04206 */ 04207 ProcessQueuedMouseEvents(); 04208 04209 } else if (Status == ID_HIDCHANGE) { 04210 TAGMSG0(DBGTAG_PNP | RIP_THERESMORE, "RIT wakes for HID Change"); 04211 EnterCrit(); 04212 ProcessDeviceChanges(DEVICE_TYPE_KEYBOARD); 04213 LeaveCrit(); 04214 } else if (Status == ID_SHUTDOWN) { 04215 04216 InitiateWin32kCleanup(); 04217 04218 ZwClose(hevtShutDown); 04219 04220 break; 04221 04222 } else if (Status == ID_WDTIMER) { 04223 //LARGE_INTEGER liTemp; 04224 04225 EnterCrit(); 04226 04227 UserAssert(gbRemoteSession); 04228 04229 /* 04230 * Call the TShare display driver to flush the frame buffer 04231 */ 04232 04233 if (!HDXDrvEscape(gpDispInfo->hDev, ESC_TIMEROBJ_SIGNALED, NULL, 0)) { 04234 UserAssert(FALSE); 04235 } 04236 LeaveCrit(); 04237 04238 } else { 04239 /* 04240 * If the master timer has expired, then process the timer 04241 * list. Otherwise, an APC caused the raw input thread to be 04242 * awakened. 04243 */ 04244 if (Status == ID_TIMER) { 04245 TimersProc(); 04246 /* 04247 * If an input degvice read failed due to insufficient resources, 04248 * we retry by signalling the proper thread: ProcessDeviceChanges 04249 * will call RetryReadInput(). 04250 */ 04251 if (gnRetryReadInput != nLastRetryReadInput) { 04252 nLastRetryReadInput = gnRetryReadInput; 04253 KeSetEvent(aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange, EVENT_INCREMENT, FALSE); 04254 KeSetEvent(aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange, EVENT_INCREMENT, FALSE); 04255 } 04256 } 04257 04258 #if DBG 04259 /* 04260 * In the debugger set gBlockSleep to n: 04261 * The RIT will sleep n millicseconds, then n timer ticks later 04262 * will sleep n milliseconds again. 04263 */ 04264 if (gBlockDelay) { 04265 gBlockDelay--; 04266 } else if ((gBlockDelay == 0) && (gBlockSleep != 0)) { 04267 UserSleep(gBlockSleep); 04268 gBlockDelay = 100 * gBlockSleep; 04269 } 04270 #endif 04271 04272 /* 04273 * if in cool task switcher window, dispose of the messages 04274 * on the queue 04275 */ 04276 if (gspwndAltTab != NULL) { 04277 EnterCrit(); 04278 xxxReceiveMessages(gptiRit); 04279 LeaveCrit(); 04280 } 04281 } 04282 } 04283 04284 return; 04285 04286 Exit: 04287 04288 UserAssert(gptiRit == NULL); 04289 04290 /* 04291 * Signal that the rit has been initialized 04292 */ 04293 KeSetEvent(pInitData->pRitReadyEvent, EVENT_INCREMENT, FALSE); 04294 04295 RIPMSG0(RIP_WARNING, "RIT initialization failure"); 04296 return; 04297 }

VOID RawInputThread PVOID  pVoid  ) 
 

Referenced by xxxInitInput().

void RemoteSyncToggleKeys ULONG  toggleKeys  ) 
 

Definition at line 2527 of file ntinput.c.

References BYTE, CheckCritIn, FALSE, GetActiveHKL(), gpqForeground, gSetLedReceived, NULL, TestRawKeyToggle, and xxxProcessKeyEvent().

Referenced by ProcessKeyboardInput().

02528 { 02529 KE ke; 02530 02531 CheckCritIn(); 02532 gSetLedReceived = toggleKeys | KEYBOARD_LED_INJECTED; 02533 02534 // Key injection only works if there is a ready application queue. 02535 if (gpqForeground != NULL) { 02536 02537 if (((gSetLedReceived & KEYBOARD_CAPS_LOCK_ON) && 02538 !TestRawKeyToggle(VK_CAPITAL)) || 02539 (!(gSetLedReceived & KEYBOARD_CAPS_LOCK_ON) && 02540 TestRawKeyToggle(VK_CAPITAL))) { 02541 02542 ke.bScanCode = (BYTE)(0x3a); 02543 ke.usFlaggedVk = VK_CAPITAL; 02544 xxxProcessKeyEvent(&ke, 0, FALSE); 02545 02546 ke.bScanCode = (BYTE)(0xba); 02547 ke.usFlaggedVk = VK_CAPITAL | KBDBREAK; 02548 xxxProcessKeyEvent(&ke, 0, FALSE); 02549 } 02550 02551 if (((gSetLedReceived & KEYBOARD_NUM_LOCK_ON) && 02552 !TestRawKeyToggle(VK_NUMLOCK)) || 02553 (!(gSetLedReceived & KEYBOARD_NUM_LOCK_ON) && 02554 TestRawKeyToggle(VK_NUMLOCK))) { 02555 02556 ke.bScanCode = (BYTE)(0x45); 02557 ke.usFlaggedVk = VK_NUMLOCK; 02558 xxxProcessKeyEvent(&ke, 0, FALSE); 02559 02560 ke.bScanCode = (BYTE)(0xc5); 02561 ke.usFlaggedVk = VK_NUMLOCK | KBDBREAK; 02562 xxxProcessKeyEvent(&ke, 0, FALSE); 02563 } 02564 02565 if (((gSetLedReceived & KEYBOARD_SCROLL_LOCK_ON) && 02566 !TestRawKeyToggle(VK_SCROLL)) || 02567 (!(gSetLedReceived & KEYBOARD_SCROLL_LOCK_ON) && 02568 TestRawKeyToggle(VK_SCROLL))) { 02569 02570 ke.bScanCode = (BYTE)(0x46); 02571 ke.usFlaggedVk = VK_SCROLL; 02572 xxxProcessKeyEvent(&ke, 0, FALSE); 02573 02574 ke.bScanCode = (BYTE)(0xc6); 02575 ke.usFlaggedVk = VK_SCROLL | KBDBREAK; 02576 xxxProcessKeyEvent(&ke, 0, FALSE); 02577 } 02578 02579 if (JAPANESE_KBD_LAYOUT(GetActiveHKL())) { 02580 if (((gSetLedReceived & KEYBOARD_KANA_LOCK_ON) && 02581 !TestRawKeyToggle(VK_KANA)) || 02582 (!(gSetLedReceived & KEYBOARD_KANA_LOCK_ON) && 02583 TestRawKeyToggle(VK_KANA))) { 02584 02585 ke.bScanCode = (BYTE)(0x70); 02586 ke.usFlaggedVk = VK_KANA; 02587 xxxProcessKeyEvent(&ke, 0, FALSE); 02588 02589 ke.bScanCode = (BYTE)(0xf0); 02590 ke.usFlaggedVk = VK_KANA | KBDBREAK; 02591 xxxProcessKeyEvent(&ke, 0, FALSE); 02592 } 02593 } 02594 02595 gSetLedReceived = 0; 02596 } 02597 }

VOID SetKeyboardRate UINT  nKeySpeedAndDelay  ) 
 

Definition at line 2932 of file ntinput.c.

References gdwUpdateKeyboard, gKeyboardInfo, gktp, KDELAY_MASK, KDELAY_SHIFT, KSPEED_MASK, UINT, UPDATE_KBD_TYPEMATIC, USHORT, and VOID().

Referenced by LW_DriversInit(), and xxxSystemParametersInfo().

02935 { 02936 UINT nKeyDelay; 02937 UINT nKeySpeed; 02938 02939 nKeyDelay = (nKeySpeedAndDelay & KDELAY_MASK) >> KDELAY_SHIFT; 02940 02941 nKeySpeed = KSPEED_MASK & nKeySpeedAndDelay; 02942 02943 gktp.Rate = (USHORT)( ( gKeyboardInfo.KeyRepeatMaximum.Rate - 02944 gKeyboardInfo.KeyRepeatMinimum.Rate 02945 ) * nKeySpeed / KSPEED_MASK 02946 ) + 02947 gKeyboardInfo.KeyRepeatMinimum.Rate; 02948 02949 gktp.Delay = (USHORT)( ( gKeyboardInfo.KeyRepeatMaximum.Delay - 02950 gKeyboardInfo.KeyRepeatMinimum.Delay 02951 ) * nKeyDelay / (KDELAY_MASK >> KDELAY_SHIFT) 02952 ) + 02953 gKeyboardInfo.KeyRepeatMinimum.Delay; 02954 02955 /* 02956 * Hand off the IOCTL to the RIT, since only the system process can 02957 * access keyboard handles 02958 */ 02959 gdwUpdateKeyboard |= UPDATE_KBD_TYPEMATIC; 02960 }

BOOL UnqueueMouseEvent PMOUSEEVENT  pme  ) 
 

Definition at line 997 of file ntinput.c.

References BOOL, DWORD, EnterMouseCrit(), FALSE, gdwMouseEvents, gdwMouseQueueHead, gMouseEventQueue, gMouseUnqueueMouseEventTime, LeaveMouseCrit(), LOGTIME, NELEM_BUTTONQUEUE, PMOUSEEVENT, and TRUE.

Referenced by ProcessQueuedMouseEvents().

01000 { 01001 DWORD dwTail; 01002 01003 EnterMouseCrit(); 01004 01005 LOGTIME(gMouseUnqueueMouseEventTime); 01006 01007 if (gdwMouseEvents == 0) { 01008 LeaveMouseCrit(); 01009 return FALSE; 01010 } else { 01011 dwTail = (gdwMouseQueueHead - gdwMouseEvents + 1) % NELEM_BUTTONQUEUE; 01012 *pme = gMouseEventQueue[dwTail]; 01013 gdwMouseEvents--; 01014 } 01015 01016 LeaveMouseCrit(); 01017 return TRUE; 01018 }

VOID UpdateKeyLights BOOL  bInjected  ) 
 

Definition at line 2985 of file ntinput.c.

References CheckCritIn, ClearRawKeyToggle, DEVICE_TYPE_KEYBOARD, EnterDeviceInfoListCrit(), gbRemoteSession, gdwUpdateKeyboard, giosbKbdControl, gKeyboardInfo, gklp, gpDeviceInfoList, gptiRit, LeaveDeviceInfoListCrit(), NULL, PtiCurrent, SetRawKeyToggle, TestAsyncKeyStateToggle, UPDATE_KBD_LEDS, and VOID().

Referenced by _SetKeyboardState(), ChangeForegroundKeyboardTable(), ProcessDeviceChanges(), RemotePassthruDisable(), UpdatePerUserKeyboardIndicators(), xxxKeyEvent(), and xxxRemoteReconnect().

02986 { 02987 /* 02988 * Looking at async keystate. Must be in critical section. 02989 */ 02990 CheckCritIn(); 02991 02992 /* 02993 * Based on the toggle bits in the async keystate table, 02994 * set the key lights. 02995 */ 02996 gklp.LedFlags = 0; 02997 if (TestAsyncKeyStateToggle(VK_CAPITAL)) { 02998 gklp.LedFlags |= KEYBOARD_CAPS_LOCK_ON; 02999 SetRawKeyToggle(VK_CAPITAL); 03000 } else { 03001 ClearRawKeyToggle(VK_CAPITAL); 03002 } 03003 03004 if (TestAsyncKeyStateToggle(VK_NUMLOCK)) { 03005 gklp.LedFlags |= KEYBOARD_NUM_LOCK_ON; 03006 SetRawKeyToggle(VK_NUMLOCK); 03007 } else { 03008 ClearRawKeyToggle(VK_NUMLOCK); 03009 } 03010 03011 if (TestAsyncKeyStateToggle(VK_SCROLL)) { 03012 gklp.LedFlags |= KEYBOARD_SCROLL_LOCK_ON; 03013 SetRawKeyToggle(VK_SCROLL); 03014 } else { 03015 ClearRawKeyToggle(VK_SCROLL); 03016 } 03017 03018 /* 03019 * Only "Japanese keyboard hardware" has "KANA" LEDs, and switch to 03020 * "KANA" state. 03021 */ 03022 if (JAPANESE_KEYBOARD(gKeyboardInfo.KeyboardIdentifier)) { 03023 if (TestAsyncKeyStateToggle(VK_KANA)) { 03024 gklp.LedFlags |= KEYBOARD_KANA_LOCK_ON; 03025 SetRawKeyToggle(VK_KANA); 03026 } else { 03027 ClearRawKeyToggle(VK_KANA); 03028 } 03029 } 03030 03031 /* 03032 * On terminal server, we need to tell the WD about application injected 03033 * toggle keys so it can update the client accordingly. 03034 */ 03035 if (gbRemoteSession) { 03036 if (bInjected) 03037 gklp.LedFlags |= KEYBOARD_LED_INJECTED; 03038 else 03039 gklp.LedFlags &= ~KEYBOARD_LED_INJECTED; 03040 } 03041 03042 03043 if (PtiCurrent() != gptiRit) { 03044 /* 03045 * Hand off the IOCTL to the RIT, since only the system process can 03046 * access the keyboard handles. Happens when applying user's profile. 03047 * IanJa: Should we check PpiCurrent() == gptiRit->ppi instead? 03048 */ 03049 gdwUpdateKeyboard |= UPDATE_KBD_LEDS; 03050 } else { 03051 /* 03052 * Do it immediately (avoids a small delay between keydown and LED 03053 * on when typing) 03054 */ 03055 PDEVICEINFO pDeviceInfo; 03056 03057 EnterDeviceInfoListCrit(); 03058 for (pDeviceInfo = gpDeviceInfoList; pDeviceInfo; pDeviceInfo = pDeviceInfo->pNext) { 03059 if ((pDeviceInfo->type == DEVICE_TYPE_KEYBOARD) && (pDeviceInfo->handle)) { 03060 ZwDeviceIoControlFile(pDeviceInfo->handle, NULL, NULL, NULL, 03061 &giosbKbdControl, IOCTL_KEYBOARD_SET_INDICATORS, 03062 (PVOID)&gklp, sizeof(gklp), NULL, 0); 03063 } 03064 } 03065 LeaveDeviceInfoListCrit(); 03066 } 03067 }

void UpdateMouseInfo void   ) 
 

Definition at line 385 of file ntinput.c.

References CheckCritIn, DEVICE_TYPE_MOUSE, DEVICEINFO, EnterDeviceInfoListCrit(), gbRemoteSession, GDIAF_ARRIVED, GDIAF_RECONNECT, ghRemoteMouseChannel, gnMice, gpDeviceInfoList, LeaveDeviceInfoListCrit(), NULL, RequestDeviceChange(), and TRUE.

Referenced by xxxRemoteReconnect().

00386 { 00387 DEVICEINFO *pDeviceInfo; 00388 CheckCritIn(); // expect no surprises 00389 00390 UserAssert(gbRemoteSession); 00391 00392 if (ghRemoteMouseChannel == NULL) { 00393 return; 00394 } 00395 00396 UserAssert(gnMice == 1); 00397 00398 /* 00399 * Mark the mice and signal the RIT to do the work asynchronously 00400 */ 00401 EnterDeviceInfoListCrit(); 00402 for (pDeviceInfo = gpDeviceInfoList; pDeviceInfo; pDeviceInfo = pDeviceInfo->pNext) { 00403 if (pDeviceInfo->type == DEVICE_TYPE_MOUSE) { 00404 TAGMSG1(DBGTAG_PNP, "UpdateMouseInfo(): pDeviceInfo %#p ARRIVED", pDeviceInfo); 00405 RequestDeviceChange(pDeviceInfo, GDIAF_ARRIVED | GDIAF_RECONNECT, TRUE); 00406 } 00407 } 00408 LeaveDeviceInfoListCrit(); 00409 }

void UpdateRawKeyState BYTE  Vk,
BOOL  fBreak
 

Definition at line 2061 of file ntinput.c.

References CheckCritIn, ClearRawKeyDown, SetRawKeyDown, TestRawKeyDown, and ToggleRawKeyToggle.

Referenced by xxxProcessKeyEvent().

02064 { 02065 CheckCritIn(); 02066 02067 if (fBreak) { 02068 ClearRawKeyDown(Vk); 02069 } else { 02070 02071 /* 02072 * This is a key make. If the key was not already down, update the 02073 * physical toggle bit. 02074 */ 02075 if (!TestRawKeyDown(Vk)) { 02076 ToggleRawKeyToggle(Vk); 02077 } 02078 02079 /* 02080 * This is a make, so turn on the physical key down bit. 02081 */ 02082 SetRawKeyDown(Vk); 02083 } 02084 }

VOID xxxButtonEvent DWORD  ButtonNumber,
POINT  ptPointer,
BOOL  fBreak,
DWORD  time,
ULONG_PTR  ExtraInfo,
BOOL  bInjected,
BOOL  fDblClk
 

Definition at line 472 of file ntinput.c.

References _PostMessage(), BOOL, CFIME, CheckCritIn, CMSHUNGAPPTIMEOUT, tagTHREADINFO::dwExpWinVer, DWORD, tagWINDOWSTATION::dwWSF_Flags, EVENT_INCREMENT, FALSE, FHungApp(), gbMouseButtonsRecentlySwapped, GetActiveHKL(), GetAppImeCompatFlags(), GETPTI, GetTopLevelWindow(), glinp, gpEventHungThread, gpqForeground, gpsi, grpdeskRitInput, gspwndAltTab, gspwndMouseOwner, gspwndScreenCapture, gwMouseOwnerButton, IS_IME_ENABLED, IsMenuStarted(), ISTS, KeSetEvent(), Lock, MOUSE_BUTTON_LEFT, MOUSE_BUTTON_MIDDLE, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_X1, MOUSE_BUTTON_X2, MouseKeys(), NULL, tagDESKTOP::pDeskInfo, PhkFirstValid(), PostEventMessage(), PostInputMessage(), PostMove(), PtiCurrent, tagLASTINPUT::ptiLastWoken, tagQ::ptiMouse, tagLASTINPUT::ptLastClick, PwndForegroundCapture(), QEVENT_CANCELMODE, QF_MOUSEMOVED, tagDESKTOP::rpwinstaParent, SHORT, SpeedHitTest(), tagDESKTOPINFO::spwnd, tagQ::spwndCapture, tagTHREADINFO::spwndDefaultIme, SYSMET, TEST_ACCESSFLAG, TestAsyncKeyStateDown, TestCF, TestWF, ThreadLockAlways, ThreadUnlock, UINT, Unlock, UpdateAsyncKeyState(), VER40, VOID(), WEFNOACTIVATE, WFINDESTROY, WSF_NOIO, xxxCallHook2(), xxxCancelCoolSwitch(), xxxHardwareMouseKeyUp(), and xxxSetForegroundWindow2().

Referenced by xxxDoButtonEvent(), xxxMKButtonSetState(), and xxxRemoteStopScreenUpdates().

00480 { 00481 UINT message, usVK, usOtherVK, wHardwareButton; 00482 PWND pwnd; 00483 LPARAM lParam; 00484 WPARAM wParam; 00485 int xbutton; 00486 TL tlpwnd; 00487 PHOOK pHook; 00488 00489 #ifdef REDIRECTION 00490 PWND pwndStart; 00491 #endif // REDIRECTION 00492 00493 CheckCritIn(); 00494 00495 00496 /* 00497 * Cancel Alt-Tab if the user presses a mouse button 00498 */ 00499 if (gspwndAltTab != NULL) { 00500 xxxCancelCoolSwitch(); 00501 } 00502 00503 /* 00504 * Grab the mouse button before we process any button swapping. 00505 * This is so we won't get confused if someone calls 00506 * SwapMouseButtons() inside a down-click/up-click. 00507 */ 00508 wHardwareButton = (UINT)ButtonNumber; 00509 00510 /* 00511 * If this is the left or right mouse button, we have to handle mouse 00512 * button swapping. 00513 */ 00514 if (ButtonNumber & (MOUSE_BUTTON_LEFT | MOUSE_BUTTON_RIGHT)) { 00515 /* 00516 * If button swapping is on, swap the mouse buttons 00517 */ 00518 if (SYSMET(SWAPBUTTON)) { 00519 ButtonNumber ^= (MOUSE_BUTTON_LEFT | MOUSE_BUTTON_RIGHT); 00520 } 00521 00522 /* 00523 * Figure out VK 00524 */ 00525 if (ButtonNumber == MOUSE_BUTTON_RIGHT) { 00526 usVK = VK_RBUTTON; 00527 usOtherVK = VK_LBUTTON; 00528 } else if (ButtonNumber == MOUSE_BUTTON_LEFT) { 00529 usVK = VK_LBUTTON; 00530 usOtherVK = VK_RBUTTON; 00531 } else { 00532 RIPMSG1(RIP_ERROR, "Unexpected Button number %d", ButtonNumber); 00533 } 00534 00535 /* 00536 * If the mouse buttons have recently been swapped AND the button 00537 * transition doesn't match what we have in our keystate, then swap the 00538 * button to match. 00539 * This is to fix the ruler (tabs and margins) in Word 97 SR1, which 00540 * calls SwapMouseButtons(0) to determine if button swapping is on, and 00541 * if so then calls SwapMouseButtons(1) to restore it: if we receive a 00542 * button event between these two calls, we may swap incorrectly, and 00543 * be left with a mouse button stuck down or see the wrong button going 00544 * down. This really messed up single/double button tab/margin setting! 00545 * The same bug shows up under Windows '95, although very infrequently: 00546 * Word 9 will use GetSystemMetrics(SM_SWAPBUTTON) instead according to 00547 * to Mark Walker (MarkWal). (IanJa) #165157 00548 */ 00549 if (gbMouseButtonsRecentlySwapped) { 00550 if ((!fBreak == !!TestAsyncKeyStateDown(usVK)) && 00551 (fBreak == !!TestAsyncKeyStateDown(usOtherVK))) { 00552 RIPMSG4(RIP_WARNING, "Correct %s %s to %s %s", 00553 ButtonNumber == MOUSE_BUTTON_LEFT ? "Left" : "Right", 00554 fBreak ? "Up" : "Down", 00555 ButtonNumber == MOUSE_BUTTON_LEFT ? "Right" : "Left", 00556 fBreak ? "Up" : "Down"); 00557 ButtonNumber ^= (MOUSE_BUTTON_LEFT | MOUSE_BUTTON_RIGHT); 00558 usVK = usOtherVK; 00559 } 00560 gbMouseButtonsRecentlySwapped = FALSE; 00561 } 00562 } 00563 00564 xbutton = 0; 00565 switch (ButtonNumber) { 00566 case MOUSE_BUTTON_RIGHT: 00567 if (fBreak) { 00568 message = WM_RBUTTONUP; 00569 } else { 00570 if (ISTS() && fDblClk) 00571 message = WM_RBUTTONDBLCLK; 00572 else 00573 message = WM_RBUTTONDOWN; 00574 } 00575 break; 00576 00577 case MOUSE_BUTTON_LEFT: 00578 if (fBreak) { 00579 message = WM_LBUTTONUP; 00580 } else { 00581 if (ISTS() && fDblClk) 00582 message = WM_LBUTTONDBLCLK; 00583 else 00584 message = WM_LBUTTONDOWN; 00585 } 00586 break; 00587 00588 case MOUSE_BUTTON_MIDDLE: 00589 if (fBreak) { 00590 message = WM_MBUTTONUP; 00591 } else { 00592 if (ISTS() && fDblClk) 00593 message = WM_MBUTTONDBLCLK; 00594 else 00595 message = WM_MBUTTONDOWN; 00596 } 00597 usVK = VK_MBUTTON; 00598 break; 00599 00600 case MOUSE_BUTTON_X1: 00601 case MOUSE_BUTTON_X2: 00602 if (fBreak) { 00603 message = WM_XBUTTONUP; 00604 } else { 00605 if (ISTS() && fDblClk) 00606 message = WM_XBUTTONDBLCLK; 00607 else 00608 message = WM_XBUTTONDOWN; 00609 } 00610 00611 if (ButtonNumber == MOUSE_BUTTON_X1) { 00612 usVK = VK_XBUTTON1; 00613 xbutton = XBUTTON1; 00614 } else { 00615 usVK = VK_XBUTTON2; 00616 xbutton = XBUTTON2; 00617 } 00618 break; 00619 00620 default: 00621 /* 00622 * Unknown button. Since we don't 00623 * have messages for these buttons, ignore them. 00624 */ 00625 return; 00626 } 00627 UserAssert(usVK != 0); 00628 00629 wParam = MAKEWPARAM(0, xbutton); 00630 00631 /* 00632 * Call low level mouse hooks to see if they allow this message 00633 * to pass through USER 00634 */ 00635 if ((pHook = PhkFirstValid(PtiCurrent(), WH_MOUSE_LL)) != NULL) { 00636 MSLLHOOKSTRUCT mslls; 00637 BOOL bAnsiHook; 00638 00639 mslls.pt = ptPointer; 00640 mslls.mouseData = (LONG)wParam; 00641 mslls.flags = bInjected; 00642 mslls.time = time; 00643 mslls.dwExtraInfo = ExtraInfo; 00644 00645 if (xxxCallHook2(pHook, HC_ACTION, (DWORD)message, (LPARAM)&mslls, &bAnsiHook)) { 00646 return; 00647 } 00648 } 00649 00650 /* 00651 * This is from HYDRA 00652 */ 00653 UserAssert(grpdeskRitInput != NULL); 00654 00655 #ifdef REDIRECTION 00656 /* 00657 * Call the speed hit test hook 00658 */ 00659 pwndStart = xxxCallSpeedHitTestHook(&ptPointer); 00660 if (pwndStart == NULL) { 00661 pwndStart = grpdeskRitInput->pDeskInfo->spwnd; 00662 } 00663 00664 pwnd = SpeedHitTest(pwndStart, ptPointer); 00665 #else 00666 pwnd = SpeedHitTest(grpdeskRitInput->pDeskInfo->spwnd, ptPointer); 00667 #endif // REDIRECTION 00668 00669 /* 00670 * Only post the message if we actually hit a window. 00671 */ 00672 if (pwnd == NULL) 00673 return; 00674 00675 /* 00676 * Assign the message to a window. 00677 */ 00678 lParam = MAKELONG((SHORT)ptPointer.x, (SHORT)ptPointer.y); 00679 00680 /* 00681 * KOREAN: 00682 * Send VK_PROCESSKEY to finalize current composition string (NT4 behavior) 00683 * Post private message to let IMM finalize the composition string (NT5) 00684 */ 00685 if (IS_IME_ENABLED() && 00686 !fBreak && 00687 KOREAN_KBD_LAYOUT(GetActiveHKL()) && 00688 !TestCF(pwnd, CFIME) && 00689 gpqForeground != NULL) { 00690 00691 PTHREADINFO ptiWnd = GETPTI(pwnd); 00692 00693 /* 00694 * 274007: MFC flushes mouse related messages if keyup is posted 00695 * while it's in context help mode. 00696 */ 00697 if (gpqForeground->spwndCapture == NULL && 00698 /* 00699 * Hack for OnScreen Keyboard: no finalization on button event. 00700 */ 00701 (GetAppImeCompatFlags(ptiWnd) & IMECOMPAT_NOFINALIZECOMPSTR) == 0) { 00702 00703 if (ptiWnd->dwExpWinVer > VER40) { 00704 PWND pwndIme = ptiWnd->spwndDefaultIme; 00705 00706 if (pwndIme && !TestWF(pwndIme, WFINDESTROY)) { 00707 /* 00708 * For new applications, we no longer post hacky WM_KEYUP. 00709 * Instead, we use private IME_SYSTEM message. 00710 */ 00711 _PostMessage(pwndIme, WM_IME_SYSTEM, IMS_FINALIZE_COMPSTR, 0); 00712 } 00713 } else { 00714 /* 00715 * For the backward compatibility w/NT4, we post WM_KEYUP to finalize 00716 * the composition string. 00717 */ 00718 PostInputMessage(gpqForeground, NULL, WM_KEYUP, VK_PROCESSKEY, 0, 0, 0); 00719 } 00720 } 00721 } 00722 00723 /* 00724 * If screen capture is active do it 00725 */ 00726 if (gspwndScreenCapture != NULL) 00727 pwnd = gspwndScreenCapture; 00728 00729 /* 00730 * If this is a button down event and there isn't already 00731 * a mouse owner, setup the mouse ownership globals. 00732 */ 00733 if (gspwndMouseOwner == NULL) { 00734 if (!fBreak) { 00735 PWND pwndCapture; 00736 00737 /* 00738 * BIG HACK: If the foreground window has the capture 00739 * and the mouse is outside the foreground queue then 00740 * send a buttondown/up pair to that queue so it'll 00741 * cancel it's modal loop. 00742 */ 00743 if (pwndCapture = PwndForegroundCapture()) { 00744 00745 if (GETPTI(pwnd)->pq != GETPTI(pwndCapture)->pq) { 00746 PQ pqCapture; 00747 00748 pqCapture = GETPTI(pwndCapture)->pq; 00749 PostInputMessage(pqCapture, pwndCapture, message, 00750 0, lParam, 0, 0); 00751 PostInputMessage(pqCapture, pwndCapture, message + 1, 00752 0, lParam, 0, 0); 00753 00754 /* 00755 * EVEN BIGGER HACK: To maintain compatibility 00756 * with how tracking deals with this, we don't 00757 * pass this event along. This prevents mouse 00758 * clicks in other windows from causing them to 00759 * become foreground while tracking. The exception 00760 * to this is when we have the sysmenu up on 00761 * an iconic window. 00762 */ 00763 if ((GETPTI(pwndCapture)->pmsd != NULL) && 00764 !IsMenuStarted(GETPTI(pwndCapture))) { 00765 return; 00766 } 00767 } 00768 } 00769 00770 Lock(&(gspwndMouseOwner), pwnd); 00771 gwMouseOwnerButton |= wHardwareButton; 00772 glinp.ptLastClick = gpsi->ptCursor; 00773 } else { 00774 00775 /* 00776 * The mouse owner must have been destroyed or unlocked 00777 * by a fullscreen switch. Keep the button state in sync. 00778 */ 00779 gwMouseOwnerButton &= ~wHardwareButton; 00780 } 00781 00782 } else { 00783 00784 /* 00785 * Give any other button events to the mouse-owner window 00786 * to be consistent with old capture semantics. 00787 */ 00788 if (gspwndScreenCapture == NULL) { 00789 /* 00790 * NT5 Foreground and Drag Drop. 00791 * If the mouse goes up on a different thread 00792 * make the mouse up thread the owner of this click 00793 */ 00794 if (fBreak && (GETPTI(pwnd) != GETPTI(gspwndMouseOwner))) { 00795 glinp.ptiLastWoken = GETPTI(pwnd); 00796 TAGMSG1(DBGTAG_FOREGROUND, "xxxButtonEvent. ptiLastWoken %#p", glinp.ptiLastWoken); 00797 } 00798 pwnd = gspwndMouseOwner; 00799 } 00800 00801 /* 00802 * If this is the button-up event for the mouse-owner 00803 * clear gspwndMouseOwner. 00804 */ 00805 if (fBreak) { 00806 gwMouseOwnerButton &= ~wHardwareButton; 00807 if (!gwMouseOwnerButton) 00808 Unlock(&gspwndMouseOwner); 00809 } else { 00810 gwMouseOwnerButton |= wHardwareButton; 00811 } 00812 } 00813 00814 /* 00815 * Only update the async keystate when we know which window this 00816 * event goes to (or else we can't keep the thread specific key 00817 * state in sync). 00818 */ 00819 UserAssert(usVK != 0); 00820 UpdateAsyncKeyState(GETPTI(pwnd)->pq, usVK, fBreak); 00821 00822 /* 00823 * Put pwnd into the foreground if this is a button down event 00824 * and it isn't already the foreground window. 00825 */ 00826 if (!fBreak && GETPTI(pwnd)->pq != gpqForeground) { 00827 /* 00828 * If this is an WM_*BUTTONDOWN on a desktop window just do 00829 * cancel-mode processing. Check to make sure that there 00830 * wasn't already a mouse owner window. See comments below. 00831 */ 00832 if ((gpqForeground != NULL) && (pwnd == grpdeskRitInput->pDeskInfo->spwnd) && 00833 ((gwMouseOwnerButton & wHardwareButton) || 00834 (gwMouseOwnerButton == 0))) { 00835 PostEventMessage(gpqForeground->ptiMouse, 00836 gpqForeground, QEVENT_CANCELMODE, NULL, 0, 0, 0); 00837 00838 } else if ((gwMouseOwnerButton & wHardwareButton) || 00839 (gwMouseOwnerButton == 0)) { 00840 00841 /* 00842 * Don't bother setting the foreground window if there's 00843 * already mouse owner window from a button-down different 00844 * than this event. This prevents weird things from happening 00845 * when the user starts a tracking operation with the left 00846 * button and clicks the right button during the tracking 00847 * operation. 00848 */ 00849 /* 00850 * If pwnd is a descendent of a WS_EX_NOACTIVATE window, then we 00851 * won't set it to the foreground 00852 */ 00853 PWND pwndTopLevel = GetTopLevelWindow(pwnd); 00854 if (!TestWF(pwndTopLevel, WEFNOACTIVATE)) { 00855 ThreadLockAlways(pwnd, &tlpwnd); 00856 xxxSetForegroundWindow2(pwnd, NULL, 0); 00857 /* 00858 * Ok to unlock right away: the above didn't really leave the crit sec. 00859 * We lock here for consistency so the debug macros work ok. 00860 */ 00861 ThreadUnlock(&tlpwnd); 00862 00863 } 00864 } 00865 } 00866 00867 if (GETPTI(pwnd)->pq->QF_flags & QF_MOUSEMOVED) { 00868 PostMove(GETPTI(pwnd)->pq); 00869 } 00870 00871 PostInputMessage(GETPTI(pwnd)->pq, pwnd, message, wParam, lParam, time, ExtraInfo); 00872 00873 /* 00874 * If this is a mouse up event and stickykeys is enabled all latched 00875 * keys will be released. 00876 */ 00877 if (fBreak && (TEST_ACCESSFLAG(StickyKeys, SKF_STICKYKEYSON) || 00878 TEST_ACCESSFLAG(MouseKeys, MKF_MOUSEKEYSON))) { 00879 xxxHardwareMouseKeyUp(ButtonNumber); 00880 } 00881 00882 if (message == WM_LBUTTONDOWN) { 00883 PDESKTOP pdesk = GETPTI(pwnd)->rpdesk; 00884 if (pdesk != NULL && pdesk->rpwinstaParent != NULL) { 00885 00886 UserAssert(!(pdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO)); 00887 00888 #ifdef HUNGAPP_GHOSTING 00889 if (FHungApp(GETPTI(pwnd), CMSHUNGAPPTIMEOUT)) { 00890 SignalGhost(pwnd); 00891 } 00892 #else // HUNGAPP_GHOSTING 00893 KeSetEvent(gpEventHungThread, EVENT_INCREMENT, FALSE); 00894 #endif // HUNGAPP_GHOSTING 00895 } 00896 } 00897 }

VOID xxxDoButtonEvent PMOUSEEVENT  pme  ) 
 

Definition at line 1020 of file ntinput.c.

References tagMOUSEEVENT::bInjected, BOOL, tagMOUSEEVENT::ButtonData, tagMOUSEEVENT::ButtonFlags, CheckCritIn, DWORD, tagMOUSEEVENT::ExtraInfo, FALSE, gbClientDoubleClickSupport, gpqForeground, NULL, PhkFirstValid(), PostInputMessage(), PtiCurrent, tagMOUSEEVENT::ptPointer, SHORT, tagMOUSEEVENT::time, TRUE, VOID(), xxxButtonEvent(), and xxxCallHook2().

Referenced by ProcessQueuedMouseEvents().

01021 { 01022 ULONG dwButtonMask; 01023 ULONG dwButtonState; 01024 LPARAM lParam; 01025 BOOL fWheel; 01026 PHOOK pHook; 01027 ULONG dwButtonData = (ULONG) pme->ButtonData; 01028 01029 CheckCritIn(); 01030 01031 dwButtonState = (ULONG) pme->ButtonFlags; 01032 fWheel = dwButtonState & MOUSE_WHEEL; 01033 dwButtonState &= ~MOUSE_WHEEL; 01034 01035 for( dwButtonMask = 1; 01036 dwButtonState != 0; 01037 dwButtonData >>= 2, dwButtonState >>= 2, dwButtonMask <<= 1) { 01038 01039 if (dwButtonState & 1) { 01040 xxxButtonEvent(dwButtonMask, pme->ptPointer, FALSE, 01041 pme->time, pme->ExtraInfo, pme->bInjected, 01042 gbClientDoubleClickSupport && (dwButtonData & 1)); 01043 } 01044 01045 if (dwButtonState & 2) { 01046 xxxButtonEvent(dwButtonMask, pme->ptPointer, TRUE, 01047 pme->time, pme->ExtraInfo, pme->bInjected ,FALSE); 01048 } 01049 } 01050 01051 /* 01052 * Handle the wheel msg. 01053 */ 01054 if (fWheel && pme->ButtonData != 0 && gpqForeground) { 01055 01056 lParam = MAKELONG((SHORT)pme->ptPointer.x, (SHORT)pme->ptPointer.y); 01057 01058 /* 01059 * Call low level mouse hooks to see if they allow this message 01060 * to pass through USER 01061 */ 01062 if ((pHook = PhkFirstValid(PtiCurrent(), WH_MOUSE_LL)) != NULL) { 01063 MSLLHOOKSTRUCT mslls; 01064 BOOL bAnsiHook; 01065 01066 mslls.pt = pme->ptPointer; 01067 mslls.mouseData = MAKELONG(0, pme->ButtonData); 01068 mslls.flags = pme->bInjected; 01069 mslls.time = pme->time; 01070 mslls.dwExtraInfo = pme->ExtraInfo; 01071 01072 if (xxxCallHook2(pHook, HC_ACTION, (DWORD)WM_MOUSEWHEEL, 01073 (LPARAM)&mslls, &bAnsiHook)) { 01074 return; 01075 } 01076 } 01077 01078 PostInputMessage( 01079 gpqForeground, 01080 NULL, 01081 WM_MOUSEWHEEL, 01082 MAKELONG(0, pme->ButtonData), 01083 lParam, pme->time, 01084 pme->ExtraInfo); 01085 01086 return; 01087 } 01088 }

BOOL xxxInitInput PTERMINAL  pTerm  ) 
 

Definition at line 140 of file ntinput.c.

References BOOL, CreateKernelEvent(), CreateSystemThread(), EnterCrit, FALSE, FreeKernelEvent(), gptiRit, KernelMode, KeWaitForSingleObject(), LeaveCrit, NT_SUCCESS, NTSTATUS(), NULL, PKSTART_ROUTINE, _RIT_INIT::pRitReadyEvent, _RIT_INIT::pTerm, RawInputThread(), Status, and WrUserRequest.

Referenced by CreateTerminalInput().

00142 { 00143 NTSTATUS Status; 00144 HANDLE hThreadRawInput; 00145 RIT_INIT initData; 00146 UserAssert(pTerm != NULL); 00147 00148 #ifdef MOUSE_LOCK_CODE 00149 /* 00150 * Lock RIT pages into memory 00151 */ 00152 LockMouseInputCodePages(); 00153 #endif 00154 00155 initData.pTerm = pTerm; 00156 initData.pRitReadyEvent = CreateKernelEvent(SynchronizationEvent, FALSE); 00157 if (initData.pRitReadyEvent == NULL) { 00158 return FALSE; 00159 } 00160 /* 00161 * Create the RIT and let it run. 00162 */ 00163 LeaveCrit(); 00164 Status = CreateSystemThread((PKSTART_ROUTINE)RawInputThread, &initData, 00165 &hThreadRawInput); 00166 if (!NT_SUCCESS(Status)) { 00167 goto Exit; 00168 } 00169 ZwClose(hThreadRawInput); 00170 00171 KeWaitForSingleObject(initData.pRitReadyEvent, WrUserRequest, 00172 KernelMode, FALSE, NULL); 00173 Exit: 00174 FreeKernelEvent(&initData.pRitReadyEvent); 00175 EnterCrit(); 00176 00177 return (gptiRit != NULL); 00178 }

VOID xxxInternalKeyEventDirect BYTE  bVk,
WORD  wScan,
DWORD  dwFlags,
DWORD  dwTime,
ULONG_PTR  dwExtraInfo
 

Definition at line 3403 of file ntinput.c.

References tagTHREADINFO::amdesk, ausNumPadCvt, BYTE, dwFlags, tagWINDOWSTATION::dwWSF_Flags, gafRawKeyState, gppiInputProvider, grpdeskRitInput, LOBYTE, tagTHREADINFO::ppi, PtiCurrent, tagTHREADINFO::rpdesk, tagDESKTOP::rpwinstaParent, RtlAreAllAccessesGranted(), TRUE, USHORT, VKFromVSC(), VOID(), WSF_NOIO, and xxxProcessKeyEvent().

Referenced by xxxSendInput().

03409 { 03410 PTHREADINFO pti = PtiCurrent(); 03411 KE KeyEvent; 03412 03413 /* 03414 * The calling thread must be on the active desktop 03415 * and have journal playback access to that desktop. 03416 */ 03417 if (pti->rpdesk != grpdeskRitInput || 03418 !RtlAreAllAccessesGranted(pti->amdesk, DESKTOP_JOURNALPLAYBACK)) { 03419 03420 RIPNTERR0(STATUS_ACCESS_DENIED, RIP_WARNING, 03421 "Injecting key failed: Non active desktop or access denied"); 03422 03423 return; 03424 } 03425 UserAssert(!(pti->rpdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO)); 03426 03427 KeyEvent.bScanCode = (BYTE)wScan; 03428 if (dwFlags & KEYEVENTF_SCANCODE) { 03429 bVk = VKFromVSC(&KeyEvent, 03430 (BYTE)(dwFlags & KEYEVENTF_EXTENDEDKEY ? 0xE0 : 0), 03431 gafRawKeyState); 03432 KeyEvent.usFlaggedVk = (USHORT)bVk; 03433 } else { 03434 KeyEvent.usFlaggedVk = bVk | KBDINJECTEDVK; 03435 } 03436 03437 if (dwFlags & KEYEVENTF_KEYUP) 03438 KeyEvent.usFlaggedVk |= KBDBREAK; 03439 03440 if (dwFlags & KEYEVENTF_UNICODE) { 03441 KeyEvent.usFlaggedVk |= KBDUNICODE; 03442 KeyEvent.wchInjected = wScan; 03443 } else if (dwFlags & KEYEVENTF_EXTENDEDKEY) { 03444 KeyEvent.usFlaggedVk |= KBDEXT; 03445 } else { 03446 // Is it from the numeric keypad? 03447 if (((bVk >= VK_NUMPAD0) && (bVk <= VK_NUMPAD9)) || (bVk == VK_DECIMAL)) { 03448 KeyEvent.usFlaggedVk |= KBDNUMPAD; 03449 } else { 03450 int i; 03451 for (i = 0; ausNumPadCvt[i] != 0; i++) { 03452 if (bVk == LOBYTE(ausNumPadCvt[i])) { 03453 KeyEvent.usFlaggedVk |= KBDNUMPAD; 03454 break; 03455 } 03456 } 03457 } 03458 } 03459 03460 /* 03461 * This process is providing input so it gets the right to 03462 * call SetForegroundWindow 03463 */ 03464 gppiInputProvider = pti->ppi; 03465 03466 KeyEvent.dwTime = dwTime; 03467 xxxProcessKeyEvent(&KeyEvent, dwExtraInfo, TRUE); 03468 }

VOID xxxKeyEvent USHORT  usFlaggedVk,
WORD  wScanCode,
DWORD  time,
ULONG_PTR  ExtraInfo,
BOOL  bInjected
 

Definition at line 1338 of file ntinput.c.

References BOOL, BYTE, CheckCritIn, DWORD, FALSE, FJOURNALPLAYBACK, FJOURNALRECORD, tagTHREADINFO::fsReserveKeys, GetActiveHKL(), GETPTI, gfEnableHexNumpad, gfInNumpadHexInput, gfsSASModifiersDown, glinp, gppiLockSFW, gpqForeground, gpsi, gptiBlockInput, gptiForeground, gptiRit, gspwndActivate, gspwndAltTab, HIBYTE, IsHexNumpadKeys(), IsHotKey(), IsSAS(), tagQ::mlInput, MODIFIER_FOR_ALT_NUMPAD, msg, tagQMSG::msg, NULL, NUMPAD_HEXMODE_LL, PhkFirstValid(), PostEventMessage(), PostInputMessage(), PostMove(), tagTHREADINFO::pq, tagMLIST::pqmsgWriteLast, PtiCurrent, tagQ::ptiKeyboard, tagLASTINPUT::ptiLastWoken, QEVENT_APPCOMMAND, tagQ::QF_flags, QF_MOUSEMOVED, QF_TABSWITCHING, SCANCODE_NUMPAD_DOT, SCANCODE_NUMPAD_PLUS, SFW_ACTIVATERESTORE, SFW_SWITCH, TestAsyncKeyStateDown, TestRawKeyDown, TestWF, ThreadLockAlways, ThreadUnlock, TRUE, UINT, Unlock, UpdateAsyncKeyState(), UpdateKeyLights(), USHORT, VKTOMODIFIERS, VOID(), WakeSomeone(), WFCHILD, xxxCallHook2(), xxxCancelCoolSwitch(), xxxDoHotKeyStuff(), xxxNextWindow(), xxxSetForegroundWindow2(), and xxxSetWindowPos().

Referenced by NlsAlphanumericModeProc(), NlsCodeInputToggleProc(), NlsHiraganaModeProc(), NlsKatakanaModeProc(), NlsRomanToggleProc(), NlsSbcsDbcsToggleProc(), xxxAltGr(), xxxICO_00(), xxxNumpadCursor(), xxxProcessKeyEvent(), xxxPushKeyEvent(), xxxShiftLock(), and xxxSimulateShiftF10().

01344 { 01345 USHORT message, usExtraStuff; 01346 BOOL fBreak; 01347 BYTE VkHanded; 01348 BYTE Vk; 01349 TL tlpwndActivate; 01350 DWORD fsReserveKeys; 01351 static BOOL fMakeAltUpASysKey; 01352 PHOOK pHook; 01353 PTHREADINFO ptiCurrent = PtiCurrent(); 01354 01355 CheckCritIn(); 01356 01357 fBreak = usFlaggedVk & KBDBREAK; 01358 gpsi->bLastRITWasKeyboard = TRUE; 01359 01360 /* 01361 * Is this a keyup or keydown event? 01362 */ 01363 message = fBreak ? WM_KEYUP : WM_KEYDOWN; 01364 01365 VkHanded = (BYTE)usFlaggedVk; // get rid of state bits - no longer needed 01366 usExtraStuff = usFlaggedVk & KBDEXT; 01367 01368 /* 01369 * Convert Left/Right Ctrl/Shift/Alt key to "unhanded" key. 01370 * ie: if VK_LCONTROL or VK_RCONTROL, convert to VK_CONTROL etc. 01371 * Update this "unhanded" key's state if necessary. 01372 */ 01373 if ((VkHanded >= VK_LSHIFT) && (VkHanded <= VK_RMENU)) { 01374 BYTE VkOtherHand = VkHanded ^ 1; 01375 01376 Vk = (BYTE)((VkHanded - VK_LSHIFT) / 2 + VK_SHIFT); 01377 if (!fBreak || !TestAsyncKeyStateDown(VkOtherHand)) { 01378 if ((gptiBlockInput == NULL) || (gptiBlockInput != ptiCurrent)) { 01379 UpdateAsyncKeyState(gpqForeground, Vk, fBreak); 01380 } 01381 } 01382 } else { 01383 Vk = VkHanded; 01384 } 01385 01386 /* 01387 * Maintain gfsSASModifiersDown to indicate which of Ctrl/Shift/Alt 01388 * are really truly physically down 01389 */ 01390 if (!bInjected && ((wScanCode & SCANCODE_SIMULATED) == 0)) { 01391 if (fBreak) { 01392 gfsSASModifiersDown &= ~VKTOMODIFIERS(Vk); 01393 } else { 01394 gfsSASModifiersDown |= VKTOMODIFIERS(Vk); 01395 } 01396 } 01397 01398 /* 01399 * Call low level keyboard hook to see if it allows this 01400 * message to pass 01401 */ 01402 if ((pHook = PhkFirstValid(ptiCurrent, WH_KEYBOARD_LL)) != NULL) { 01403 KBDLLHOOKSTRUCT kbds; 01404 BOOL bAnsiHook; 01405 USHORT msg = message; 01406 01407 /* 01408 * Check if this is a WM_SYS* message 01409 */ 01410 if (TestRawKeyDown(VK_MENU) && 01411 !TestRawKeyDown(VK_CONTROL)) { 01412 01413 msg += (WM_SYSKEYDOWN - WM_KEYDOWN); 01414 usExtraStuff |= 0x2000; // ALT key down 01415 } 01416 kbds.vkCode = (DWORD)VkHanded; 01417 kbds.scanCode = (DWORD)wScanCode; 01418 kbds.flags = HIBYTE(usExtraStuff | (bInjected ? (LLKHF_INJECTED << 8) : 0)); 01419 kbds.flags |= (fBreak ? (KBDBREAK >> 8) : 0); 01420 kbds.time = time; 01421 kbds.dwExtraInfo = ExtraInfo; 01422 01423 if (xxxCallHook2(pHook, HC_ACTION, (DWORD)msg, (LPARAM)&kbds, &bAnsiHook)) { 01424 01425 UINT fsModifiers; 01426 01427 /* 01428 * We can't let low level hooks or BlockInput() eat SAS 01429 * or someone could write a trojan winlogon look alike. 01430 */ 01431 if (IsSAS(VkHanded, &fsModifiers)) { 01432 RIPMSG0(RIP_WARNING, "xxxKeyEvent: SAS ignore bad response from low level hook"); 01433 } else { 01434 return; 01435 } 01436 } 01437 } 01438 01439 /* 01440 * If someone is blocking input and it's not us, don't allow this input 01441 */ 01442 if (gptiBlockInput && (gptiBlockInput != ptiCurrent)) { 01443 UINT fsModifiers; 01444 if (IsSAS(VkHanded, &fsModifiers)) { 01445 RIPMSG0(RIP_WARNING, "xxxKeyEvent: SAS unblocks BlockInput"); 01446 gptiBlockInput = NULL; 01447 } else { 01448 return; 01449 } 01450 } 01451 01452 UpdateAsyncKeyState(gpqForeground, VkHanded, fBreak); 01453 01454 /* 01455 * Clear gfInNumpadHexInput if Menu key is up. 01456 */ 01457 if (gfEnableHexNumpad) { 01458 if (!TestAsyncKeyStateDown(VK_MENU)) { 01459 if (gfInNumpadHexInput & NUMPAD_HEXMODE_LL) { 01460 gfInNumpadHexInput &= ~NUMPAD_HEXMODE_LL; 01461 } 01462 } else { 01463 if (!fBreak) { // if it's key down 01464 if ((gfInNumpadHexInput & NUMPAD_HEXMODE_LL) || 01465 wScanCode == SCANCODE_NUMPAD_PLUS || wScanCode == SCANCODE_NUMPAD_DOT) { 01466 if ((usExtraStuff & KBDEXT) == 0) { 01467 /* 01468 * We need to check whether the input is escape character 01469 * of hex input mode. 01470 * This should be equivalent code as in xxxInternalToUnicode(). 01471 * If you change this code, you may need to change 01472 * xxxInternalToUnicode() as well. 01473 */ 01474 WORD wModBits = 0; 01475 01476 wModBits |= TestAsyncKeyStateDown(VK_MENU) ? KBDALT : 0; 01477 wModBits |= TestAsyncKeyStateDown(VK_SHIFT) ? KBDSHIFT : 0; 01478 wModBits |= TestAsyncKeyStateDown(VK_KANA) ? KBDKANA : 0; 01479 01480 if (MODIFIER_FOR_ALT_NUMPAD(wModBits)) { 01481 if ((gfInNumpadHexInput & NUMPAD_HEXMODE_LL) == 0) { 01482 /* 01483 * Only if it's not a hotkey, we enter hex Alt+Numpad mode. 01484 */ 01485 UINT wHotKeyMod = 0; 01486 01487 wHotKeyMod |= (wModBits & KBDSHIFT) ? MOD_SHIFT : 0; 01488 wHotKeyMod |= TestAsyncKeyStateDown(VK_CONTROL) ? MOD_CONTROL : 0; 01489 UserAssert(wModBits & KBDALT); 01490 wHotKeyMod |= MOD_ALT; 01491 wHotKeyMod |= TestAsyncKeyStateDown(VK_LWIN) || TestAsyncKeyStateDown(VK_RWIN) ? 01492 MOD_WIN : 0; 01493 01494 if (IsHotKey(wHotKeyMod, Vk) == NULL) { 01495 UserAssert(wScanCode == SCANCODE_NUMPAD_PLUS || wScanCode == SCANCODE_NUMPAD_DOT); 01496 gfInNumpadHexInput |= NUMPAD_HEXMODE_LL; 01497 } 01498 } else if (!IsHexNumpadKeys(Vk, wScanCode)) { 01499 gfInNumpadHexInput &= ~NUMPAD_HEXMODE_LL; 01500 } 01501 } else { 01502 gfInNumpadHexInput &= ~NUMPAD_HEXMODE_LL; 01503 } 01504 } else { 01505 gfInNumpadHexInput &= ~NUMPAD_HEXMODE_LL; 01506 } 01507 } else { 01508 UserAssert((gfInNumpadHexInput & NUMPAD_HEXMODE_LL) == 0); 01509 } 01510 } 01511 } 01512 } 01513 01514 /* 01515 * If this is a make and the key is one linked to the keyboard LEDs, 01516 * update their state. 01517 */ 01518 01519 if (!fBreak && 01520 ((Vk == VK_CAPITAL) || (Vk == VK_NUMLOCK) || (Vk == VK_SCROLL) || 01521 (Vk == VK_KANA && JAPANESE_KBD_LAYOUT(GetActiveHKL())))) { 01522 /* 01523 * Only Japanese keyboard layout could generate VK_KANA. 01524 * 01525 * [Comments for before] 01526 * Since NT 3.x, UpdatesKeyLisghts() had been called for VK_KANA 01527 * at both of 'make' and 'break' to support NEC PC-9800 Series 01528 * keyboard hardware, but for NT 4.0, thier keyboard driver emurate 01529 * PC/AT keyboard hardware, then this is changed to 01530 * "Call UpdateKeyLights() only at 'make' for VK_KANA" 01531 */ 01532 UpdateKeyLights(bInjected); 01533 } 01534 01535 /* 01536 * check for reserved keys 01537 */ 01538 fsReserveKeys = 0; 01539 if (gptiForeground != NULL) 01540 fsReserveKeys = gptiForeground->fsReserveKeys; 01541 01542 /* 01543 * Check the RIT's queue to see if it's doing the cool switch thing. 01544 * Cancel if the user presses any other key. 01545 */ 01546 if (gspwndAltTab != NULL && (!fBreak) && 01547 Vk != VK_TAB && Vk != VK_SHIFT && Vk != VK_MENU) { 01548 01549 /* 01550 * Remove the Alt-tab window 01551 */ 01552 xxxCancelCoolSwitch(); 01553 01554 /* 01555 * eat VK_ESCAPE if the app doesn't want it 01556 */ 01557 if ((Vk == VK_ESCAPE) && !(fsReserveKeys & CONSOLE_ALTESC)) { 01558 return; 01559 } 01560 } 01561 01562 /* 01563 * Check for hotkeys. 01564 */ 01565 if (xxxDoHotKeyStuff(Vk, fBreak, fsReserveKeys)) { 01566 01567 /* 01568 * The hotkey was processed so don't pass on the event. 01569 */ 01570 return; 01571 } 01572 01573 /* 01574 * If the ALT key is down and the CTRL key 01575 * isn't, this is a WM_SYS* message. 01576 */ 01577 if (TestAsyncKeyStateDown(VK_MENU) && !TestAsyncKeyStateDown(VK_CONTROL) && Vk != VK_JUNJA) { 01578 // VK_JUNJA is ALT+'+'. Since all KOR VKs are not converted to IME hotkey IDs and 01579 // should be passed directly to IME, KOR related VKs are not treated as SYSKEYDOWN. 01580 message += (WM_SYSKEYDOWN - WM_KEYDOWN); 01581 usExtraStuff |= 0x2000; 01582 01583 /* 01584 * If this is the ALT-down set this flag, otherwise 01585 * clear it since we got a key inbetween the ALT-down 01586 * and ALT-up. (see comment below) 01587 */ 01588 if (Vk == VK_MENU) { 01589 fMakeAltUpASysKey = TRUE; 01590 /* 01591 * Unlock SetForegroundWindow (if locked) when the ALT key went down. 01592 */ 01593 if (!fBreak) { 01594 gppiLockSFW = NULL; 01595 } 01596 } else { 01597 fMakeAltUpASysKey = FALSE; 01598 } 01599 01600 } else if (Vk == VK_MENU) { 01601 if (fBreak) { 01602 /* 01603 * End our switch if we are in the middle of one. 01604 */ 01605 if (fMakeAltUpASysKey) { 01606 01607 /* 01608 * We don't make the keyup of the ALT key a WM_SYSKEYUP if any 01609 * other key is typed while the ALT key was down. I don't know 01610 * why we do this, but it's been here since version 1 and any 01611 * app that uses SDM relies on it (eg - opus). 01612 * 01613 * The Alt bit is not set for the KEYUP message either. 01614 */ 01615 message += (WM_SYSKEYDOWN - WM_KEYDOWN); 01616 } 01617 01618 if (gspwndAltTab != NULL) { 01619 01620 /* 01621 * Send the alt up message before we change queues 01622 */ 01623 if (gpqForeground != NULL) { 01624 01625 /* 01626 * Set this flag so that we know we're doing a tab-switch. 01627 * This makes sure that both cases where the ALT-KEY is released 01628 * before or after the TAB-KEY is handled. It is checked in 01629 * xxxDefWindowProc(). 01630 */ 01631 gpqForeground->QF_flags |= QF_TABSWITCHING; 01632 01633 PostInputMessage(gpqForeground, NULL, message, (DWORD)Vk, 01634 MAKELONG(1, (wScanCode | usExtraStuff)), 01635 time, ExtraInfo); 01636 } 01637 01638 /* 01639 * Remove the Alt-tab window 01640 */ 01641 xxxCancelCoolSwitch(); 01642 01643 if (gspwndActivate != NULL) { 01644 /* 01645 * Make our selected window active and destroy our 01646 * switch window. If the new window is minmized, 01647 * restore it. If we are switching in the same 01648 * queue, we clear out gpqForeground to make 01649 * xxxSetForegroundWindow2 to change the pwnd 01650 * and make the switch. This case will happen 01651 * with WOW and Console apps. 01652 */ 01653 if (gpqForeground == GETPTI(gspwndActivate)->pq) { 01654 gpqForeground = NULL; 01655 } 01656 01657 /* 01658 * Make the selected window thread the owner of the last input; 01659 * since the user has selected him, he owns the ALT-TAB. 01660 */ 01661 glinp.ptiLastWoken = GETPTI(gspwndActivate); 01662 01663 01664 ThreadLockAlways(gspwndActivate, &tlpwndActivate); 01665 xxxSetForegroundWindow2(gspwndActivate, NULL, 01666 SFW_SWITCH | SFW_ACTIVATERESTORE); 01667 /* 01668 * Win3.1 calls SetWindowPos() with activate, which z-orders 01669 * first regardless, then activates. Our code relies on 01670 * xxxActivateThisWindow() to z-order, and it'll only do 01671 * it if the window does not have the child bit set (regardless 01672 * that the window is a child of the desktop). 01673 * 01674 * To be compatible, we'll just force z-order here if the 01675 * window has the child bit set. This z-order is asynchronous, 01676 * so this'll z-order after the activate event is processed. 01677 * That'll allow it to come on top because it'll be foreground 01678 * then. (Grammatik has a top level window with the child 01679 * bit set that wants to be come the active window). 01680 */ 01681 if (TestWF(gspwndActivate, WFCHILD)) { 01682 xxxSetWindowPos(gspwndActivate, (PWND)HWND_TOP, 0, 0, 0, 0, 01683 SWP_NOSIZE | SWP_NOMOVE | SWP_ASYNCWINDOWPOS); 01684 } 01685 ThreadUnlock(&tlpwndActivate); 01686 01687 Unlock(&gspwndActivate); 01688 } 01689 return; 01690 } 01691 } else { 01692 /* 01693 * The ALT key is down, unlock SetForegroundWindow (if locked) 01694 */ 01695 gppiLockSFW = NULL; 01696 } 01697 } 01698 01699 /* 01700 * Handle switching. Eat the Key if we are doing switching. 01701 */ 01702 if (!FJOURNALPLAYBACK() && !FJOURNALRECORD() && (!fBreak) && 01703 (TestAsyncKeyStateDown(VK_MENU)) && 01704 (!TestAsyncKeyStateDown(VK_CONTROL)) && //gpqForeground && 01705 (((Vk == VK_TAB) && !(fsReserveKeys & CONSOLE_ALTTAB)) || 01706 ((Vk == VK_ESCAPE) && !(fsReserveKeys & CONSOLE_ALTESC)))) { 01707 01708 xxxNextWindow(gpqForeground ? gpqForeground : gptiRit->pq, Vk); 01709 01710 } else if (gpqForeground != NULL) { 01711 PQMSG pqmsgPrev = gpqForeground->mlInput.pqmsgWriteLast; 01712 DWORD wParam = (DWORD)Vk; 01713 LONG lParam; 01714 01715 /* 01716 * We have a packet containing a Unicode character 01717 * This is injected by Pen via SendInput 01718 */ 01719 if ((Vk == VK_PACKET) && (usFlaggedVk & KBDUNICODE)) { 01720 wParam |= (wScanCode << 16); 01721 wScanCode = 0; 01722 } 01723 lParam = MAKELONG(1, (wScanCode | usExtraStuff)); 01724 01725 /* 01726 * WM_*KEYDOWN messages are left unchanged on the queue except the 01727 * repeat count field (LOWORD(lParam)) is incremented. 01728 */ 01729 if (pqmsgPrev != NULL && 01730 pqmsgPrev->msg.message == message && 01731 (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) && 01732 pqmsgPrev->msg.wParam == wParam && 01733 HIWORD(pqmsgPrev->msg.lParam) == HIWORD(lParam)) { 01734 /* 01735 * Increment the queued message's repeat count. This could 01736 * conceivably overflow but Win 3.0 doesn't deal with it 01737 * and anyone who buffers up 65536 keystrokes is a chimp 01738 * and deserves to have it wrap anyway. 01739 */ 01740 pqmsgPrev->msg.lParam = MAKELONG(LOWORD(pqmsgPrev->msg.lParam) + 1, 01741 HIWORD(lParam)); 01742 01743 WakeSomeone(gpqForeground, message, pqmsgPrev); 01744 01745 } else { 01746 /* 01747 * check if these are speedracer keys - bug 339877 01748 * for the speedracer keys we want to post an event message and generate the 01749 * wm_appcommand in xxxprocesseventmessage 01750 * Since SpeedRacer software looks for the hotkeys we want to let those through 01751 * It is going in here since we don't want the ability to eat up tons of pool memory 01752 * so we post the event message here and then post the input message for the wm_keydown 01753 * below - that way if the key is repeated then there is coalescing done above and no more 01754 * qevent_appcommands are posted to the input queue. 01755 */ 01756 if (VK_APPCOMMAND_FIRST <= Vk && Vk <= VK_APPCOMMAND_LAST) { 01757 /* 01758 * Only send wm_appcommands for wm_keydown (& wm_syskeydown) messages - 01759 * essentially we ignore wm_keyup for those vk's defined for wm_appcommand messages 01760 */ 01761 if (!fBreak && gpqForeground) { 01762 /* 01763 * post an event message so we can syncronize with normal types of input 01764 * send through the vk - we will construct the message in xxxProcessEventMessage 01765 */ 01766 PostEventMessage(gpqForeground->ptiKeyboard, gpqForeground, QEVENT_APPCOMMAND, 01767 NULL, 0, (WPARAM)0, Vk); 01768 } 01769 } 01770 /* 01771 * We let the key go through since we want wm_keydowns/ups to get generated for these 01772 * SpeedRacer keys 01773 */ 01774 01775 if (gpqForeground->QF_flags & QF_MOUSEMOVED) { 01776 PostMove(gpqForeground); 01777 } 01778 01779 PostInputMessage(gpqForeground, NULL, message, wParam, 01780 lParam, time, ExtraInfo); 01781 } 01782 } 01783 }

VOID xxxMouseEventDirect DWORD  dx,
DWORD  dy,
DWORD  mouseData,
DWORD  dwMEFlags,
DWORD  dwTime,
ULONG_PTR  dwExtraInfo
 

Definition at line 3213 of file ntinput.c.

References AccessCheckObject(), tagTHREADINFO::amdesk, BOOL, CheckGrantedAccess(), DesktopMapping, tagTHREADINFO::dwExpWinVer, DWORD, tagWINDOWSTATION::dwWSF_Flags, EnterCrit, FALSE, gppiInputProvider, gptCursorAsync, grpdeskRitInput, KernelMode, LeaveCrit, max, min, NtGetTickCount(), NULL, tagTHREADINFO::ppi, ProcessQueuedMouseEvents(), PtiCurrent, QueueMouseEvent(), tagTHREADINFO::rpdesk, tagDESKTOP::rpwinstaParent, TRUE, USHORT, VER40, VOID(), WSF_NOIO, and xxxMoveEvent().

Referenced by xxxSendInput().

03220 { 03221 DWORD dwDriverMouseFlags; 03222 DWORD dwDriverMouseData; 03223 03224 PTHREADINFO pti = PtiCurrent(); 03225 if (dwTime == 0) { 03226 dwTime = NtGetTickCount(); 03227 } 03228 03229 /* 03230 * The calling thread must be on the active desktop 03231 * and have journal playback access to that desktop. 03232 */ 03233 if (pti->rpdesk == grpdeskRitInput) { 03234 UserAssert(!(pti->rpdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO)); 03235 if (!CheckGrantedAccess(pti->amdesk, DESKTOP_JOURNALPLAYBACK)) { 03236 RIPMSG0(RIP_ERROR, "mouse_event(): No DESKTOP_JOURNALPLAYBACK access to input desktop." ); 03237 return; 03238 } 03239 } else { 03240 /* 03241 * 3/22/95 BradG - Only allow below HACK for pre 4.0 applications 03242 */ 03243 if (pti->dwExpWinVer >= VER40) { 03244 RIPMSG0(RIP_VERBOSE,"mouse_event(): Calls not forwarded for 4.0 or greater apps."); 03245 return; 03246 } else { 03247 BOOL fAccessToDesktop; 03248 03249 /* 03250 * 3/22/95 BradG - Bug #9314: Screensavers are not deactivated by mouse_event() 03251 * The main problem is the check above, since screensavers run on their own 03252 * desktop. This causes the above check to fail because the process using 03253 * mouse_event() is running on another desktop. The solution is to determine 03254 * if we have access to the input desktop by calling xxxOpenDesktop for the 03255 * current input desktop, grpdeskRitInput, with a request for DESKTOP_JOURNALPLAYBACK 03256 * access. If this succeeds, we can allow this mouse_event() request to pass 03257 * through, otherwise return. 03258 */ 03259 UserAssert(grpdeskRitInput != NULL); 03260 03261 UserAssert(!(grpdeskRitInput->rpwinstaParent->dwWSF_Flags & WSF_NOIO)); 03262 fAccessToDesktop = AccessCheckObject(grpdeskRitInput, 03263 DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS | DESKTOP_JOURNALPLAYBACK, 03264 KernelMode, 03265 &DesktopMapping); 03266 if (!fAccessToDesktop) { 03267 RIPMSG0(RIP_VERBOSE, "mouse_event(): Call NOT forwarded to input desktop" ); 03268 return; 03269 } 03270 03271 /* 03272 * We do have access to the desktop, so 03273 * let this mouse_event() call go through. 03274 */ 03275 RIPMSG0( RIP_VERBOSE, "mouse_event(): Call forwarded to input desktop" ); 03276 } 03277 } 03278 03279 /* 03280 * This process is providing input so it gets the right to 03281 * call SetForegroundWindow 03282 */ 03283 gppiInputProvider = pti->ppi; 03284 03285 LeaveCrit(); 03286 03287 /* 03288 * Process coordinates first. This is especially useful for absolute 03289 * pointing devices like touch-screens and tablets. 03290 */ 03291 if (dwMEFlags & MOUSEEVENTF_MOVE) { 03292 xxxMoveEvent(dx, dy, dwMEFlags, dwExtraInfo, dwTime, TRUE); 03293 } 03294 03295 /* 03296 * The following code assumes that MOUSEEVENTF_MOVE == 1, 03297 * that MOUSEEVENTF_ABSOLUTE > all button flags, and that the 03298 * mouse_event button flags are defined in the same order as the 03299 * MOUSE_INPUT_DATA button bits. 03300 */ 03301 #if MOUSEEVENTF_MOVE != 1 03302 # error("MOUSEEVENTF_MOVE != 1") 03303 #endif 03304 #if MOUSEEVENTF_LEFTDOWN != MOUSE_LEFT_BUTTON_DOWN * 2 03305 # error("MOUSEEVENTF_LEFTDOWN != MOUSE_LEFT_BUTTON_DOWN * 2") 03306 #endif 03307 #if MOUSEEVENTF_LEFTUP != MOUSE_LEFT_BUTTON_UP * 2 03308 # error("MOUSEEVENTF_LEFTUP != MOUSE_LEFT_BUTTON_UP * 2") 03309 #endif 03310 #if MOUSEEVENTF_RIGHTDOWN != MOUSE_RIGHT_BUTTON_DOWN * 2 03311 # error("MOUSEEVENTF_RIGHTDOWN != MOUSE_RIGHT_BUTTON_DOWN * 2") 03312 #endif 03313 #if MOUSEEVENTF_RIGHTUP != MOUSE_RIGHT_BUTTON_UP * 2 03314 # error("MOUSEEVENTF_RIGHTUP != MOUSE_RIGHT_BUTTON_UP * 2") 03315 #endif 03316 #if MOUSEEVENTF_MIDDLEDOWN != MOUSE_MIDDLE_BUTTON_DOWN * 2 03317 # error("MOUSEEVENTF_MIDDLEDOWN != MOUSE_MIDDLE_BUTTON_DOWN * 2") 03318 #endif 03319 #if MOUSEEVENTF_MIDDLEUP != MOUSE_MIDDLE_BUTTON_UP * 2 03320 # error("MOUSEEVENTF_MIDDLEUP != MOUSE_MIDDLE_BUTTON_UP * 2") 03321 #endif 03322 #if MOUSEEVENTF_WHEEL != MOUSE_WHEEL * 2 03323 # error("MOUSEEVENTF_WHEEL != MOUSE_WHEEL * 2") 03324 #endif 03325 03326 /* set legal values */ 03327 dwDriverMouseFlags = dwMEFlags & MOUSEEVENTF_BUTTONMASK; 03328 03329 /* remove MOUSEEVENTF_XDOWN/UP because we are going to add 03330 MOUSEEVENTF_DRIVER_X1/2DOWN/UP later */ 03331 dwDriverMouseFlags &= ~(MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP); 03332 03333 dwDriverMouseData = 0; 03334 03335 /* 03336 * Handle mouse wheel and xbutton inputs. 03337 * 03338 * Note that MOUSEEVENTF_XDOWN/UP and MOUSEEVENTF_MOUSEWHEEL cannot both 03339 * be specified since they share the mouseData field 03340 */ 03341 if ( ((dwMEFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_WHEEL)) == (MOUSEEVENTF_XDOWN | MOUSEEVENTF_WHEEL)) || 03342 ((dwMEFlags & (MOUSEEVENTF_XUP | MOUSEEVENTF_WHEEL)) == (MOUSEEVENTF_XUP | MOUSEEVENTF_WHEEL))) { 03343 03344 RIPMSG1(RIP_WARNING, "Can't specify both MOUSEEVENTF_XDOWN/UP and MOUSEEVENTF_WHEEL in call to SendInput, dwFlags=0x%.8X", dwMEFlags); 03345 dwDriverMouseFlags &= ~(MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP | MOUSEEVENTF_WHEEL); 03346 } else if (dwMEFlags & MOUSEEVENTF_WHEEL) { 03347 /* 03348 * Force the value to a short. We cannot fail if it is out of range 03349 * because we accepted a 32 bit value in NT 4. 03350 */ 03351 dwDriverMouseData = min(max(SHRT_MIN, (LONG)mouseData), SHRT_MAX); 03352 } else { 03353 /* don't process xbuttons if mousedata has invalid buttons */ 03354 if (~XBUTTON_MASK & mouseData) { 03355 RIPMSG1(RIP_WARNING, "Invalid xbutton specified in SendInput, mouseData=0x%.8X", mouseData); 03356 } else { 03357 if (dwMEFlags & MOUSEEVENTF_XDOWN) { 03358 if (mouseData & XBUTTON1) { 03359 dwDriverMouseFlags |= MOUSEEVENTF_DRIVER_X1DOWN; 03360 } 03361 if (mouseData & XBUTTON2) { 03362 dwDriverMouseFlags |= MOUSEEVENTF_DRIVER_X2DOWN; 03363 } 03364 } 03365 if (dwMEFlags & MOUSEEVENTF_XUP) { 03366 if (mouseData & XBUTTON1) { 03367 dwDriverMouseFlags |= MOUSEEVENTF_DRIVER_X1UP; 03368 } 03369 if (mouseData & XBUTTON2) { 03370 dwDriverMouseFlags |= MOUSEEVENTF_DRIVER_X2UP; 03371 } 03372 } 03373 } 03374 } 03375 03376 /* Convert the MOUSEEVENTF_ flags to MOUSE_BUTTON flags sent by the driver */ 03377 dwDriverMouseFlags >>= 1; 03378 03379 QueueMouseEvent( 03380 (USHORT) dwDriverMouseFlags, 03381 (USHORT) dwDriverMouseData, 03382 dwExtraInfo, 03383 gptCursorAsync, 03384 dwTime, 03385 TRUE, 03386 FALSE 03387 ); 03388 03389 ProcessQueuedMouseEvents(); 03390 03391 EnterCrit(); 03392 }

VOID xxxMoveEvent LONG  dx,
LONG  dy,
DWORD  dwFlags,
ULONG_PTR  dwExtraInfo,
DWORD  time,
BOOL  bInjected
 

Definition at line 2020 of file ntinput.c.

References CheckCritOut, ConvertToMouseDriverFlags, dwFlags, GetMouseCoord(), gptCursorAsync, VOID(), and xxxMoveEventAbsolute().

Referenced by xxxMKMouseMove(), xxxMKMoveAccelCursorTimer(), xxxMKMoveConstCursorTimer(), and xxxMouseEventDirect().

02027 { 02028 POINT ptLastMove = gptCursorAsync; 02029 02030 CheckCritOut(); 02031 02032 /* 02033 * Get the actual point that will be injected. 02034 */ 02035 GetMouseCoord(dx, dy, ConvertToMouseDriverFlags(dwFlags), 02036 time, dwExtraInfo, &ptLastMove); 02037 02038 /* 02039 * move the mouse 02040 */ 02041 xxxMoveEventAbsolute( 02042 ptLastMove.x, 02043 ptLastMove.y, 02044 dwExtraInfo, 02045 time, 02046 bInjected); 02047 }

VOID xxxMoveEventAbsolute LONG  x,
LONG  y,
ULONG_PTR  dwExtraInfo,
DWORD  time,
BOOL  bInjected
 

Definition at line 1936 of file ntinput.c.

References BOOL, BoundCursor(), CheckCritOut, EnterCrit, FALSE, gdwMouseMoveTimeStamp, gpDispInfo, gptCursorAsync, gptiRit, tagDISPLAYINFO::hDev, IsGlobalHooked, IsHooked, LeaveCrit, NULL, PhkFirstValid(), VOID(), WHF_FROM_WH, and xxxCallHook2().

Referenced by ProcessMouseInput(), and xxxMoveEvent().

01943 { 01944 CheckCritOut(); 01945 01946 if (IsHooked(gptiRit, WHF_FROM_WH(WH_MOUSE_LL))) { 01947 MSLLHOOKSTRUCT mslls; 01948 BOOL bEatEvent = FALSE; 01949 BOOL bAnsiHook; 01950 PHOOK pHook; 01951 01952 mslls.pt.x = x; 01953 mslls.pt.y = y; 01954 mslls.mouseData = 0; 01955 mslls.flags = bInjected; 01956 mslls.time = time; 01957 mslls.dwExtraInfo = dwExtraInfo; 01958 01959 /* 01960 * Call low level mouse hooks to see if they allow this message 01961 * to pass through USER 01962 */ 01963 01964 EnterCrit(); 01965 01966 /* 01967 * Check again to see if we still have the hook installed. Fix for 80477. 01968 */ 01969 if ((pHook = PhkFirstValid(gptiRit, WH_MOUSE_LL)) != NULL) { 01970 bEatEvent = (xxxCallHook2(pHook, HC_ACTION, WM_MOUSEMOVE, (LPARAM)&mslls, &bAnsiHook) != 0); 01971 } 01972 01973 LeaveCrit(); 01974 01975 if (bEatEvent) { 01976 return; 01977 } 01978 } 01979 01980 /* 01981 * Blow off the event if WH_JOURNALPLAYBACK is installed. Do not 01982 * use FJOURNALPLAYBACK() because this routine may be called from 01983 * multiple desktop threads and the hook check must be done 01984 * for the rit thread, not the calling thread. 01985 */ 01986 if (IsGlobalHooked(gptiRit, WHF_FROM_WH(WH_JOURNALPLAYBACK))) { 01987 return; 01988 } 01989 01990 gptCursorAsync.x = x; 01991 gptCursorAsync.y = y; 01992 01993 BoundCursor(&gptCursorAsync); 01994 01995 /* 01996 * Move the screen pointer. 01997 */ 01998 GreMovePointer(gpDispInfo->hDev, gptCursorAsync.x, gptCursorAsync.y); 01999 02000 /* 02001 * Save the time stamp in a global so we can use it in PostMove 02002 */ 02003 gdwMouseMoveTimeStamp = time; 02004 }

VOID xxxProcessKeyEvent PKE  pke,
ULONG_PTR  ExtraInformation,
BOOL  bInjected
 

Definition at line 2791 of file ntinput.c.

References BYTE, CheckCritIn, tagLASTINPUT::dwFlags, GetActiveHKL(), glinp, gpDispInfo, gpsi, KEOEMProcs(), LINP_INPUTTIMEOUTS, LINP_KEYBOARD, LINP_POWERTIMEOUTS, NtGetTickCount(), tagDISPLAYINFO::pmdev, TestRawKeyDown, tagLASTINPUT::timeLastInputMessage, UpdateRawKeyState(), VOID(), xxxKELocaleProcs(), xxxKENLSProcs(), and xxxKeyEvent().

Referenced by ProcessKeyboardInput(), RemoteSyncToggleKeys(), xxxFKAcceptanceDelayTimer(), xxxFKRepeatRateTimer(), xxxInternalKeyEventDirect(), xxxStickyKeys(), xxxToggleKeysTimer(), and xxxUpdateModifierState().

02795 { 02796 BYTE Vk; 02797 02798 CheckCritIn(); 02799 02800 Vk = (BYTE)pke->usFlaggedVk; 02801 02802 /* 02803 * KOREAN: 02804 * Check this is Korean keyboard layout, or not.. 02805 * 02806 * NOTE: 02807 * It would be better check this by "keyboard hardware" or 02808 * "keyboard layout" ??? 02809 * 02810 * 1. Check by hardware : 02811 * 02812 * if (KOREAN_KEYBOARD(gKeyboardInfo.KeyboardIdentifier)) { 02813 * 02814 * 2. Check by layout : 02815 * 02816 * if (KOREAN_KBD_LAYOUT(_GetKeyboardLayout(0L))) { 02817 */ 02818 if (KOREAN_KBD_LAYOUT(GetActiveHKL())) { 02819 if ((pke->usFlaggedVk & KBDBREAK) && 02820 !(pke->usFlaggedVk & KBDUNICODE) && 02821 (pke->bScanCode == 0xF1 || pke->bScanCode == 0xF2) && 02822 !TestRawKeyDown(Vk)) { 02823 /* 02824 * This is actually a keydown with a scancode of 0xF1 or 0xF2 from a 02825 * Korean keyboard. Korean IMEs and apps want a WM_KEYDOWN with a 02826 * scancode of 0xF1 or 0xF2. They don't mind not getting the WM_KEYUP. 02827 * Don't update physical keystate to allow a real 0x71/0x72 keydown. 02828 */ 02829 pke->usFlaggedVk &= ~KBDBREAK; 02830 } else { 02831 UpdateRawKeyState(Vk, pke->usFlaggedVk & KBDBREAK); 02832 } 02833 } else { 02834 UpdateRawKeyState(Vk, pke->usFlaggedVk & KBDBREAK); 02835 } 02836 02837 /* 02838 * Convert Left/Right Ctrl/Shift/Alt key to "unhanded" key. 02839 * ie: if VK_LCONTROL or VK_RCONTROL, convert to VK_CONTROL etc. 02840 */ 02841 if ((Vk >= VK_LSHIFT) && (Vk <= VK_RMENU)) { 02842 Vk = (BYTE)((Vk - VK_LSHIFT) / 2 + VK_SHIFT); 02843 UpdateRawKeyState(Vk, pke->usFlaggedVk & KBDBREAK); 02844 } 02845 02846 /* 02847 * Setup to shutdown screen saver and exit video power down mode. 02848 */ 02849 if (glinp.dwFlags & LINP_POWERTIMEOUTS) { 02850 /* 02851 * Call video driver here to exit power down mode. 02852 */ 02853 KdPrint(("Exit video power down mode\n")); 02854 DrvSetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD0); 02855 } 02856 glinp.dwFlags = (glinp.dwFlags & ~LINP_INPUTTIMEOUTS) | LINP_KEYBOARD; 02857 glinp.timeLastInputMessage = gpsi->dwLastRITEventTickCount = NtGetTickCount(); 02858 if (!bInjected || (pke->dwTime == 0)) { 02859 pke->dwTime = glinp.timeLastInputMessage; 02860 } 02861 02862 /* 02863 * Now call all the OEM- and Locale- specific KEProcs. 02864 * If KEProcs return FALSE, the keystroke has been discarded, in 02865 * which case don't pass the key event on to xxxKeyEvent(). 02866 */ 02867 if (pke->usFlaggedVk & KBDUNICODE) { 02868 xxxKeyEvent(pke->usFlaggedVk, pke->wchInjected, 02869 pke->dwTime, ExtraInformation, bInjected); 02870 } else { 02871 if (KEOEMProcs(pke) && xxxKELocaleProcs(pke) && xxxKENLSProcs(pke,ExtraInformation)) { 02872 xxxKeyEvent(pke->usFlaggedVk, pke->bScanCode, 02873 pke->dwTime, ExtraInformation, bInjected); 02874 } 02875 } 02876 }

UINT xxxSendInput UINT  nInputs,
LPINPUT  pInputs
 

Definition at line 3575 of file ntinput.c.

References DWORD, LOBYTE, PtiCurrent, UINT, xxxInternalKeyEventDirect(), and xxxMouseEventDirect().

Referenced by NtUserSendInput().

03578 { 03579 UINT nEv; 03580 LPINPUT pEvent; 03581 DWORD dwExpWinVer = PtiCurrent()->dwExpWinVer; 03582 03583 for (nEv = 0, pEvent = pInputs; nEv < nInputs; nEv++) { 03584 03585 switch (pEvent->type) { 03586 case INPUT_MOUSE: 03587 xxxMouseEventDirect( 03588 pEvent->mi.dx, 03589 pEvent->mi.dy, 03590 pEvent->mi.mouseData, 03591 pEvent->mi.dwFlags, 03592 pEvent->mi.time, 03593 pEvent->mi.dwExtraInfo); 03594 break; 03595 03596 case INPUT_KEYBOARD: 03597 if ((pEvent->ki.dwFlags & KEYEVENTF_UNICODE) && 03598 (pEvent->ki.wVk == 0) && 03599 ((pEvent->ki.dwFlags & ~(KEYEVENTF_KEYUP | KEYEVENTF_UNICODE)) == 0)) { 03600 xxxInternalKeyEventDirect( 03601 VK_PACKET, 03602 pEvent->ki.wScan, // actually a Unicode character 03603 pEvent->ki.dwFlags, 03604 pEvent->ki.time, 03605 pEvent->ki.dwExtraInfo); 03606 } else { 03607 xxxInternalKeyEventDirect( 03608 LOBYTE(pEvent->ki.wVk), 03609 LOBYTE(pEvent->ki.wScan), 03610 pEvent->ki.dwFlags, 03611 pEvent->ki.time, 03612 pEvent->ki.dwExtraInfo); 03613 } 03614 break; 03615 03616 case INPUT_HARDWARE: 03617 break; 03618 } 03619 03620 pEvent++; 03621 } 03622 return nInputs; 03623 }


Variable Documentation

PVOID* apObjects
 

Definition at line 84 of file ntinput.c.

Referenced by RawInputThread(), Win32kNtUserCleanup(), and xxxMsgWaitForMultipleObjects().

ULONG gMouseProcessMiceInputTime = 0
 

Definition at line 38 of file ntinput.c.

Referenced by ProcessMouseInput().

ULONG gMouseQueueMouseEventTime = 0
 

Definition at line 39 of file ntinput.c.

Referenced by QueueMouseEvent().

ULONG gMouseUnqueueMouseEventTime = 0
 

Definition at line 40 of file ntinput.c.

Referenced by UnqueueMouseEvent().

PKTIMER gptmrWD
 

Definition at line 82 of file ntinput.c.

Referenced by RawInputThread(), and Win32kNtUserCleanup().

PKWAIT_BLOCK gWaitBlockArray
 

Definition at line 18 of file ntinput.c.

Referenced by RawInputThread(), and Win32kNtUserCleanup().

INT idxRemainder
 

Definition at line 32 of file ntinput.c.

Referenced by GetMouseCoord().

INT idyRemainder
 

Definition at line 32 of file ntinput.c.

Referenced by GetMouseCoord().

KEYBOARD_UNIT_ID_PARAMETER kuid
 

Definition at line 20 of file ntinput.c.

MOUSE_UNIT_ID_PARAMETER muid
 

Definition at line 21 of file ntinput.c.


Generated on Sat May 15 19:44:53 2004 for test by doxygen 1.3.7