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.

971 lines
31 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. if(hLFNT32) {
  236. logfont32 = GlobalLock(hLFNT32);
  237. if(logfont32) {
  238. GetObject(HOBJ32(ptag16->wParam), sizeof(LOGFONT), logfont32);
  239. GlobalUnlock(hLFNT32);
  240. }
  241. }
  242. }
  243. else {
  244. hLFNT32 = NULL;
  245. }
  246. STOREDWORD(imestruct32->lParam1, hLFNT32);
  247. }
  248. break;
  249. case IME_SETCONVERSIONFONTEX:
  250. {
  251. LOGFONT * logfont32;
  252. STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
  253. if (!ptag16->lParam1) {
  254. imestruct32->lParam1 = (ULONG)NULL;
  255. break;
  256. }
  257. // HANDLE of LOGFONT check
  258. // If lParam1 is Invalid Handle, hLFNT32 is NULL
  259. if (FETCHWORD(ptag16->lParam1) &&
  260. (vp = GlobalLock16(FETCHWORD(ptag16->lParam1), NULL))) {
  261. hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
  262. if(hLFNT32) {
  263. logfont32 = GlobalLock(hLFNT32);
  264. if(logfont32) {
  265. // GETMISCPTR(vp, logfont16);
  266. GETLOGFONT16(vp, logfont32);
  267. GlobalUnlock16(FETCHWORD(ptag16->lParam1));
  268. GlobalUnlock(hLFNT32);
  269. }
  270. }
  271. }
  272. else {
  273. hLFNT32 = NULL;
  274. }
  275. STOREDWORD(imestruct32->lParam1, hLFNT32);
  276. }
  277. break;
  278. case IME_PRIVATE:
  279. LOGDEBUG(0,(" ERROR:SendIMEMessage IME_PRIVATE NOT IMPLEMENTED\n"));
  280. goto eee;
  281. case IME_ENABLEDOSIME: // (IME_ENABLE)
  282. default:
  283. LOGDEBUG(0,(" ERROR:SendIMEMessage unexpected subfunction\n"));
  284. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGE %s\n",
  285. wow32imedebug[ptag16->fnc]));
  286. goto eee;
  287. }
  288. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGE %s\n",
  289. wow32imedebug[ptag16->fnc]));
  290. if (ptag16 -> fnc != IME_SETCONVERSIONWINDOW) {
  291. LOGDEBUG(1,("WINNLS: fnc == %x wParam == %x wCount == %x\n",
  292. imestruct32->fnc, imestruct32->wParam, imestruct32->wCount ));
  293. LOGDEBUG(1,("WINNLS: dchDest == %x dchSource == %x\n",
  294. imestruct32->dchDest, imestruct32->dchSource));
  295. LOGDEBUG(1,("WINNLS: lParam1 == %x lParam2 == %x lParam3 == %x\n",
  296. imestruct32->lParam1, imestruct32->lParam2, imestruct32->lParam3));
  297. LOGDEBUG(1,("WINNLS: hwnd == %x %x\n",
  298. parg16->hwnd,HWND32(parg16->hwnd)));
  299. }
  300. GlobalUnlock(hIME32);
  301. // For win31 compatibility, since win31 didn't check the first
  302. // parm, check it here and fill in a dummy (WOW) hwnd if its bogus
  303. // so that NT doesn't reject the call
  304. ul = SendIMEMessageEx(
  305. ((parg16->hwnd) ? HWND32(parg16->hwnd) : (HWND)0xffff0000),
  306. (LPARAM)hIME32);
  307. LOGDEBUG(1,("WINNLS: Ret == %x\n", ul ));
  308. imestruct32 = GlobalLock(hIME32);
  309. LOGDEBUG(1,("WINNLS: wParam == %x\n\n", imestruct32->wParam ));
  310. STOREWORD(ptag16->wParam, ul);
  311. switch (ptag16->fnc) {
  312. case IME_GETOPEN:
  313. STOREWORD(ptag16->wCount, imestruct32->wCount);
  314. break;
  315. case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
  316. if (hlParam1)
  317. GlobalFree(hlParam1);
  318. if (hlParam2)
  319. GlobalFree(hlParam2);
  320. break;
  321. case IME_SETCONVERSIONFONT: // (IME_SETFONT)
  322. {
  323. HAND16 hTmp;
  324. hTmp = ptag16->wParam;
  325. ptag16->wParam = hFnt16;
  326. hFnt16 = hTmp;
  327. if ( hLFNT32 )
  328. GlobalFree(hLFNT32);
  329. }
  330. break;
  331. case IME_SETCONVERSIONFONTEX:
  332. if ( hLFNT32 )
  333. GlobalFree(hLFNT32);
  334. break;
  335. case IME_GETVERSION:
  336. // PowerPoint4J must have version returned as 3.1
  337. // Or else it thinks that the ime doesn't support IR_UNDETERMINE
  338. if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_PPT4J_IME_GETVERSION) {
  339. STOREWORD(ptag16->wParam, 0x0A03);
  340. }
  341. // WARNING: For DaytonaJ RC1 only!!!
  342. // Tell Winword6J that the IME doesn't support TrueInline (undetermine msgs)
  343. // So, that WinWord6J doesn't hang up doing the input loop processing of it.
  344. else if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_WORDJ_IME_GETVERSION) {
  345. STOREWORD(ptag16->wParam, 0x0003);
  346. }
  347. break;
  348. default:
  349. break;
  350. }
  351. eee:
  352. GlobalUnlock(hIME32);
  353. GlobalFree(hIME32);
  354. GlobalUnlock16(FETCHWORD(parg16->lParam));
  355. FREEVDMPTR(ptag16);
  356. FREEARGPTR(parg16);
  357. return(ul);
  358. }
  359. ULONG FASTCALL WN32SendIMEMessageEx(PVDMFRAME pFrame)
  360. {
  361. ULONG ul = 0;
  362. PSENDIMEMESSAGE16 parg16;
  363. IMESTRUCT * imestruct32;
  364. register PIMESTRUCT16 ptag16;
  365. HANDLE hIME32;
  366. INT cb;
  367. VPVOID vp;
  368. HANDLE hlParam1 = NULL; // IME_ENTERWORDREGISTERMODE
  369. HANDLE hlParam2 = NULL;
  370. HANDLE hLFNT32 = NULL; // IME_SETCONVERSIONFONT(EX)
  371. GETARGPTR(pFrame, sizeof(SENDIMEMESSAGE16), parg16);
  372. vp = GlobalLock16(FETCHWORD(parg16->lParam), NULL);
  373. GETMISCPTR(vp, ptag16);
  374. hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
  375. imestruct32 = GlobalLock(hIME32);
  376. // if can't lock hIME32 fail gracefully
  377. if (!ptag16 || !imestruct32) {
  378. LOGDEBUG(1,(" WINNLS:(Jun)ptag16==NULL!! or imestruct32 == NULL"));
  379. goto eee;
  380. }
  381. switch (ptag16->fnc) {
  382. case IME_HANJAMODE:
  383. // Korea specific function
  384. if (GetSystemDefaultLangID() != 0x412)
  385. goto eee;
  386. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  387. STOREDWORD(imestruct32->wParam, 0);
  388. // The 4th word of imestruct32 must contains ptag16->dchSource.
  389. // msime95 will find ptag16->dchSource on the 4th word.
  390. *((LPSTR)(imestruct32) + sizeof(ptag16->fnc) +
  391. sizeof(ptag16->wParam) +
  392. sizeof(ptag16->wCount) )
  393. = (CHAR)ptag16->dchSource;
  394. *((LPSTR)(imestruct32) + ptag16->dchSource)
  395. = *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource);
  396. *((LPSTR)(imestruct32) + ptag16->dchSource + 1)
  397. = *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource + 1);
  398. break;
  399. case IME_CONVERTLIST:
  400. case IME_AUTOMATA:
  401. case IME_CODECONVERT:
  402. case IME_SETLEVEL:
  403. case IME_GETLEVEL:
  404. case IME_GETMNTABLE:
  405. // Korea specific function
  406. if (GetSystemDefaultLangID() != 0x412)
  407. goto eee;
  408. goto standard;
  409. case IME_SETCONVERSIONWINDOW: // (IME_MOVECONVERTWINDOW)
  410. // IME_MOVEIMEWINDOW for Korea
  411. if (GetSystemDefaultLangID() != 0x412 &&
  412. CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_AMIPRO_PM4J_IME) {
  413. // Don't pass the MCW_DEFAULT.
  414. // because, Conversion window will be flushed when
  415. // default conversion window and AMIPRO's window have overlap.
  416. //
  417. // Also, for PM4J, when the codebox is moved Pagemaker
  418. // thinks it needs to be displayed at default. Prevent
  419. // endless loop of default screen|window displays
  420. //
  421. if (ptag16->wParam == MCW_DEFAULT) {
  422. ul = FALSE;
  423. goto eee;
  424. }
  425. }
  426. case IME_GETOPEN:
  427. case IME_SETOPEN:
  428. case IME_GETIMECAPS: // (IME_QUERY)
  429. case IME_SETCONVERSIONMODE: // (IME_SET_MODE)
  430. case IME_GETCONVERSIONMODE: // (IME_GET_MODE)
  431. case IME_SENDVKEY: // (IME_SENDKEY)
  432. case IME_DESTROYIME: // (IME_DESTROY)
  433. case IME_WINDOWUPDATE:
  434. case IME_SELECT:
  435. case IME_GETVERSION: // Win3.1
  436. standard:
  437. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  438. STOREDWORD(imestruct32->wParam, ptag16->wParam);
  439. STOREDWORD(imestruct32->wCount, ptag16->wCount);
  440. STOREDWORD(imestruct32->dchSource, ptag16->dchSource);
  441. STOREDWORD(imestruct32->dchDest, ptag16->dchDest);
  442. STOREDWORD(imestruct32->lParam1, ptag16->lParam1);
  443. STOREDWORD(imestruct32->lParam2, ptag16->lParam2);
  444. STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
  445. break;
  446. case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
  447. {
  448. LPBYTE lpMem16;
  449. LPBYTE lpMem32;
  450. STOREDWORD(imestruct32->fnc, ptag16->fnc);
  451. if (ptag16->lParam1) {
  452. vp = GlobalLock16(FETCHWORD(ptag16->lParam1), &cb);
  453. hlParam1 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
  454. lpMem32 = GlobalLock(hlParam1);
  455. if (vp) {
  456. if (lpMem32) {
  457. GETMISCPTR(vp, lpMem16);
  458. RtlCopyMemory(lpMem32, lpMem16, cb);
  459. GlobalUnlock(hlParam1);
  460. }
  461. GlobalUnlock16(FETCHWORD(ptag16->lParam1));
  462. }
  463. }
  464. if (ptag16->lParam2) {
  465. vp = GlobalLock16(FETCHWORD(ptag16->lParam2), &cb);
  466. hlParam2 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
  467. lpMem32 = GlobalLock(hlParam2);
  468. if (vp) {
  469. if (lpMem32) {
  470. GETMISCPTR(vp, lpMem16);
  471. RtlCopyMemory(lpMem32, lpMem16, cb);
  472. GlobalUnlock(hlParam2);
  473. }
  474. GlobalUnlock16(FETCHWORD(ptag16->lParam2));
  475. }
  476. }
  477. imestruct32->lParam1 = (LPARAM)hlParam1;
  478. imestruct32->lParam2 = (LPARAM)hlParam2;
  479. STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
  480. }
  481. break;
  482. case IME_SETCONVERSIONFONT: // (IME_SET_MODE - Korea)
  483. {
  484. LOGFONT * logfont32 = NULL;
  485. if (GetSystemDefaultLangID() == 0x412) {
  486. // Hunguel WOW should do anything for IME_SET_MODE function
  487. goto eee;
  488. }
  489. STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
  490. if ( ptag16->wParam ) {
  491. hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
  492. if(hLFNT32) {
  493. logfont32 = GlobalLock(hLFNT32);
  494. if(logfont32) {
  495. GetObject(HOBJ32(ptag16->wParam),sizeof(LOGFONT),logfont32);
  496. GlobalUnlock(hLFNT32);
  497. }
  498. }
  499. }
  500. else {
  501. hLFNT32 = NULL;
  502. }
  503. imestruct32->lParam1 = (LPARAM)hLFNT32;
  504. }
  505. break;
  506. case IME_SETCONVERSIONFONTEX: // Win3.1
  507. {
  508. LOGFONT * logfont32 = NULL;
  509. STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
  510. if (!(ptag16->lParam1)) {
  511. imestruct32->lParam1 = (LPARAM)NULL;
  512. break;
  513. }
  514. hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
  515. if(hLFNT32) {
  516. logfont32 = GlobalLock(hLFNT32);
  517. if (logfont32) {
  518. vp = GlobalLock16(FETCHWORD(ptag16->lParam1), NULL);
  519. // GETMISCPTR(vp, logfont16);
  520. GETLOGFONT16(vp, logfont32);
  521. GlobalUnlock16(FETCHWORD(ptag16->lParam1));
  522. GlobalUnlock(hLFNT32);
  523. }
  524. }
  525. imestruct32->lParam1 = (LPARAM)hLFNT32;
  526. }
  527. break;
  528. case IME_PRIVATE:
  529. LOGDEBUG(0,(" ERROR:SendIMEMessageEx IME_PRIVATE NOT YET IMPLEMENTED\n"));
  530. goto eee;
  531. case IME_ENABLEDOSIME: // (IME_ENABLE)
  532. default:
  533. LOGDEBUG(0,(" ERROR:SendIMEMessageEx unexpected subfunction\n"));
  534. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGEEX %s\n",
  535. wow32imedebug[ptag16->fnc]));
  536. goto eee;
  537. }
  538. LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGEEX %s\n",
  539. wow32imedebug[ptag16->fnc]));
  540. LOGDEBUG(1,(" IMESTRUCT16 Size = %d\n",
  541. sizeof(IMESTRUCT16)));
  542. LOGDEBUG(1,("WINNLS: IMESTRUCT.fnc == %x wParam == %x\n",
  543. imestruct32->fnc,imestruct32->wParam));
  544. LOGDEBUG(1,("WINNLS: IMESTRUCT.wCount == %x dchSource == %x\n",
  545. imestruct32->wCount,imestruct32->dchSource));
  546. LOGDEBUG(1,("WINNLS: IMESTRUCT.dchDest == %x lParam1 == %x\n",
  547. imestruct32->dchDest,imestruct32->lParam1));
  548. LOGDEBUG(1,("WINNLS: IMESTRUCT.lParam2 == %x lParam3 == %x\n",
  549. imestruct32->lParam2,imestruct32->lParam3));
  550. LOGDEBUG(1,("WINNLS: hwnd == %x %x\n",
  551. parg16->hwnd,HWND32(parg16->hwnd)));
  552. GlobalUnlock(hIME32);
  553. // For win31 compatibility, since win31 didn't check the first
  554. // parm, check it here and fill in a dummy (WOW) hwnd if its bogus
  555. // so that NT doesn't reject the call
  556. ul = SendIMEMessageEx(
  557. ((parg16->hwnd) ? HWND32(parg16->hwnd) : (HWND)0xffff0000),
  558. (LPARAM)hIME32);
  559. LOGDEBUG(1,("WINNLS: Ret == %x\n", ul ));
  560. imestruct32=GlobalLock(hIME32);
  561. if ( NULL == imestruct32 ) {
  562. LOGDEBUG(1,("WINNLS: imestruct32 == NULL"));
  563. goto eee;
  564. }
  565. LOGDEBUG(1,("WINNLS: wParam == %x\n\n", imestruct32->wParam ));
  566. STOREWORD(ptag16->wParam, imestruct32->wParam);
  567. switch (ptag16->fnc) {
  568. case IME_GETOPEN:
  569. STOREWORD(ptag16->wCount, imestruct32->wCount);
  570. break;
  571. case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
  572. if (hlParam1)
  573. GlobalFree(hlParam1);
  574. if (hlParam2)
  575. GlobalFree(hlParam2);
  576. break;
  577. case IME_SETCONVERSIONFONT: // (IME_SETFONT)
  578. {
  579. HAND16 hTmp;
  580. hTmp = ptag16->wParam;
  581. ul = (hFnt16);
  582. hFnt16 = hTmp;
  583. ul = TRUE;
  584. // kksuszuka #1765 v-hidekk
  585. if(hLFNT32)
  586. GlobalFree(hLFNT32);
  587. }
  588. break;
  589. case IME_SETCONVERSIONFONTEX:
  590. if(ptag16->lParam1 && hLFNT32)
  591. GlobalFree(hLFNT32);
  592. break;
  593. case IME_GETVERSION:
  594. // PowerPoint4J must have version returned as 3.1
  595. // Or else it thinks that the ime doesn't support IR_UNDETERMINE
  596. if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_PPT4J_IME_GETVERSION) {
  597. STOREWORD(ptag16->wParam, 0x0A03);
  598. }
  599. // WARNING: For DaytonaJ RC1 only!!!
  600. // Tell Winword6J that the IME doesn't support TrueInline (undetermine msgs)
  601. // So, that WinWord6J doesn't hang up doing the input loop processing of it.
  602. else if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_WORDJ_IME_GETVERSION) {
  603. STOREWORD(ptag16->wParam, 0x0003);
  604. }
  605. break;
  606. default:
  607. break;
  608. }
  609. eee:
  610. GlobalUnlock(hIME32);
  611. GlobalFree(hIME32);
  612. GlobalUnlock16(FETCHWORD(parg16->lParam));
  613. FREEVDMPTR(ptag16);
  614. FREEARGPTR(parg16);
  615. return(ul);
  616. }
  617. ULONG FASTCALL WN32WINNLSGetIMEHotkey(PVDMFRAME pFrame)
  618. {
  619. ULONG ul;
  620. register PWINNLSGETIMEHOTKEY16 parg16;
  621. GETARGPTR(pFrame, sizeof(WINNLSGETIMEHOTKEY16), parg16);
  622. LOGDEBUG(1,(" WINNLS:GetIMEHotkey %x \n",
  623. parg16->hwnd));
  624. ul = GETWORD16(WINNLSGetIMEHotkey(
  625. HWND32(parg16->hwnd)
  626. ));
  627. FREEARGPTR(parg16);
  628. RETURN(ul);
  629. }
  630. ULONG FASTCALL WN32WINNLSEnableIME(PVDMFRAME pFrame)
  631. {
  632. ULONG ul;
  633. register PWINNLSENABLEIME16 parg16;
  634. GETARGPTR(pFrame, sizeof(WINNLSENABLEIME16), parg16);
  635. // The spec says the first parameter should always be NULL.
  636. // Windows 3.1 ignores the first parameter and lets the call proceed.
  637. // Windows NT ignores the call if the first paramater is non-null
  638. // For compatibility purposes, pass NULL to user32 so that the call
  639. // will proceed as in win3.1
  640. //
  641. ul = GETBOOL16(WINNLSEnableIME( NULL, WORD32(parg16->fEnabled) ));
  642. LOGDEBUG(1,(" WINNLS:EnableIME %x %x %x\n",
  643. parg16->hwnd, parg16->fEnabled, ul ));
  644. FREEARGPTR(parg16);
  645. RETURN(ul);
  646. }
  647. ULONG FASTCALL WN32WINNLSGetEnableStatus(PVDMFRAME pFrame)
  648. {
  649. ULONG ul;
  650. register PWINNLSGETENABLESTATUS16 parg16;
  651. GETARGPTR(pFrame, sizeof(WINNLSGETENABLESTATUS16), parg16);
  652. LOGDEBUG(1,(" WINNLS:GetEnableStatus %x \n",
  653. parg16->hwnd));
  654. // Call the user32 with a NULL pwnd for the same reason as
  655. // in WINNLSEnableIME above.
  656. //
  657. ul = GETWORD16(WINNLSGetEnableStatus( NULL ));
  658. FREEARGPTR(parg16);
  659. RETURN(ul);
  660. }
  661. ULONG FASTCALL WN32IMPQueryIME(PVDMFRAME pFrame)
  662. {
  663. ULONG ul=0;
  664. PIMPQUERYIME16 parg16;
  665. register PIMEPRO16 pime16;
  666. PIMEPRO pimepro32;
  667. HANDLE hIME32;
  668. GETARGPTR(pFrame, sizeof(IMPQUERYIME16), parg16);
  669. GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
  670. if(pime16==NULL){
  671. LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
  672. goto fff;
  673. }
  674. LOGDEBUG(1,(" WINNLS:IMPQueryIME called\n"));
  675. hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
  676. pimepro32=GlobalLock(hIME32);
  677. if (pimepro32 ) {
  678. if (pime16->szName[0])
  679. GETIMEPRO16(pimepro32,pime16);
  680. else
  681. pimepro32->szName[0]=pime16->szName[0];
  682. ul=IMPQueryIME(pimepro32);
  683. SETIMEPRO16(pime16,pimepro32);
  684. GlobalUnlock(hIME32);
  685. }
  686. if ( hIME32 ) {
  687. GlobalFree(hIME32);
  688. }
  689. fff:
  690. FREEVDMPTR(pime16);
  691. FREEARGPTR(parg16);
  692. return (ul);
  693. }
  694. ULONG FASTCALL WN32IMPGetIME(PVDMFRAME pFrame)
  695. {
  696. ULONG ul = 0;
  697. PIMPGETIME16 parg16;
  698. register PIMEPRO16 pime16;
  699. PIMEPRO pimepro32;
  700. HANDLE hIME32;
  701. GETARGPTR(pFrame, sizeof(IMPGETIME16), parg16);
  702. GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
  703. if(pime16==NULL){
  704. LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
  705. goto fff;
  706. }
  707. LOGDEBUG(1,(" WINNLS:IMPGetIME called\n"));
  708. hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
  709. pimepro32=GlobalLock(hIME32);
  710. if (pimepro32 ) {
  711. // not use app,s handle IMPGetIME(HWND32(parg16->hwnd), pimepro32);
  712. ul=IMPGetIME(NULL, pimepro32);
  713. SETIMEPRO16(pime16, pimepro32);
  714. }
  715. GlobalUnlock(hIME32);
  716. if ( hIME32 ) {
  717. GlobalFree(hIME32);
  718. }
  719. fff:
  720. FREEVDMPTR(pime16);
  721. FREEARGPTR(parg16);
  722. return (ul);
  723. }
  724. ULONG FASTCALL WN32IMPSetIME(PVDMFRAME pFrame)
  725. {
  726. ULONG ul = 0;
  727. PIMPSETIME16 parg16;
  728. register PIMEPRO16 pime16;
  729. PIMEPRO pimepro32;
  730. HANDLE hIME32;
  731. INT i;
  732. GETARGPTR(pFrame, sizeof(IMPSETIME16), parg16);
  733. GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
  734. if(pime16==NULL){
  735. LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
  736. goto fff;
  737. }
  738. LOGDEBUG(1,(" WINNLS:IMPSetIME called\n"));
  739. hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
  740. pimepro32=GlobalLock(hIME32);
  741. if (pimepro32 ) {
  742. if (pime16->szName[0]) {
  743. for(i=0; i < (sizeof(pimepro32->szName) /
  744. sizeof(pimepro32->szName[0])); i++)
  745. pimepro32->szName[i]=pime16->szName[i];
  746. }
  747. else
  748. pimepro32->szName[0]=pime16->szName[0];
  749. // not use app,s handle IMPSetIME(HWND32(parg16->hwnd), pimepro32);
  750. ul = IMPSetIME(NULL, pimepro32);
  751. GlobalUnlock(hIME32);
  752. GlobalFree(hIME32);
  753. }
  754. fff:
  755. FREEVDMPTR(pime16);
  756. FREEARGPTR(parg16);
  757. return (ul);
  758. }
  759. VOID GETIMEPRO16(PIMEPRO pimepro32,PIMEPRO16 pime16)
  760. {
  761. INT i;
  762. pimepro32->hWnd = HWND32(pime16->hWnd);
  763. STOREWORD(pimepro32->InstDate.year, pime16->InstDate.year);
  764. STOREWORD(pimepro32->InstDate.month, pime16->InstDate.month);
  765. STOREWORD(pimepro32->InstDate.day, pime16->InstDate.day);
  766. STOREWORD(pimepro32->InstDate.hour, pime16->InstDate.hour);
  767. STOREWORD(pimepro32->InstDate.min, pime16->InstDate.min);
  768. STOREWORD(pimepro32->InstDate.sec, pime16->InstDate.sec);
  769. STOREWORD(pimepro32->wVersion, pime16->wVersion);
  770. for(i=0;i<(sizeof(pimepro32->szDescription)/
  771. sizeof(pimepro32->szDescription[0]));i++)
  772. pimepro32->szDescription[i]=pime16->szDescription[i];
  773. for(i=0;i<(sizeof(pimepro32->szName)/
  774. sizeof(pimepro32->szName[0]));i++)
  775. pimepro32->szName[i]=pime16->szName[i];
  776. for(i=0;i<(sizeof(pimepro32->szOptions)/
  777. sizeof(pimepro32->szOptions[0]));i++)
  778. pimepro32->szOptions[i]=pime16->szOptions[i];
  779. }
  780. VOID SETIMEPRO16(PIMEPRO16 pime16, PIMEPRO pimepro32)
  781. {
  782. INT i;
  783. pime16->hWnd = GETHWND16(pimepro32->hWnd);
  784. STOREWORD(pime16->InstDate.year,pimepro32->InstDate.year);
  785. STOREWORD(pime16->InstDate.month,pimepro32->InstDate.month);
  786. STOREWORD(pime16->InstDate.day,pimepro32->InstDate.day);
  787. STOREWORD(pime16->InstDate.hour,pimepro32->InstDate.hour);
  788. STOREWORD(pime16->InstDate.min,pimepro32->InstDate.min);
  789. STOREWORD(pime16->InstDate.sec,pimepro32->InstDate.sec);
  790. STOREWORD(pime16->wVersion,pimepro32->wVersion);
  791. for(i=0;i<(sizeof(pimepro32->szDescription)/
  792. sizeof(pimepro32->szDescription[0]));i++)
  793. pime16->szDescription[i]=pimepro32->szDescription[i];
  794. for(i=0;i<(sizeof(pimepro32->szName)/
  795. sizeof(pimepro32->szName[0]));i++)
  796. pime16->szName[i]=pimepro32->szName[i];
  797. for(i=0;i<(sizeof(pimepro32->szOptions)/
  798. sizeof(pimepro32->szOptions[0]));i++)
  799. pime16->szOptions[i]=pimepro32->szOptions[i];
  800. }
  801. //
  802. // Notify IMM32 wow task exit so that
  803. // it can perform any clean up.
  804. //
  805. VOID WN32WINNLSSImeNotifyTaskExit()
  806. {
  807. #if 0
  808. HANDLE hIME32;
  809. IMESTRUCT * imestruct32;
  810. hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
  811. if ( hIME32 == NULL )
  812. return;
  813. if ( (imestruct32 = GlobalLock(hIME32) ) != NULL ) {
  814. imestruct32->fnc = IME_NOTIFYWOWTASKEXIT;
  815. GlobalUnlock(hIME32);
  816. SendIMEMessageEx( NULL, (LPARAM)hIME32 );
  817. }
  818. GlobalFree(hIME32);
  819. #endif
  820. }
  821. #endif // FE_IME