You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
834 lines
31 KiB
834 lines
31 KiB
/****************************************************************************/
|
|
/* ih.cpp */
|
|
/* */
|
|
/* Input Handler functions */
|
|
/* */
|
|
/* Copyright (c) 1997-1999 Microsoft Corporation */
|
|
/****************************************************************************/
|
|
|
|
#include <adcg.h>
|
|
|
|
extern "C" {
|
|
#define TRC_GROUP TRC_GROUP_CORE
|
|
#define TRC_FILE "aihapi"
|
|
#include <atrcapi.h>
|
|
}
|
|
|
|
#include "ih.h"
|
|
#include "cc.h"
|
|
|
|
CIH::CIH(CObjs* objs)
|
|
{
|
|
DC_BEGIN_FN("CIH::CIH");
|
|
_pClientObjects = objs;
|
|
_hKeyboardHook = NULL;
|
|
_fUseHookBypass = FALSE;
|
|
_fCanUseKeyboardHook = FALSE;
|
|
|
|
memset(_KeyboardState, 0, sizeof(_KeyboardState));
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
|
|
CIH::~CIH()
|
|
{
|
|
DC_BEGIN_FN("CIH::~CIH");
|
|
DC_END_FN();
|
|
}
|
|
|
|
VOID CIH::IH_StaticInit(HINSTANCE hInstance)
|
|
{
|
|
DC_BEGIN_FN("CIH::IH_StaticInit");
|
|
|
|
UNREFERENCED_PARAMETER(hInstance);
|
|
|
|
TRC_ASSERT(CIH::TlsIndex == 0xFFFFFFFF, (TB, _T("")));
|
|
CIH::TlsIndex = TlsAlloc();
|
|
|
|
if (CIH::TlsIndex == 0xFFFFFFFF) {
|
|
TRC_ALT((TB, _T("Unable to allocate Thread Local Storage")));
|
|
}
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
VOID CIH::IH_StaticTerm()
|
|
{
|
|
if (CIH::TlsIndex != 0xFFFFFFFF) {
|
|
TlsFree(CIH::TlsIndex);
|
|
CIH::TlsIndex = 0xFFFFFFFF;
|
|
}
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_Init */
|
|
/* */
|
|
/* Purpose: Initialize Input Handler */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_Init(DCVOID)
|
|
{
|
|
DC_BEGIN_FN("IH_Init");
|
|
|
|
//Setup local object pointers
|
|
_pUt = _pClientObjects->_pUtObject;
|
|
_pUi = _pClientObjects->_pUiObject;
|
|
_pSl = _pClientObjects->_pSlObject;
|
|
_pUh = _pClientObjects->_pUHObject;
|
|
_pCd = _pClientObjects->_pCdObject;
|
|
_pIh = _pClientObjects->_pIhObject;
|
|
_pOr = _pClientObjects->_pOrObject;
|
|
_pFs = _pClientObjects->_pFsObject;
|
|
_pCc = _pClientObjects->_pCcObject;
|
|
_pOp = _pClientObjects->_pOPObject;
|
|
|
|
/************************************************************************/
|
|
/* Initialize the global data and the IH FSM state */
|
|
/************************************************************************/
|
|
DC_MEMSET(&_IH, 0, sizeof(_IH));
|
|
_IH.fsmState = IH_STATE_RESET;
|
|
|
|
/************************************************************************/
|
|
/* Call the FSM to enter init state */
|
|
/************************************************************************/
|
|
IHFSMProc(IH_FSM_INIT, 0);
|
|
|
|
DC_END_FN();
|
|
} /* IH_Init */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_Term */
|
|
/* */
|
|
/* Purpose: Terminate Input Handler */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_Term(DCVOID)
|
|
{
|
|
DC_BEGIN_FN("IH_Term");
|
|
|
|
/************************************************************************/
|
|
/* Call the FSM to clean up and enter reset state. */
|
|
/************************************************************************/
|
|
IHFSMProc(IH_FSM_TERM, 0);
|
|
|
|
DC_END_FN();
|
|
} /* IH_Term */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_Enable */
|
|
/* */
|
|
/* Purpose: Called to enable _IH. */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_Enable(DCVOID)
|
|
{
|
|
DC_BEGIN_FN("IH_Enable");
|
|
|
|
/************************************************************************/
|
|
/* Call the FSM */
|
|
/************************************************************************/
|
|
IHFSMProc(IH_FSM_ENABLE, 0);
|
|
|
|
DC_END_FN();
|
|
} /* IH_Enable */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_Disable */
|
|
/* */
|
|
/* Purpose: Called to disable _IH. This can safely be called even if */
|
|
/* IH is not enabled. */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_Disable(DCVOID)
|
|
{
|
|
DC_BEGIN_FN("IH_Disable");
|
|
|
|
/************************************************************************/
|
|
/* Call the FSM */
|
|
/************************************************************************/
|
|
IHFSMProc(IH_FSM_DISABLE, 0);
|
|
|
|
DC_END_FN();
|
|
} /* IH_Disable */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_BufferAvailable */
|
|
/* */
|
|
/* Purpose: Called when the network indicates that it is ready to send */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_BufferAvailable(DCVOID)
|
|
{
|
|
DC_BEGIN_FN("IH_BufferAvailable");
|
|
|
|
IHFSMProc(IH_FSM_BUFFERAVAILABLE, 0);
|
|
|
|
DC_END_FN();
|
|
} /* IH_BufferAvailable */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_GetInputHandlerWindow */
|
|
/* */
|
|
/* Purpose: Returns the handle of the Input Handler Window. */
|
|
/* */
|
|
/* Returns: Window handle. */
|
|
/****************************************************************************/
|
|
HWND DCAPI CIH::IH_GetInputHandlerWindow(DCVOID)
|
|
{
|
|
HWND rc;
|
|
|
|
DC_BEGIN_FN("IH_GetInputHandlerWindow");
|
|
|
|
rc = _IH.inputCaptureWindow;
|
|
|
|
DC_END_FN();
|
|
|
|
return(rc);
|
|
} /* IH_GetInputHandlerWindow */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_SetAcceleratorPassthrough */
|
|
/* */
|
|
/* Purpose: Sets the state of the accelerator passthrough. */
|
|
/* */
|
|
/* Params: enabled - 0 if disabled, 1 if enabled. */
|
|
/* */
|
|
/* Ideally this parameter would be of type DCBOOL, but this */
|
|
/* function is called directly by the Component Decoupler so */
|
|
/* must conform to the standard CD_SIMPLE_NOTIFICATION_FN */
|
|
/* function type. */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_SetAcceleratorPassthrough(ULONG_PTR enabled)
|
|
{
|
|
DC_BEGIN_FN("IH_SetAcceleratorPassthrough");
|
|
|
|
TRC_ASSERT( ((enabled == 0) || (enabled == 1)),
|
|
(TB, _T("Invalid value for enabled: %u"), enabled) );
|
|
|
|
_IH.acceleratorPassthroughEnabled = (DCBOOL)enabled;
|
|
|
|
DC_END_FN();
|
|
} /* IH_SetAcceleratorPassthrough */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_SetCursorPos */
|
|
/* */
|
|
/* Purpose: Move the cursor - decoupled from CM */
|
|
/* */
|
|
/* Params: IN pData - new position (in remote coordinates) */
|
|
/* IN dataLen - length of data */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_SetCursorPos(PDCVOID pData, DCUINT dataLen)
|
|
{
|
|
PPOINT pPos = (PPOINT)pData;
|
|
|
|
DC_BEGIN_FN("IH_SetCursorPos");
|
|
|
|
TRC_ASSERT((dataLen == sizeof(POINT)), (TB, _T("Invalid point size")));
|
|
DC_IGNORE_PARAMETER(dataLen);
|
|
|
|
/************************************************************************/
|
|
/* Only move the mouse when IH has the focus */
|
|
/************************************************************************/
|
|
if (_IH.fsmState == IH_STATE_ACTIVE)
|
|
{
|
|
/********************************************************************/
|
|
/* If the local mouse is already outside the client window then we */
|
|
/* should ignore this message, even though we have the focus */
|
|
/* */
|
|
/* First get the position (screen coords) */
|
|
/********************************************************************/
|
|
POINT localMousePos;
|
|
GetCursorPos(&localMousePos);
|
|
|
|
/********************************************************************/
|
|
/* now convert to Window coords */
|
|
/********************************************************************/
|
|
ScreenToClient(_pUi->UI_GetUIContainerWindow(), &localMousePos);
|
|
|
|
if ((localMousePos.x < _IH.visibleArea.left) ||
|
|
(localMousePos.x > _IH.visibleArea.right)||
|
|
(localMousePos.y < _IH.visibleArea.top) ||
|
|
(localMousePos.y > _IH.visibleArea.bottom))
|
|
{
|
|
TRC_ALT((TB, _T("MouseMove ignored - client mouse outside client")));
|
|
TRC_DBG((TB, _T("local mouse (%d,%d), desired mouse (%d,%d)"),
|
|
localMousePos.x, localMousePos.y, pPos->x, pPos->y));
|
|
TRC_DBG((TB, _T("vis area l/t r/b (%d,%d %d,%d)"),
|
|
_IH.visibleArea.left, _IH.visibleArea.top,
|
|
_IH.visibleArea.right, _IH.visibleArea.bottom));
|
|
|
|
}
|
|
/********************************************************************/
|
|
/* Don't move the mouse out of the client window. */
|
|
/********************************************************************/
|
|
else if ((pPos->x < _IH.visibleArea.left) ||
|
|
(pPos->x > _IH.visibleArea.right)||
|
|
(pPos->y < _IH.visibleArea.top) ||
|
|
(pPos->y > _IH.visibleArea.bottom))
|
|
{
|
|
TRC_ALT((TB, _T("MouseMove ignored - dest is outside client")));
|
|
TRC_DBG((TB, _T("desired mouse (%d,%d)"), pPos->x, pPos->y));
|
|
TRC_DBG((TB, _T("vis area l/t r/b (%d,%d %d,%d)"),
|
|
_IH.visibleArea.left, _IH.visibleArea.top,
|
|
_IH.visibleArea.right, _IH.visibleArea.bottom));
|
|
}
|
|
else
|
|
{
|
|
/****************************************************************/
|
|
/* Finally we actually apply the move, converting to screen */
|
|
/* co-ordinates first */
|
|
/****************************************************************/
|
|
|
|
TRC_DBG((TB, _T("New Pos %d,%d (window co-ords)"),pPos->x, pPos->y));
|
|
|
|
#ifdef SMART_SIZING
|
|
//
|
|
// Scale the mouse position in line with the shrunken desktop size
|
|
// Do this before we translate to a screen position
|
|
//
|
|
DCSIZE desktopSize;
|
|
|
|
_pUi->UI_GetDesktopSize(&desktopSize);
|
|
|
|
|
|
if (_pUi->UI_GetSmartSizing() &&
|
|
desktopSize.width != 0 &&
|
|
desktopSize.height != 0)
|
|
{
|
|
pPos->x = (DCINT16)(pPos->x * _scaleSize.width / desktopSize.width);
|
|
pPos->y = (DCINT16)(pPos->y * _scaleSize.height / desktopSize.height);
|
|
}
|
|
TRC_DBG((TB, _T("SmartSized Pos %d,%d (window co-ords)"),pPos->x, pPos->y));
|
|
#endif
|
|
ClientToScreen(_pUi->UI_GetUIContainerWindow(), pPos);
|
|
|
|
TRC_DBG((TB, _T("Warp pointer to %d,%d (screen)"),pPos->x, pPos->y));
|
|
SetCursorPos(pPos->x, pPos->y);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
TRC_NRM((TB, _T("Ignore mouse warp - don't have the focus")));
|
|
}
|
|
|
|
DC_END_FN();
|
|
} /* IH_SetCursorPos */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_SetCursorShape */
|
|
/* */
|
|
/* Purpose: Set the cursor shape - called by CM */
|
|
/* */
|
|
/* Params: IN pData new cursor handle */
|
|
/* IN dataLen - length of data */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_SetCursorShape(ULONG_PTR data)
|
|
{
|
|
DC_BEGIN_FN("IH_SetCursorShape");
|
|
|
|
/************************************************************************/
|
|
/* Don't do this unless the session is active. */
|
|
/************************************************************************/
|
|
if ((_IH.fsmState == IH_STATE_ACTIVE) ||
|
|
(_IH.fsmState == IH_STATE_PENDACTIVE) ||
|
|
(_IH.fsmState == IH_STATE_SUSPENDED))
|
|
{
|
|
IHSetCursorShape((HCURSOR)data);
|
|
}
|
|
|
|
DC_END_FN();
|
|
} /* IH_SetCursorShape */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_SetVisiblePos */
|
|
/* */
|
|
/* Purpose: Set the visible window region, for mouse clipping */
|
|
/* */
|
|
/* Params: IN pData - position of window */
|
|
/* IN dataLen - length of data */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_SetVisiblePos(PDCVOID pData, DCUINT dataLen)
|
|
{
|
|
PPOINT pNewPos = (PPOINT)pData;
|
|
DCINT deltaX;
|
|
DCINT deltaY;
|
|
|
|
DC_BEGIN_FN("IH_SetVisiblePos");
|
|
|
|
DC_IGNORE_PARAMETER(dataLen);
|
|
|
|
/************************************************************************/
|
|
/* Position should be negative */
|
|
/************************************************************************/
|
|
deltaX = _IH.visibleArea.left + pNewPos->x;
|
|
deltaY = _IH.visibleArea.top + pNewPos->y;
|
|
|
|
_IH.visibleArea.left -= deltaX;
|
|
_IH.visibleArea.top -= deltaY;
|
|
_IH.visibleArea.right -= deltaX;
|
|
_IH.visibleArea.bottom -= deltaY;
|
|
|
|
TRC_NRM((TB, _T("Top %d Left %d"), _IH.visibleArea.top, _IH.visibleArea.left));
|
|
TRC_NRM((TB, _T("right %d bottom %d"),
|
|
_IH.visibleArea.right, _IH.visibleArea.bottom));
|
|
|
|
DC_END_FN();
|
|
} /* IH_SetVisiblePos */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_SetVisibleSize */
|
|
/* */
|
|
/* Purpose: Set the visible window region, for mouse clipping */
|
|
/* */
|
|
/* Params: IN data size of window */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_SetVisibleSize(ULONG_PTR data)
|
|
{
|
|
DCUINT width;
|
|
DCUINT height;
|
|
|
|
DC_BEGIN_FN("IH_SetVisibleSize");
|
|
width = LOWORD(data);
|
|
height = HIWORD(data);
|
|
|
|
_IH.visibleArea.right = width + _IH.visibleArea.left - 1;
|
|
_IH.visibleArea.bottom = height + _IH.visibleArea.top - 1;
|
|
|
|
TRC_NRM((TB, _T("Top %d Left %d"), _IH.visibleArea.top, _IH.visibleArea.left));
|
|
TRC_NRM((TB, _T("right %d bottom %d"),
|
|
_IH.visibleArea.right, _IH.visibleArea.bottom));
|
|
|
|
DC_END_FN();
|
|
} /* IH_SetVisibleSize */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_SetHotkey */
|
|
/* */
|
|
/* Purpose: To store the value of all the hotkeys passed from the UI */
|
|
/* */
|
|
/* Params: hotKey - IN - the value for UI.Hotkey */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_SetHotkey(PDCVOID pData, DCUINT len)
|
|
{
|
|
DC_BEGIN_FN("IH_SetHotkey");
|
|
|
|
TRC_ASSERT((len == sizeof(PDCHOTKEY)),
|
|
(TB, _T("Hotkey pointer is invalid")));
|
|
DC_IGNORE_PARAMETER(len);
|
|
|
|
_IH.pHotkey = *((PDCHOTKEY DCPTR)pData);
|
|
|
|
DC_END_FN();
|
|
} /* IH_SetHotkey */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_ProcessInputCaps */
|
|
/* */
|
|
/* Purpose: Process input capabilities from the server */
|
|
/* */
|
|
/* Params: IN pInputCaps - pointer to caps */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_ProcessInputCaps(PTS_INPUT_CAPABILITYSET pInputCaps)
|
|
{
|
|
DC_BEGIN_FN("IH_ProcessInputCaps");
|
|
TRC_ASSERT(pInputCaps, (TB,_T("pInputCaps parameter NULL in call to IH_ProcessInputCaps")));
|
|
if(!pInputCaps)
|
|
{
|
|
DC_QUIT;
|
|
}
|
|
|
|
if (pInputCaps->inputFlags & TS_INPUT_FLAG_SCANCODES)
|
|
{
|
|
TRC_NRM((TB, _T("Server supports scancodes")));
|
|
_IH.useScancodes = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/********************************************************************/
|
|
/* Note that current versions of the server should support */
|
|
/* scancodes. */
|
|
/********************************************************************/
|
|
TRC_ALT((TB, _T("Server doesn't support scancodes")));
|
|
_IH.useScancodes = FALSE;
|
|
}
|
|
|
|
if (pInputCaps->inputFlags & TS_INPUT_FLAG_MOUSEX)
|
|
{
|
|
TRC_NRM((TB, _T("Server supports mouse XButtons")));
|
|
_IH.useXButtons = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TRC_ALT((TB, _T("Server doesn't support mouse XButtons")));
|
|
_IH.useXButtons = FALSE;
|
|
}
|
|
|
|
// Fast-path input added to RDP 5.0.
|
|
if (pInputCaps->inputFlags & TS_INPUT_FLAG_FASTPATH_INPUT2) {
|
|
TRC_NRM((TB,_T("Server supports fast-path input packets")));
|
|
_IH.bUseFastPathInput = TRUE;
|
|
}
|
|
else {
|
|
TRC_ALT((TB,_T("Server does not support fast-path input packets")));
|
|
_IH.bUseFastPathInput = FALSE;
|
|
}
|
|
|
|
// VK_PACKET support added in RDP 5.1.1.
|
|
if (pInputCaps->inputFlags & TS_INPUT_FLAG_VKPACKET)
|
|
{
|
|
TRC_NRM((TB,_T("Server supports VK_PACKET input packets")));
|
|
_IH.fUseVKPacket = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TRC_NRM((TB,_T("Server does not support VK_PACKET input packets")));
|
|
_IH.fUseVKPacket = FALSE;
|
|
}
|
|
|
|
DC_END_FN();
|
|
DC_EXIT_POINT:
|
|
return;
|
|
} /* IH_ProcessInputCaps */
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_UpdateKeyboardIndicators */
|
|
/* */
|
|
/* Purpose: Updates server-initiated keyboard indicator states */
|
|
/* */
|
|
/* Params: IN - UnitId UnitId */
|
|
/* LedFlags LedFlags */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_UpdateKeyboardIndicators(DCUINT16 UnitId,
|
|
DCUINT16 LedFlags)
|
|
{
|
|
DCUINT8 keyStates[256];
|
|
|
|
DC_BEGIN_FN("IH_UpdateKeyboardIndicators");
|
|
DC_IGNORE_PARAMETER(UnitId);
|
|
|
|
/************************************************************************/
|
|
/* Only set the leds when IH has the focus */
|
|
/************************************************************************/
|
|
if (_IH.fsmState == IH_STATE_ACTIVE)
|
|
{
|
|
/********************************************************************/
|
|
/* Get the current keyboard toggle states */
|
|
/********************************************************************/
|
|
#ifdef OS_WINCE
|
|
{
|
|
KEY_STATE_FLAGS KeyStateFlags;
|
|
KeyStateFlags = GetAsyncShiftFlags(0);
|
|
keyStates[VK_SCROLL] = 0; // CE doesn't support this?
|
|
keyStates[VK_NUMLOCK] = (DCUINT8)((KeyStateFlags & KeyShiftNumLockFlag) ? 1 : 0);
|
|
keyStates[VK_CAPITAL] = (DCUINT8)((KeyStateFlags & KeyShiftCapitalFlag) ? 1 : 0);
|
|
}
|
|
#else
|
|
GetKeyboardState(keyStates);
|
|
#endif
|
|
|
|
/********************************************************************/
|
|
/* Process any SCROLL_LOCK changes */
|
|
/********************************************************************/
|
|
IHUpdateKeyboardIndicator(keyStates,
|
|
(DCUINT8) (LedFlags & TS_SYNC_SCROLL_LOCK),
|
|
(DCUINT8) VK_SCROLL);
|
|
|
|
/********************************************************************/
|
|
/* Process any NUM_LOCK changes */
|
|
/********************************************************************/
|
|
IHUpdateKeyboardIndicator(keyStates,
|
|
(DCUINT8) (LedFlags & TS_SYNC_NUM_LOCK),
|
|
(DCUINT8) VK_NUMLOCK);
|
|
|
|
/************************************************************************/
|
|
/* Keep track of NumLock state */
|
|
/************************************************************************/
|
|
_IH.NumLock = (GetKeyState(VK_NUMLOCK) & IH_KEYSTATE_TOGGLED);
|
|
|
|
/********************************************************************/
|
|
/* Process any CAPS_LOCK changes */
|
|
/********************************************************************/
|
|
IHUpdateKeyboardIndicator(keyStates,
|
|
(DCUINT8) (LedFlags & TS_SYNC_CAPS_LOCK),
|
|
(DCUINT8) VK_CAPITAL);
|
|
|
|
/********************************************************************/
|
|
/* Process any KANA_LOCK changes */
|
|
/********************************************************************/
|
|
#if defined(OS_WIN32)
|
|
if (JAPANESE_KBD_LAYOUT(_pCc->_ccCombinedCapabilities.inputCapabilitySet.keyboardLayout))
|
|
{
|
|
IHUpdateKeyboardIndicator(keyStates,
|
|
(DCUINT8) (LedFlags & TS_SYNC_KANA_LOCK),
|
|
(DCUINT8) VK_KANA);
|
|
}
|
|
#endif // OS_WIN32
|
|
}
|
|
else
|
|
{
|
|
TRC_NRM((TB, _T("Ignore keyboard set leds - don't have the focus")));
|
|
}
|
|
|
|
DC_END_FN();
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_InputEvent */
|
|
/* */
|
|
/* Purpose: Handle input events from UI */
|
|
/* */
|
|
/* Params: msg - message received from UI */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_InputEvent(ULONG_PTR msg)
|
|
{
|
|
DC_BEGIN_FN("IH_InputEvent");
|
|
|
|
#ifndef OS_WINCE
|
|
|
|
TRC_NRM((TB, _T("Msg %d"), msg));
|
|
|
|
switch (msg)
|
|
{
|
|
#ifdef OS_WINNT
|
|
case WM_ENTERSIZEMOVE:
|
|
{
|
|
TRC_NRM((TB, _T("WM_ENTERSIZEMOVE")));
|
|
_IH.inSizeMove = TRUE;
|
|
IHFSMProc(IH_FSM_FOCUS_LOSE, 0);
|
|
}
|
|
break;
|
|
|
|
case WM_EXITSIZEMOVE:
|
|
{
|
|
TRC_NRM((TB, _T("WM_EXITSIZEMOVE")));
|
|
_IH.inSizeMove = FALSE;
|
|
IHFSMProc(IH_FSM_FOCUS_GAIN, 0);
|
|
}
|
|
break;
|
|
|
|
case WM_EXITMENULOOP:
|
|
{
|
|
TRC_NRM((TB, _T("WM_EXITMENULOOP")));
|
|
_IH.focusSyncRequired = TRUE;
|
|
if (_IH.inSizeMove)
|
|
{
|
|
TRC_NRM((TB, _T("Was in size/move")));
|
|
_IH.inSizeMove = FALSE;
|
|
IHFSMProc(IH_FSM_FOCUS_GAIN, 0);
|
|
}
|
|
}
|
|
break;
|
|
#endif //OS_WINNT
|
|
|
|
default:
|
|
{
|
|
TRC_ERR((TB, _T("Unexpected message %d from UI"), msg));
|
|
}
|
|
break;
|
|
}
|
|
#endif //OS_WINCE
|
|
|
|
DC_END_FN();
|
|
return;
|
|
}
|
|
|
|
|
|
/****************************************************************************/
|
|
/* Name: IH_SetKeyboardImeStatus */
|
|
/* */
|
|
/* Purpose: Updates server-initiated keyboard IME states */
|
|
/* */
|
|
/* Params: IN pData size of ImeStatus */
|
|
/* IN dataLen - length of data */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_SetKeyboardImeStatus(DCUINT32 ImeOpen, DCUINT32 ImeConvMode)
|
|
{
|
|
DC_BEGIN_FN("IH_SetKeyboardImeStatus");
|
|
|
|
#if defined(OS_WINNT)
|
|
if (_pUt->_UT.F3AHVOasysDll.hInst &&
|
|
_pUt->lpfnFujitsuOyayubiControl != NULL) {
|
|
_pUt->lpfnFujitsuOyayubiControl(ImeOpen, ImeConvMode);
|
|
}
|
|
#else
|
|
DC_IGNORE_PARAMETER(ImeOpen);
|
|
DC_IGNORE_PARAMETER(ImeConvMode);
|
|
#endif // OS_WINNT
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
//
|
|
// Called to notify the IH that we have entered fullscreen mode
|
|
//
|
|
VOID DCAPI CIH::IH_NotifyEnterFullScreen()
|
|
{
|
|
if(_fCanUseKeyboardHook &&
|
|
(UTREG_UI_KEYBOARD_HOOK_FULLSCREEN == _pUi->_UI.keyboardHookMode))
|
|
{
|
|
//Start keyboard hooking
|
|
_fUseHookBypass = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Called to notify the IH that we have left fullscreen mode
|
|
//
|
|
VOID DCAPI CIH::IH_NotifyLeaveFullScreen()
|
|
{
|
|
if(_fCanUseKeyboardHook &&
|
|
(UTREG_UI_KEYBOARD_HOOK_FULLSCREEN == _pUi->_UI.keyboardHookMode))
|
|
{
|
|
//Stop keyboard hooking
|
|
_fUseHookBypass = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Inject multiple VKEYS in an atomic way
|
|
//
|
|
DCVOID DCAPI CIH::IH_InjectMultipleVKeys(ULONG_PTR ihRequestPacket)
|
|
{
|
|
PIH_INJECT_VKEYS_REQUEST pihIrp = (PIH_INJECT_VKEYS_REQUEST)ihRequestPacket;
|
|
INT i;
|
|
TS_INPUT_EVENT * pEvent;
|
|
MSG msg;
|
|
|
|
DC_BEGIN_FN("IH_InjectMultipleVKeys");
|
|
|
|
if (!_IH.pInputPDU)
|
|
{
|
|
//
|
|
// This can happen if we're in the wrong state e.g IH_Disable
|
|
//
|
|
TRC_ERR((TB,_T("Called when no pInputPDU available")));
|
|
pihIrp->fReturnStatus = FALSE;
|
|
return;
|
|
}
|
|
|
|
//Flush any current input packet
|
|
_IH.priorityEventsQueued = TRUE;
|
|
IHMaybeSendPDU();
|
|
|
|
|
|
//Clear any keyboard state
|
|
if (_IH.pInputPDU->numberEvents > 0)
|
|
{
|
|
TRC_NRM((TB, _T("Cannot clear sync as the packet is not empty")));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Inject a Tab-up (the official clear-menu highlighting key because it
|
|
// happens normally when alt-tabbing) before we sync. That way if
|
|
// we thought the alt key was down when we sync, the server injected
|
|
// alt up won't highlight the menu
|
|
//
|
|
|
|
IHInjectVKey(WM_SYSKEYUP, VK_TAB);
|
|
|
|
//
|
|
// Add the Sync event, setting toggles for CapsLock, NumLock and
|
|
// ScrollLock.
|
|
//
|
|
TRC_DBG((TB, _T("Add sync event")));
|
|
pEvent = &(_IH.pInputPDU->eventList[_IH.pInputPDU->numberEvents]);
|
|
DC_MEMSET(pEvent, 0, sizeof(TS_INPUT_EVENT));
|
|
|
|
pEvent->messageType = TS_INPUT_EVENT_SYNC;
|
|
pEvent->eventTime = _pUt->UT_GetCurrentTimeMS();
|
|
pEvent->u.sync.toggleFlags = 0;
|
|
|
|
_IH.pInputPDU->numberEvents++;
|
|
TS_DATAPKT_LEN(_IH.pInputPDU) += sizeof(TS_INPUT_EVENT);
|
|
TS_UNCOMP_LEN(_IH.pInputPDU) += sizeof(TS_INPUT_EVENT);
|
|
|
|
//
|
|
// Construct dummy message for IHAddEventToPDU.
|
|
//
|
|
msg.hwnd = NULL;
|
|
msg.lParam = 0;
|
|
msg.wParam = 0;
|
|
|
|
#ifdef OS_WINNT
|
|
//
|
|
// Initialize the state of the Alt & Ctrl keys to up.
|
|
//
|
|
_IH.dwModifierKeyState = 0;
|
|
#endif
|
|
|
|
//Dummy message
|
|
IHAddEventToPDU(&msg);
|
|
_IH.priorityEventsQueued = TRUE;
|
|
IHMaybeSendPDU();
|
|
|
|
|
|
//
|
|
//Now send our injected keys
|
|
//
|
|
|
|
for(i=0; i< pihIrp->numKeys; i++)
|
|
{
|
|
IHInjectKey(pihIrp->pfArrayKeyUp[i] ? WM_KEYUP : WM_KEYDOWN,
|
|
0, //VKEY is ignored
|
|
(DCUINT16)pihIrp->plKeyData[i]);
|
|
}
|
|
|
|
//Sync tor restore keyboard state
|
|
IHSync();
|
|
|
|
pihIrp->fReturnStatus = TRUE;
|
|
|
|
DC_END_FN();
|
|
}
|
|
|
|
#ifdef SMART_SIZING
|
|
/****************************************************************************/
|
|
/* Name: IH_MainWindowSizeChange */
|
|
/* */
|
|
/* Purpose: Remembers the size of the container for scaling */
|
|
/****************************************************************************/
|
|
DCVOID DCAPI CIH::IH_MainWindowSizeChange(ULONG_PTR msg)
|
|
{
|
|
DCSIZE desktopSize;
|
|
DCUINT width;
|
|
DCUINT height;
|
|
|
|
width = LOWORD(msg);
|
|
height = HIWORD(msg);
|
|
|
|
if (_pUi) {
|
|
|
|
_pUi->UI_GetDesktopSize(&desktopSize);
|
|
|
|
if (width <= desktopSize.width) {
|
|
_scaleSize.width = width;
|
|
} else {
|
|
// full screen, or other times the window is bigger than the
|
|
// display resolution
|
|
_scaleSize.width = desktopSize.width;
|
|
}
|
|
|
|
// Similarly
|
|
if (height <= desktopSize.height) {
|
|
_scaleSize.height = height;
|
|
} else {
|
|
_scaleSize.height = desktopSize.height;
|
|
}
|
|
}
|
|
}
|
|
#endif // SMART_SIZING
|