Leaked source code of windows server 2003
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.

833 lines
31 KiB

  1. /****************************************************************************/
  2. /* ih.cpp */
  3. /* */
  4. /* Input Handler functions */
  5. /* */
  6. /* Copyright (c) 1997-1999 Microsoft Corporation */
  7. /****************************************************************************/
  8. #include <adcg.h>
  9. extern "C" {
  10. #define TRC_GROUP TRC_GROUP_CORE
  11. #define TRC_FILE "aihapi"
  12. #include <atrcapi.h>
  13. }
  14. #include "ih.h"
  15. #include "cc.h"
  16. CIH::CIH(CObjs* objs)
  17. {
  18. DC_BEGIN_FN("CIH::CIH");
  19. _pClientObjects = objs;
  20. _hKeyboardHook = NULL;
  21. _fUseHookBypass = FALSE;
  22. _fCanUseKeyboardHook = FALSE;
  23. memset(_KeyboardState, 0, sizeof(_KeyboardState));
  24. DC_END_FN();
  25. }
  26. CIH::~CIH()
  27. {
  28. DC_BEGIN_FN("CIH::~CIH");
  29. DC_END_FN();
  30. }
  31. VOID CIH::IH_StaticInit(HINSTANCE hInstance)
  32. {
  33. DC_BEGIN_FN("CIH::IH_StaticInit");
  34. UNREFERENCED_PARAMETER(hInstance);
  35. TRC_ASSERT(CIH::TlsIndex == 0xFFFFFFFF, (TB, _T("")));
  36. CIH::TlsIndex = TlsAlloc();
  37. if (CIH::TlsIndex == 0xFFFFFFFF) {
  38. TRC_ALT((TB, _T("Unable to allocate Thread Local Storage")));
  39. }
  40. DC_END_FN();
  41. }
  42. VOID CIH::IH_StaticTerm()
  43. {
  44. if (CIH::TlsIndex != 0xFFFFFFFF) {
  45. TlsFree(CIH::TlsIndex);
  46. CIH::TlsIndex = 0xFFFFFFFF;
  47. }
  48. }
  49. /****************************************************************************/
  50. /* Name: IH_Init */
  51. /* */
  52. /* Purpose: Initialize Input Handler */
  53. /****************************************************************************/
  54. DCVOID DCAPI CIH::IH_Init(DCVOID)
  55. {
  56. DC_BEGIN_FN("IH_Init");
  57. //Setup local object pointers
  58. _pUt = _pClientObjects->_pUtObject;
  59. _pUi = _pClientObjects->_pUiObject;
  60. _pSl = _pClientObjects->_pSlObject;
  61. _pUh = _pClientObjects->_pUHObject;
  62. _pCd = _pClientObjects->_pCdObject;
  63. _pIh = _pClientObjects->_pIhObject;
  64. _pOr = _pClientObjects->_pOrObject;
  65. _pFs = _pClientObjects->_pFsObject;
  66. _pCc = _pClientObjects->_pCcObject;
  67. _pOp = _pClientObjects->_pOPObject;
  68. /************************************************************************/
  69. /* Initialize the global data and the IH FSM state */
  70. /************************************************************************/
  71. DC_MEMSET(&_IH, 0, sizeof(_IH));
  72. _IH.fsmState = IH_STATE_RESET;
  73. /************************************************************************/
  74. /* Call the FSM to enter init state */
  75. /************************************************************************/
  76. IHFSMProc(IH_FSM_INIT, 0);
  77. DC_END_FN();
  78. } /* IH_Init */
  79. /****************************************************************************/
  80. /* Name: IH_Term */
  81. /* */
  82. /* Purpose: Terminate Input Handler */
  83. /****************************************************************************/
  84. DCVOID DCAPI CIH::IH_Term(DCVOID)
  85. {
  86. DC_BEGIN_FN("IH_Term");
  87. /************************************************************************/
  88. /* Call the FSM to clean up and enter reset state. */
  89. /************************************************************************/
  90. IHFSMProc(IH_FSM_TERM, 0);
  91. DC_END_FN();
  92. } /* IH_Term */
  93. /****************************************************************************/
  94. /* Name: IH_Enable */
  95. /* */
  96. /* Purpose: Called to enable _IH. */
  97. /****************************************************************************/
  98. DCVOID DCAPI CIH::IH_Enable(DCVOID)
  99. {
  100. DC_BEGIN_FN("IH_Enable");
  101. /************************************************************************/
  102. /* Call the FSM */
  103. /************************************************************************/
  104. IHFSMProc(IH_FSM_ENABLE, 0);
  105. DC_END_FN();
  106. } /* IH_Enable */
  107. /****************************************************************************/
  108. /* Name: IH_Disable */
  109. /* */
  110. /* Purpose: Called to disable _IH. This can safely be called even if */
  111. /* IH is not enabled. */
  112. /****************************************************************************/
  113. DCVOID DCAPI CIH::IH_Disable(DCVOID)
  114. {
  115. DC_BEGIN_FN("IH_Disable");
  116. /************************************************************************/
  117. /* Call the FSM */
  118. /************************************************************************/
  119. IHFSMProc(IH_FSM_DISABLE, 0);
  120. DC_END_FN();
  121. } /* IH_Disable */
  122. /****************************************************************************/
  123. /* Name: IH_BufferAvailable */
  124. /* */
  125. /* Purpose: Called when the network indicates that it is ready to send */
  126. /****************************************************************************/
  127. DCVOID DCAPI CIH::IH_BufferAvailable(DCVOID)
  128. {
  129. DC_BEGIN_FN("IH_BufferAvailable");
  130. IHFSMProc(IH_FSM_BUFFERAVAILABLE, 0);
  131. DC_END_FN();
  132. } /* IH_BufferAvailable */
  133. /****************************************************************************/
  134. /* Name: IH_GetInputHandlerWindow */
  135. /* */
  136. /* Purpose: Returns the handle of the Input Handler Window. */
  137. /* */
  138. /* Returns: Window handle. */
  139. /****************************************************************************/
  140. HWND DCAPI CIH::IH_GetInputHandlerWindow(DCVOID)
  141. {
  142. HWND rc;
  143. DC_BEGIN_FN("IH_GetInputHandlerWindow");
  144. rc = _IH.inputCaptureWindow;
  145. DC_END_FN();
  146. return(rc);
  147. } /* IH_GetInputHandlerWindow */
  148. /****************************************************************************/
  149. /* Name: IH_SetAcceleratorPassthrough */
  150. /* */
  151. /* Purpose: Sets the state of the accelerator passthrough. */
  152. /* */
  153. /* Params: enabled - 0 if disabled, 1 if enabled. */
  154. /* */
  155. /* Ideally this parameter would be of type DCBOOL, but this */
  156. /* function is called directly by the Component Decoupler so */
  157. /* must conform to the standard CD_SIMPLE_NOTIFICATION_FN */
  158. /* function type. */
  159. /****************************************************************************/
  160. DCVOID DCAPI CIH::IH_SetAcceleratorPassthrough(ULONG_PTR enabled)
  161. {
  162. DC_BEGIN_FN("IH_SetAcceleratorPassthrough");
  163. TRC_ASSERT( ((enabled == 0) || (enabled == 1)),
  164. (TB, _T("Invalid value for enabled: %u"), enabled) );
  165. _IH.acceleratorPassthroughEnabled = (DCBOOL)enabled;
  166. DC_END_FN();
  167. } /* IH_SetAcceleratorPassthrough */
  168. /****************************************************************************/
  169. /* Name: IH_SetCursorPos */
  170. /* */
  171. /* Purpose: Move the cursor - decoupled from CM */
  172. /* */
  173. /* Params: IN pData - new position (in remote coordinates) */
  174. /* IN dataLen - length of data */
  175. /****************************************************************************/
  176. DCVOID DCAPI CIH::IH_SetCursorPos(PDCVOID pData, DCUINT dataLen)
  177. {
  178. PPOINT pPos = (PPOINT)pData;
  179. DC_BEGIN_FN("IH_SetCursorPos");
  180. TRC_ASSERT((dataLen == sizeof(POINT)), (TB, _T("Invalid point size")));
  181. DC_IGNORE_PARAMETER(dataLen);
  182. /************************************************************************/
  183. /* Only move the mouse when IH has the focus */
  184. /************************************************************************/
  185. if (_IH.fsmState == IH_STATE_ACTIVE)
  186. {
  187. /********************************************************************/
  188. /* If the local mouse is already outside the client window then we */
  189. /* should ignore this message, even though we have the focus */
  190. /* */
  191. /* First get the position (screen coords) */
  192. /********************************************************************/
  193. POINT localMousePos;
  194. GetCursorPos(&localMousePos);
  195. /********************************************************************/
  196. /* now convert to Window coords */
  197. /********************************************************************/
  198. ScreenToClient(_pUi->UI_GetUIContainerWindow(), &localMousePos);
  199. if ((localMousePos.x < _IH.visibleArea.left) ||
  200. (localMousePos.x > _IH.visibleArea.right)||
  201. (localMousePos.y < _IH.visibleArea.top) ||
  202. (localMousePos.y > _IH.visibleArea.bottom))
  203. {
  204. TRC_ALT((TB, _T("MouseMove ignored - client mouse outside client")));
  205. TRC_DBG((TB, _T("local mouse (%d,%d), desired mouse (%d,%d)"),
  206. localMousePos.x, localMousePos.y, pPos->x, pPos->y));
  207. TRC_DBG((TB, _T("vis area l/t r/b (%d,%d %d,%d)"),
  208. _IH.visibleArea.left, _IH.visibleArea.top,
  209. _IH.visibleArea.right, _IH.visibleArea.bottom));
  210. }
  211. /********************************************************************/
  212. /* Don't move the mouse out of the client window. */
  213. /********************************************************************/
  214. else if ((pPos->x < _IH.visibleArea.left) ||
  215. (pPos->x > _IH.visibleArea.right)||
  216. (pPos->y < _IH.visibleArea.top) ||
  217. (pPos->y > _IH.visibleArea.bottom))
  218. {
  219. TRC_ALT((TB, _T("MouseMove ignored - dest is outside client")));
  220. TRC_DBG((TB, _T("desired mouse (%d,%d)"), pPos->x, pPos->y));
  221. TRC_DBG((TB, _T("vis area l/t r/b (%d,%d %d,%d)"),
  222. _IH.visibleArea.left, _IH.visibleArea.top,
  223. _IH.visibleArea.right, _IH.visibleArea.bottom));
  224. }
  225. else
  226. {
  227. /****************************************************************/
  228. /* Finally we actually apply the move, converting to screen */
  229. /* co-ordinates first */
  230. /****************************************************************/
  231. TRC_DBG((TB, _T("New Pos %d,%d (window co-ords)"),pPos->x, pPos->y));
  232. #ifdef SMART_SIZING
  233. //
  234. // Scale the mouse position in line with the shrunken desktop size
  235. // Do this before we translate to a screen position
  236. //
  237. DCSIZE desktopSize;
  238. _pUi->UI_GetDesktopSize(&desktopSize);
  239. if (_pUi->UI_GetSmartSizing() &&
  240. desktopSize.width != 0 &&
  241. desktopSize.height != 0)
  242. {
  243. pPos->x = (DCINT16)(pPos->x * _scaleSize.width / desktopSize.width);
  244. pPos->y = (DCINT16)(pPos->y * _scaleSize.height / desktopSize.height);
  245. }
  246. TRC_DBG((TB, _T("SmartSized Pos %d,%d (window co-ords)"),pPos->x, pPos->y));
  247. #endif
  248. ClientToScreen(_pUi->UI_GetUIContainerWindow(), pPos);
  249. TRC_DBG((TB, _T("Warp pointer to %d,%d (screen)"),pPos->x, pPos->y));
  250. SetCursorPos(pPos->x, pPos->y);
  251. }
  252. }
  253. else
  254. {
  255. TRC_NRM((TB, _T("Ignore mouse warp - don't have the focus")));
  256. }
  257. DC_END_FN();
  258. } /* IH_SetCursorPos */
  259. /****************************************************************************/
  260. /* Name: IH_SetCursorShape */
  261. /* */
  262. /* Purpose: Set the cursor shape - called by CM */
  263. /* */
  264. /* Params: IN pData new cursor handle */
  265. /* IN dataLen - length of data */
  266. /****************************************************************************/
  267. DCVOID DCAPI CIH::IH_SetCursorShape(ULONG_PTR data)
  268. {
  269. DC_BEGIN_FN("IH_SetCursorShape");
  270. /************************************************************************/
  271. /* Don't do this unless the session is active. */
  272. /************************************************************************/
  273. if ((_IH.fsmState == IH_STATE_ACTIVE) ||
  274. (_IH.fsmState == IH_STATE_PENDACTIVE) ||
  275. (_IH.fsmState == IH_STATE_SUSPENDED))
  276. {
  277. IHSetCursorShape((HCURSOR)data);
  278. }
  279. DC_END_FN();
  280. } /* IH_SetCursorShape */
  281. /****************************************************************************/
  282. /* Name: IH_SetVisiblePos */
  283. /* */
  284. /* Purpose: Set the visible window region, for mouse clipping */
  285. /* */
  286. /* Params: IN pData - position of window */
  287. /* IN dataLen - length of data */
  288. /****************************************************************************/
  289. DCVOID DCAPI CIH::IH_SetVisiblePos(PDCVOID pData, DCUINT dataLen)
  290. {
  291. PPOINT pNewPos = (PPOINT)pData;
  292. DCINT deltaX;
  293. DCINT deltaY;
  294. DC_BEGIN_FN("IH_SetVisiblePos");
  295. DC_IGNORE_PARAMETER(dataLen);
  296. /************************************************************************/
  297. /* Position should be negative */
  298. /************************************************************************/
  299. deltaX = _IH.visibleArea.left + pNewPos->x;
  300. deltaY = _IH.visibleArea.top + pNewPos->y;
  301. _IH.visibleArea.left -= deltaX;
  302. _IH.visibleArea.top -= deltaY;
  303. _IH.visibleArea.right -= deltaX;
  304. _IH.visibleArea.bottom -= deltaY;
  305. TRC_NRM((TB, _T("Top %d Left %d"), _IH.visibleArea.top, _IH.visibleArea.left));
  306. TRC_NRM((TB, _T("right %d bottom %d"),
  307. _IH.visibleArea.right, _IH.visibleArea.bottom));
  308. DC_END_FN();
  309. } /* IH_SetVisiblePos */
  310. /****************************************************************************/
  311. /* Name: IH_SetVisibleSize */
  312. /* */
  313. /* Purpose: Set the visible window region, for mouse clipping */
  314. /* */
  315. /* Params: IN data size of window */
  316. /****************************************************************************/
  317. DCVOID DCAPI CIH::IH_SetVisibleSize(ULONG_PTR data)
  318. {
  319. DCUINT width;
  320. DCUINT height;
  321. DC_BEGIN_FN("IH_SetVisibleSize");
  322. width = LOWORD(data);
  323. height = HIWORD(data);
  324. _IH.visibleArea.right = width + _IH.visibleArea.left - 1;
  325. _IH.visibleArea.bottom = height + _IH.visibleArea.top - 1;
  326. TRC_NRM((TB, _T("Top %d Left %d"), _IH.visibleArea.top, _IH.visibleArea.left));
  327. TRC_NRM((TB, _T("right %d bottom %d"),
  328. _IH.visibleArea.right, _IH.visibleArea.bottom));
  329. DC_END_FN();
  330. } /* IH_SetVisibleSize */
  331. /****************************************************************************/
  332. /* Name: IH_SetHotkey */
  333. /* */
  334. /* Purpose: To store the value of all the hotkeys passed from the UI */
  335. /* */
  336. /* Params: hotKey - IN - the value for UI.Hotkey */
  337. /****************************************************************************/
  338. DCVOID DCAPI CIH::IH_SetHotkey(PDCVOID pData, DCUINT len)
  339. {
  340. DC_BEGIN_FN("IH_SetHotkey");
  341. TRC_ASSERT((len == sizeof(PDCHOTKEY)),
  342. (TB, _T("Hotkey pointer is invalid")));
  343. DC_IGNORE_PARAMETER(len);
  344. _IH.pHotkey = *((PDCHOTKEY DCPTR)pData);
  345. DC_END_FN();
  346. } /* IH_SetHotkey */
  347. /****************************************************************************/
  348. /* Name: IH_ProcessInputCaps */
  349. /* */
  350. /* Purpose: Process input capabilities from the server */
  351. /* */
  352. /* Params: IN pInputCaps - pointer to caps */
  353. /****************************************************************************/
  354. DCVOID DCAPI CIH::IH_ProcessInputCaps(PTS_INPUT_CAPABILITYSET pInputCaps)
  355. {
  356. DC_BEGIN_FN("IH_ProcessInputCaps");
  357. TRC_ASSERT(pInputCaps, (TB,_T("pInputCaps parameter NULL in call to IH_ProcessInputCaps")));
  358. if(!pInputCaps)
  359. {
  360. DC_QUIT;
  361. }
  362. if (pInputCaps->inputFlags & TS_INPUT_FLAG_SCANCODES)
  363. {
  364. TRC_NRM((TB, _T("Server supports scancodes")));
  365. _IH.useScancodes = TRUE;
  366. }
  367. else
  368. {
  369. /********************************************************************/
  370. /* Note that current versions of the server should support */
  371. /* scancodes. */
  372. /********************************************************************/
  373. TRC_ALT((TB, _T("Server doesn't support scancodes")));
  374. _IH.useScancodes = FALSE;
  375. }
  376. if (pInputCaps->inputFlags & TS_INPUT_FLAG_MOUSEX)
  377. {
  378. TRC_NRM((TB, _T("Server supports mouse XButtons")));
  379. _IH.useXButtons = TRUE;
  380. }
  381. else
  382. {
  383. TRC_ALT((TB, _T("Server doesn't support mouse XButtons")));
  384. _IH.useXButtons = FALSE;
  385. }
  386. // Fast-path input added to RDP 5.0.
  387. if (pInputCaps->inputFlags & TS_INPUT_FLAG_FASTPATH_INPUT2) {
  388. TRC_NRM((TB,_T("Server supports fast-path input packets")));
  389. _IH.bUseFastPathInput = TRUE;
  390. }
  391. else {
  392. TRC_ALT((TB,_T("Server does not support fast-path input packets")));
  393. _IH.bUseFastPathInput = FALSE;
  394. }
  395. // VK_PACKET support added in RDP 5.1.1.
  396. if (pInputCaps->inputFlags & TS_INPUT_FLAG_VKPACKET)
  397. {
  398. TRC_NRM((TB,_T("Server supports VK_PACKET input packets")));
  399. _IH.fUseVKPacket = TRUE;
  400. }
  401. else
  402. {
  403. TRC_NRM((TB,_T("Server does not support VK_PACKET input packets")));
  404. _IH.fUseVKPacket = FALSE;
  405. }
  406. DC_END_FN();
  407. DC_EXIT_POINT:
  408. return;
  409. } /* IH_ProcessInputCaps */
  410. /****************************************************************************/
  411. /* Name: IH_UpdateKeyboardIndicators */
  412. /* */
  413. /* Purpose: Updates server-initiated keyboard indicator states */
  414. /* */
  415. /* Params: IN - UnitId UnitId */
  416. /* LedFlags LedFlags */
  417. /****************************************************************************/
  418. DCVOID DCAPI CIH::IH_UpdateKeyboardIndicators(DCUINT16 UnitId,
  419. DCUINT16 LedFlags)
  420. {
  421. DCUINT8 keyStates[256];
  422. DC_BEGIN_FN("IH_UpdateKeyboardIndicators");
  423. DC_IGNORE_PARAMETER(UnitId);
  424. /************************************************************************/
  425. /* Only set the leds when IH has the focus */
  426. /************************************************************************/
  427. if (_IH.fsmState == IH_STATE_ACTIVE)
  428. {
  429. /********************************************************************/
  430. /* Get the current keyboard toggle states */
  431. /********************************************************************/
  432. #ifdef OS_WINCE
  433. {
  434. KEY_STATE_FLAGS KeyStateFlags;
  435. KeyStateFlags = GetAsyncShiftFlags(0);
  436. keyStates[VK_SCROLL] = 0; // CE doesn't support this?
  437. keyStates[VK_NUMLOCK] = (DCUINT8)((KeyStateFlags & KeyShiftNumLockFlag) ? 1 : 0);
  438. keyStates[VK_CAPITAL] = (DCUINT8)((KeyStateFlags & KeyShiftCapitalFlag) ? 1 : 0);
  439. }
  440. #else
  441. GetKeyboardState(keyStates);
  442. #endif
  443. /********************************************************************/
  444. /* Process any SCROLL_LOCK changes */
  445. /********************************************************************/
  446. IHUpdateKeyboardIndicator(keyStates,
  447. (DCUINT8) (LedFlags & TS_SYNC_SCROLL_LOCK),
  448. (DCUINT8) VK_SCROLL);
  449. /********************************************************************/
  450. /* Process any NUM_LOCK changes */
  451. /********************************************************************/
  452. IHUpdateKeyboardIndicator(keyStates,
  453. (DCUINT8) (LedFlags & TS_SYNC_NUM_LOCK),
  454. (DCUINT8) VK_NUMLOCK);
  455. /************************************************************************/
  456. /* Keep track of NumLock state */
  457. /************************************************************************/
  458. _IH.NumLock = (GetKeyState(VK_NUMLOCK) & IH_KEYSTATE_TOGGLED);
  459. /********************************************************************/
  460. /* Process any CAPS_LOCK changes */
  461. /********************************************************************/
  462. IHUpdateKeyboardIndicator(keyStates,
  463. (DCUINT8) (LedFlags & TS_SYNC_CAPS_LOCK),
  464. (DCUINT8) VK_CAPITAL);
  465. /********************************************************************/
  466. /* Process any KANA_LOCK changes */
  467. /********************************************************************/
  468. #if defined(OS_WIN32)
  469. if (JAPANESE_KBD_LAYOUT(_pCc->_ccCombinedCapabilities.inputCapabilitySet.keyboardLayout))
  470. {
  471. IHUpdateKeyboardIndicator(keyStates,
  472. (DCUINT8) (LedFlags & TS_SYNC_KANA_LOCK),
  473. (DCUINT8) VK_KANA);
  474. }
  475. #endif // OS_WIN32
  476. }
  477. else
  478. {
  479. TRC_NRM((TB, _T("Ignore keyboard set leds - don't have the focus")));
  480. }
  481. DC_END_FN();
  482. return;
  483. }
  484. /****************************************************************************/
  485. /* Name: IH_InputEvent */
  486. /* */
  487. /* Purpose: Handle input events from UI */
  488. /* */
  489. /* Params: msg - message received from UI */
  490. /****************************************************************************/
  491. DCVOID DCAPI CIH::IH_InputEvent(ULONG_PTR msg)
  492. {
  493. DC_BEGIN_FN("IH_InputEvent");
  494. #ifndef OS_WINCE
  495. TRC_NRM((TB, _T("Msg %d"), msg));
  496. switch (msg)
  497. {
  498. #ifdef OS_WINNT
  499. case WM_ENTERSIZEMOVE:
  500. {
  501. TRC_NRM((TB, _T("WM_ENTERSIZEMOVE")));
  502. _IH.inSizeMove = TRUE;
  503. IHFSMProc(IH_FSM_FOCUS_LOSE, 0);
  504. }
  505. break;
  506. case WM_EXITSIZEMOVE:
  507. {
  508. TRC_NRM((TB, _T("WM_EXITSIZEMOVE")));
  509. _IH.inSizeMove = FALSE;
  510. IHFSMProc(IH_FSM_FOCUS_GAIN, 0);
  511. }
  512. break;
  513. case WM_EXITMENULOOP:
  514. {
  515. TRC_NRM((TB, _T("WM_EXITMENULOOP")));
  516. _IH.focusSyncRequired = TRUE;
  517. if (_IH.inSizeMove)
  518. {
  519. TRC_NRM((TB, _T("Was in size/move")));
  520. _IH.inSizeMove = FALSE;
  521. IHFSMProc(IH_FSM_FOCUS_GAIN, 0);
  522. }
  523. }
  524. break;
  525. #endif //OS_WINNT
  526. default:
  527. {
  528. TRC_ERR((TB, _T("Unexpected message %d from UI"), msg));
  529. }
  530. break;
  531. }
  532. #endif //OS_WINCE
  533. DC_END_FN();
  534. return;
  535. }
  536. /****************************************************************************/
  537. /* Name: IH_SetKeyboardImeStatus */
  538. /* */
  539. /* Purpose: Updates server-initiated keyboard IME states */
  540. /* */
  541. /* Params: IN pData size of ImeStatus */
  542. /* IN dataLen - length of data */
  543. /****************************************************************************/
  544. DCVOID DCAPI CIH::IH_SetKeyboardImeStatus(DCUINT32 ImeOpen, DCUINT32 ImeConvMode)
  545. {
  546. DC_BEGIN_FN("IH_SetKeyboardImeStatus");
  547. #if defined(OS_WINNT)
  548. if (_pUt->_UT.F3AHVOasysDll.hInst &&
  549. _pUt->lpfnFujitsuOyayubiControl != NULL) {
  550. _pUt->lpfnFujitsuOyayubiControl(ImeOpen, ImeConvMode);
  551. }
  552. #else
  553. DC_IGNORE_PARAMETER(ImeOpen);
  554. DC_IGNORE_PARAMETER(ImeConvMode);
  555. #endif // OS_WINNT
  556. DC_END_FN();
  557. }
  558. //
  559. // Called to notify the IH that we have entered fullscreen mode
  560. //
  561. VOID DCAPI CIH::IH_NotifyEnterFullScreen()
  562. {
  563. if(_fCanUseKeyboardHook &&
  564. (UTREG_UI_KEYBOARD_HOOK_FULLSCREEN == _pUi->_UI.keyboardHookMode))
  565. {
  566. //Start keyboard hooking
  567. _fUseHookBypass = TRUE;
  568. }
  569. }
  570. //
  571. // Called to notify the IH that we have left fullscreen mode
  572. //
  573. VOID DCAPI CIH::IH_NotifyLeaveFullScreen()
  574. {
  575. if(_fCanUseKeyboardHook &&
  576. (UTREG_UI_KEYBOARD_HOOK_FULLSCREEN == _pUi->_UI.keyboardHookMode))
  577. {
  578. //Stop keyboard hooking
  579. _fUseHookBypass = FALSE;
  580. }
  581. }
  582. //
  583. // Inject multiple VKEYS in an atomic way
  584. //
  585. DCVOID DCAPI CIH::IH_InjectMultipleVKeys(ULONG_PTR ihRequestPacket)
  586. {
  587. PIH_INJECT_VKEYS_REQUEST pihIrp = (PIH_INJECT_VKEYS_REQUEST)ihRequestPacket;
  588. INT i;
  589. TS_INPUT_EVENT * pEvent;
  590. MSG msg;
  591. DC_BEGIN_FN("IH_InjectMultipleVKeys");
  592. if (!_IH.pInputPDU)
  593. {
  594. //
  595. // This can happen if we're in the wrong state e.g IH_Disable
  596. //
  597. TRC_ERR((TB,_T("Called when no pInputPDU available")));
  598. pihIrp->fReturnStatus = FALSE;
  599. return;
  600. }
  601. //Flush any current input packet
  602. _IH.priorityEventsQueued = TRUE;
  603. IHMaybeSendPDU();
  604. //Clear any keyboard state
  605. if (_IH.pInputPDU->numberEvents > 0)
  606. {
  607. TRC_NRM((TB, _T("Cannot clear sync as the packet is not empty")));
  608. return;
  609. }
  610. //
  611. // Inject a Tab-up (the official clear-menu highlighting key because it
  612. // happens normally when alt-tabbing) before we sync. That way if
  613. // we thought the alt key was down when we sync, the server injected
  614. // alt up won't highlight the menu
  615. //
  616. IHInjectVKey(WM_SYSKEYUP, VK_TAB);
  617. //
  618. // Add the Sync event, setting toggles for CapsLock, NumLock and
  619. // ScrollLock.
  620. //
  621. TRC_DBG((TB, _T("Add sync event")));
  622. pEvent = &(_IH.pInputPDU->eventList[_IH.pInputPDU->numberEvents]);
  623. DC_MEMSET(pEvent, 0, sizeof(TS_INPUT_EVENT));
  624. pEvent->messageType = TS_INPUT_EVENT_SYNC;
  625. pEvent->eventTime = _pUt->UT_GetCurrentTimeMS();
  626. pEvent->u.sync.toggleFlags = 0;
  627. _IH.pInputPDU->numberEvents++;
  628. TS_DATAPKT_LEN(_IH.pInputPDU) += sizeof(TS_INPUT_EVENT);
  629. TS_UNCOMP_LEN(_IH.pInputPDU) += sizeof(TS_INPUT_EVENT);
  630. //
  631. // Construct dummy message for IHAddEventToPDU.
  632. //
  633. msg.hwnd = NULL;
  634. msg.lParam = 0;
  635. msg.wParam = 0;
  636. #ifdef OS_WINNT
  637. //
  638. // Initialize the state of the Alt & Ctrl keys to up.
  639. //
  640. _IH.dwModifierKeyState = 0;
  641. #endif
  642. //Dummy message
  643. IHAddEventToPDU(&msg);
  644. _IH.priorityEventsQueued = TRUE;
  645. IHMaybeSendPDU();
  646. //
  647. //Now send our injected keys
  648. //
  649. for(i=0; i< pihIrp->numKeys; i++)
  650. {
  651. IHInjectKey(pihIrp->pfArrayKeyUp[i] ? WM_KEYUP : WM_KEYDOWN,
  652. 0, //VKEY is ignored
  653. (DCUINT16)pihIrp->plKeyData[i]);
  654. }
  655. //Sync tor restore keyboard state
  656. IHSync();
  657. pihIrp->fReturnStatus = TRUE;
  658. DC_END_FN();
  659. }
  660. #ifdef SMART_SIZING
  661. /****************************************************************************/
  662. /* Name: IH_MainWindowSizeChange */
  663. /* */
  664. /* Purpose: Remembers the size of the container for scaling */
  665. /****************************************************************************/
  666. DCVOID DCAPI CIH::IH_MainWindowSizeChange(ULONG_PTR msg)
  667. {
  668. DCSIZE desktopSize;
  669. DCUINT width;
  670. DCUINT height;
  671. width = LOWORD(msg);
  672. height = HIWORD(msg);
  673. if (_pUi) {
  674. _pUi->UI_GetDesktopSize(&desktopSize);
  675. if (width <= desktopSize.width) {
  676. _scaleSize.width = width;
  677. } else {
  678. // full screen, or other times the window is bigger than the
  679. // display resolution
  680. _scaleSize.width = desktopSize.width;
  681. }
  682. // Similarly
  683. if (height <= desktopSize.height) {
  684. _scaleSize.height = height;
  685. } else {
  686. _scaleSize.height = desktopSize.height;
  687. }
  688. }
  689. }
  690. #endif // SMART_SIZING