39 #define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
40 #define FOREGROUND_BLACK 0
41 #define FOREGROUND_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN)
42 #define FOREGROUND_CYAN (FOREGROUND_GREEN | FOREGROUND_BLUE)
43 #define FOREGROUND_MAGENTA (FOREGROUND_RED | FOREGROUND_BLUE)
44 #define BACKGROUND_WHITE (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
45 #define BACKGROUND_BLACK 0
46 #define BACKGROUND_YELLOW (BACKGROUND_RED | BACKGROUND_GREEN)
47 #define BACKGROUND_CYAN (BACKGROUND_GREEN | BACKGROUND_BLUE)
48 #define BACKGROUND_MAGENTA (BACKGROUND_RED | BACKGROUND_BLUE)
51 #define FB_INTENSITY 2
54 #define F_INTENSITY_OFF1 21
55 #define F_INTENSITY_OFF2 22
56 #define B_INTENSITY_OFF 25
57 #define INVERSE_OFF 27
77 #define CURSOR_SIZE_SMALL 25
78 #define CURSOR_SIZE_MIDDLE 50
79 #define CURSOR_SIZE_LARGE 100
82 CONSOLE_SCREEN_BUFFER_INFO csbi;
90 struct captured_screen {
93 struct screen_info si;
96 static void get_screen_info(
uv_tty_t* tty_out,
struct screen_info* si) {
97 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &(si->csbi)));
98 si->width = si->csbi.dwSize.X;
99 si->height = si->csbi.srWindow.Bottom - si->csbi.srWindow.Top + 1;
100 si->length = si->width * si->height;
101 si->default_attr = si->csbi.wAttributes;
102 si->top = si->csbi.srWindow.Top;
105 static void set_cursor_position(
uv_tty_t* tty_out, COORD
pos) {
106 HANDLE
handle = tty_out->handle;
107 CONSOLE_SCREEN_BUFFER_INFO info;
110 pos.Y += info.srWindow.Top - 1;
114 static void get_cursor_position(
uv_tty_t* tty_out, COORD* cursor_position) {
115 HANDLE
handle = tty_out->handle;
116 CONSOLE_SCREEN_BUFFER_INFO info;
118 cursor_position->X = info.dwCursorPosition.X + 1;
119 cursor_position->Y = info.dwCursorPosition.Y - info.srWindow.Top + 1;
122 static void set_cursor_to_home(
uv_tty_t* tty_out) {
124 set_cursor_position(tty_out,
origin);
127 static CONSOLE_CURSOR_INFO get_cursor_info(
uv_tty_t* tty_out) {
128 HANDLE
handle = tty_out->handle;
129 CONSOLE_CURSOR_INFO info;
134 static void set_cursor_size(
uv_tty_t* tty_out, DWORD
size) {
135 CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out);
137 ASSERT(SetConsoleCursorInfo(tty_out->handle, &info));
140 static DWORD get_cursor_size(
uv_tty_t* tty_out) {
141 return get_cursor_info(tty_out).dwSize;
144 static void set_cursor_visibility(
uv_tty_t* tty_out,
BOOL visible) {
145 CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out);
146 info.bVisible = visible;
147 ASSERT(SetConsoleCursorInfo(tty_out->handle, &info));
151 return get_cursor_info(tty_out).bVisible;
154 static BOOL is_scrolling(
uv_tty_t* tty_out,
struct screen_info si) {
155 CONSOLE_SCREEN_BUFFER_INFO info;
156 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info));
157 return info.srWindow.Top != si.top;
160 static void write_console(
uv_tty_t* tty_out,
char* src) {
165 buf.len = strlen(
buf.base);
172 static void setup_screen(
uv_tty_t* tty_out) {
173 DWORD
length, number_of_written;
175 CONSOLE_SCREEN_BUFFER_INFO info;
176 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info));
177 length = info.dwSize.X * (info.srWindow.Bottom - info.srWindow.Top + 1);
179 origin.Y = info.srWindow.Top;
180 ASSERT(FillConsoleOutputCharacter(
181 tty_out->handle,
'.',
length,
origin, &number_of_written));
185 static void clear_screen(
uv_tty_t* tty_out,
struct screen_info* si) {
186 DWORD
length, number_of_written;
188 CONSOLE_SCREEN_BUFFER_INFO info;
189 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info));
190 length = (info.srWindow.Bottom - info.srWindow.Top + 1) * info.dwSize.X - 1;
192 origin.Y = info.srWindow.Top;
193 FillConsoleOutputCharacterA(
194 tty_out->handle,
' ',
length,
origin, &number_of_written);
196 FillConsoleOutputAttribute(
197 tty_out->handle, si->default_attr,
length,
origin, &number_of_written);
201 static void free_screen(
struct captured_screen*
cs) {
204 free(
cs->attributes);
205 cs->attributes = NULL;
208 static void capture_screen(
uv_tty_t* tty_out,
struct captured_screen*
cs) {
211 get_screen_info(tty_out, &(
cs->si));
213 origin.Y =
cs->si.csbi.srWindow.Top;
214 cs->text = malloc(
cs->si.length *
sizeof(*
cs->text));
216 cs->attributes = (WORD*) malloc(
cs->si.length *
sizeof(*
cs->attributes));
218 ASSERT(ReadConsoleOutputCharacter(
221 ASSERT(ReadConsoleOutputAttribute(
226 static void make_expect_screen_erase(
struct captured_screen*
cs,
227 COORD cursor_position,
229 BOOL entire_screen) {
233 start =
cs->text +
cs->si.width * (cursor_position.Y - 1);
237 end =
cs->text +
cs->si.length;
243 start += cursor_position.X - 1;
244 }
else if (dir == 1) {
251 }
else if (dir == 2) {
256 end =
cs->text +
cs->si.length;
271 static void make_expect_screen_write(
struct captured_screen*
cs,
272 COORD cursor_position,
276 start =
cs->text +
cs->si.width * (cursor_position.Y - 1) +
277 cursor_position.X - 1;
279 size_t remain_length =
cs->si.length - (
cs->text -
start);
284 static void make_expect_screen_set_attr(
struct captured_screen*
cs,
285 COORD cursor_position,
289 start =
cs->attributes +
cs->si.width * (cursor_position.Y - 1) +
290 cursor_position.X - 1;
291 size_t remain_length =
cs->si.length - (
cs->attributes -
start);
301 struct captured_screen* actual,
302 struct captured_screen* expect) {
307 ASSERT(actual->attributes);
309 ASSERT(expect->attributes);
310 if (actual->si.length != expect->si.length) {
313 if (actual->si.width != expect->si.width) {
316 if (actual->si.height != expect->si.height) {
319 while (current < actual->si.length) {
320 if (*(actual->text + current) != *(expect->text + current)) {
321 line = current / actual->si.width + 1;
322 col = current - actual->si.width * (
line - 1) + 1;
324 "line:%d col:%d expected character '%c' but found '%c'\n",
327 *(expect->text + current),
328 *(actual->text + current));
331 if (*(actual->attributes + current) != *(expect->attributes + current)) {
332 line = current / actual->si.width + 1;
333 col = current - actual->si.width * (
line - 1) + 1;
335 "line:%d col:%d expected attributes '%u' but found '%u'\n",
338 *(expect->attributes + current),
339 *(actual->attributes + current));
344 clear_screen(tty_out, &expect->si);
350 static void initialize_tty(
uv_tty_t* tty_out) {
358 handle = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
359 FILE_SHARE_READ | FILE_SHARE_WRITE,
361 CONSOLE_TEXTMODE_BUFFER,
372 static void terminate_tty(
uv_tty_t* tty_out) {
373 set_cursor_to_home(tty_out);
380 COORD cursor_pos, cursor_pos_old;
382 struct screen_info si;
386 initialize_tty(&tty_out);
387 get_screen_info(&tty_out, &si);
389 cursor_pos_old.X = si.width / 2;
390 cursor_pos_old.Y = si.height / 2;
391 set_cursor_position(&tty_out, cursor_pos_old);
395 write_console(&tty_out,
buffer);
396 get_cursor_position(&tty_out, &cursor_pos);
397 ASSERT(cursor_pos_old.Y - 1 == cursor_pos.Y);
398 ASSERT(cursor_pos_old.X == cursor_pos.X);
401 cursor_pos_old = cursor_pos;
402 snprintf(
buffer,
sizeof(
buffer),
"%s%dA", CSI, si.height / 4);
403 write_console(&tty_out,
buffer);
404 get_cursor_position(&tty_out, &cursor_pos);
405 ASSERT(cursor_pos_old.Y - si.height / 4 == cursor_pos.Y);
406 ASSERT(cursor_pos_old.X == cursor_pos.X);
409 cursor_pos_old.X = 1;
410 cursor_pos_old.Y = 1;
411 set_cursor_position(&tty_out, cursor_pos_old);
413 write_console(&tty_out,
buffer);
414 get_cursor_position(&tty_out, &cursor_pos);
415 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
416 ASSERT(cursor_pos_old.X == cursor_pos.X);
417 ASSERT(!is_scrolling(&tty_out, si));
419 terminate_tty(&tty_out);
431 COORD cursor_pos, cursor_pos_old;
433 struct screen_info si;
437 initialize_tty(&tty_out);
438 get_screen_info(&tty_out, &si);
440 cursor_pos_old.X = si.width / 2;
441 cursor_pos_old.Y = si.height / 2;
442 set_cursor_position(&tty_out, cursor_pos_old);
446 write_console(&tty_out,
buffer);
447 get_cursor_position(&tty_out, &cursor_pos);
448 ASSERT(cursor_pos_old.Y + 1 == cursor_pos.Y);
449 ASSERT(cursor_pos_old.X == cursor_pos.X);
452 cursor_pos_old = cursor_pos;
453 snprintf(
buffer,
sizeof(
buffer),
"%s%dB", CSI, si.height / 4);
454 write_console(&tty_out,
buffer);
455 get_cursor_position(&tty_out, &cursor_pos);
456 ASSERT(cursor_pos_old.Y + si.height / 4 == cursor_pos.Y);
457 ASSERT(cursor_pos_old.X == cursor_pos.X);
460 cursor_pos_old.X = si.width / 2;
461 cursor_pos_old.Y = si.height;
462 set_cursor_position(&tty_out, cursor_pos_old);
464 write_console(&tty_out,
buffer);
465 get_cursor_position(&tty_out, &cursor_pos);
466 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
467 ASSERT(cursor_pos_old.X == cursor_pos.X);
468 ASSERT(!is_scrolling(&tty_out, si));
470 terminate_tty(&tty_out);
482 COORD cursor_pos, cursor_pos_old;
484 struct screen_info si;
488 initialize_tty(&tty_out);
489 get_screen_info(&tty_out, &si);
491 cursor_pos_old.X = si.width / 2;
492 cursor_pos_old.Y = si.height / 2;
493 set_cursor_position(&tty_out, cursor_pos_old);
497 write_console(&tty_out,
buffer);
498 get_cursor_position(&tty_out, &cursor_pos);
499 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
500 ASSERT(cursor_pos_old.X + 1 == cursor_pos.X);
503 cursor_pos_old = cursor_pos;
504 snprintf(
buffer,
sizeof(
buffer),
"%s%dC", CSI, si.width / 4);
505 write_console(&tty_out,
buffer);
506 get_cursor_position(&tty_out, &cursor_pos);
507 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
508 ASSERT(cursor_pos_old.X + si.width / 4 == cursor_pos.X);
511 cursor_pos_old.X = si.width;
512 cursor_pos_old.Y = si.height / 2;
513 set_cursor_position(&tty_out, cursor_pos_old);
515 write_console(&tty_out,
buffer);
516 get_cursor_position(&tty_out, &cursor_pos);
517 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
518 ASSERT(cursor_pos_old.X == cursor_pos.X);
521 cursor_pos_old.X = si.width;
522 cursor_pos_old.Y = si.height;
523 set_cursor_position(&tty_out, cursor_pos_old);
525 write_console(&tty_out,
buffer);
526 get_cursor_position(&tty_out, &cursor_pos);
527 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
528 ASSERT(cursor_pos_old.X == cursor_pos.X);
529 ASSERT(!is_scrolling(&tty_out, si));
531 terminate_tty(&tty_out);
543 COORD cursor_pos, cursor_pos_old;
545 struct screen_info si;
549 initialize_tty(&tty_out);
550 get_screen_info(&tty_out, &si);
552 cursor_pos_old.X = si.width / 2;
553 cursor_pos_old.Y = si.height / 2;
554 set_cursor_position(&tty_out, cursor_pos_old);
558 write_console(&tty_out,
buffer);
559 get_cursor_position(&tty_out, &cursor_pos);
560 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
561 ASSERT(cursor_pos_old.X - 1 == cursor_pos.X);
564 cursor_pos_old = cursor_pos;
565 snprintf(
buffer,
sizeof(
buffer),
"%s%dD", CSI, si.width / 4);
566 write_console(&tty_out,
buffer);
567 get_cursor_position(&tty_out, &cursor_pos);
568 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
569 ASSERT(cursor_pos_old.X - si.width / 4 == cursor_pos.X);
572 cursor_pos_old.X = 1;
573 cursor_pos_old.Y = si.height / 2;
574 set_cursor_position(&tty_out, cursor_pos_old);
576 write_console(&tty_out,
buffer);
577 get_cursor_position(&tty_out, &cursor_pos);
578 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
579 ASSERT(cursor_pos_old.X == cursor_pos.X);
582 cursor_pos_old.X = 1;
583 cursor_pos_old.Y = 1;
584 set_cursor_position(&tty_out, cursor_pos_old);
586 write_console(&tty_out,
buffer);
587 get_cursor_position(&tty_out, &cursor_pos);
588 ASSERT(1 == cursor_pos.Y);
589 ASSERT(1 == cursor_pos.X);
590 ASSERT(!is_scrolling(&tty_out, si));
592 terminate_tty(&tty_out);
604 COORD cursor_pos, cursor_pos_old;
606 struct screen_info si;
610 initialize_tty(&tty_out);
611 get_screen_info(&tty_out, &si);
613 cursor_pos_old.X = si.width / 2;
614 cursor_pos_old.Y = si.height / 2;
615 set_cursor_position(&tty_out, cursor_pos_old);
619 write_console(&tty_out,
buffer);
620 get_cursor_position(&tty_out, &cursor_pos);
621 ASSERT(cursor_pos_old.Y + 1 == cursor_pos.Y);
622 ASSERT(1 == cursor_pos.X);
625 cursor_pos_old = cursor_pos;
626 snprintf(
buffer,
sizeof(
buffer),
"%s%dE", CSI, si.height / 4);
627 write_console(&tty_out,
buffer);
628 get_cursor_position(&tty_out, &cursor_pos);
629 ASSERT(cursor_pos_old.Y + si.height / 4 == cursor_pos.Y);
630 ASSERT(1 == cursor_pos.X);
633 cursor_pos_old.X = si.width / 2;
634 cursor_pos_old.Y = si.height;
635 set_cursor_position(&tty_out, cursor_pos_old);
637 write_console(&tty_out,
buffer);
638 get_cursor_position(&tty_out, &cursor_pos);
639 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
640 ASSERT(1 == cursor_pos.X);
641 ASSERT(!is_scrolling(&tty_out, si));
643 terminate_tty(&tty_out);
655 COORD cursor_pos, cursor_pos_old;
657 struct screen_info si;
661 initialize_tty(&tty_out);
662 get_screen_info(&tty_out, &si);
664 cursor_pos_old.X = si.width / 2;
665 cursor_pos_old.Y = si.height / 2;
666 set_cursor_position(&tty_out, cursor_pos_old);
670 write_console(&tty_out,
buffer);
671 get_cursor_position(&tty_out, &cursor_pos);
672 ASSERT(cursor_pos_old.Y - 1 == cursor_pos.Y);
673 ASSERT(1 == cursor_pos.X);
676 cursor_pos_old = cursor_pos;
677 snprintf(
buffer,
sizeof(
buffer),
"%s%dF", CSI, si.height / 4);
678 write_console(&tty_out,
buffer);
679 get_cursor_position(&tty_out, &cursor_pos);
680 ASSERT(cursor_pos_old.Y - si.height / 4 == cursor_pos.Y);
681 ASSERT(1 == cursor_pos.X);
684 cursor_pos_old.X = 1;
685 cursor_pos_old.Y = 1;
686 set_cursor_position(&tty_out, cursor_pos_old);
688 write_console(&tty_out,
buffer);
689 get_cursor_position(&tty_out, &cursor_pos);
690 ASSERT(1 == cursor_pos.Y);
691 ASSERT(1 == cursor_pos.X);
692 ASSERT(!is_scrolling(&tty_out, si));
694 terminate_tty(&tty_out);
703 TEST_IMPL(tty_cursor_horizontal_move_absolute) {
706 COORD cursor_pos, cursor_pos_old;
708 struct screen_info si;
712 initialize_tty(&tty_out);
713 get_screen_info(&tty_out, &si);
715 cursor_pos_old.X = si.width / 2;
716 cursor_pos_old.Y = si.height / 2;
717 set_cursor_position(&tty_out, cursor_pos_old);
721 write_console(&tty_out,
buffer);
722 get_cursor_position(&tty_out, &cursor_pos);
723 ASSERT(1 == cursor_pos.X);
724 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
727 snprintf(
buffer,
sizeof(
buffer),
"%s%dG", CSI, si.width / 4);
728 write_console(&tty_out,
buffer);
729 get_cursor_position(&tty_out, &cursor_pos);
730 ASSERT(si.width / 4 == cursor_pos.X);
731 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
734 snprintf(
buffer,
sizeof(
buffer),
"%s%dG", CSI, si.width + 1);
735 write_console(&tty_out,
buffer);
736 get_cursor_position(&tty_out, &cursor_pos);
737 ASSERT(si.width == cursor_pos.X);
738 ASSERT(cursor_pos_old.Y == cursor_pos.Y);
740 terminate_tty(&tty_out);
754 struct screen_info si;
758 initialize_tty(&tty_out);
759 get_screen_info(&tty_out, &si);
761 cursor_pos.X = si.width / 2;
762 cursor_pos.Y = si.height / 2;
763 set_cursor_position(&tty_out, cursor_pos);
767 write_console(&tty_out,
buffer);
768 get_cursor_position(&tty_out, &cursor_pos);
769 ASSERT(1 == cursor_pos.X);
770 ASSERT(1 == cursor_pos.Y);
774 buffer,
sizeof(
buffer),
"%s%d;%df", CSI, si.height / 2, si.width / 2);
775 write_console(&tty_out,
buffer);
776 get_cursor_position(&tty_out, &cursor_pos);
777 ASSERT(si.width / 2 == cursor_pos.X);
778 ASSERT(si.height / 2 == cursor_pos.Y);
782 buffer,
sizeof(
buffer),
"%s%d;%df", CSI, si.height / 2, si.width + 1);
783 write_console(&tty_out,
buffer);
784 get_cursor_position(&tty_out, &cursor_pos);
785 ASSERT(si.width == cursor_pos.X);
786 ASSERT(si.height / 2 == cursor_pos.Y);
789 buffer,
sizeof(
buffer),
"%s%d;%df", CSI, si.height + 1, si.width / 2);
790 write_console(&tty_out,
buffer);
791 get_cursor_position(&tty_out, &cursor_pos);
792 ASSERT(si.width / 2 == cursor_pos.X);
793 ASSERT(si.height == cursor_pos.Y);
794 ASSERT(!is_scrolling(&tty_out, si));
796 terminate_tty(&tty_out);
809 BOOL saved_cursor_visibility;
813 initialize_tty(&tty_out);
815 saved_cursor_visibility = get_cursor_visibility(&tty_out);
818 set_cursor_visibility(&tty_out,
TRUE);
820 write_console(&tty_out,
buffer);
821 ASSERT(!get_cursor_visibility(&tty_out));
824 set_cursor_visibility(&tty_out,
FALSE);
826 write_console(&tty_out,
buffer);
827 ASSERT(get_cursor_visibility(&tty_out));
829 set_cursor_visibility(&tty_out, saved_cursor_visibility);
830 terminate_tty(&tty_out);
845 struct captured_screen actual = {0}, expect = {0};
849 initialize_tty(&tty_out);
853 setup_screen(&tty_out);
854 capture_screen(&tty_out, &expect);
855 cursor_pos.X = expect.si.width / 2;
856 cursor_pos.Y = expect.si.height / 2;
857 make_expect_screen_erase(&expect, cursor_pos, dir,
TRUE);
859 set_cursor_position(&tty_out, cursor_pos);
861 write_console(&tty_out,
buffer);
862 capture_screen(&tty_out, &actual);
864 ASSERT(compare_screen(&tty_out, &actual, &expect));
867 setup_screen(&tty_out);
868 capture_screen(&tty_out, &expect);
869 make_expect_screen_erase(&expect, cursor_pos, dir,
TRUE);
871 set_cursor_position(&tty_out, cursor_pos);
873 write_console(&tty_out,
buffer);
874 capture_screen(&tty_out, &actual);
876 ASSERT(compare_screen(&tty_out, &actual, &expect));
880 setup_screen(&tty_out);
881 capture_screen(&tty_out, &expect);
882 make_expect_screen_erase(&expect, cursor_pos, dir,
TRUE);
884 set_cursor_position(&tty_out, cursor_pos);
886 write_console(&tty_out,
buffer);
887 capture_screen(&tty_out, &actual);
889 ASSERT(compare_screen(&tty_out, &actual, &expect));
893 setup_screen(&tty_out);
894 capture_screen(&tty_out, &expect);
895 make_expect_screen_erase(&expect, cursor_pos, dir,
TRUE);
897 set_cursor_position(&tty_out, cursor_pos);
899 write_console(&tty_out,
buffer);
900 capture_screen(&tty_out, &actual);
902 ASSERT(compare_screen(&tty_out, &actual, &expect));
904 terminate_tty(&tty_out);
919 struct captured_screen actual = {0}, expect = {0};
923 initialize_tty(&tty_out);
927 setup_screen(&tty_out);
928 capture_screen(&tty_out, &expect);
929 cursor_pos.X = expect.si.width / 2;
930 cursor_pos.Y = expect.si.height / 2;
931 make_expect_screen_erase(&expect, cursor_pos, dir,
FALSE);
933 set_cursor_position(&tty_out, cursor_pos);
935 write_console(&tty_out,
buffer);
936 capture_screen(&tty_out, &actual);
938 ASSERT(compare_screen(&tty_out, &actual, &expect));
941 setup_screen(&tty_out);
942 capture_screen(&tty_out, &expect);
943 make_expect_screen_erase(&expect, cursor_pos, dir,
FALSE);
945 set_cursor_position(&tty_out, cursor_pos);
947 write_console(&tty_out,
buffer);
948 capture_screen(&tty_out, &actual);
950 ASSERT(compare_screen(&tty_out, &actual, &expect));
954 setup_screen(&tty_out);
955 capture_screen(&tty_out, &expect);
956 make_expect_screen_erase(&expect, cursor_pos, dir,
FALSE);
958 set_cursor_position(&tty_out, cursor_pos);
960 write_console(&tty_out,
buffer);
961 capture_screen(&tty_out, &actual);
963 ASSERT(compare_screen(&tty_out, &actual, &expect));
967 setup_screen(&tty_out);
968 capture_screen(&tty_out, &expect);
969 make_expect_screen_erase(&expect, cursor_pos, dir,
FALSE);
971 set_cursor_position(&tty_out, cursor_pos);
973 write_console(&tty_out,
buffer);
974 capture_screen(&tty_out, &actual);
976 ASSERT(compare_screen(&tty_out, &actual, &expect));
978 terminate_tty(&tty_out);
990 DWORD saved_cursor_size;
995 initialize_tty(&tty_out);
997 saved_cursor_size = get_cursor_size(&tty_out);
1000 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE);
1002 write_console(&tty_out,
buffer);
1006 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE);
1008 write_console(&tty_out,
buffer);
1010 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE);
1012 write_console(&tty_out,
buffer);
1016 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE);
1018 write_console(&tty_out,
buffer);
1020 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE);
1022 write_console(&tty_out,
buffer);
1026 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE);
1028 write_console(&tty_out,
buffer);
1029 ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_MIDDLE);
1033 write_console(&tty_out,
buffer);
1034 ASSERT(get_cursor_size(&tty_out) == saved_cursor_size);
1036 terminate_tty(&tty_out);
1050 struct captured_screen actual = {0}, expect = {0};
1052 WORD fg_attrs[9][2] = {{F_BLACK, FOREGROUND_BLACK},
1053 {F_RED, FOREGROUND_RED},
1054 {F_GREEN, FOREGROUND_GREEN},
1055 {F_YELLOW, FOREGROUND_YELLOW},
1056 {F_BLUE, FOREGROUND_BLUE},
1057 {F_MAGENTA, FOREGROUND_MAGENTA},
1058 {F_CYAN, FOREGROUND_CYAN},
1059 {F_WHITE, FOREGROUND_WHITE},
1061 WORD bg_attrs[9][2] = {{B_DEFAULT, 0},
1062 {B_BLACK, BACKGROUND_BLACK},
1063 {B_RED, BACKGROUND_RED},
1064 {B_GREEN, BACKGROUND_GREEN},
1065 {B_YELLOW, BACKGROUND_YELLOW},
1066 {B_BLUE, BACKGROUND_BLUE},
1067 {B_MAGENTA, BACKGROUND_MAGENTA},
1068 {B_CYAN, BACKGROUND_CYAN},
1069 {B_WHITE, BACKGROUND_WHITE}};
1075 initialize_tty(&tty_out);
1077 capture_screen(&tty_out, &expect);
1078 fg_attrs[8][1] = expect.si.default_attr & FOREGROUND_WHITE;
1079 bg_attrs[0][1] = expect.si.default_attr & BACKGROUND_WHITE;
1084 capture_screen(&tty_out, &expect);
1085 cursor_pos.X = expect.si.width / 2;
1086 cursor_pos.Y = expect.si.height / 2;
1087 attr = (expect.si.default_attr & ~FOREGROUND_WHITE) | fg_attrs[
i][1];
1088 make_expect_screen_write(&expect, cursor_pos, HELLO);
1089 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO),
attr);
1091 set_cursor_position(&tty_out, cursor_pos);
1093 buffer,
sizeof(
buffer),
"%s%dm%s%sm", CSI, fg_attrs[
i][0], HELLO, CSI);
1094 write_console(&tty_out,
buffer);
1095 capture_screen(&tty_out, &actual);
1097 ASSERT(compare_screen(&tty_out, &actual, &expect));
1103 capture_screen(&tty_out, &expect);
1104 cursor_pos.X = expect.si.width / 2;
1105 cursor_pos.Y = expect.si.height / 2;
1106 attr = (expect.si.default_attr & ~BACKGROUND_WHITE) | bg_attrs[
i][1];
1107 make_expect_screen_write(&expect, cursor_pos, HELLO);
1108 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO),
attr);
1110 set_cursor_position(&tty_out, cursor_pos);
1112 buffer,
sizeof(
buffer),
"%s%dm%s%sm", CSI, bg_attrs[
i][0], HELLO, CSI);
1113 write_console(&tty_out,
buffer);
1114 capture_screen(&tty_out, &actual);
1116 ASSERT(compare_screen(&tty_out, &actual, &expect));
1123 capture_screen(&tty_out, &expect);
1124 cursor_pos.X = expect.si.width / 2;
1125 cursor_pos.Y = expect.si.height / 2;
1126 attr = expect.si.default_attr & ~FOREGROUND_WHITE & ~BACKGROUND_WHITE;
1127 attr |= fg_attrs[
i][1] | bg_attrs[
i][1];
1128 make_expect_screen_write(&expect, cursor_pos, HELLO);
1129 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO),
attr);
1131 set_cursor_position(&tty_out, cursor_pos);
1140 write_console(&tty_out,
buffer);
1141 capture_screen(&tty_out, &actual);
1143 ASSERT(compare_screen(&tty_out, &actual, &expect));
1147 capture_screen(&tty_out, &expect);
1148 cursor_pos.X = expect.si.width / 2;
1149 cursor_pos.Y = expect.si.height / 2;
1150 set_cursor_position(&tty_out, cursor_pos);
1151 attr = expect.si.default_attr;
1152 attr |= FOREGROUND_INTENSITY;
1153 make_expect_screen_write(&expect, cursor_pos, HELLO);
1154 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO),
attr);
1155 cursor_pos.X += strlen(HELLO);
1156 make_expect_screen_write(&expect, cursor_pos, HELLO);
1157 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO),
attr);
1161 "%s%dm%s%s%dm%s%dm%s%s%dm",
1172 write_console(&tty_out,
buffer);
1173 capture_screen(&tty_out, &actual);
1175 ASSERT(compare_screen(&tty_out, &actual, &expect));
1178 capture_screen(&tty_out, &expect);
1179 cursor_pos.X = expect.si.width / 2;
1180 cursor_pos.Y = expect.si.height / 2;
1181 set_cursor_position(&tty_out, cursor_pos);
1182 attr = expect.si.default_attr;
1183 attr |= BACKGROUND_INTENSITY;
1184 make_expect_screen_write(&expect, cursor_pos, HELLO);
1185 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO),
attr);
1195 write_console(&tty_out,
buffer);
1196 capture_screen(&tty_out, &actual);
1198 ASSERT(compare_screen(&tty_out, &actual, &expect));
1201 capture_screen(&tty_out, &expect);
1202 cursor_pos.X = expect.si.width / 2;
1203 cursor_pos.Y = expect.si.height / 2;
1204 set_cursor_position(&tty_out, cursor_pos);
1205 attr = expect.si.default_attr;
1206 fg =
attr & FOREGROUND_WHITE;
1207 bg =
attr & BACKGROUND_WHITE;
1208 attr &= (~FOREGROUND_WHITE & ~BACKGROUND_WHITE);
1212 make_expect_screen_write(&expect, cursor_pos, HELLO);
1213 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO),
attr);
1214 cursor_pos.X += strlen(HELLO);
1215 make_expect_screen_write(&expect, cursor_pos, HELLO);
1226 write_console(&tty_out,
buffer);
1227 capture_screen(&tty_out, &actual);
1229 ASSERT(compare_screen(&tty_out, &actual, &expect));
1231 terminate_tty(&tty_out);
1240 TEST_IMPL(tty_save_restore_cursor_position) {
1243 COORD cursor_pos, cursor_pos_old;
1245 struct screen_info si;
1249 initialize_tty(&tty_out);
1250 get_screen_info(&tty_out, &si);
1252 cursor_pos_old.X = si.width / 2;
1253 cursor_pos_old.Y = si.height / 2;
1254 set_cursor_position(&tty_out, cursor_pos_old);
1258 write_console(&tty_out,
buffer);
1260 cursor_pos.X = si.width / 4;
1261 cursor_pos.Y = si.height / 4;
1262 set_cursor_position(&tty_out, cursor_pos);
1266 write_console(&tty_out,
buffer);
1267 get_cursor_position(&tty_out, &cursor_pos);
1268 ASSERT(cursor_pos.X == cursor_pos_old.X);
1269 ASSERT(cursor_pos.Y == cursor_pos_old.Y);
1271 cursor_pos_old.X = si.width / 2;
1272 cursor_pos_old.Y = si.height / 2;
1273 set_cursor_position(&tty_out, cursor_pos_old);
1277 write_console(&tty_out,
buffer);
1279 cursor_pos.X = si.width / 4;
1280 cursor_pos.Y = si.height / 4;
1281 set_cursor_position(&tty_out, cursor_pos);
1285 write_console(&tty_out,
buffer);
1286 get_cursor_position(&tty_out, &cursor_pos);
1287 ASSERT(cursor_pos.X == cursor_pos_old.X);
1288 ASSERT(cursor_pos.Y == cursor_pos_old.Y);
1290 terminate_tty(&tty_out);
1303 struct captured_screen actual = {0}, expect = {0};
1305 DWORD saved_cursor_size;
1306 BOOL saved_cursor_visibility;
1310 initialize_tty(&tty_out);
1312 capture_screen(&tty_out, &expect);
1313 setup_screen(&tty_out);
1314 cursor_pos.X = expect.si.width;
1315 cursor_pos.Y = expect.si.height;
1316 set_cursor_position(&tty_out, cursor_pos);
1317 snprintf(
buffer,
sizeof(
buffer),
"%s%d;%dm%s", CSI, F_CYAN, B_YELLOW, HELLO);
1318 saved_cursor_size = get_cursor_size(&tty_out);
1319 set_cursor_size(&tty_out,
1322 saved_cursor_visibility = get_cursor_visibility(&tty_out);
1323 set_cursor_visibility(&tty_out, saved_cursor_visibility ?
FALSE :
TRUE);
1324 write_console(&tty_out,
buffer);
1326 write_console(&tty_out,
buffer);
1327 capture_screen(&tty_out, &actual);
1328 ASSERT(compare_screen(&tty_out, &actual, &expect));
1329 ASSERT(get_cursor_size(&tty_out) == saved_cursor_size);
1330 ASSERT(get_cursor_visibility(&tty_out) == saved_cursor_visibility);
1331 ASSERT(actual.si.csbi.srWindow.Top == 0);
1333 terminate_tty(&tty_out);
1342 TEST_IMPL(tty_escape_sequence_processing) {
1345 COORD cursor_pos, cursor_pos_old;
1346 DWORD saved_cursor_size;
1348 struct captured_screen actual = {0}, expect = {0};
1353 initialize_tty(&tty_out);
1358 set_cursor_position(&tty_out, cursor_pos);
1359 capture_screen(&tty_out, &expect);
1360 make_expect_screen_write(&expect, cursor_pos, HELLO);
1361 cursor_pos.X += strlen(HELLO);
1362 make_expect_screen_write(&expect, cursor_pos, HELLO);
1363 snprintf(
buffer,
sizeof(
buffer),
"%s@%s%s~%s", CSI, HELLO, CSI, HELLO);
1364 write_console(&tty_out,
buffer);
1365 capture_screen(&tty_out, &actual);
1366 ASSERT(compare_screen(&tty_out, &actual, &expect));
1371 set_cursor_position(&tty_out, cursor_pos);
1372 capture_screen(&tty_out, &expect);
1373 make_expect_screen_write(&expect, cursor_pos, HELLO);
1374 cursor_pos.X += strlen(HELLO);
1375 make_expect_screen_write(&expect, cursor_pos, HELLO);
1376 snprintf(
buffer,
sizeof(
buffer),
"\xC2\x9B@%s\xC2\x9B~%s", HELLO, HELLO);
1377 write_console(&tty_out,
buffer);
1378 capture_screen(&tty_out, &actual);
1379 ASSERT(compare_screen(&tty_out, &actual, &expect));
1384 set_cursor_position(&tty_out, cursor_pos);
1385 capture_screen(&tty_out, &expect);
1386 make_expect_screen_write(&expect, cursor_pos, HELLO);
1387 cursor_pos.X += strlen(HELLO);
1388 make_expect_screen_write(&expect, cursor_pos, HELLO);
1389 snprintf(
buffer,
sizeof(
buffer),
"%s @%s%s/~%s", CSI, HELLO, CSI, HELLO);
1390 write_console(&tty_out,
buffer);
1391 capture_screen(&tty_out, &actual);
1392 ASSERT(compare_screen(&tty_out, &actual, &expect));
1397 set_cursor_position(&tty_out, cursor_pos);
1398 capture_screen(&tty_out, &expect);
1401 "%s0@%s%s>~%s%s?~%s",
1408 make_expect_screen_write(&expect, cursor_pos, HELLO);
1409 cursor_pos.X += strlen(HELLO);
1410 make_expect_screen_write(&expect, cursor_pos, HELLO);
1411 cursor_pos.X += strlen(HELLO);
1412 make_expect_screen_write(&expect, cursor_pos, HELLO);
1413 write_console(&tty_out,
buffer);
1414 capture_screen(&tty_out, &actual);
1415 ASSERT(compare_screen(&tty_out, &actual, &expect));
1420 set_cursor_position(&tty_out, cursor_pos);
1421 capture_screen(&tty_out, &expect);
1422 make_expect_screen_write(&expect, cursor_pos, HELLO);
1423 cursor_pos.X += strlen(HELLO);
1424 make_expect_screen_write(&expect, cursor_pos, HELLO);
1425 snprintf(
buffer,
sizeof(
buffer),
"%s @%s%s/~%s", CSI, HELLO, CSI, HELLO);
1426 write_console(&tty_out,
buffer);
1427 capture_screen(&tty_out, &actual);
1428 ASSERT(compare_screen(&tty_out, &actual, &expect));
1434 set_cursor_position(&tty_out, cursor_pos);
1435 capture_screen(&tty_out, &expect);
1436 make_expect_screen_write(&expect, cursor_pos, HELLO);
1437 snprintf(
buffer,
sizeof(
buffer),
"%s]0;%s%s%s", ESC, HELLO, BEL, HELLO);
1438 write_console(&tty_out,
buffer);
1439 capture_screen(&tty_out, &actual);
1440 ASSERT(compare_screen(&tty_out, &actual, &expect));
1444 set_cursor_position(&tty_out, cursor_pos);
1445 capture_screen(&tty_out, &expect);
1446 make_expect_screen_write(&expect, cursor_pos, HELLO);
1447 snprintf(
buffer,
sizeof(
buffer),
"%sP$m%s%s", ESC, ST, HELLO);
1448 write_console(&tty_out,
buffer);
1449 capture_screen(&tty_out, &actual);
1450 ASSERT(compare_screen(&tty_out, &actual, &expect));
1454 set_cursor_position(&tty_out, cursor_pos);
1455 capture_screen(&tty_out, &expect);
1456 make_expect_screen_write(&expect, cursor_pos, HELLO);
1459 "%s^\"%s\\\"%s\"%s%s",
1465 write_console(&tty_out,
buffer);
1466 capture_screen(&tty_out, &actual);
1467 ASSERT(compare_screen(&tty_out, &actual, &expect));
1471 set_cursor_position(&tty_out, cursor_pos);
1472 capture_screen(&tty_out, &expect);
1473 make_expect_screen_write(&expect, cursor_pos, HELLO);
1476 "%s_\"%s%s%s\"%s%s",
1483 write_console(&tty_out,
buffer);
1484 capture_screen(&tty_out, &actual);
1485 ASSERT(compare_screen(&tty_out, &actual, &expect));
1490 set_cursor_position(&tty_out, cursor_pos);
1491 capture_screen(&tty_out, &expect);
1492 make_expect_screen_write(&expect, cursor_pos, HELLO);
1493 cursor_pos.X += strlen(HELLO);
1494 make_expect_screen_write(&expect, cursor_pos, HELLO);
1504 write_console(&tty_out,
buffer);
1505 capture_screen(&tty_out, &actual);
1506 ASSERT(compare_screen(&tty_out, &actual, &expect));
1509 set_cursor_to_home(&tty_out);
1511 write_console(&tty_out,
buffer);
1512 get_cursor_position(&tty_out, &cursor_pos);
1513 ASSERT(cursor_pos.X == 1);
1514 ASSERT(cursor_pos.Y == 1);
1519 set_cursor_position(&tty_out, cursor_pos);
1520 capture_screen(&tty_out, &expect);
1521 make_expect_screen_write(&expect, cursor_pos, HELLO);
1524 "%s%d;%d;%d;%d;%dm%s%sm",
1533 write_console(&tty_out,
buffer);
1534 capture_screen(&tty_out, &actual);
1535 ASSERT(compare_screen(&tty_out, &actual, &expect));
1538 set_cursor_to_home(&tty_out);
1543 expect.si.height / 2,
1544 expect.si.width / 2);
1545 write_console(&tty_out,
buffer);
1546 get_cursor_position(&tty_out, &cursor_pos);
1547 ASSERT(cursor_pos.X == 1);
1548 ASSERT(cursor_pos.Y == 1);
1551 saved_cursor_size = get_cursor_size(&tty_out);
1552 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE);
1554 write_console(&tty_out,
buffer);
1555 ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_MIDDLE);
1557 write_console(&tty_out,
buffer);
1558 ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_MIDDLE);
1559 set_cursor_size(&tty_out, saved_cursor_size);
1563 write_console(&tty_out,
buffer);
1564 ASSERT(get_cursor_visibility(&tty_out));
1566 write_console(&tty_out,
buffer);
1567 ASSERT(get_cursor_visibility(&tty_out));
1568 cursor_pos_old.X = expect.si.width / 2;
1569 cursor_pos_old.Y = expect.si.height / 2;
1570 set_cursor_position(&tty_out, cursor_pos_old);
1575 expect.si.height / 4,
1576 expect.si.width / 4);
1577 write_console(&tty_out,
buffer);
1578 get_cursor_position(&tty_out, &cursor_pos);
1579 ASSERT(cursor_pos.X = cursor_pos_old.X);
1580 ASSERT(cursor_pos.Y = cursor_pos_old.Y);
1581 set_cursor_to_home(&tty_out);
1585 write_console(&tty_out,
buffer);
1586 ASSERT(get_cursor_visibility(&tty_out));
1590 setup_screen(&tty_out);
1591 capture_screen(&tty_out, &expect);
1592 set_cursor_position(&tty_out, cursor_pos);
1594 write_console(&tty_out,
buffer);
1595 capture_screen(&tty_out, &actual);
1596 ASSERT(compare_screen(&tty_out, &actual, &expect));
1599 cursor_pos.X = expect.si.width / 2;
1600 cursor_pos.Y = expect.si.height / 2;
1601 set_cursor_position(&tty_out, cursor_pos);
1602 capture_screen(&tty_out, &expect);
1603 make_expect_screen_write(&expect, cursor_pos, HELLO);
1605 write_console(&tty_out,
buffer);
1606 capture_screen(&tty_out, &actual);
1607 ASSERT(compare_screen(&tty_out, &actual, &expect));
1609 terminate_tty(&tty_out);