1 /* 2 * PROJECT: ReactOS IMM32 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Implementing IMM32 registering/unregistering words 5 * COPYRIGHT: Copyright 2020-2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8 #include "precomp.h" 9 10 WINE_DEFAULT_DEBUG_CHANNEL(imm); 11 12 typedef struct ENUM_WORD_A2W 13 { 14 REGISTERWORDENUMPROCW lpfnEnumProc; 15 LPVOID lpData; 16 UINT ret; 17 UINT uCodePage; 18 } ENUM_WORD_A2W, *LPENUM_WORD_A2W; 19 20 typedef struct ENUM_WORD_W2A 21 { 22 REGISTERWORDENUMPROCA lpfnEnumProc; 23 LPVOID lpData; 24 UINT ret; 25 UINT uCodePage; 26 } ENUM_WORD_W2A, *LPENUM_WORD_W2A; 27 28 /* 29 * These functions absorb the difference between Ansi and Wide. 30 */ 31 static INT CALLBACK 32 Imm32EnumWordProcA2W(LPCSTR pszReadingA, DWORD dwStyle, LPCSTR pszRegisterA, LPVOID lpData) 33 { 34 INT ret = 0; 35 LPENUM_WORD_A2W lpEnumData = lpData; 36 LPWSTR pszReadingW = NULL, pszRegisterW = NULL; 37 38 if (pszReadingA) 39 { 40 pszReadingW = Imm32WideFromAnsi(lpEnumData->uCodePage, pszReadingA); 41 if (IS_NULL_UNEXPECTEDLY(pszReadingW)) 42 goto Quit; 43 } 44 45 if (pszRegisterA) 46 { 47 pszRegisterW = Imm32WideFromAnsi(lpEnumData->uCodePage, pszRegisterA); 48 if (IS_NULL_UNEXPECTEDLY(pszRegisterW)) 49 goto Quit; 50 } 51 52 ret = lpEnumData->lpfnEnumProc(pszReadingW, dwStyle, pszRegisterW, lpEnumData->lpData); 53 lpEnumData->ret = ret; 54 55 Quit: 56 ImmLocalFree(pszReadingW); 57 ImmLocalFree(pszRegisterW); 58 return ret; 59 } 60 61 static INT CALLBACK 62 Imm32EnumWordProcW2A(LPCWSTR pszReadingW, DWORD dwStyle, LPCWSTR pszRegisterW, LPVOID lpData) 63 { 64 INT ret = 0; 65 LPENUM_WORD_W2A lpEnumData = lpData; 66 LPSTR pszReadingA = NULL, pszRegisterA = NULL; 67 68 if (pszReadingW) 69 { 70 pszReadingA = Imm32AnsiFromWide(lpEnumData->uCodePage, pszReadingW); 71 if (IS_NULL_UNEXPECTEDLY(pszReadingW)) 72 goto Quit; 73 } 74 75 if (pszRegisterW) 76 { 77 pszRegisterA = Imm32AnsiFromWide(lpEnumData->uCodePage, pszRegisterW); 78 if (IS_NULL_UNEXPECTEDLY(pszRegisterA)) 79 goto Quit; 80 } 81 82 ret = lpEnumData->lpfnEnumProc(pszReadingA, dwStyle, pszRegisterA, lpEnumData->lpData); 83 lpEnumData->ret = ret; 84 85 Quit: 86 ImmLocalFree(pszReadingA); 87 ImmLocalFree(pszRegisterA); 88 return ret; 89 } 90 91 /*********************************************************************** 92 * ImmEnumRegisterWordA (IMM32.@) 93 */ 94 UINT WINAPI 95 ImmEnumRegisterWordA(HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc, 96 LPCSTR lpszReading, DWORD dwStyle, 97 LPCSTR lpszRegister, LPVOID lpData) 98 { 99 UINT ret = 0; 100 LPWSTR pszReadingW = NULL, pszRegisterW = NULL; 101 ENUM_WORD_W2A EnumDataW2A; 102 PIMEDPI pImeDpi; 103 104 TRACE("(%p, %p, %s, 0x%lX, %s, %p)\n", hKL, lpfnEnumProc, debugstr_a(lpszReading), 105 dwStyle, debugstr_a(lpszRegister), lpData); 106 107 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 108 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 109 return 0; 110 111 if (!ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 112 { 113 ret = pImeDpi->ImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle, 114 lpszRegister, lpData); 115 ImmUnlockImeDpi(pImeDpi); 116 return ret; 117 } 118 119 if (lpszReading) 120 { 121 pszReadingW = Imm32WideFromAnsi(pImeDpi->uCodePage, lpszReading); 122 if (IS_NULL_UNEXPECTEDLY(pszReadingW)) 123 goto Quit; 124 } 125 126 if (lpszRegister) 127 { 128 pszRegisterW = Imm32WideFromAnsi(pImeDpi->uCodePage, lpszRegister); 129 if (IS_NULL_UNEXPECTEDLY(pszRegisterW)) 130 goto Quit; 131 } 132 133 EnumDataW2A.lpfnEnumProc = lpfnEnumProc; 134 EnumDataW2A.lpData = lpData; 135 EnumDataW2A.ret = 0; 136 EnumDataW2A.uCodePage = pImeDpi->uCodePage; 137 pImeDpi->ImeEnumRegisterWord(Imm32EnumWordProcW2A, pszReadingW, dwStyle, 138 pszRegisterW, &EnumDataW2A); 139 ret = EnumDataW2A.ret; 140 141 Quit: 142 ImmLocalFree(pszReadingW); 143 ImmLocalFree(pszRegisterW); 144 ImmUnlockImeDpi(pImeDpi); 145 return ret; 146 } 147 148 /*********************************************************************** 149 * ImmEnumRegisterWordW (IMM32.@) 150 */ 151 UINT WINAPI 152 ImmEnumRegisterWordW(HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc, 153 LPCWSTR lpszReading, DWORD dwStyle, 154 LPCWSTR lpszRegister, LPVOID lpData) 155 { 156 UINT ret = 0; 157 LPSTR pszReadingA = NULL, pszRegisterA = NULL; 158 ENUM_WORD_A2W EnumDataA2W; 159 PIMEDPI pImeDpi; 160 161 TRACE("(%p, %p, %s, 0x%lX, %s, %p)\n", hKL, lpfnEnumProc, debugstr_w(lpszReading), 162 dwStyle, debugstr_w(lpszRegister), lpData); 163 164 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 165 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 166 return 0; 167 168 if (ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 169 { 170 ret = pImeDpi->ImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle, 171 lpszRegister, lpData); 172 ImmUnlockImeDpi(pImeDpi); 173 return ret; 174 } 175 176 if (lpszReading) 177 { 178 pszReadingA = Imm32AnsiFromWide(pImeDpi->uCodePage, lpszReading); 179 if (IS_NULL_UNEXPECTEDLY(pszReadingA)) 180 goto Quit; 181 } 182 183 if (lpszRegister) 184 { 185 pszRegisterA = Imm32AnsiFromWide(pImeDpi->uCodePage, lpszRegister); 186 if (IS_NULL_UNEXPECTEDLY(pszRegisterA)) 187 goto Quit; 188 } 189 190 EnumDataA2W.lpfnEnumProc = lpfnEnumProc; 191 EnumDataA2W.lpData = lpData; 192 EnumDataA2W.ret = 0; 193 EnumDataA2W.uCodePage = pImeDpi->uCodePage; 194 pImeDpi->ImeEnumRegisterWord(Imm32EnumWordProcA2W, pszReadingA, dwStyle, 195 pszRegisterA, &EnumDataA2W); 196 ret = EnumDataA2W.ret; 197 198 Quit: 199 ImmLocalFree(pszReadingA); 200 ImmLocalFree(pszRegisterA); 201 ImmUnlockImeDpi(pImeDpi); 202 TRACE("ret: %u\n", ret); 203 return ret; 204 } 205 206 /*********************************************************************** 207 * ImmGetRegisterWordStyleA (IMM32.@) 208 */ 209 UINT WINAPI ImmGetRegisterWordStyleA(HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf) 210 { 211 UINT iItem, ret = 0; 212 PIMEDPI pImeDpi; 213 LPSTYLEBUFA pDestA; 214 LPSTYLEBUFW pSrcW, pNewStylesW = NULL; 215 size_t cchW; 216 INT cchA; 217 218 TRACE("(%p, %u, %p)\n", hKL, nItem, lpStyleBuf); 219 220 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 221 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 222 return 0; 223 224 if (!ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 225 { 226 ret = pImeDpi->ImeGetRegisterWordStyle(nItem, lpStyleBuf); 227 goto Quit; 228 } 229 230 if (nItem > 0) 231 { 232 pNewStylesW = ImmLocalAlloc(0, nItem * sizeof(STYLEBUFW)); 233 if (IS_NULL_UNEXPECTEDLY(pNewStylesW)) 234 goto Quit; 235 } 236 237 ret = pImeDpi->ImeGetRegisterWordStyle(nItem, pNewStylesW); 238 239 if (nItem > 0) 240 { 241 /* lpStyleBuf <-- pNewStylesW */ 242 for (iItem = 0; iItem < ret; ++iItem) 243 { 244 pSrcW = &pNewStylesW[iItem]; 245 pDestA = &lpStyleBuf[iItem]; 246 pDestA->dwStyle = pSrcW->dwStyle; 247 StringCchLengthW(pSrcW->szDescription, _countof(pSrcW->szDescription), &cchW); 248 cchA = WideCharToMultiByte(pImeDpi->uCodePage, MB_PRECOMPOSED, 249 pSrcW->szDescription, (INT)cchW, 250 pDestA->szDescription, _countof(pDestA->szDescription), 251 NULL, NULL); 252 if (cchA > _countof(pDestA->szDescription) - 1) 253 cchA = _countof(pDestA->szDescription) - 1; 254 pDestA->szDescription[cchA] = 0; 255 } 256 } 257 258 Quit: 259 ImmLocalFree(pNewStylesW); 260 ImmUnlockImeDpi(pImeDpi); 261 TRACE("ret: %u\n", ret); 262 return ret; 263 } 264 265 /*********************************************************************** 266 * ImmGetRegisterWordStyleW (IMM32.@) 267 */ 268 UINT WINAPI ImmGetRegisterWordStyleW(HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf) 269 { 270 UINT iItem, ret = 0; 271 PIMEDPI pImeDpi; 272 LPSTYLEBUFA pSrcA, pNewStylesA = NULL; 273 LPSTYLEBUFW pDestW; 274 size_t cchA; 275 INT cchW; 276 277 TRACE("(%p, %u, %p)\n", hKL, nItem, lpStyleBuf); 278 279 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 280 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 281 return 0; 282 283 if (ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 284 { 285 ret = pImeDpi->ImeGetRegisterWordStyle(nItem, lpStyleBuf); 286 goto Quit; 287 } 288 289 if (nItem > 0) 290 { 291 pNewStylesA = ImmLocalAlloc(0, nItem * sizeof(STYLEBUFA)); 292 if (IS_NULL_UNEXPECTEDLY(pNewStylesA)) 293 goto Quit; 294 } 295 296 ret = pImeDpi->ImeGetRegisterWordStyle(nItem, pNewStylesA); 297 298 if (nItem > 0) 299 { 300 /* lpStyleBuf <-- pNewStylesA */ 301 for (iItem = 0; iItem < ret; ++iItem) 302 { 303 pSrcA = &pNewStylesA[iItem]; 304 pDestW = &lpStyleBuf[iItem]; 305 pDestW->dwStyle = pSrcA->dwStyle; 306 StringCchLengthA(pSrcA->szDescription, _countof(pSrcA->szDescription), &cchA); 307 cchW = MultiByteToWideChar(pImeDpi->uCodePage, MB_PRECOMPOSED, 308 pSrcA->szDescription, (INT)cchA, 309 pDestW->szDescription, _countof(pDestW->szDescription)); 310 if (cchW > _countof(pDestW->szDescription) - 1) 311 cchW = _countof(pDestW->szDescription) - 1; 312 pDestW->szDescription[cchW] = 0; 313 } 314 } 315 316 Quit: 317 ImmLocalFree(pNewStylesA); 318 ImmUnlockImeDpi(pImeDpi); 319 TRACE("ret: %u\n", ret); 320 return ret; 321 } 322 323 /*********************************************************************** 324 * ImmRegisterWordA (IMM32.@) 325 */ 326 BOOL WINAPI 327 ImmRegisterWordA(HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister) 328 { 329 BOOL ret = FALSE; 330 PIMEDPI pImeDpi; 331 LPWSTR pszReadingW = NULL, pszRegisterW = NULL; 332 333 TRACE("(%p, %s, 0x%lX, %s)\n", hKL, debugstr_a(lpszReading), dwStyle, 334 debugstr_a(lpszRegister)); 335 336 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 337 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 338 return FALSE; 339 340 if (!ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 341 { 342 ret = pImeDpi->ImeRegisterWord(lpszReading, dwStyle, lpszRegister); 343 ImmUnlockImeDpi(pImeDpi); 344 return ret; 345 } 346 347 if (lpszReading) 348 { 349 pszReadingW = Imm32WideFromAnsi(pImeDpi->uCodePage, lpszReading); 350 if (IS_NULL_UNEXPECTEDLY(pszReadingW)) 351 goto Quit; 352 } 353 354 if (lpszRegister) 355 { 356 pszRegisterW = Imm32WideFromAnsi(pImeDpi->uCodePage, lpszRegister); 357 if (IS_NULL_UNEXPECTEDLY(pszRegisterW)) 358 goto Quit; 359 } 360 361 ret = pImeDpi->ImeRegisterWord(pszReadingW, dwStyle, pszRegisterW); 362 363 Quit: 364 ImmLocalFree(pszReadingW); 365 ImmLocalFree(pszRegisterW); 366 ImmUnlockImeDpi(pImeDpi); 367 TRACE("ret: %d\n", ret); 368 return ret; 369 } 370 371 /*********************************************************************** 372 * ImmRegisterWordW (IMM32.@) 373 */ 374 BOOL WINAPI 375 ImmRegisterWordW(HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister) 376 { 377 BOOL ret = FALSE; 378 PIMEDPI pImeDpi; 379 LPSTR pszReadingA = NULL, pszRegisterA = NULL; 380 381 TRACE("(%p, %s, 0x%lX, %s)\n", hKL, debugstr_w(lpszReading), dwStyle, 382 debugstr_w(lpszRegister)); 383 384 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 385 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 386 return FALSE; 387 388 if (ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 389 { 390 ret = pImeDpi->ImeRegisterWord(lpszReading, dwStyle, lpszRegister); 391 ImmUnlockImeDpi(pImeDpi); 392 return ret; 393 } 394 395 if (lpszReading) 396 { 397 pszReadingA = Imm32AnsiFromWide(pImeDpi->uCodePage, lpszReading); 398 if (IS_NULL_UNEXPECTEDLY(pszReadingA)) 399 goto Quit; 400 } 401 402 if (lpszRegister) 403 { 404 pszRegisterA = Imm32AnsiFromWide(pImeDpi->uCodePage, lpszRegister); 405 if (IS_NULL_UNEXPECTEDLY(pszRegisterA)) 406 goto Quit; 407 } 408 409 ret = pImeDpi->ImeRegisterWord(pszReadingA, dwStyle, pszRegisterA); 410 411 Quit: 412 ImmLocalFree(pszReadingA); 413 ImmLocalFree(pszRegisterA); 414 ImmUnlockImeDpi(pImeDpi); 415 TRACE("ret: %d\n", ret); 416 return ret; 417 } 418 419 /*********************************************************************** 420 * ImmUnregisterWordA (IMM32.@) 421 */ 422 BOOL WINAPI 423 ImmUnregisterWordA(HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszUnregister) 424 { 425 BOOL ret = FALSE; 426 PIMEDPI pImeDpi; 427 LPWSTR pszReadingW = NULL, pszUnregisterW = NULL; 428 429 TRACE("(%p, %s, 0x%lX, %s)\n", hKL, debugstr_a(lpszReading), dwStyle, 430 debugstr_a(lpszUnregister)); 431 432 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 433 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 434 return FALSE; 435 436 if (!ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 437 { 438 ret = pImeDpi->ImeUnregisterWord(lpszReading, dwStyle, lpszUnregister); 439 ImmUnlockImeDpi(pImeDpi); 440 return ret; 441 } 442 443 if (lpszReading) 444 { 445 pszReadingW = Imm32WideFromAnsi(pImeDpi->uCodePage, lpszReading); 446 if (IS_NULL_UNEXPECTEDLY(pszReadingW)) 447 goto Quit; 448 } 449 450 if (lpszUnregister) 451 { 452 pszUnregisterW = Imm32WideFromAnsi(pImeDpi->uCodePage, lpszUnregister); 453 if (IS_NULL_UNEXPECTEDLY(pszUnregisterW)) 454 goto Quit; 455 } 456 457 ret = pImeDpi->ImeUnregisterWord(pszReadingW, dwStyle, pszUnregisterW); 458 459 Quit: 460 ImmLocalFree(pszReadingW); 461 ImmLocalFree(pszUnregisterW); 462 ImmUnlockImeDpi(pImeDpi); 463 TRACE("ret: %d\n", ret); 464 return ret; 465 } 466 467 /*********************************************************************** 468 * ImmUnregisterWordW (IMM32.@) 469 */ 470 BOOL WINAPI 471 ImmUnregisterWordW(HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszUnregister) 472 { 473 BOOL ret = FALSE; 474 PIMEDPI pImeDpi; 475 LPSTR pszReadingA = NULL, pszUnregisterA = NULL; 476 477 TRACE("(%p, %s, 0x%lX, %s)\n", hKL, debugstr_w(lpszReading), dwStyle, 478 debugstr_w(lpszUnregister)); 479 480 pImeDpi = Imm32FindOrLoadImeDpi(hKL); 481 if (IS_NULL_UNEXPECTEDLY(pImeDpi)) 482 return FALSE; 483 484 if (ImeDpi_IsUnicode(pImeDpi)) /* No conversion needed */ 485 { 486 ret = pImeDpi->ImeUnregisterWord(lpszReading, dwStyle, lpszUnregister); 487 ImmUnlockImeDpi(pImeDpi); 488 return ret; 489 } 490 491 if (lpszReading) 492 { 493 pszReadingA = Imm32AnsiFromWide(pImeDpi->uCodePage, lpszReading); 494 if (IS_NULL_UNEXPECTEDLY(pszReadingA)) 495 goto Quit; 496 } 497 498 if (lpszUnregister) 499 { 500 pszUnregisterA = Imm32AnsiFromWide(pImeDpi->uCodePage, lpszUnregister); 501 if (IS_NULL_UNEXPECTEDLY(pszUnregisterA)) 502 goto Quit; 503 } 504 505 ret = pImeDpi->ImeUnregisterWord(pszReadingA, dwStyle, pszUnregisterA); 506 507 Quit: 508 ImmLocalFree(pszReadingA); 509 ImmLocalFree(pszUnregisterA); 510 ImmUnlockImeDpi(pImeDpi); 511 TRACE("ret: %d\n", ret); 512 return ret; 513 } 514