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.

494 lines
12 KiB

  1. /**************************************************************************\
  2. * Module Name: softkbdes.cpp
  3. *
  4. * Copyright (c) 1985 - 2000, Microsoft Corporation
  5. *
  6. * Soft Keyboard Event Sink for the Symbol layout
  7. *
  8. * History:
  9. * 28-March-2000 weibz Created
  10. \**************************************************************************/
  11. #include "private.h"
  12. #include "globals.h"
  13. #include "immxutil.h"
  14. #include "proputil.h"
  15. #include "kes.h"
  16. #include "helpers.h"
  17. #include "editcb.h"
  18. #include "dispattr.h"
  19. #include "computil.h"
  20. #include "regsvr.h"
  21. #include "korimx.h"
  22. #include "SoftKbdES.h"
  23. #include "osver.h"
  24. //////////////////////////////////////////////////////////////////////
  25. // Construction/Destruction
  26. //////////////////////////////////////////////////////////////////////
  27. CSoftKeyboardEventSink::CSoftKeyboardEventSink(CKorIMX *pKorIMX, DWORD dwSoftLayout)
  28. {
  29. m_pKorIMX = pKorIMX;
  30. _dwSoftLayout = dwSoftLayout;
  31. _fCaps = fFalse;
  32. _fShift = fFalse;
  33. _fAlt = fFalse;
  34. _fCtrl = fFalse;
  35. _tid = pKorIMX->GetTID();
  36. _tim = pKorIMX->GetTIM();
  37. _tim->AddRef( );
  38. _cRef = 1;
  39. }
  40. CSoftKeyboardEventSink::~CSoftKeyboardEventSink()
  41. {
  42. SafeReleaseClear(_tim);
  43. }
  44. //+---------------------------------------------------------------------------
  45. //
  46. // IUnknown
  47. //
  48. //----------------------------------------------------------------------------
  49. STDAPI CSoftKeyboardEventSink::QueryInterface(REFIID riid, void **ppvObj)
  50. {
  51. *ppvObj = NULL;
  52. if (IsEqualIID(riid, IID_IUnknown) ||
  53. IsEqualIID(riid, IID_ISoftKeyboardEventSink))
  54. {
  55. *ppvObj = SAFECAST(this, CSoftKeyboardEventSink *);
  56. }
  57. if (*ppvObj)
  58. {
  59. AddRef();
  60. return S_OK;
  61. }
  62. return E_NOINTERFACE;
  63. }
  64. STDAPI_(ULONG) CSoftKeyboardEventSink::AddRef()
  65. {
  66. return ++_cRef;
  67. }
  68. STDAPI_(ULONG) CSoftKeyboardEventSink::Release()
  69. {
  70. long cr;
  71. cr = --_cRef;
  72. Assert(cr >= 0);
  73. if (cr == 0)
  74. {
  75. delete this;
  76. }
  77. return cr;
  78. }
  79. //
  80. // ISoftKeyboardEventSink
  81. //
  82. STDAPI CSoftKeyboardEventSink::OnKeySelection(KEYID KeySelected, WCHAR *lpszLabel)
  83. {
  84. KEYID keyId;
  85. BYTE bVk, bScan;
  86. BOOL fModifierSpecial = fFalse;
  87. HKL hKL;
  88. INT_PTR iHKL;
  89. HRESULT hr;
  90. hr = S_OK;
  91. bScan = (BYTE)KeySelected;
  92. hKL = GetKeyboardLayout(0);
  93. if (!IsOnNT())
  94. {
  95. // We have to handle IME hkl specially on Win9x.
  96. // For some reason, Win9x cannot receive IME HKL as parameter in MapVirtualKeyEx and ToAsciiEx.
  97. iHKL = (INT_PTR)hKL;
  98. if ((iHKL & 0xF0000000) == 0xE0000000)
  99. {
  100. // this is FE IME HKL.
  101. iHKL = iHKL & 0x0000FFFF;
  102. hKL = (HKL)iHKL;
  103. }
  104. }
  105. bVk = (BYTE)MapVirtualKeyEx((UINT)bScan, 1, hKL);
  106. switch (KeySelected)
  107. {
  108. case KID_CTRL :
  109. _fCtrl = !_fCtrl;
  110. // Generate proper key msg
  111. if (_fCtrl)
  112. keybd_event(bVk, bScan, 0, 0);
  113. else
  114. keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
  115. break;
  116. case KID_ALT :
  117. _fAlt = !_fAlt;
  118. // Generate proper key msg
  119. if (_fAlt)
  120. keybd_event(bVk, bScan, 0, 0);
  121. else
  122. keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
  123. break;
  124. case KID_CAPS :
  125. if (m_pKorIMX->GetConvMode(m_pKorIMX->GetIC()) == TIP_ALPHANUMERIC_MODE)
  126. {
  127. _fCaps = !_fCaps;
  128. if (_fCaps == _fShift)
  129. // use state 0
  130. m_pKorIMX->GetHangulSKbd()->dwCurLabel = 0;
  131. else
  132. // use state 1
  133. m_pKorIMX->GetHangulSKbd()->dwCurLabel = 1;
  134. hr = SetCompartmentDWORD(_tid, _tim, GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, _dwSoftLayout, fFalse);
  135. }
  136. // specially handle Caps Lock
  137. // this is a togglable key
  138. keybd_event(bVk, bScan, 0, 0);
  139. keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
  140. break;
  141. case KID_LSHFT :
  142. case KID_RSHFT :
  143. _fShift = !_fShift;
  144. if (_fCaps == _fShift)
  145. // use state 0
  146. m_pKorIMX->GetHangulSKbd()->dwCurLabel = 0;
  147. else
  148. // use state 1
  149. m_pKorIMX->GetHangulSKbd()->dwCurLabel = 1;
  150. hr = SetCompartmentDWORD(_tid, _tim, GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, _dwSoftLayout, fFalse);
  151. // Generate proper key msg
  152. if (_fShift)
  153. keybd_event(bVk, bScan, 0, 0);
  154. else
  155. keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
  156. break;
  157. /*
  158. case KID_F1 :
  159. case KID_F2 :
  160. case KID_F3 :
  161. case KID_F4 :
  162. case KID_F5 :
  163. case KID_F6 :
  164. case KID_F7 :
  165. case KID_F8 :
  166. case KID_F9 :
  167. case KID_F10 :
  168. case KID_F11 :
  169. case KID_F12 :
  170. case KID_TAB :
  171. // simulate a key event and send to system.
  172. case KID_ENTER :
  173. case KID_ESC :
  174. case KID_SPACE :
  175. case KID_BACK :
  176. case KID_UP :
  177. case KID_DOWN :
  178. case KID_LEFT :
  179. case KID_RIGHT :
  180. */
  181. default:
  182. {
  183. int j, jIndex;
  184. BOOL fExtendKey, fPictureKey;
  185. keyId = KeySelected;
  186. fPictureKey = fFalse;
  187. // Check picture key
  188. for (j=0; j < NUM_PICTURE_KEYS; j++)
  189. {
  190. if (gPictureKeys[j].uScanCode == keyId)
  191. {
  192. // This is a picture key.
  193. // it may be a extended key.
  194. jIndex = j;
  195. fPictureKey = fTrue;
  196. break;
  197. }
  198. if (gPictureKeys[j].uScanCode == 0)
  199. {
  200. // This is the last item in gPictureKeys.
  201. break;
  202. }
  203. }
  204. fExtendKey = fFalse;
  205. // Picture key handling
  206. if (fPictureKey)
  207. {
  208. if ((keyId & 0xFF00) == 0xE000)
  209. {
  210. fExtendKey = fTrue;
  211. bScan = (BYTE)(keyId & 0x000000ff);
  212. }
  213. else
  214. bScan = (BYTE)keyId;
  215. // Get virtual key code
  216. bVk = (BYTE)(gPictureKeys[jIndex].uVkey);
  217. }
  218. // Generate Keyboard event
  219. if (fExtendKey)
  220. {
  221. keybd_event(bVk, bScan, (DWORD)KEYEVENTF_EXTENDEDKEY, 0);
  222. keybd_event(bVk, bScan, (DWORD)(KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP), 0);
  223. }
  224. else
  225. {
  226. keybd_event(bVk, bScan, 0, 0);
  227. keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
  228. }
  229. #if 0
  230. // if the Shift Key is pressed, we need to release this key.
  231. if (GetKeyState(VK_SHIFT) & 0x80)
  232. {
  233. fModifierSpecial = fTrue;
  234. _fShift = !_fShift;
  235. // simulate the SHIFT-UP key event.
  236. keybd_event((BYTE)VK_SHIFT, (BYTE)KID_LSHFT, (DWORD)KEYEVENTF_KEYUP, 0);
  237. }
  238. // if the Ctrl Key is pressed, we need to release this key.
  239. if (GetKeyState(VK_CONTROL) & 0x80)
  240. {
  241. fModifierSpecial = fTrue;
  242. // simulate the Ctrl-UP key event.
  243. keybd_event((BYTE)VK_CONTROL, (BYTE)KID_CTRL, (DWORD)KEYEVENTF_KEYUP, 0);
  244. }
  245. #endif
  246. #if 0
  247. // if the Alt Key is pressed, we need to release this key.
  248. if (lpCurKbdLayout->ModifierStatus & MODIFIER_ALT)
  249. {
  250. fModifierSpecial = TRUE;
  251. lpCurKbdLayout->ModifierStatus &= ~((WORD)MODIFIER_ALT);
  252. // simulate the SHIFT-UP key event.
  253. keybd_event((BYTE)VK_MENU, (BYTE)KID_ALT, (DWORD)KEYEVENTF_KEYUP, 0);
  254. }
  255. // if the Right Alt Key is pressed, we need to release this key.
  256. if (lpCurKbdLayout->ModifierStatus & MODIFIER_ALTGR)
  257. {
  258. fModifierSpecial = TRUE;
  259. lpCurKbdLayout->ModifierStatus &= ~((WORD)MODIFIER_ALTGR);
  260. // simulate the SHIFT-UP key event.
  261. keybd_event((BYTE)VK_RMENU, (BYTE)KID_RALT, (DWORD)KEYEVENTF_KEYUP, 0);
  262. }
  263. #endif
  264. if (fModifierSpecial)
  265. {
  266. if (_fCaps == _fShift)
  267. // use state 0
  268. m_pKorIMX->GetHangulSKbd()->dwCurLabel = 0;
  269. else
  270. // use state 1
  271. m_pKorIMX->GetHangulSKbd()->dwCurLabel = 1;
  272. hr = SetCompartmentDWORD(_tid, _tim, GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, _dwSoftLayout, fFalse);
  273. }
  274. break;
  275. }
  276. /*
  277. default :
  278. if ( lpszLabel == NULL )
  279. {
  280. hr = E_FAIL;
  281. return hr;
  282. }
  283. pic = m_pKorIMX->GetIC( );
  284. if ( pic == NULL )
  285. {
  286. return hr;
  287. }
  288. if (pes = new CEditSession(CKorIMX::_EditSessionCallback))
  289. {
  290. WCHAR *lpLabel;
  291. int i, iLen;
  292. iLen = (int) wcslen(lpszLabel);
  293. lpLabel = (WCHAR *)cicMemAllocClear((iLen+1)*sizeof(WCHAR));
  294. if ( lpLabel == NULL )
  295. {
  296. // not enough memory.
  297. hr = E_OUTOFMEMORY;
  298. return hr;
  299. }
  300. for ( i=0; i<iLen; i++)
  301. lpLabel[i] = lpszLabel[i];
  302. lpLabel[iLen] = L'\0';
  303. pes->_state.u = ESCB_KEYLABEL;
  304. pes->_state.pv = m_pKorIMX;
  305. pes->_state.wParam = (WPARAM)KeySelected;
  306. pes->_state.lParam = (LPARAM)lpLabel;
  307. pes->_state.pic = pic;
  308. pes->_state.pv1 = NULL;
  309. pic->EditSession(m_pKorIMX->_tid,
  310. pes,
  311. TF_ES_READWRITE,
  312. &hr);
  313. if ( FAILED(hr) )
  314. {
  315. SafeFreePointer(lpLabel);
  316. }
  317. SafeRelease(pes);
  318. }
  319. else
  320. hr = E_FAIL;
  321. SafeRelease(pic);
  322. break;
  323. */
  324. }
  325. return hr;
  326. }
  327. CSoftKbdWindowEventSink::CSoftKbdWindowEventSink(CKorIMX *pKorIMX)
  328. {
  329. m_pKorIMX = pKorIMX;
  330. _cRef = 1;
  331. }
  332. CSoftKbdWindowEventSink::~CSoftKbdWindowEventSink()
  333. {
  334. }
  335. //+---------------------------------------------------------------------------
  336. //
  337. // IUnknown
  338. //
  339. //----------------------------------------------------------------------------
  340. STDAPI CSoftKbdWindowEventSink::QueryInterface(REFIID riid, void **ppvObj)
  341. {
  342. *ppvObj = NULL;
  343. if (IsEqualIID(riid, IID_IUnknown) ||
  344. IsEqualIID(riid, IID_ISoftKbdWindowEventSink))
  345. {
  346. *ppvObj = SAFECAST(this, CSoftKbdWindowEventSink *);
  347. }
  348. if (*ppvObj)
  349. {
  350. AddRef();
  351. return S_OK;
  352. }
  353. return E_NOINTERFACE;
  354. }
  355. STDAPI_(ULONG) CSoftKbdWindowEventSink::AddRef()
  356. {
  357. return ++_cRef;
  358. }
  359. STDAPI_(ULONG) CSoftKbdWindowEventSink::Release()
  360. {
  361. long cr;
  362. cr = --_cRef;
  363. Assert(cr >= 0);
  364. if (cr == 0)
  365. {
  366. delete this;
  367. }
  368. return cr;
  369. }
  370. //
  371. // ISoftKbdWindowEventSink
  372. //
  373. STDAPI CSoftKbdWindowEventSink::OnWindowClose( )
  374. {
  375. HRESULT hr = S_OK;
  376. if (m_pKorIMX)
  377. m_pKorIMX->SetSoftKBDOnOff(FALSE);
  378. return hr;
  379. }
  380. STDAPI CSoftKbdWindowEventSink::OnWindowMove(int xWnd, int yWnd, int width, int height)
  381. {
  382. HRESULT hr = S_OK;
  383. if (m_pKorIMX)
  384. m_pKorIMX->SetSoftKBDPosition(xWnd, yWnd);
  385. // support size change later.
  386. UNREFERENCED_PARAMETER(width);
  387. UNREFERENCED_PARAMETER(height);
  388. return hr;
  389. }