1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Tests for i18n console. 5 * COPYRIGHT: Copyright 2017-2020 Katayama Hirofumi MZ 6 * Copyright 2020 Hermes Belusca-Maito 7 */ 8 9 #include "precomp.h" 10 11 #define okCURSOR(hCon, c) \ 12 do { \ 13 CONSOLE_SCREEN_BUFFER_INFO __sbi; \ 14 BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \ 15 __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \ 16 ok(expect, "Expected cursor at (%d,%d), got (%d,%d)\n", \ 17 (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \ 18 } while (0) 19 20 #define ATTR (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) 21 22 static const WCHAR u0414[] = {0x0414, 0}; /* Д */ 23 static const WCHAR u9580[] = {0x9580, 0}; /* 門 */ 24 static const WCHAR space[] = {L' ', 0}; 25 static const WCHAR ideograph_space = (WCHAR)0x3000; /* fullwidth space */ 26 static const WCHAR s_str[] = {L'A', 0x9580, 'B', 0}; 27 static LCID lcidJapanese = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT), SORT_DEFAULT); 28 static LCID lcidRussian = MAKELCID(MAKELANGID(LANG_RUSSIAN , SUBLANG_DEFAULT), SORT_DEFAULT); 29 static BOOL s_bIs8Plus; 30 31 static BOOL IsCJKCodePage(void) 32 { 33 switch (GetOEMCP()) 34 { 35 case 936: // Chinese PRC 36 case 932: // Japanese 37 case 949: // Korean 38 case 1361: // Korean (Johab) 39 case 950: // Taiwan 40 return TRUE; 41 } 42 return FALSE; 43 } 44 45 /* Russian Code Page 855 */ 46 // NOTE that CP 866 can also be used 47 static void test_cp855(HANDLE hConOut) 48 { 49 BOOL ret; 50 DWORD oldcp; 51 int n; 52 DWORD len; 53 COORD c; 54 CONSOLE_SCREEN_BUFFER_INFO csbi; 55 int count; 56 WCHAR str[32]; 57 WORD attrs[16]; 58 59 if (!IsValidCodePage(855)) 60 { 61 skip("Codepage 855 not available\n"); 62 return; 63 } 64 65 /* Set code page */ 66 oldcp = GetConsoleOutputCP(); 67 SetLastError(0xdeadbeef); 68 ret = SetConsoleOutputCP(855); 69 if (!ret) 70 { 71 skip("SetConsoleOutputCP failed with last error %lu\n", GetLastError()); 72 return; 73 } 74 75 /* Get info */ 76 ret = GetConsoleScreenBufferInfo(hConOut, &csbi); 77 ok(ret, "GetConsoleScreenBufferInfo failed\n"); 78 trace("csbi.dwSize.X:%d, csbi.dwSize.Y:%d\n", csbi.dwSize.X, csbi.dwSize.Y); 79 count = 200; 80 81 /* "\u0414" */ 82 { 83 /* Output u0414 "count" times at (0,0) */ 84 c.X = c.Y = 0; 85 SetConsoleCursorPosition(hConOut, c); 86 okCURSOR(hConOut, c); 87 for (n = 0; n < count; ++n) 88 { 89 ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL); 90 ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n"); 91 } 92 93 /* Check cursor */ 94 len = count; /* u0414 is normal width in Russian */ 95 c.X = (SHORT)(len % csbi.dwSize.X); 96 c.Y = (SHORT)(len / csbi.dwSize.X); 97 okCURSOR(hConOut, c); 98 99 /* Read characters at (0,0) */ 100 c.X = c.Y = 0; 101 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 102 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 103 ok_long(len, 6); 104 ok_int(str[0], 0x414); 105 ok_int(str[1], 0x414); 106 ok_int(str[2], 0x414); 107 108 /* Read attributes at (0,0) */ 109 c.X = c.Y = 0; 110 ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); 111 ok(ret, "ReadConsoleOutputAttribute failed\n"); 112 ok_long(len, 6); 113 ok_int(attrs[0], ATTR); 114 115 /* Check cursor */ 116 c.X = 1; 117 c.Y = 0; 118 ret = SetConsoleCursorPosition(hConOut, c); 119 ok(ret, "SetConsoleCursorPosition failed\n"); 120 okCURSOR(hConOut, c); 121 122 /* Fill by space */ 123 c.X = c.Y = 0; 124 FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len); 125 126 /* Output u0414 "count" times at (1,0) */ 127 c.X = 1; 128 c.Y = 0; 129 SetConsoleCursorPosition(hConOut, c); 130 okCURSOR(hConOut, c); 131 for (n = 0; n < count; ++n) 132 { 133 ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL); 134 ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n"); 135 } 136 137 /* Check cursor */ 138 len = 1 + count; 139 c.X = (SHORT)(len % csbi.dwSize.X); 140 c.Y = (SHORT)(len / csbi.dwSize.X); 141 okCURSOR(hConOut, c); 142 143 /* Read characters at (0,0) */ 144 c.X = c.Y = 0; 145 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 146 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 147 ok_long(len, 6); 148 ok_int(str[0], L' '); 149 ok_int(str[1], 0x414); 150 ok_int(str[2], 0x414); 151 } 152 153 /* "\u9580" */ 154 { 155 /* Output u9580 "count" times at (0,0) */ 156 c.X = c.Y = 0; 157 SetConsoleCursorPosition(hConOut, c); 158 okCURSOR(hConOut, c); 159 for (n = 0; n < count; ++n) 160 { 161 ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); 162 ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); 163 } 164 165 /* Check cursor */ 166 len = count; /* u9580 is normal width in Russian */ 167 c.X = (SHORT)(len % csbi.dwSize.X); 168 c.Y = (SHORT)(len / csbi.dwSize.X); 169 okCURSOR(hConOut, c); 170 171 /* Check cursor */ 172 c.X = 1; 173 c.Y = 0; 174 ret = SetConsoleCursorPosition(hConOut, c); 175 ok(ret, "SetConsoleCursorPosition failed\n"); 176 okCURSOR(hConOut, c); 177 178 /* Fill by space */ 179 c.X = c.Y = 0; 180 ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len); 181 ok(ret, "FillConsoleOutputCharacterW failed\n"); 182 ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); 183 184 /* Output u9580 "count" times at (1,0) */ 185 c.X = 1; 186 c.Y = 0; 187 SetConsoleCursorPosition(hConOut, c); 188 okCURSOR(hConOut, c); 189 for (n = 0; n < count; ++n) 190 { 191 ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); 192 ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); 193 } 194 195 /* Check cursor */ 196 len = 1 + count; 197 c.X = (SHORT)(len % csbi.dwSize.X); 198 c.Y = (SHORT)(len / csbi.dwSize.X); 199 okCURSOR(hConOut, c); 200 201 /* Fill by ideograph space */ 202 c.X = c.Y = 0; 203 ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len); 204 ok(ret, "FillConsoleOutputCharacterW failed\n"); 205 ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); 206 207 /* Read characters at (0,0) */ 208 c.X = c.Y = 0; 209 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 210 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 211 ok_long(len, 6); 212 ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]); 213 ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]); 214 ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]); 215 216 /* Read attributes at (0,0) */ 217 c.X = c.Y = 0; 218 ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); 219 ok(ret, "ReadConsoleOutputAttribute failed\n"); 220 ok_long(len, 6); 221 ok_int(attrs[0], ATTR); 222 223 /* Read characters at (1,0) */ 224 c.X = 1; 225 c.Y = 0; 226 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 227 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 228 ok_long(len, 6); 229 ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]); 230 ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]); 231 ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]); 232 233 /* Output u9580 "count" once at (1,0) */ 234 c.X = 1; 235 c.Y = 0; 236 SetConsoleCursorPosition(hConOut, c); 237 okCURSOR(hConOut, c); 238 ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); 239 ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); 240 241 /* Read attributes at (1,0) */ 242 c.X = 1; 243 c.Y = 0; 244 ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); 245 ok(ret, "ReadConsoleOutputAttribute failed\n"); 246 ok_long(len, 1); 247 ok_int(attrs[0], ATTR); 248 249 /* Check cursor */ 250 c.X = 2; 251 c.Y = 0; 252 okCURSOR(hConOut, c); 253 254 /* Read characters at (0,0) */ 255 c.X = c.Y = 0; 256 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 257 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 258 ok_long(len, 6); 259 ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]); 260 ok(str[1] == u9580[0] || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]); 261 ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]); 262 } 263 264 /* Restore code page */ 265 SetConsoleOutputCP(oldcp); 266 } 267 268 /* Japanese Code Page 932 */ 269 static void test_cp932(HANDLE hConOut) 270 { 271 BOOL ret; 272 DWORD oldcp; 273 int n; 274 DWORD len; 275 COORD c, buffSize; 276 CONSOLE_SCREEN_BUFFER_INFO csbi; 277 int count; 278 WCHAR str[32]; 279 WORD attrs[16]; 280 CHAR_INFO buff[16]; 281 SMALL_RECT sr; 282 283 if (!IsValidCodePage(932)) 284 { 285 skip("Codepage 932 not available\n"); 286 return; 287 } 288 289 /* Set code page */ 290 oldcp = GetConsoleOutputCP(); 291 SetLastError(0xdeadbeef); 292 ret = SetConsoleOutputCP(932); 293 if (!ret) 294 { 295 skip("SetConsoleOutputCP failed with last error %lu\n", GetLastError()); 296 return; 297 } 298 299 /* Get info */ 300 ret = GetConsoleScreenBufferInfo(hConOut, &csbi); 301 ok(ret, "GetConsoleScreenBufferInfo failed\n"); 302 trace("csbi.dwSize.X:%d, csbi.dwSize.Y:%d\n", csbi.dwSize.X, csbi.dwSize.Y); 303 count = 200; 304 305 /* "\u0414" */ 306 { 307 /* Output u0414 "count" times at (0,0) */ 308 c.X = c.Y = 0; 309 SetConsoleCursorPosition(hConOut, c); 310 okCURSOR(hConOut, c); 311 for (n = 0; n < count; ++n) 312 { 313 ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL); 314 ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n"); 315 } 316 317 /* Check cursor */ 318 GetConsoleScreenBufferInfo(hConOut, &csbi); 319 len = count * 2; /* u0414 is fullwidth in Japanese */ 320 c.X = (SHORT)(len % csbi.dwSize.X); 321 c.Y = (SHORT)(len / csbi.dwSize.X); 322 okCURSOR(hConOut, c); 323 324 /* Read characters at (0,0) */ 325 c.X = c.Y = 0; 326 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 327 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 328 ok_long(len, 3); 329 ok_int(str[0], 0x414); 330 ok_int(str[1], 0x414); 331 ok_int(str[2], 0x414); 332 333 /* Read attributes at (0,0) */ 334 c.X = c.Y = 0; 335 ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); 336 ok(ret, "ReadConsoleOutputAttribute failed\n"); 337 ok_long(len, 6); 338 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 339 ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); 340 341 /* Check cursor */ 342 c.X = 1; 343 c.Y = 0; 344 ret = SetConsoleCursorPosition(hConOut, c); 345 ok(ret, "SetConsoleCursorPosition failed\n"); 346 okCURSOR(hConOut, c); 347 348 /* Fill by space */ 349 c.X = c.Y = 0; 350 FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len); 351 352 /* Output u0414 "count" times at (1,0) */ 353 c.X = 1; 354 c.Y = 0; 355 SetConsoleCursorPosition(hConOut, c); 356 okCURSOR(hConOut, c); 357 for (n = 0; n < count; ++n) 358 { 359 ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL); 360 ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n"); 361 } 362 363 /* Check cursor */ 364 len = csbi.dwSize.X + (count - (csbi.dwSize.X - 1) / 2) * 2; 365 c.X = (SHORT)(len % csbi.dwSize.X); 366 c.Y = (SHORT)(len / csbi.dwSize.X); 367 okCURSOR(hConOut, c); 368 369 /* Read characters at (0,0) */ 370 c.X = 0; 371 c.Y = 0; 372 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 373 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 374 ok_long(len, 4); 375 ok_int(str[0], L' '); 376 ok_int(str[1], 0x414); 377 ok_int(str[2], 0x414); 378 } 379 380 /* "\u9580" */ 381 { 382 /* Output u9580 "count" times at (0,0) */ 383 c.X = c.Y = 0; 384 SetConsoleCursorPosition(hConOut, c); 385 okCURSOR(hConOut, c); 386 for (n = 0; n < count; ++n) 387 { 388 ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); 389 ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); 390 } 391 392 /* Check cursor */ 393 len = count * 2; /* u9580 is fullwidth in Japanese */ 394 c.X = (SHORT)(len % csbi.dwSize.X); 395 c.Y = (SHORT)(len / csbi.dwSize.X); 396 okCURSOR(hConOut, c); 397 398 /* Check cursor */ 399 c.X = 1; 400 c.Y = 0; 401 ret = SetConsoleCursorPosition(hConOut, c); 402 ok(ret, "SetConsoleCursorPosition failed\n"); 403 okCURSOR(hConOut, c); 404 405 /* Fill by space */ 406 c.X = c.Y = 0; 407 ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len); 408 ok(ret, "FillConsoleOutputCharacterW failed\n"); 409 ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); 410 411 /* Output u9580 "count" times at (1,0) */ 412 c.X = 1; 413 c.Y = 0; 414 SetConsoleCursorPosition(hConOut, c); 415 okCURSOR(hConOut, c); 416 for (n = 0; n < count; ++n) 417 { 418 ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); 419 ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); 420 } 421 422 /* Check cursor */ 423 len = csbi.dwSize.X + (count - (csbi.dwSize.X - 1) / 2) * 2; 424 c.X = (SHORT)(len % csbi.dwSize.X); 425 c.Y = (SHORT)(len / csbi.dwSize.X); 426 okCURSOR(hConOut, c); 427 428 /* Fill by ideograph space */ 429 c.X = c.Y = 0; 430 ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len); 431 ok(ret, "FillConsoleOutputCharacterW failed\n"); 432 if (s_bIs8Plus) 433 ok_long(len, csbi.dwSize.X * csbi.dwSize.Y / 2); 434 else 435 ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); 436 437 /* Read characters at (0,0) */ 438 c.X = c.Y = 0; 439 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 440 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 441 ok_long(len, 3); 442 ok_int(str[0], ideograph_space); 443 ok_int(str[1], ideograph_space); 444 ok_int(str[2], ideograph_space); 445 446 /* Read attributes at (0,0) */ 447 c.X = c.Y = 0; 448 ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); 449 ok(ret, "ReadConsoleOutputAttribute failed\n"); 450 ok_long(len, 6); 451 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 452 ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); 453 ok_int(attrs[2], ATTR | COMMON_LVB_LEADING_BYTE); 454 ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE); 455 ok_int(attrs[4], ATTR | COMMON_LVB_LEADING_BYTE); 456 ok_int(attrs[5], ATTR | COMMON_LVB_TRAILING_BYTE); 457 458 /* Output u9580 "count" once at (1,0) */ 459 c.X = 1; 460 c.Y = 0; 461 SetConsoleCursorPosition(hConOut, c); 462 okCURSOR(hConOut, c); 463 ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); 464 ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); 465 466 /* 467 * Read attributes at (1,0) - 468 * Note that if only one attribute of a fullwidth character 469 * is retrieved, no leading/trailing byte flag is set! 470 */ 471 c.X = 1; 472 c.Y = 0; 473 ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); 474 ok(ret, "ReadConsoleOutputAttribute failed\n"); 475 ok_long(len, 1); 476 ok_int(attrs[0], ATTR); 477 478 /* Check that the same problem happens for the trailing byte */ 479 c.X = 2; 480 c.Y = 0; 481 ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); 482 ok(ret, "ReadConsoleOutputAttribute failed\n"); 483 ok_long(len, 1); 484 ok_int(attrs[0], ATTR); 485 486 /* Read attributes at (1,0) */ 487 c.X = 1; 488 c.Y = 0; 489 ret = ReadConsoleOutputAttribute(hConOut, attrs, 2, c, &len); 490 ok(ret, "ReadConsoleOutputAttribute failed\n"); 491 ok_long(len, 2); 492 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 493 ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); 494 495 /* Read attributes at (1,0) */ 496 ret = ReadConsoleOutputAttribute(hConOut, attrs, 3, c, &len); 497 ok(ret, "ReadConsoleOutputAttribute failed\n"); 498 ok_long(len, 3); 499 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 500 ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); 501 if (s_bIs8Plus) 502 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 503 else 504 ok_int(attrs[2], ATTR); 505 506 /* Read attributes at (0,0) */ 507 c.X = c.Y = 0; 508 ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); 509 ok(ret, "ReadConsoleOutputAttribute failed\n"); 510 ok_long(len, 4); 511 if (s_bIs8Plus) 512 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 513 else 514 ok_int(attrs[0], ATTR); 515 ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); 516 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 517 if (s_bIs8Plus) 518 ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE); 519 else 520 ok_int(attrs[3], ATTR); 521 522 /* Check cursor */ 523 c.X = 3; 524 c.Y = 0; 525 okCURSOR(hConOut, c); 526 527 /* Read characters */ 528 c.X = c.Y = 0; 529 ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); 530 ok(ret, "ReadConsoleOutputCharacterW failed\n"); 531 if (s_bIs8Plus) 532 { 533 ok_long(len, 3); 534 ok_int(str[0], ideograph_space); 535 ok_int(str[1], u9580[0]); 536 ok_int(str[2], ideograph_space); 537 } 538 else 539 { 540 ok_long(len, 4); 541 ok_int(str[0], L' '); 542 ok_int(str[1], u9580[0]); 543 ok_int(str[2], L' '); 544 } 545 } 546 547 /* COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE for u0414 */ 548 { 549 /* set cursor */ 550 c.X = c.Y = 0; 551 SetConsoleCursorPosition(hConOut, c); 552 okCURSOR(hConOut, c); 553 554 /* fill by 'A' */ 555 ret = FillConsoleOutputCharacterW(hConOut, L'A', csbi.dwSize.X * 2, c, &len); 556 ok_int(ret, 1); 557 ok_long(len, csbi.dwSize.X * 2); 558 559 /* reset buff */ 560 buffSize.X = ARRAYSIZE(buff); 561 buffSize.Y = 1; 562 memset(buff, 0x7F, sizeof(buff)); 563 564 /* read output */ 565 c.X = c.Y = 0; 566 ZeroMemory(&sr, sizeof(sr)); 567 sr.Right = buffSize.X - 1; 568 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 569 ok_int(ret, 1); 570 ok_int(sr.Left, 0); 571 ok_int(sr.Top, 0); 572 ok_int(sr.Right, buffSize.X - 1); 573 ok_int(sr.Bottom, 0); 574 575 /* check buff */ 576 ok_int(buff[0].Char.UnicodeChar, L'A'); 577 ok_int(buff[0].Attributes, ATTR); 578 579 /* read attr */ 580 ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); 581 ok_int(ret, 1); 582 ok_long(len, 1); 583 ok_int(attrs[0], ATTR); 584 585 /* read char */ 586 c.X = c.Y = 0; 587 memset(str, 0x7F, sizeof(str)); 588 ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); 589 ok_int(ret, 1); 590 ok_long(len, 4); 591 ok_int(str[0], L'A'); 592 ok_int(str[1], L'A'); 593 ok_int(str[2], L'A'); 594 ok_int(str[3], L'A'); 595 596 /* set cursor */ 597 c.X = c.Y = 0; 598 SetConsoleCursorPosition(hConOut, c); 599 okCURSOR(hConOut, c); 600 601 /* write u0414 */ 602 ret = WriteConsoleW(hConOut, u0414, 1, &len, NULL); 603 ok_int(ret, 1); 604 ok_long(len, 1); 605 606 /* reset buff */ 607 buffSize.X = ARRAYSIZE(buff); 608 buffSize.Y = 1; 609 memset(buff, 0x7F, sizeof(buff)); 610 611 /* read output */ 612 c.X = c.Y = 0; 613 ZeroMemory(&sr, sizeof(sr)); 614 sr.Right = buffSize.X - 1; 615 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 616 ok_int(ret, 1); 617 ok_int(sr.Left, 0); 618 ok_int(sr.Top, 0); 619 ok_int(sr.Right, buffSize.X - 1); 620 ok_int(sr.Bottom, 0); 621 622 /* check buff */ 623 if (s_bIs8Plus) 624 { 625 ok_int(buff[0].Char.UnicodeChar, 0x0414); 626 ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 627 ok_int(buff[1].Char.UnicodeChar, 0x0414); 628 ok_int(buff[1].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); 629 } 630 else 631 { 632 ok_int(buff[0].Char.UnicodeChar, 0x0414); 633 ok_int(buff[0].Attributes, ATTR); 634 ok_int(buff[1].Char.UnicodeChar, L'A'); 635 ok_int(buff[1].Attributes, ATTR); 636 } 637 ok_int(buff[2].Char.UnicodeChar, L'A'); 638 ok_int(buff[2].Attributes, ATTR); 639 ok_int(buff[3].Char.UnicodeChar, L'A'); 640 ok_int(buff[3].Attributes, ATTR); 641 642 /* read attr */ 643 ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len); 644 ok_int(ret, 1); 645 ok_long(len, ARRAYSIZE(attrs)); 646 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 647 ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); 648 ok_int(attrs[2], ATTR); 649 ok_int(attrs[3], ATTR); 650 651 /* read char */ 652 c.X = c.Y = 0; 653 memset(str, 0x7F, sizeof(str)); 654 ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); 655 ok_int(ret, 1); 656 ok_long(len, 3); 657 ok_int(str[0], 0x0414); 658 ok_int(str[1], L'A'); 659 ok_int(str[2], L'A'); 660 if (s_bIs8Plus) 661 ok_int(str[3], 0); 662 else 663 ok_int(str[3], 0x7F7F); 664 665 /* set cursor */ 666 c.X = 1; 667 c.Y = 0; 668 SetConsoleCursorPosition(hConOut, c); 669 okCURSOR(hConOut, c); 670 671 /* write u0414 */ 672 ret = WriteConsoleW(hConOut, u0414, 1, &len, NULL); 673 ok_int(ret, 1); 674 ok_long(len, 1); 675 676 /* read output */ 677 c.X = c.Y = 0; 678 ZeroMemory(&sr, sizeof(sr)); 679 sr.Right = buffSize.X - 1; 680 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 681 ok_int(ret, 1); 682 ok_int(sr.Left, 0); 683 ok_int(sr.Top, 0); 684 ok_int(sr.Right, buffSize.X - 1); 685 ok_int(sr.Bottom, 0); 686 687 /* check buff */ 688 if (s_bIs8Plus) 689 { 690 ok_int(buff[0].Char.UnicodeChar, 0x0414); 691 ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 692 ok_int(buff[1].Char.UnicodeChar, 0x0414); 693 ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 694 ok_int(buff[2].Char.UnicodeChar, 0x0414); 695 ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); 696 } 697 else 698 { 699 ok_int(buff[0].Char.UnicodeChar, L' '); 700 ok_int(buff[0].Attributes, ATTR); 701 ok_int(buff[1].Char.UnicodeChar, 0x0414); 702 ok_int(buff[1].Attributes, ATTR); 703 ok_int(buff[2].Char.UnicodeChar, L'A'); 704 ok_int(buff[2].Attributes, ATTR); 705 } 706 ok_int(buff[3].Char.UnicodeChar, L'A'); 707 ok_int(buff[3].Attributes, ATTR); 708 709 /* read attr */ 710 c.X = c.Y = 0; 711 ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len); 712 ok_int(ret, 1); 713 ok_long(len, ARRAYSIZE(attrs)); 714 if (s_bIs8Plus) 715 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 716 else 717 ok_int(attrs[0], ATTR); 718 ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); 719 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 720 ok_int(attrs[3], ATTR); 721 722 /* read char */ 723 c.X = c.Y = 0; 724 memset(str, 0x7F, sizeof(str)); 725 ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); 726 ok_int(ret, 1); 727 ok_long(len, 3); 728 if (s_bIs8Plus) 729 { 730 ok_int(str[0], 0x0414); 731 ok_int(str[1], 0x0414); 732 ok_int(str[2], L'A'); 733 ok_int(str[3], 0); 734 } 735 else 736 { 737 ok_int(str[0], L' '); 738 ok_int(str[1], 0x0414); 739 ok_int(str[2], L'A'); 740 ok_int(str[3], 0x7F7F); 741 } 742 743 /* set cursor */ 744 c.X = csbi.dwSize.X - 1; 745 c.Y = 0; 746 SetConsoleCursorPosition(hConOut, c); 747 okCURSOR(hConOut, c); 748 749 /* write u0414 */ 750 WriteConsoleW(hConOut, u0414, 1, &len, NULL); 751 ok_int(ret, 1); 752 ok_long(len, 1); 753 754 /* reset buff */ 755 buffSize.X = ARRAYSIZE(buff); 756 buffSize.Y = 1; 757 memset(buff, 0x7F, sizeof(buff)); 758 759 /* read output */ 760 c.X = c.Y = 0; 761 sr.Left = csbi.dwSize.X - 2; 762 sr.Top = 0; 763 sr.Right = csbi.dwSize.X - 1; 764 sr.Bottom = 0; 765 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 766 ok_int(ret, 1); 767 ok_int(sr.Left, csbi.dwSize.X - 2); 768 ok_int(sr.Top, 0); 769 ok_int(sr.Right, csbi.dwSize.X - 1); 770 ok_int(sr.Bottom, 0); 771 772 /* check buff */ 773 ok_int(buff[0].Char.UnicodeChar, L'A'); 774 ok_int(buff[0].Attributes, ATTR); 775 ok_int(buff[1].Char.UnicodeChar, L'A'); 776 ok_int(buff[1].Attributes, ATTR); 777 778 /* read attrs */ 779 c.X = csbi.dwSize.X - 2; 780 c.Y = 0; 781 ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len); 782 ok_int(ret, 1); 783 ok_long(len, ARRAYSIZE(attrs)); 784 ok_int(attrs[0], ATTR); 785 ok_int(attrs[1], ATTR); 786 787 /* read char */ 788 ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len); 789 ok_int(ret, 1); 790 ok_long(len, 2); 791 ok_int(str[0], L'A'); 792 ok_int(str[1], L'A'); 793 794 /* fill by 'A' */ 795 c.X = c.Y = 0; 796 ret = FillConsoleOutputCharacterW(hConOut, L'A', 10, c, &len); 797 ok_int(ret, 1); 798 ok_long(len, 10); 799 800 /* fill by u0414 */ 801 c.X = 1; 802 c.Y = 0; 803 ret = FillConsoleOutputCharacterW(hConOut, 0x0414, 1, c, &len); 804 c.X = c.Y = 0; 805 ok_int(ret, 1); 806 ok_long(len, 1); 807 808 /* reset buff */ 809 buffSize.X = ARRAYSIZE(buff); 810 buffSize.Y = 1; 811 memset(buff, 0x7F, sizeof(buff)); 812 813 /* read output */ 814 c.X = c.Y = 0; 815 sr.Left = 0; 816 sr.Top = 0; 817 sr.Right = 4; 818 sr.Bottom = 0; 819 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 820 ok_int(ret, 1); 821 ok_int(sr.Left, 0); 822 ok_int(sr.Top, 0); 823 ok_int(sr.Right, 4); 824 ok_int(sr.Bottom, 0); 825 826 /* check buff */ 827 ok_int(buff[0].Char.UnicodeChar, L'A'); 828 ok_int(buff[0].Attributes, ATTR); 829 if (s_bIs8Plus) 830 { 831 ok_int(buff[1].Char.UnicodeChar, 0x0414); 832 ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 833 ok_int(buff[2].Char.UnicodeChar, 0x0414); 834 ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); 835 } 836 else 837 { 838 ok_int(buff[1].Char.UnicodeChar, L' '); 839 ok_int(buff[1].Attributes, ATTR); 840 ok_int(buff[2].Char.UnicodeChar, L'A'); 841 ok_int(buff[2].Attributes, ATTR); 842 } 843 ok_int(buff[3].Char.UnicodeChar, L'A'); 844 ok_int(buff[3].Attributes, ATTR); 845 ok_int(buff[4].Char.UnicodeChar, L'A'); 846 ok_int(buff[4].Attributes, ATTR); 847 848 /* read attrs */ 849 c.X = 0; 850 c.Y = 0; 851 ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); 852 ok_int(ret, 1); 853 ok_long(len, 4); 854 ok_int(attrs[0], ATTR); 855 if (s_bIs8Plus) 856 { 857 ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); 858 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 859 } 860 else 861 { 862 ok_int(attrs[1], ATTR); 863 ok_int(attrs[2], ATTR); 864 } 865 ok_int(attrs[3], ATTR); 866 } 867 868 /* COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE for u9580 */ 869 { 870 /* set cursor */ 871 c.X = c.Y = 0; 872 SetConsoleCursorPosition(hConOut, c); 873 okCURSOR(hConOut, c); 874 875 /* fill by 'A' */ 876 ret = FillConsoleOutputCharacterW(hConOut, L'A', csbi.dwSize.X * 2, c, &len); 877 ok_int(ret, 1); 878 ok_long(len, csbi.dwSize.X * 2); 879 880 /* reset buff */ 881 buffSize.X = ARRAYSIZE(buff); 882 buffSize.Y = 1; 883 memset(buff, 0x7F, sizeof(buff)); 884 885 /* read output */ 886 c.X = c.Y = 0; 887 ZeroMemory(&sr, sizeof(sr)); 888 sr.Right = buffSize.X - 1; 889 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 890 ok_int(ret, 1); 891 ok_int(sr.Left, 0); 892 ok_int(sr.Top, 0); 893 ok_int(sr.Right, buffSize.X - 1); 894 ok_int(sr.Bottom, 0); 895 896 /* check buff */ 897 ok_int(buff[0].Char.UnicodeChar, L'A'); 898 ok_int(buff[0].Attributes, ATTR); 899 900 /* read attr */ 901 ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); 902 ok_int(ret, 1); 903 ok_long(len, 1); 904 ok_int(attrs[0], ATTR); 905 906 /* read char */ 907 memset(str, 0x7F, sizeof(str)); 908 ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len); 909 ok_int(ret, 1); 910 ok_long(len, 2); 911 ok_int(str[0], L'A'); 912 ok_int(str[1], L'A'); 913 914 /* set cursor */ 915 c.X = 0; 916 c.Y = 0; 917 SetConsoleCursorPosition(hConOut, c); 918 okCURSOR(hConOut, c); 919 920 /* write u9580 */ 921 ret = WriteConsoleW(hConOut, u9580, 1, &len, NULL); 922 ok_int(ret, 1); 923 ok_long(len, 1); 924 925 /* reset buff */ 926 buffSize.X = ARRAYSIZE(buff); 927 buffSize.Y = 1; 928 memset(buff, 0x7F, sizeof(buff)); 929 930 /* read output */ 931 c.X = c.Y = 0; 932 ZeroMemory(&sr, sizeof(sr)); 933 sr.Right = buffSize.X - 1; 934 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 935 ok_int(ret, 1); 936 ok_int(sr.Left, 0); 937 ok_int(sr.Top, 0); 938 ok_int(sr.Right, buffSize.X - 1); 939 ok_int(sr.Bottom, 0); 940 941 /* check buff */ 942 if (s_bIs8Plus) 943 { 944 ok_int(buff[0].Char.UnicodeChar, u9580[0]); 945 ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 946 ok_int(buff[1].Char.UnicodeChar, u9580[0]); 947 ok_int(buff[1].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); 948 } 949 else 950 { 951 ok_int(buff[0].Char.UnicodeChar, u9580[0]); 952 ok_int(buff[0].Attributes, ATTR); 953 ok_int(buff[1].Char.UnicodeChar, L'A'); 954 ok_int(buff[1].Attributes, ATTR); 955 } 956 ok_int(buff[2].Char.UnicodeChar, L'A'); 957 ok_int(buff[2].Attributes, ATTR); 958 ok_int(buff[3].Char.UnicodeChar, L'A'); 959 ok_int(buff[3].Attributes, ATTR); 960 961 /* read attr */ 962 ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len); 963 ok_int(ret, 1); 964 ok_long(len, ARRAYSIZE(attrs)); 965 966 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 967 ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); 968 ok_int(attrs[2], ATTR); 969 ok_int(attrs[3], ATTR); 970 971 /* read char */ 972 c.X = c.Y = 0; 973 memset(str, 0x7F, sizeof(str)); 974 ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); 975 ok_int(ret, 1); 976 ok_long(len, 3); 977 ok_int(str[0], u9580[0]); 978 ok_int(str[1], L'A'); 979 ok_int(str[2], L'A'); 980 if (s_bIs8Plus) 981 ok_int(str[3], 0); 982 else 983 ok_int(str[3], 0x7F7F); 984 985 /* set cursor */ 986 c.X = 1; 987 c.Y = 0; 988 SetConsoleCursorPosition(hConOut, c); 989 okCURSOR(hConOut, c); 990 991 /* write u9580 */ 992 ret = WriteConsoleW(hConOut, u9580, 1, &len, NULL); 993 ok_int(ret, 1); 994 ok_long(len, 1); 995 996 /* read output */ 997 c.X = c.Y = 0; 998 ZeroMemory(&sr, sizeof(sr)); 999 sr.Right = buffSize.X - 1; 1000 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 1001 ok_int(ret, 1); 1002 ok_int(sr.Left, 0); 1003 ok_int(sr.Top, 0); 1004 ok_int(sr.Right, buffSize.X - 1); 1005 ok_int(sr.Bottom, 0); 1006 1007 /* check buff */ 1008 if (s_bIs8Plus) 1009 { 1010 ok_int(buff[0].Char.UnicodeChar, u9580[0]); 1011 ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 1012 ok_int(buff[1].Char.UnicodeChar, u9580[0]); 1013 ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 1014 ok_int(buff[2].Char.UnicodeChar, u9580[0]); 1015 ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); 1016 } 1017 else 1018 { 1019 ok_int(buff[0].Char.UnicodeChar, L' '); 1020 ok_int(buff[0].Attributes, ATTR); 1021 ok_int(buff[1].Char.UnicodeChar, u9580[0]); 1022 ok_int(buff[1].Attributes, ATTR); 1023 ok_int(buff[2].Char.UnicodeChar, L'A'); 1024 ok_int(buff[2].Attributes, ATTR); 1025 } 1026 ok_int(buff[3].Char.UnicodeChar, L'A'); 1027 ok_int(buff[3].Attributes, ATTR); 1028 1029 /* read attr */ 1030 c.X = c.Y = 0; 1031 ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len); 1032 ok_int(ret, 1); 1033 ok_long(len, ARRAYSIZE(attrs)); 1034 1035 if (s_bIs8Plus) 1036 { 1037 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 1038 } 1039 else 1040 { 1041 ok_int(attrs[0], ATTR); 1042 } 1043 ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); 1044 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 1045 ok_int(attrs[3], ATTR); 1046 1047 /* set cursor */ 1048 c.X = csbi.dwSize.X - 1; 1049 c.Y = 0; 1050 SetConsoleCursorPosition(hConOut, c); 1051 okCURSOR(hConOut, c); 1052 1053 /* write u9580 */ 1054 WriteConsoleW(hConOut, u9580, 1, &len, NULL); 1055 ok_int(ret, 1); 1056 ok_long(len, 1); 1057 1058 /* reset buff */ 1059 buffSize.X = ARRAYSIZE(buff); 1060 buffSize.Y = 1; 1061 memset(buff, 0x7F, sizeof(buff)); 1062 1063 /* read output */ 1064 c.X = c.Y = 0; 1065 sr.Left = csbi.dwSize.X - 2; 1066 sr.Top = 0; 1067 sr.Right = csbi.dwSize.X - 1; 1068 sr.Bottom = 0; 1069 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 1070 ok_int(ret, 1); 1071 ok_int(sr.Left, csbi.dwSize.X - 2); 1072 ok_int(sr.Top, 0); 1073 ok_int(sr.Right, csbi.dwSize.X - 1); 1074 ok_int(sr.Bottom, 0); 1075 1076 /* check buff */ 1077 ok_int(buff[0].Char.UnicodeChar, L'A'); 1078 ok_int(buff[0].Attributes, ATTR); 1079 ok_int(buff[1].Char.UnicodeChar, L'A'); 1080 ok_int(buff[1].Attributes, ATTR); 1081 1082 /* read attr */ 1083 c.X = csbi.dwSize.X - 2; 1084 c.Y = 0; 1085 ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len); 1086 ok_int(ret, 1); 1087 ok_long(len, ARRAYSIZE(attrs)); 1088 ok_int(attrs[0], ATTR); 1089 ok_int(attrs[1], ATTR); 1090 1091 /* read char */ 1092 memset(str, 0x7F, sizeof(str)); 1093 ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len); 1094 ok_int(ret, 1); 1095 ok_long(len, 2); 1096 ok_int(str[0], L'A'); 1097 ok_int(str[1], L'A'); 1098 1099 /* fill by 'A' */ 1100 c.X = c.Y = 0; 1101 ret = FillConsoleOutputCharacterW(hConOut, L'A', 10, c, &len); 1102 ok_int(ret, 1); 1103 ok_long(len, 10); 1104 1105 /* fill by u9580 */ 1106 c.X = 1; 1107 c.Y = 0; 1108 ret = FillConsoleOutputCharacterW(hConOut, u9580[0], 1, c, &len); 1109 c.X = c.Y = 0; 1110 ok_int(ret, 1); 1111 ok_long(len, 1); 1112 1113 /* reset buff */ 1114 buffSize.X = ARRAYSIZE(buff); 1115 buffSize.Y = 1; 1116 memset(buff, 0x7F, sizeof(buff)); 1117 1118 /* read output */ 1119 c.X = c.Y = 0; 1120 sr.Left = 0; 1121 sr.Top = 0; 1122 sr.Right = 4; 1123 sr.Bottom = 0; 1124 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 1125 ok_int(ret, 1); 1126 ok_int(sr.Left, 0); 1127 ok_int(sr.Top, 0); 1128 ok_int(sr.Right, 4); 1129 ok_int(sr.Bottom, 0); 1130 1131 /* check buff */ 1132 ok_int(buff[0].Char.UnicodeChar, L'A'); 1133 ok_int(buff[0].Attributes, ATTR); 1134 if (s_bIs8Plus) 1135 { 1136 ok_int(buff[1].Char.UnicodeChar, u9580[0]); 1137 ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 1138 ok_int(buff[2].Char.UnicodeChar, u9580[0]); 1139 ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); 1140 } 1141 else 1142 { 1143 ok_int(buff[1].Char.UnicodeChar, L' '); 1144 ok_int(buff[1].Attributes, ATTR); 1145 ok_int(buff[2].Char.UnicodeChar, L'A'); 1146 ok_int(buff[2].Attributes, ATTR); 1147 } 1148 ok_int(buff[3].Char.UnicodeChar, L'A'); 1149 ok_int(buff[3].Attributes, ATTR); 1150 ok_int(buff[4].Char.UnicodeChar, L'A'); 1151 ok_int(buff[4].Attributes, ATTR); 1152 1153 /* read attrs */ 1154 c.X = 0; 1155 c.Y = 0; 1156 ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); 1157 ok_int(ret, 1); 1158 ok_long(len, 4); 1159 ok_int(attrs[0], ATTR); 1160 if (s_bIs8Plus) 1161 { 1162 ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); 1163 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 1164 } 1165 else 1166 { 1167 ok_int(attrs[1], ATTR); 1168 ok_int(attrs[2], ATTR); 1169 } 1170 ok_int(attrs[3], ATTR); 1171 } 1172 1173 /* FillConsoleOutputAttribute and WriteConsoleOutput */ 1174 { 1175 c.X = c.Y = 0; 1176 SetConsoleCursorPosition(hConOut, c); 1177 okCURSOR(hConOut, c); 1178 for (n = 0; n < count; ++n) 1179 { 1180 ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL); 1181 ok_int(ret, 1); 1182 ok_long(len, 1); 1183 } 1184 1185 /* fill attrs */ 1186 c.X = c.Y = 0; 1187 SetConsoleCursorPosition(hConOut, c); 1188 okCURSOR(hConOut, c); 1189 ret = FillConsoleOutputAttribute(hConOut, 0xFFFF, 2, c, &len); 1190 ok_int(ret, 1); 1191 ok_long(len, 2); 1192 1193 /* read attrs */ 1194 memset(attrs, 0x7F, sizeof(attrs)); 1195 ret = ReadConsoleOutputAttribute(hConOut, attrs, 3, c, &len); 1196 ok_int(ret, 1); 1197 ok_long(len, 3); 1198 if (s_bIs8Plus) 1199 { 1200 ok_int(attrs[0], 0xDCFF); 1201 ok_int(attrs[1], 0xDCFF); 1202 } 1203 else 1204 { 1205 ok_int(attrs[0], 0xFCFF); 1206 ok_int(attrs[1], 0xFCFF); 1207 } 1208 ok_int(attrs[2], ATTR); 1209 1210 /* fill attrs */ 1211 c.X = c.Y = 0; 1212 SetConsoleCursorPosition(hConOut, c); 1213 okCURSOR(hConOut, c); 1214 ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len); 1215 ok_int(ret, 1); 1216 ok_long(len, 4); 1217 1218 /* write */ 1219 c.X = c.Y = 0; 1220 sr.Left = 0; 1221 sr.Top = 0; 1222 sr.Right = 4; 1223 sr.Bottom = 0; 1224 // Check how Read/WriteConsoleOutput() handle inconsistent DBCS flags. 1225 buff[0].Char.UnicodeChar = u9580[0]; 1226 buff[0].Attributes = ATTR | COMMON_LVB_LEADING_BYTE; 1227 buff[1].Char.UnicodeChar = u9580[0]; 1228 buff[1].Attributes = ATTR | COMMON_LVB_LEADING_BYTE; 1229 buff[2].Char.UnicodeChar = u9580[0]; 1230 buff[2].Attributes = ATTR | COMMON_LVB_TRAILING_BYTE; 1231 buff[3].Char.UnicodeChar = L'A'; 1232 buff[3].Attributes = ATTR; 1233 buff[4].Char.UnicodeChar = L' '; 1234 buff[4].Attributes = 0xFFFF; 1235 buffSize.X = 4; 1236 buffSize.Y = 1; 1237 ret = WriteConsoleOutputW(hConOut, buff, buffSize, c, &sr); 1238 ok_int(ret, 1); 1239 ok_int(sr.Left, 0); 1240 ok_int(sr.Top, 0); 1241 ok_int(sr.Right, 3); 1242 ok_int(sr.Bottom, 0); 1243 1244 /* read output */ 1245 sr.Left = 0; 1246 sr.Top = 0; 1247 sr.Right = 4; 1248 sr.Bottom = 0; 1249 memset(buff, 0x7F, sizeof(buff)); 1250 ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); 1251 ok_int(ret, 1); 1252 ok_int(sr.Left, 0); 1253 ok_int(sr.Top, 0); 1254 ok_int(sr.Right, 3); 1255 ok_int(sr.Bottom, 0); 1256 1257 /* check buff */ 1258 if (s_bIs8Plus) 1259 { 1260 ok_int(buff[0].Char.UnicodeChar, u9580[0]); 1261 ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 1262 ok_int(buff[1].Char.UnicodeChar, u9580[0]); 1263 ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); 1264 ok_int(buff[2].Char.UnicodeChar, u9580[0]); 1265 ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); 1266 ok_int(buff[3].Char.UnicodeChar, L'A'); 1267 ok_int(buff[3].Attributes, ATTR); 1268 ok_int(buff[4].Char.UnicodeChar, 0x7F7F); 1269 ok_int(buff[4].Attributes, 0x7F7F); 1270 } 1271 else 1272 { 1273 ok_int(buff[0].Char.UnicodeChar, u9580[0]); 1274 ok_int(buff[0].Attributes, ATTR); 1275 ok_int(buff[1].Char.UnicodeChar, u9580[0]); 1276 ok_int(buff[1].Attributes, ATTR); 1277 ok_int(buff[2].Char.UnicodeChar, 0); 1278 ok_int(buff[2].Attributes, 0); 1279 ok_int(buff[3].Char.UnicodeChar, 0); 1280 ok_int(buff[3].Attributes, 0); 1281 ok_int(buff[4].Char.UnicodeChar, 0x7F7F); 1282 ok_int(buff[4].Attributes, 0x7F7F); 1283 } 1284 1285 /* read attrs */ 1286 c.X = c.Y = 0; 1287 memset(attrs, 0x7F, sizeof(attrs)); 1288 ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); 1289 ok_int(ret, 1); 1290 ok_long(len, 6); 1291 ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); 1292 if (s_bIs8Plus) 1293 { 1294 ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); 1295 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 1296 ok_int(attrs[3], ATTR); 1297 } 1298 else 1299 { 1300 ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); 1301 ok_int(attrs[2], ATTR | COMMON_LVB_LEADING_BYTE); 1302 ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE); 1303 } 1304 ok_int(attrs[4], ATTR); 1305 ok_int(attrs[5], ATTR); 1306 } 1307 1308 /* WriteConsoleOutputCharacterW and WriteConsoleOutputAttribute */ 1309 { 1310 c.X = c.Y = 0; 1311 SetConsoleCursorPosition(hConOut, c); 1312 okCURSOR(hConOut, c); 1313 for (n = 0; n < count; ++n) 1314 { 1315 ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL); 1316 ok_int(ret, 1); 1317 ok_long(len, 1); 1318 } 1319 1320 /* write attrs */ 1321 attrs[0] = ATTR; 1322 attrs[1] = 0xFFFF; 1323 attrs[2] = ATTR; 1324 attrs[3] = 0; 1325 ret = WriteConsoleOutputAttribute(hConOut, attrs, 4, c, &len); 1326 ok_int(ret, 1); 1327 ok_long(len, 4); 1328 1329 /* read attrs */ 1330 memset(attrs, 0x7F, sizeof(attrs)); 1331 ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); 1332 ok_int(ret, 1); 1333 ok_long(len, 4); 1334 ok_int(attrs[0], ATTR); 1335 if (s_bIs8Plus) 1336 ok_int(attrs[1], 0xDCFF); 1337 else 1338 ok_int(attrs[1], 0xFCFF); 1339 ok_int(attrs[2], ATTR); 1340 ok_int(attrs[3], 0); 1341 1342 /* fill attr */ 1343 ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len); 1344 ok_int(ret, 1); 1345 ok_long(len, 4); 1346 1347 /* write char */ 1348 ret = WriteConsoleOutputCharacterW(hConOut, s_str, 4, c, &len); 1349 ok_int(ret, 1); 1350 ok_long(len, 4); 1351 1352 /* read attrs */ 1353 memset(attrs, 0x7F, sizeof(attrs)); 1354 ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); 1355 ok_int(ret, 1); 1356 ok_long(len, 4); 1357 ok_int(attrs[0], ATTR); 1358 ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); 1359 ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); 1360 ok_int(attrs[3], ATTR); 1361 } 1362 1363 /* Restore code page */ 1364 SetConsoleOutputCP(oldcp); 1365 } 1366 1367 START_TEST(ConsoleCP) 1368 { 1369 HANDLE hConIn, hConOut; 1370 OSVERSIONINFOA osver = { sizeof(osver) }; 1371 1372 // https://github.com/reactos/reactos/pull/2131#issuecomment-563189380 1373 GetVersionExA(&osver); 1374 s_bIs8Plus = (osver.dwMajorVersion > 6) || 1375 (osver.dwMajorVersion == 6 && osver.dwMinorVersion >= 2); 1376 1377 FreeConsole(); 1378 ok(AllocConsole(), "Couldn't alloc console\n"); 1379 1380 hConIn = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1381 hConOut = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1382 ok(hConIn != INVALID_HANDLE_VALUE, "Opening ConIn\n"); 1383 ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n"); 1384 1385 if (IsValidLocale(lcidRussian, LCID_INSTALLED)) 1386 { 1387 if (!IsCJKCodePage()) 1388 test_cp855(hConOut); 1389 else 1390 skip("Russian testcase is skipped because of CJK\n"); 1391 } 1392 else 1393 { 1394 skip("Russian locale is not installed\n"); 1395 } 1396 1397 if (IsValidLocale(lcidJapanese, LCID_INSTALLED)) 1398 { 1399 if (IsCJKCodePage()) 1400 test_cp932(hConOut); 1401 else 1402 skip("Japanese testcase is skipped because of not CJK\n"); 1403 } 1404 else 1405 { 1406 skip("Japanese locale is not installed\n"); 1407 } 1408 1409 CloseHandle(hConIn); 1410 CloseHandle(hConOut); 1411 FreeConsole(); 1412 ok(AllocConsole(), "Couldn't alloc console\n"); 1413 } 1414