Source code of Windows XP (NT5)
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.

954 lines
30 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WNMAN.C
  8. * WOW32 16-bit Winnls API support (manually-coded thunks)
  9. *
  10. * History:
  11. * Created 19-Feb-1992 by Junichi Okubo (junichio)
  12. * Changed 30-Jun-1992 by Hiroyuki Hanaoka (hiroh)
  13. * Changed 05-Nov-1992 by Kazuyuki Kato (v-kazuyk)
  14. *
  15. --*/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #ifdef FE_IME
  19. #include "ime.h"
  20. #include "imep.h"
  21. #include "winnls32.h"
  22. #include "wcall16.h" // use GlobalLock16
  23. #include "wownls.h"
  24. #include "wnman.h"
  25. MODNAME(wnman.c);
  26. struct _wow32imedebug {
  27. LPSZ subfunction;
  28. } wow32imedebug[]={
  29. {"undefined IME function"}, //0x00
  30. {"undefined IME function"}, //0x01
  31. {"undefined IME function"}, //0x02
  32. {"IME_GETIMECAPS"}, //0x03
  33. {"IME_SETOPEN"}, //0x04
  34. {"IME_GETOPEN"}, //0x05
  35. {"IME_ENABLEDOSIME"}, //0x06
  36. {"IME_GETVERSION"}, //0x07
  37. {"IME_SETCONVERSIONWINDOW"}, //0x08
  38. {"undefined IME function"}, //0x09
  39. {"undefined IME function"}, //0x0a
  40. {"undefined IME function"}, //0x0b
  41. {"undefined IME function"}, //0x0c
  42. {"undefined IME function"}, //0x0d
  43. {"undefined IME function"}, //0x0e
  44. {"undefined IME function"}, //0x0f
  45. {"IME_SETCONVERSIONMODE, (undefined IME function - KOREA)"}, //0x10
  46. {"IME_GETCONVERSIONMODE, (IME_GET_MODE - KOREA)"}, //0x11
  47. {"IME_SETCONVERSIONFONT, (IME_SET_MODE - KOREA)"}, //0x12
  48. {"IME_SENDVKEY"}, //0x13
  49. {"IME_DESTROYIME"}, //0x14
  50. {"IME_PRIVATE"}, //0x15
  51. {"IME_WINDOWUPDATE"}, //0x16
  52. {"IME_SELECT"}, //0x17
  53. {"IME_ENTERWORDREGISTERMODE"}, //0x18
  54. {"IME_SETCONVERSIONFONTEX"}, //0x19
  55. {"undefined IME function"}, //0x1a
  56. {"undefined IME function"}, //0x1b
  57. {"undefined IME function"}, //0x1c
  58. {"undefined IME function"}, //0x1d
  59. {"undefined IME function"}, //0x1e
  60. {"undefined IME function"}, //0x1f
  61. {"IME_CODECONVERT"}, //0x20
  62. {"IME_CONVERTLIST"}, //0x21
  63. {"undefined IME function"}, //0x22
  64. {"undefined IME function"}, //0x23
  65. {"undefined IME function"}, //0x24
  66. {"undefined IME function"}, //0x25
  67. {"undefined IME function"}, //0x26
  68. {"undefined IME function"}, //0x27
  69. {"undefined IME function"}, //0x28
  70. {"undefined IME function"}, //0x29
  71. {"undefined IME function"}, //0x2a
  72. {"undefined IME function"}, //0x2b
  73. {"undefined IME function"}, //0x2c
  74. {"undefined IME function"}, //0x2d
  75. {"undefined IME function"}, //0x2e
  76. {"undefined IME function"}, //0x2f
  77. {"IME_AUTOMATA"}, //0x30
  78. {"IME_HANJAMODE"}, //0x31
  79. {"undefined IME function"}, //0x32
  80. {"undefined IME function"}, //0x33
  81. {"undefined IME function"}, //0x34
  82. {"undefined IME function"}, //0x35
  83. {"undefined IME function"}, //0x36
  84. {"undefined IME function"}, //0x37
  85. {"undefined IME function"}, //0x38
  86. {"undefined IME function"}, //0x39
  87. {"undefined IME function"}, //0x3a
  88. {"undefined IME function"}, //0x3b
  89. {"undefined IME function"}, //0x3c
  90. {"undefined IME function"}, //0x3d
  91. {"undefined IME function"}, //0x3e
  92. {"undefined IME function"}, //0x3f
  93. {"IME_GETLEVEL"}, //0x40
  94. {"IME_SETLEVEL"}, //0x41
  95. {"IME_GETMNTABLE"} //0x42
  96. };
  97. INT wow32imedebugMax=0x43;
  98. HAND16 hFnt16; // 16 bit Font handle;
  99. #define IME_MOVEIMEWINDOW IME_SETCONVERSIONWINDOW
  100. ULONG FASTCALL WN32SendIMEMessage(PVDMFRAME pFrame)
  101. {
  102. ULONG ul = 0;
  103. PSENDIMEMESSAGE16 parg16;
  104. IMESTRUCT * imestruct32;
  105. register PIMESTRUCT16 ptag16;
  106. HANDLE hIME32;
  107. INT cb;
  108. VPVOID vp;
  109. HANDLE hlParam1 = NULL; // IME_ENTERWORDREGISTERMODE
  110. HANDLE hlParam2 = NULL;
  111. HANDLE hLFNT32 = NULL; // IMW_SETCONVERSIONFONT(EX)
  112. GETARGPTR(pFrame, sizeof(SENDIMEMESSAGE16), parg16);
  113. vp = GlobalLock16(FETCHWORD(parg16->lParam), NULL);
  114. GETMISCPTR(vp, ptag16); // Get IME struct16 ptr
  115. hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
  116. imestruct32 = GlobalLock(hIME32);
  117. // check for GlobalLock return as well when checking ptag16
  118. if (!ptag16 || !imestruct32) {
  119. LOGDEBUG(1,(" WINNLS:(Jun)ptag16==NULL!! || imestruct32 == NULL"));
  120. goto eee;
  121. }
  122. switch (ptag16 -> fnc) {
  123. case IME_HANJAMODE:
  124. // Korea specific function
  125. if (GetSystemDefaultLangID() != 0x412)
  126. goto eee;
  127. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  128. STOREDWORD(imestruct32->wParam, 0);
  129. // The 4th word of imestruct32 must contains ptag16->dchSource.
  130. // msime95 will find ptag16->dchSource on the 4th word.
  131. *((LPSTR)(imestruct32) + sizeof(ptag16->fnc) +
  132. sizeof(ptag16->wParam) +
  133. sizeof(ptag16->wCount) )
  134. = (CHAR)ptag16->dchSource;
  135. *((LPSTR)(imestruct32) + ptag16->dchSource)
  136. = *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource);
  137. *((LPSTR)(imestruct32) + ptag16->dchSource + 1)
  138. = *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource + 1);
  139. // Quattro Pro Window use null window handle when it call Hanja conversion.
  140. if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_QPW_FIXINVALIDWINHANDLE)
  141. parg16->hwnd = GETHWND16(GetFocus());
  142. break;
  143. case IME_CONVERTLIST:
  144. case IME_AUTOMATA:
  145. case IME_CODECONVERT:
  146. case IME_SETLEVEL:
  147. case IME_GETLEVEL:
  148. case IME_GETMNTABLE:
  149. // Korea specific function
  150. if (GetSystemDefaultLangID() != 0x412)
  151. goto eee;
  152. goto standard;
  153. case IME_SETCONVERSIONWINDOW: // (IME_MOVECONVERTWINDOW)
  154. // IME_MOVEIMEWINDOW for Korea
  155. if (GetSystemDefaultLangID() != 0x412 &&
  156. CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_AMIPRO_PM4J_IME) {
  157. // Don't pass the MCW_DEFAULT.
  158. // because, Conversion window will be flushed when
  159. // default conversion window and AMIPRO's window have overlap.
  160. //
  161. // Also, for PM4J, when the codebox is moved Pagemaker
  162. // thinks it needs to be displayed at default. Prevent
  163. // endless loop of default screen|window displays
  164. //
  165. if (ptag16->wParam == MCW_DEFAULT) {
  166. ul = FALSE;
  167. goto eee;
  168. }
  169. }
  170. case IME_GETOPEN:
  171. case IME_SETOPEN:
  172. case IME_GETIMECAPS: // (IME_QUERY)
  173. case IME_SETCONVERSIONMODE: // (IME_SET_MODE)
  174. case IME_GETCONVERSIONMODE: // (IME_GET_MODE)
  175. case IME_SENDVKEY: // (IME_SENDKEY)
  176. case IME_DESTROYIME: // (IME_DESTROY)
  177. case IME_WINDOWUPDATE:
  178. case IME_SELECT:
  179. case IME_GETVERSION:
  180. standard:
  181. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  182. STOREDWORD(imestruct32->wParam, ptag16->wParam);
  183. STOREDWORD(imestruct32->wCount, ptag16->wCount);
  184. STOREDWORD(imestruct32->dchSource, ptag16->dchSource);
  185. STOREDWORD(imestruct32->dchDest, ptag16->dchDest);
  186. /*** STOREWORD -> STOREDWORD v-kazyk ***/
  187. STOREDWORD(imestruct32->lParam1, ptag16->lParam1);
  188. STOREDWORD(imestruct32->lParam2, ptag16->lParam2);
  189. STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
  190. break;
  191. case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
  192. {
  193. LPBYTE lpMem16;
  194. LPBYTE lpMem32;
  195. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  196. if (ptag16->lParam1) {
  197. vp = GlobalLock16(FETCHWORD(ptag16->lParam1), &cb);
  198. hlParam1 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
  199. lpMem32 = GlobalLock(hlParam1);
  200. if (!lpMem32) {
  201. goto eee;
  202. }
  203. GETMISCPTR(vp, lpMem16);
  204. RtlCopyMemory(lpMem32, lpMem16, cb);
  205. GlobalUnlock(hlParam1);
  206. GlobalUnlock16(FETCHWORD(ptag16->lParam1));
  207. }
  208. if (ptag16->lParam2) {
  209. vp = GlobalLock16(FETCHWORD(ptag16->lParam2), &cb);
  210. hlParam2 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
  211. lpMem32 = GlobalLock(hlParam2);
  212. if (!lpMem32) {
  213. goto eee;
  214. }
  215. GETMISCPTR(vp, lpMem16);
  216. RtlCopyMemory(lpMem32, lpMem16, cb);
  217. GlobalUnlock(hlParam2);
  218. GlobalUnlock16(FETCHWORD(ptag16->lParam2));
  219. }
  220. STOREDWORD(imestruct32->lParam1, hlParam1);
  221. STOREDWORD(imestruct32->lParam2, hlParam2);
  222. STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
  223. }
  224. break;
  225. case IME_SETCONVERSIONFONT: // (IME_SET_MODE - Korea)
  226. {
  227. LOGFONT * logfont32;
  228. if (GetSystemDefaultLangID() == 0x412) {
  229. // Hunguel WOW should do anything for IME_SET_MODE function
  230. goto eee;
  231. }
  232. STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
  233. if ( ptag16->wParam ) {
  234. hLFNT32 = GlobalAlloc( GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
  235. logfont32 = GlobalLock(hLFNT32);
  236. GetObject(HOBJ32(ptag16->wParam), sizeof(LOGFONT), logfont32);
  237. GlobalUnlock(hLFNT32);
  238. }
  239. else {
  240. hLFNT32 = NULL;
  241. }
  242. STOREDWORD(imestruct32->lParam1, hLFNT32);
  243. }
  244. break;
  245. case IME_SETCONVERSIONFONTEX:
  246. {
  247. LOGFONT * logfont32;
  248. STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
  249. if (!ptag16->lParam1) {
  250. imestruct32->lParam1 = (ULONG)NULL;
  251. break;
  252. }
  253. // HANDLE of LOGFONT check
  254. // If lParam1 is Invalid Handle, hLFNT32 is NULL
  255. if (FETCHWORD(ptag16->lParam1) &&
  256. (vp = GlobalLock16(FETCHWORD(ptag16->lParam1), NULL))) {
  257. hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
  258. logfont32 = GlobalLock(hLFNT32);
  259. // GETMISCPTR(vp, logfont16);
  260. GETLOGFONT16(vp, logfont32);
  261. GlobalUnlock16(FETCHWORD(ptag16->lParam1));
  262. GlobalUnlock(hLFNT32);
  263. }
  264. else {
  265. hLFNT32 = NULL;
  266. }
  267. STOREDWORD(imestruct32->lParam1, hLFNT32);
  268. }
  269. break;
  270. case IME_PRIVATE:
  271. LOGDEBUG(0,(" ERROR:SendIMEMessage IME_PRIVATE NOT IMPLEMENTED\n"));
  272. goto eee;
  273. case IME_ENABLEDOSIME: // (IME_ENABLE)
  274. default:
  275. LOGDEBUG(0,(" ERROR:SendIMEMessage unexpected subfunction\n"));
  276. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGE %s\n",
  277. wow32imedebug[ptag16->fnc]));
  278. goto eee;
  279. }
  280. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGE %s\n",
  281. wow32imedebug[ptag16->fnc]));
  282. if (ptag16 -> fnc != IME_SETCONVERSIONWINDOW) {
  283. LOGDEBUG(1,("WINNLS: fnc == %x wParam == %x wCount == %x\n",
  284. imestruct32->fnc, imestruct32->wParam, imestruct32->wCount ));
  285. LOGDEBUG(1,("WINNLS: dchDest == %x dchSource == %x\n",
  286. imestruct32->dchDest, imestruct32->dchSource));
  287. LOGDEBUG(1,("WINNLS: lParam1 == %x lParam2 == %x lParam3 == %x\n",
  288. imestruct32->lParam1, imestruct32->lParam2, imestruct32->lParam3));
  289. LOGDEBUG(1,("WINNLS: hwnd == %x %x\n",
  290. parg16->hwnd,HWND32(parg16->hwnd)));
  291. }
  292. GlobalUnlock(hIME32);
  293. // For win31 compatibility, since win31 didn't check the first
  294. // parm, check it here and fill in a dummy (WOW) hwnd if its bogus
  295. // so that NT doesn't reject the call
  296. ul = SendIMEMessageEx(
  297. ((parg16->hwnd) ? HWND32(parg16->hwnd) : (HWND)0xffff0000),
  298. (LPARAM)hIME32);
  299. LOGDEBUG(1,("WINNLS: Ret == %x\n", ul ));
  300. imestruct32 = GlobalLock(hIME32);
  301. LOGDEBUG(1,("WINNLS: wParam == %x\n\n", imestruct32->wParam ));
  302. STOREWORD(ptag16->wParam, ul);
  303. switch (ptag16->fnc) {
  304. case IME_GETOPEN:
  305. STOREWORD(ptag16->wCount, imestruct32->wCount);
  306. break;
  307. case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
  308. if (hlParam1)
  309. GlobalFree(hlParam1);
  310. if (hlParam2)
  311. GlobalFree(hlParam2);
  312. break;
  313. case IME_SETCONVERSIONFONT: // (IME_SETFONT)
  314. {
  315. HAND16 hTmp;
  316. hTmp = ptag16->wParam;
  317. ptag16->wParam = hFnt16;
  318. hFnt16 = hTmp;
  319. if ( hLFNT32 )
  320. GlobalFree(hLFNT32);
  321. }
  322. break;
  323. case IME_SETCONVERSIONFONTEX:
  324. if ( hLFNT32 )
  325. GlobalFree(hLFNT32);
  326. break;
  327. case IME_GETVERSION:
  328. // PowerPoint4J must have version returned as 3.1
  329. // Or else it thinks that the ime doesn't support IR_UNDETERMINE
  330. if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_PPT4J_IME_GETVERSION) {
  331. STOREWORD(ptag16->wParam, 0x0A03);
  332. }
  333. // WARNING: For DaytonaJ RC1 only!!!
  334. // Tell Winword6J that the IME doesn't support TrueInline (undetermine msgs)
  335. // So, that WinWord6J doesn't hang up doing the input loop processing of it.
  336. else if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_WORDJ_IME_GETVERSION) {
  337. STOREWORD(ptag16->wParam, 0x0003);
  338. }
  339. break;
  340. default:
  341. break;
  342. }
  343. eee:
  344. GlobalUnlock(hIME32);
  345. GlobalFree(hIME32);
  346. GlobalUnlock16(FETCHWORD(parg16->lParam));
  347. FREEVDMPTR(ptag16);
  348. FREEARGPTR(parg16);
  349. return(ul);
  350. }
  351. ULONG FASTCALL WN32SendIMEMessageEx(PVDMFRAME pFrame)
  352. {
  353. ULONG ul = 0;
  354. PSENDIMEMESSAGE16 parg16;
  355. IMESTRUCT * imestruct32;
  356. register PIMESTRUCT16 ptag16;
  357. HANDLE hIME32;
  358. INT cb;
  359. VPVOID vp;
  360. HANDLE hlParam1 = NULL; // IME_ENTERWORDREGISTERMODE
  361. HANDLE hlParam2 = NULL;
  362. HANDLE hLFNT32; // IME_SETCONVERSIONFONT(EX)
  363. GETARGPTR(pFrame, sizeof(SENDIMEMESSAGE16), parg16);
  364. vp = GlobalLock16(FETCHWORD(parg16->lParam), NULL);
  365. GETMISCPTR(vp, ptag16);
  366. hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
  367. imestruct32 = GlobalLock(hIME32);
  368. // if can't lock hIME32 fail gracefully
  369. if (!ptag16 || !imestruct32) {
  370. LOGDEBUG(1,(" WINNLS:(Jun)ptag16==NULL!! or imestruct32 == NULL"));
  371. goto eee;
  372. }
  373. switch (ptag16->fnc) {
  374. case IME_HANJAMODE:
  375. // Korea specific function
  376. if (GetSystemDefaultLangID() != 0x412)
  377. goto eee;
  378. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  379. STOREDWORD(imestruct32->wParam, 0);
  380. // The 4th word of imestruct32 must contains ptag16->dchSource.
  381. // msime95 will find ptag16->dchSource on the 4th word.
  382. *((LPSTR)(imestruct32) + sizeof(ptag16->fnc) +
  383. sizeof(ptag16->wParam) +
  384. sizeof(ptag16->wCount) )
  385. = (CHAR)ptag16->dchSource;
  386. *((LPSTR)(imestruct32) + ptag16->dchSource)
  387. = *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource);
  388. *((LPSTR)(imestruct32) + ptag16->dchSource + 1)
  389. = *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource + 1);
  390. break;
  391. case IME_CONVERTLIST:
  392. case IME_AUTOMATA:
  393. case IME_CODECONVERT:
  394. case IME_SETLEVEL:
  395. case IME_GETLEVEL:
  396. case IME_GETMNTABLE:
  397. // Korea specific function
  398. if (GetSystemDefaultLangID() != 0x412)
  399. goto eee;
  400. goto standard;
  401. case IME_SETCONVERSIONWINDOW: // (IME_MOVECONVERTWINDOW)
  402. // IME_MOVEIMEWINDOW for Korea
  403. if (GetSystemDefaultLangID() != 0x412 &&
  404. CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_AMIPRO_PM4J_IME) {
  405. // Don't pass the MCW_DEFAULT.
  406. // because, Conversion window will be flushed when
  407. // default conversion window and AMIPRO's window have overlap.
  408. //
  409. // Also, for PM4J, when the codebox is moved Pagemaker
  410. // thinks it needs to be displayed at default. Prevent
  411. // endless loop of default screen|window displays
  412. //
  413. if (ptag16->wParam == MCW_DEFAULT) {
  414. ul = FALSE;
  415. goto eee;
  416. }
  417. }
  418. case IME_GETOPEN:
  419. case IME_SETOPEN:
  420. case IME_GETIMECAPS: // (IME_QUERY)
  421. case IME_SETCONVERSIONMODE: // (IME_SET_MODE)
  422. case IME_GETCONVERSIONMODE: // (IME_GET_MODE)
  423. case IME_SENDVKEY: // (IME_SENDKEY)
  424. case IME_DESTROYIME: // (IME_DESTROY)
  425. case IME_WINDOWUPDATE:
  426. case IME_SELECT:
  427. case IME_GETVERSION: // Win3.1
  428. standard:
  429. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  430. STOREDWORD(imestruct32->wParam, ptag16->wParam);
  431. STOREDWORD(imestruct32->wCount, ptag16->wCount);
  432. STOREDWORD(imestruct32->dchSource, ptag16->dchSource);
  433. STOREDWORD(imestruct32->dchDest, ptag16->dchDest);
  434. STOREDWORD(imestruct32->lParam1, ptag16->lParam1);
  435. STOREDWORD(imestruct32->lParam2, ptag16->lParam2);
  436. STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
  437. break;
  438. case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
  439. {
  440. LPBYTE lpMem16;
  441. LPBYTE lpMem32;
  442. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  443. if (ptag16->lParam1) {
  444. vp = GlobalLock16(FETCHWORD(ptag16->lParam1), &cb);
  445. hlParam1 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
  446. lpMem32 = GlobalLock(hlParam1);
  447. if (vp) {
  448. if (lpMem32) {
  449. GETMISCPTR(vp, lpMem16);
  450. RtlCopyMemory(lpMem32, lpMem16, cb);
  451. GlobalUnlock(hlParam1);
  452. }
  453. GlobalUnlock16(FETCHWORD(ptag16->lParam1));
  454. }
  455. }
  456. if (ptag16->lParam2) {
  457. vp = GlobalLock16(FETCHWORD(ptag16->lParam2), &cb);
  458. hlParam2 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
  459. lpMem32 = GlobalLock(hlParam2);
  460. if (vp) {
  461. if (lpMem32) {
  462. GETMISCPTR(vp, lpMem16);
  463. RtlCopyMemory(lpMem32, lpMem16, cb);
  464. GlobalUnlock(hlParam2);
  465. }
  466. GlobalUnlock16(FETCHWORD(ptag16->lParam2));
  467. }
  468. }
  469. imestruct32->lParam1 = (LPARAM)hlParam1;
  470. imestruct32->lParam2 = (LPARAM)hlParam2;
  471. STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
  472. }
  473. break;
  474. case IME_SETCONVERSIONFONT: // (IME_SET_MODE - Korea)
  475. {
  476. LOGFONT * logfont32;
  477. if (GetSystemDefaultLangID() == 0x412) {
  478. // Hunguel WOW should do anything for IME_SET_MODE function
  479. goto eee;
  480. }
  481. STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
  482. if ( ptag16->wParam ) {
  483. hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
  484. logfont32 = GlobalLock(hLFNT32);
  485. GetObject(HOBJ32(ptag16->wParam), sizeof(LOGFONT), logfont32);
  486. GlobalUnlock(hLFNT32);
  487. }
  488. else {
  489. hLFNT32 = NULL;
  490. }
  491. imestruct32->lParam1 = (LPARAM)hLFNT32;
  492. }
  493. break;
  494. case IME_SETCONVERSIONFONTEX: // Win3.1
  495. {
  496. LOGFONT * logfont32;
  497. STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
  498. if (!(ptag16->lParam1)) {
  499. imestruct32->lParam1 = (LPARAM)NULL;
  500. break;
  501. }
  502. hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
  503. logfont32 = GlobalLock(hLFNT32);
  504. if (logfont32) {
  505. vp = GlobalLock16(FETCHWORD(ptag16->lParam1), NULL);
  506. // GETMISCPTR(vp, logfont16);
  507. GETLOGFONT16(vp, logfont32);
  508. GlobalUnlock16(FETCHWORD(ptag16->lParam1));
  509. GlobalUnlock(hLFNT32);
  510. }
  511. imestruct32->lParam1 = (LPARAM)hLFNT32;
  512. }
  513. break;
  514. case IME_PRIVATE:
  515. LOGDEBUG(0,(" ERROR:SendIMEMessageEx IME_PRIVATE NOT YET IMPLEMENTED\n"));
  516. goto eee;
  517. case IME_ENABLEDOSIME: // (IME_ENABLE)
  518. default:
  519. LOGDEBUG(0,(" ERROR:SendIMEMessageEx unexpected subfunction\n"));
  520. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGEEX %s\n",
  521. wow32imedebug[ptag16->fnc]));
  522. goto eee;
  523. }
  524. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGEEX %s\n",
  525. wow32imedebug[ptag16->fnc]));
  526. LOGDEBUG(1,(" IMESTRUCT16 Size = %d\n",
  527. sizeof(IMESTRUCT16)));
  528. LOGDEBUG(1,("WINNLS: IMESTRUCT.fnc == %x wParam == %x\n",
  529. imestruct32->fnc,imestruct32->wParam));
  530. LOGDEBUG(1,("WINNLS: IMESTRUCT.wCount == %x dchSource == %x\n",
  531. imestruct32->wCount,imestruct32->dchSource));
  532. LOGDEBUG(1,("WINNLS: IMESTRUCT.dchDest == %x lParam1 == %x\n",
  533. imestruct32->dchDest,imestruct32->lParam1));
  534. LOGDEBUG(1,("WINNLS: IMESTRUCT.lParam2 == %x lParam3 == %x\n",
  535. imestruct32->lParam2,imestruct32->lParam3));
  536. LOGDEBUG(1,("WINNLS: hwnd == %x %x\n",
  537. parg16->hwnd,HWND32(parg16->hwnd)));
  538. GlobalUnlock(hIME32);
  539. // For win31 compatibility, since win31 didn't check the first
  540. // parm, check it here and fill in a dummy (WOW) hwnd if its bogus
  541. // so that NT doesn't reject the call
  542. ul = SendIMEMessageEx(
  543. ((parg16->hwnd) ? HWND32(parg16->hwnd) : (HWND)0xffff0000),
  544. (LPARAM)hIME32);
  545. LOGDEBUG(1,("WINNLS: Ret == %x\n", ul ));
  546. imestruct32=GlobalLock(hIME32);
  547. if ( NULL == imestruct32 ) {
  548. LOGDEBUG(1,("WINNLS: imestruct32 == NULL"));
  549. goto eee;
  550. }
  551. LOGDEBUG(1,("WINNLS: wParam == %x\n\n", imestruct32->wParam ));
  552. STOREWORD(ptag16->wParam, imestruct32->wParam);
  553. switch (ptag16->fnc) {
  554. case IME_GETOPEN:
  555. STOREWORD(ptag16->wCount, imestruct32->wCount);
  556. break;
  557. case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
  558. if (hlParam1)
  559. GlobalFree(hlParam1);
  560. if (hlParam2)
  561. GlobalFree(hlParam2);
  562. break;
  563. case IME_SETCONVERSIONFONT: // (IME_SETFONT)
  564. {
  565. HAND16 hTmp;
  566. hTmp = ptag16->wParam;
  567. ul = (hFnt16);
  568. hFnt16 = hTmp;
  569. ul = TRUE;
  570. // kksuszuka #1765 v-hidekk
  571. if(hLFNT32)
  572. GlobalFree(hLFNT32);
  573. }
  574. break;
  575. case IME_SETCONVERSIONFONTEX:
  576. if(ptag16->lParam1)
  577. GlobalFree(hLFNT32);
  578. break;
  579. case IME_GETVERSION:
  580. // PowerPoint4J must have version returned as 3.1
  581. // Or else it thinks that the ime doesn't support IR_UNDETERMINE
  582. if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_PPT4J_IME_GETVERSION) {
  583. STOREWORD(ptag16->wParam, 0x0A03);
  584. }
  585. // WARNING: For DaytonaJ RC1 only!!!
  586. // Tell Winword6J that the IME doesn't support TrueInline (undetermine msgs)
  587. // So, that WinWord6J doesn't hang up doing the input loop processing of it.
  588. else if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_WORDJ_IME_GETVERSION) {
  589. STOREWORD(ptag16->wParam, 0x0003);
  590. }
  591. break;
  592. default:
  593. break;
  594. }
  595. eee:
  596. GlobalUnlock(hIME32);
  597. GlobalFree(hIME32);
  598. GlobalUnlock16(FETCHWORD(parg16->lParam));
  599. FREEVDMPTR(ptag16);
  600. FREEARGPTR(parg16);
  601. return(ul);
  602. }
  603. ULONG FASTCALL WN32WINNLSGetIMEHotkey(PVDMFRAME pFrame)
  604. {
  605. ULONG ul;
  606. register PWINNLSGETIMEHOTKEY16 parg16;
  607. GETARGPTR(pFrame, sizeof(WINNLSGETIMEHOTKEY16), parg16);
  608. LOGDEBUG(1,(" WINNLS:GetIMEHotkey %x \n",
  609. parg16->hwnd));
  610. ul = GETWORD16(WINNLSGetIMEHotkey(
  611. HWND32(parg16->hwnd)
  612. ));
  613. FREEARGPTR(parg16);
  614. RETURN(ul);
  615. }
  616. ULONG FASTCALL WN32WINNLSEnableIME(PVDMFRAME pFrame)
  617. {
  618. ULONG ul;
  619. register PWINNLSENABLEIME16 parg16;
  620. GETARGPTR(pFrame, sizeof(WINNLSENABLEIME16), parg16);
  621. // The spec says the first parameter should always be NULL.
  622. // Windows 3.1 ignores the first parameter and lets the call proceed.
  623. // Windows NT ignores the call if the first paramater is non-null
  624. // For compatibility purposes, pass NULL to user32 so that the call
  625. // will proceed as in win3.1
  626. //
  627. ul = GETBOOL16(WINNLSEnableIME( NULL, WORD32(parg16->fEnabled) ));
  628. LOGDEBUG(1,(" WINNLS:EnableIME %x %x %x\n",
  629. parg16->hwnd, parg16->fEnabled, ul ));
  630. FREEARGPTR(parg16);
  631. RETURN(ul);
  632. }
  633. ULONG FASTCALL WN32WINNLSGetEnableStatus(PVDMFRAME pFrame)
  634. {
  635. ULONG ul;
  636. register PWINNLSGETENABLESTATUS16 parg16;
  637. GETARGPTR(pFrame, sizeof(WINNLSGETENABLESTATUS16), parg16);
  638. LOGDEBUG(1,(" WINNLS:GetEnableStatus %x \n",
  639. parg16->hwnd));
  640. // Call the user32 with a NULL pwnd for the same reason as
  641. // in WINNLSEnableIME above.
  642. //
  643. ul = GETWORD16(WINNLSGetEnableStatus( NULL ));
  644. FREEARGPTR(parg16);
  645. RETURN(ul);
  646. }
  647. ULONG FASTCALL WN32IMPQueryIME(PVDMFRAME pFrame)
  648. {
  649. ULONG ul=0;
  650. PIMPQUERYIME16 parg16;
  651. register PIMEPRO16 pime16;
  652. PIMEPRO pimepro32;
  653. HANDLE hIME32;
  654. GETARGPTR(pFrame, sizeof(IMPQUERYIME16), parg16);
  655. GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
  656. if(pime16==NULL){
  657. LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
  658. goto fff;
  659. }
  660. LOGDEBUG(1,(" WINNLS:IMPQueryIME called\n"));
  661. hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
  662. pimepro32=GlobalLock(hIME32);
  663. if (pimepro32 ) {
  664. if (pime16->szName[0])
  665. GETIMEPRO16(pimepro32,pime16);
  666. else
  667. pimepro32->szName[0]=pime16->szName[0];
  668. ul=IMPQueryIME(pimepro32);
  669. SETIMEPRO16(pime16,pimepro32);
  670. GlobalUnlock(hIME32);
  671. }
  672. if ( hIME32 ) {
  673. GlobalFree(hIME32);
  674. }
  675. fff:
  676. FREEVDMPTR(pime16);
  677. FREEARGPTR(parg16);
  678. return (ul);
  679. }
  680. ULONG FASTCALL WN32IMPGetIME(PVDMFRAME pFrame)
  681. {
  682. ULONG ul = 0;
  683. PIMPGETIME16 parg16;
  684. register PIMEPRO16 pime16;
  685. PIMEPRO pimepro32;
  686. HANDLE hIME32;
  687. GETARGPTR(pFrame, sizeof(IMPGETIME16), parg16);
  688. GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
  689. if(pime16==NULL){
  690. LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
  691. goto fff;
  692. }
  693. LOGDEBUG(1,(" WINNLS:IMPGetIME called\n"));
  694. hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
  695. pimepro32=GlobalLock(hIME32);
  696. if (pimepro32 ) {
  697. // not use app,s handle IMPGetIME(HWND32(parg16->hwnd), pimepro32);
  698. ul=IMPGetIME(NULL, pimepro32);
  699. SETIMEPRO16(pime16, pimepro32);
  700. }
  701. GlobalUnlock(hIME32);
  702. if ( hIME32 ) {
  703. GlobalFree(hIME32);
  704. }
  705. fff:
  706. FREEVDMPTR(pime16);
  707. FREEARGPTR(parg16);
  708. return (ul);
  709. }
  710. ULONG FASTCALL WN32IMPSetIME(PVDMFRAME pFrame)
  711. {
  712. ULONG ul = 0;
  713. PIMPSETIME16 parg16;
  714. register PIMEPRO16 pime16;
  715. PIMEPRO pimepro32;
  716. HANDLE hIME32;
  717. INT i;
  718. GETARGPTR(pFrame, sizeof(IMPSETIME16), parg16);
  719. GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
  720. if(pime16==NULL){
  721. LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
  722. goto fff;
  723. }
  724. LOGDEBUG(1,(" WINNLS:IMPSetIME called\n"));
  725. hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
  726. pimepro32=GlobalLock(hIME32);
  727. if (pime16->szName[0]) {
  728. for(i=0; i < (sizeof(pimepro32->szName) /
  729. sizeof(pimepro32->szName[0])); i++)
  730. pimepro32->szName[i]=pime16->szName[i];
  731. }
  732. else
  733. pimepro32->szName[0]=pime16->szName[0];
  734. // not use app,s handle IMPSetIME(HWND32(parg16->hwnd), pimepro32);
  735. ul = IMPSetIME(NULL, pimepro32);
  736. GlobalUnlock(hIME32);
  737. GlobalFree(hIME32);
  738. fff:
  739. FREEVDMPTR(pime16);
  740. FREEARGPTR(parg16);
  741. return (ul);
  742. }
  743. VOID GETIMEPRO16(PIMEPRO pimepro32,PIMEPRO16 pime16)
  744. {
  745. INT i;
  746. pimepro32->hWnd = HWND32(pime16->hWnd);
  747. STOREWORD(pimepro32->InstDate.year, pime16->InstDate.year);
  748. STOREWORD(pimepro32->InstDate.month, pime16->InstDate.month);
  749. STOREWORD(pimepro32->InstDate.day, pime16->InstDate.day);
  750. STOREWORD(pimepro32->InstDate.hour, pime16->InstDate.hour);
  751. STOREWORD(pimepro32->InstDate.min, pime16->InstDate.min);
  752. STOREWORD(pimepro32->InstDate.sec, pime16->InstDate.sec);
  753. STOREWORD(pimepro32->wVersion, pime16->wVersion);
  754. for(i=0;i<(sizeof(pimepro32->szDescription)/
  755. sizeof(pimepro32->szDescription[0]));i++)
  756. pimepro32->szDescription[i]=pime16->szDescription[i];
  757. for(i=0;i<(sizeof(pimepro32->szName)/
  758. sizeof(pimepro32->szName[0]));i++)
  759. pimepro32->szName[i]=pime16->szName[i];
  760. for(i=0;i<(sizeof(pimepro32->szOptions)/
  761. sizeof(pimepro32->szOptions[0]));i++)
  762. pimepro32->szOptions[i]=pime16->szOptions[i];
  763. }
  764. VOID SETIMEPRO16(PIMEPRO16 pime16, PIMEPRO pimepro32)
  765. {
  766. INT i;
  767. pime16->hWnd = GETHWND16(pimepro32->hWnd);
  768. STOREWORD(pime16->InstDate.year,pimepro32->InstDate.year);
  769. STOREWORD(pime16->InstDate.month,pimepro32->InstDate.month);
  770. STOREWORD(pime16->InstDate.day,pimepro32->InstDate.day);
  771. STOREWORD(pime16->InstDate.hour,pimepro32->InstDate.hour);
  772. STOREWORD(pime16->InstDate.min,pimepro32->InstDate.min);
  773. STOREWORD(pime16->InstDate.sec,pimepro32->InstDate.sec);
  774. STOREWORD(pime16->wVersion,pimepro32->wVersion);
  775. for(i=0;i<(sizeof(pimepro32->szDescription)/
  776. sizeof(pimepro32->szDescription[0]));i++)
  777. pime16->szDescription[i]=pimepro32->szDescription[i];
  778. for(i=0;i<(sizeof(pimepro32->szName)/
  779. sizeof(pimepro32->szName[0]));i++)
  780. pime16->szName[i]=pimepro32->szName[i];
  781. for(i=0;i<(sizeof(pimepro32->szOptions)/
  782. sizeof(pimepro32->szOptions[0]));i++)
  783. pime16->szOptions[i]=pimepro32->szOptions[i];
  784. }
  785. //
  786. // Notify IMM32 wow task exit so that
  787. // it can perform any clean up.
  788. //
  789. VOID WN32WINNLSSImeNotifyTaskExit()
  790. {
  791. #if 0
  792. HANDLE hIME32;
  793. IMESTRUCT * imestruct32;
  794. hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
  795. if ( hIME32 == NULL )
  796. return;
  797. if ( (imestruct32 = GlobalLock(hIME32) ) != NULL ) {
  798. imestruct32->fnc = IME_NOTIFYWOWTASKEXIT;
  799. GlobalUnlock(hIME32);
  800. SendIMEMessageEx( NULL, (LPARAM)hIME32 );
  801. }
  802. GlobalFree(hIME32);
  803. #endif
  804. }
  805. #endif // FE_IME