1e66f31c5Sopenharmony_ci/* Copyright libuv project contributors. All rights reserved. 2e66f31c5Sopenharmony_ci * 3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the 6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions: 9e66f31c5Sopenharmony_ci * 10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software. 12e66f31c5Sopenharmony_ci * 13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19e66f31c5Sopenharmony_ci * IN THE SOFTWARE. 20e66f31c5Sopenharmony_ci */ 21e66f31c5Sopenharmony_ci 22e66f31c5Sopenharmony_ci#ifdef _WIN32 23e66f31c5Sopenharmony_ci 24e66f31c5Sopenharmony_ci#include "task.h" 25e66f31c5Sopenharmony_ci#include "uv.h" 26e66f31c5Sopenharmony_ci 27e66f31c5Sopenharmony_ci#include <io.h> 28e66f31c5Sopenharmony_ci#include <windows.h> 29e66f31c5Sopenharmony_ci 30e66f31c5Sopenharmony_ci#include <errno.h> 31e66f31c5Sopenharmony_ci#include <string.h> 32e66f31c5Sopenharmony_ci 33e66f31c5Sopenharmony_ci#define ESC "\033" 34e66f31c5Sopenharmony_ci#define CSI ESC "[" 35e66f31c5Sopenharmony_ci#define ST ESC "\\" 36e66f31c5Sopenharmony_ci#define BEL "\x07" 37e66f31c5Sopenharmony_ci#define HELLO "Hello" 38e66f31c5Sopenharmony_ci 39e66f31c5Sopenharmony_ci#define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) 40e66f31c5Sopenharmony_ci#define FOREGROUND_BLACK 0 41e66f31c5Sopenharmony_ci#define FOREGROUND_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN) 42e66f31c5Sopenharmony_ci#define FOREGROUND_CYAN (FOREGROUND_GREEN | FOREGROUND_BLUE) 43e66f31c5Sopenharmony_ci#define FOREGROUND_MAGENTA (FOREGROUND_RED | FOREGROUND_BLUE) 44e66f31c5Sopenharmony_ci#define BACKGROUND_WHITE (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE) 45e66f31c5Sopenharmony_ci#define BACKGROUND_BLACK 0 46e66f31c5Sopenharmony_ci#define BACKGROUND_YELLOW (BACKGROUND_RED | BACKGROUND_GREEN) 47e66f31c5Sopenharmony_ci#define BACKGROUND_CYAN (BACKGROUND_GREEN | BACKGROUND_BLUE) 48e66f31c5Sopenharmony_ci#define BACKGROUND_MAGENTA (BACKGROUND_RED | BACKGROUND_BLUE) 49e66f31c5Sopenharmony_ci 50e66f31c5Sopenharmony_ci#define F_INTENSITY 1 51e66f31c5Sopenharmony_ci#define FB_INTENSITY 2 52e66f31c5Sopenharmony_ci#define B_INTENSITY 5 53e66f31c5Sopenharmony_ci#define INVERSE 7 54e66f31c5Sopenharmony_ci#define F_INTENSITY_OFF1 21 55e66f31c5Sopenharmony_ci#define F_INTENSITY_OFF2 22 56e66f31c5Sopenharmony_ci#define B_INTENSITY_OFF 25 57e66f31c5Sopenharmony_ci#define INVERSE_OFF 27 58e66f31c5Sopenharmony_ci#define F_BLACK 30 59e66f31c5Sopenharmony_ci#define F_RED 31 60e66f31c5Sopenharmony_ci#define F_GREEN 32 61e66f31c5Sopenharmony_ci#define F_YELLOW 33 62e66f31c5Sopenharmony_ci#define F_BLUE 34 63e66f31c5Sopenharmony_ci#define F_MAGENTA 35 64e66f31c5Sopenharmony_ci#define F_CYAN 36 65e66f31c5Sopenharmony_ci#define F_WHITE 37 66e66f31c5Sopenharmony_ci#define F_DEFAULT 39 67e66f31c5Sopenharmony_ci#define B_BLACK 40 68e66f31c5Sopenharmony_ci#define B_RED 41 69e66f31c5Sopenharmony_ci#define B_GREEN 42 70e66f31c5Sopenharmony_ci#define B_YELLOW 43 71e66f31c5Sopenharmony_ci#define B_BLUE 44 72e66f31c5Sopenharmony_ci#define B_MAGENTA 45 73e66f31c5Sopenharmony_ci#define B_CYAN 46 74e66f31c5Sopenharmony_ci#define B_WHITE 47 75e66f31c5Sopenharmony_ci#define B_DEFAULT 49 76e66f31c5Sopenharmony_ci 77e66f31c5Sopenharmony_ci#define CURSOR_SIZE_SMALL 25 78e66f31c5Sopenharmony_ci#define CURSOR_SIZE_MIDDLE 50 79e66f31c5Sopenharmony_ci#define CURSOR_SIZE_LARGE 100 80e66f31c5Sopenharmony_ci 81e66f31c5Sopenharmony_cistruct screen_info { 82e66f31c5Sopenharmony_ci CONSOLE_SCREEN_BUFFER_INFO csbi; 83e66f31c5Sopenharmony_ci int top; 84e66f31c5Sopenharmony_ci int width; 85e66f31c5Sopenharmony_ci int height; 86e66f31c5Sopenharmony_ci int length; 87e66f31c5Sopenharmony_ci WORD default_attr; 88e66f31c5Sopenharmony_ci}; 89e66f31c5Sopenharmony_ci 90e66f31c5Sopenharmony_cistruct captured_screen { 91e66f31c5Sopenharmony_ci char* text; 92e66f31c5Sopenharmony_ci WORD* attributes; 93e66f31c5Sopenharmony_ci struct screen_info si; 94e66f31c5Sopenharmony_ci}; 95e66f31c5Sopenharmony_ci 96e66f31c5Sopenharmony_cistatic void get_screen_info(uv_tty_t* tty_out, struct screen_info* si) { 97e66f31c5Sopenharmony_ci ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &(si->csbi))); 98e66f31c5Sopenharmony_ci si->width = si->csbi.dwSize.X; 99e66f31c5Sopenharmony_ci si->height = si->csbi.srWindow.Bottom - si->csbi.srWindow.Top + 1; 100e66f31c5Sopenharmony_ci si->length = si->width * si->height; 101e66f31c5Sopenharmony_ci si->default_attr = si->csbi.wAttributes; 102e66f31c5Sopenharmony_ci si->top = si->csbi.srWindow.Top; 103e66f31c5Sopenharmony_ci} 104e66f31c5Sopenharmony_ci 105e66f31c5Sopenharmony_cistatic void set_cursor_position(uv_tty_t* tty_out, COORD pos) { 106e66f31c5Sopenharmony_ci HANDLE handle = tty_out->handle; 107e66f31c5Sopenharmony_ci CONSOLE_SCREEN_BUFFER_INFO info; 108e66f31c5Sopenharmony_ci ASSERT(GetConsoleScreenBufferInfo(handle, &info)); 109e66f31c5Sopenharmony_ci pos.X -= 1; 110e66f31c5Sopenharmony_ci pos.Y += info.srWindow.Top - 1; 111e66f31c5Sopenharmony_ci ASSERT(SetConsoleCursorPosition(handle, pos)); 112e66f31c5Sopenharmony_ci} 113e66f31c5Sopenharmony_ci 114e66f31c5Sopenharmony_cistatic void get_cursor_position(uv_tty_t* tty_out, COORD* cursor_position) { 115e66f31c5Sopenharmony_ci HANDLE handle = tty_out->handle; 116e66f31c5Sopenharmony_ci CONSOLE_SCREEN_BUFFER_INFO info; 117e66f31c5Sopenharmony_ci ASSERT(GetConsoleScreenBufferInfo(handle, &info)); 118e66f31c5Sopenharmony_ci cursor_position->X = info.dwCursorPosition.X + 1; 119e66f31c5Sopenharmony_ci cursor_position->Y = info.dwCursorPosition.Y - info.srWindow.Top + 1; 120e66f31c5Sopenharmony_ci} 121e66f31c5Sopenharmony_ci 122e66f31c5Sopenharmony_cistatic void set_cursor_to_home(uv_tty_t* tty_out) { 123e66f31c5Sopenharmony_ci COORD origin = {1, 1}; 124e66f31c5Sopenharmony_ci set_cursor_position(tty_out, origin); 125e66f31c5Sopenharmony_ci} 126e66f31c5Sopenharmony_ci 127e66f31c5Sopenharmony_cistatic CONSOLE_CURSOR_INFO get_cursor_info(uv_tty_t* tty_out) { 128e66f31c5Sopenharmony_ci HANDLE handle = tty_out->handle; 129e66f31c5Sopenharmony_ci CONSOLE_CURSOR_INFO info; 130e66f31c5Sopenharmony_ci ASSERT(GetConsoleCursorInfo(handle, &info)); 131e66f31c5Sopenharmony_ci return info; 132e66f31c5Sopenharmony_ci} 133e66f31c5Sopenharmony_ci 134e66f31c5Sopenharmony_cistatic void set_cursor_size(uv_tty_t* tty_out, DWORD size) { 135e66f31c5Sopenharmony_ci CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out); 136e66f31c5Sopenharmony_ci info.dwSize = size; 137e66f31c5Sopenharmony_ci ASSERT(SetConsoleCursorInfo(tty_out->handle, &info)); 138e66f31c5Sopenharmony_ci} 139e66f31c5Sopenharmony_ci 140e66f31c5Sopenharmony_cistatic DWORD get_cursor_size(uv_tty_t* tty_out) { 141e66f31c5Sopenharmony_ci return get_cursor_info(tty_out).dwSize; 142e66f31c5Sopenharmony_ci} 143e66f31c5Sopenharmony_ci 144e66f31c5Sopenharmony_cistatic void set_cursor_visibility(uv_tty_t* tty_out, BOOL visible) { 145e66f31c5Sopenharmony_ci CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out); 146e66f31c5Sopenharmony_ci info.bVisible = visible; 147e66f31c5Sopenharmony_ci ASSERT(SetConsoleCursorInfo(tty_out->handle, &info)); 148e66f31c5Sopenharmony_ci} 149e66f31c5Sopenharmony_ci 150e66f31c5Sopenharmony_cistatic BOOL get_cursor_visibility(uv_tty_t* tty_out) { 151e66f31c5Sopenharmony_ci return get_cursor_info(tty_out).bVisible; 152e66f31c5Sopenharmony_ci} 153e66f31c5Sopenharmony_ci 154e66f31c5Sopenharmony_cistatic BOOL is_scrolling(uv_tty_t* tty_out, struct screen_info si) { 155e66f31c5Sopenharmony_ci CONSOLE_SCREEN_BUFFER_INFO info; 156e66f31c5Sopenharmony_ci ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); 157e66f31c5Sopenharmony_ci return info.srWindow.Top != si.top; 158e66f31c5Sopenharmony_ci} 159e66f31c5Sopenharmony_ci 160e66f31c5Sopenharmony_cistatic void write_console(uv_tty_t* tty_out, char* src) { 161e66f31c5Sopenharmony_ci int r; 162e66f31c5Sopenharmony_ci uv_buf_t buf; 163e66f31c5Sopenharmony_ci 164e66f31c5Sopenharmony_ci buf.base = src; 165e66f31c5Sopenharmony_ci buf.len = strlen(buf.base); 166e66f31c5Sopenharmony_ci 167e66f31c5Sopenharmony_ci r = uv_try_write((uv_stream_t*) tty_out, &buf, 1); 168e66f31c5Sopenharmony_ci ASSERT_GE(r, 0); 169e66f31c5Sopenharmony_ci ASSERT_EQ((unsigned int) r, buf.len); 170e66f31c5Sopenharmony_ci} 171e66f31c5Sopenharmony_ci 172e66f31c5Sopenharmony_cistatic void setup_screen(uv_tty_t* tty_out) { 173e66f31c5Sopenharmony_ci DWORD length, number_of_written; 174e66f31c5Sopenharmony_ci COORD origin; 175e66f31c5Sopenharmony_ci CONSOLE_SCREEN_BUFFER_INFO info; 176e66f31c5Sopenharmony_ci ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); 177e66f31c5Sopenharmony_ci length = info.dwSize.X * (info.srWindow.Bottom - info.srWindow.Top + 1); 178e66f31c5Sopenharmony_ci origin.X = 0; 179e66f31c5Sopenharmony_ci origin.Y = info.srWindow.Top; 180e66f31c5Sopenharmony_ci ASSERT(FillConsoleOutputCharacter( 181e66f31c5Sopenharmony_ci tty_out->handle, '.', length, origin, &number_of_written)); 182e66f31c5Sopenharmony_ci ASSERT_EQ(length, number_of_written); 183e66f31c5Sopenharmony_ci} 184e66f31c5Sopenharmony_ci 185e66f31c5Sopenharmony_cistatic void clear_screen(uv_tty_t* tty_out, struct screen_info* si) { 186e66f31c5Sopenharmony_ci DWORD length, number_of_written; 187e66f31c5Sopenharmony_ci COORD origin; 188e66f31c5Sopenharmony_ci CONSOLE_SCREEN_BUFFER_INFO info; 189e66f31c5Sopenharmony_ci ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); 190e66f31c5Sopenharmony_ci length = (info.srWindow.Bottom - info.srWindow.Top + 1) * info.dwSize.X - 1; 191e66f31c5Sopenharmony_ci origin.X = 0; 192e66f31c5Sopenharmony_ci origin.Y = info.srWindow.Top; 193e66f31c5Sopenharmony_ci FillConsoleOutputCharacterA( 194e66f31c5Sopenharmony_ci tty_out->handle, ' ', length, origin, &number_of_written); 195e66f31c5Sopenharmony_ci ASSERT_EQ(length, number_of_written); 196e66f31c5Sopenharmony_ci FillConsoleOutputAttribute( 197e66f31c5Sopenharmony_ci tty_out->handle, si->default_attr, length, origin, &number_of_written); 198e66f31c5Sopenharmony_ci ASSERT_EQ(length, number_of_written); 199e66f31c5Sopenharmony_ci} 200e66f31c5Sopenharmony_ci 201e66f31c5Sopenharmony_cistatic void free_screen(struct captured_screen* cs) { 202e66f31c5Sopenharmony_ci free(cs->text); 203e66f31c5Sopenharmony_ci cs->text = NULL; 204e66f31c5Sopenharmony_ci free(cs->attributes); 205e66f31c5Sopenharmony_ci cs->attributes = NULL; 206e66f31c5Sopenharmony_ci} 207e66f31c5Sopenharmony_ci 208e66f31c5Sopenharmony_cistatic void capture_screen(uv_tty_t* tty_out, struct captured_screen* cs) { 209e66f31c5Sopenharmony_ci DWORD length; 210e66f31c5Sopenharmony_ci COORD origin; 211e66f31c5Sopenharmony_ci get_screen_info(tty_out, &(cs->si)); 212e66f31c5Sopenharmony_ci origin.X = 0; 213e66f31c5Sopenharmony_ci origin.Y = cs->si.csbi.srWindow.Top; 214e66f31c5Sopenharmony_ci cs->text = malloc(cs->si.length * sizeof(*cs->text)); 215e66f31c5Sopenharmony_ci ASSERT_NOT_NULL(cs->text); 216e66f31c5Sopenharmony_ci cs->attributes = (WORD*) malloc(cs->si.length * sizeof(*cs->attributes)); 217e66f31c5Sopenharmony_ci ASSERT_NOT_NULL(cs->attributes); 218e66f31c5Sopenharmony_ci ASSERT(ReadConsoleOutputCharacter( 219e66f31c5Sopenharmony_ci tty_out->handle, cs->text, cs->si.length, origin, &length)); 220e66f31c5Sopenharmony_ci ASSERT_EQ((unsigned int) cs->si.length, length); 221e66f31c5Sopenharmony_ci ASSERT(ReadConsoleOutputAttribute( 222e66f31c5Sopenharmony_ci tty_out->handle, cs->attributes, cs->si.length, origin, &length)); 223e66f31c5Sopenharmony_ci ASSERT_EQ((unsigned int) cs->si.length, length); 224e66f31c5Sopenharmony_ci} 225e66f31c5Sopenharmony_ci 226e66f31c5Sopenharmony_cistatic void make_expect_screen_erase(struct captured_screen* cs, 227e66f31c5Sopenharmony_ci COORD cursor_position, 228e66f31c5Sopenharmony_ci int dir, 229e66f31c5Sopenharmony_ci BOOL entire_screen) { 230e66f31c5Sopenharmony_ci /* beginning of line */ 231e66f31c5Sopenharmony_ci char* start; 232e66f31c5Sopenharmony_ci char* end; 233e66f31c5Sopenharmony_ci start = cs->text + cs->si.width * (cursor_position.Y - 1); 234e66f31c5Sopenharmony_ci if (dir == 0) { 235e66f31c5Sopenharmony_ci if (entire_screen) { 236e66f31c5Sopenharmony_ci /* erase to end of screen */ 237e66f31c5Sopenharmony_ci end = cs->text + cs->si.length; 238e66f31c5Sopenharmony_ci } else { 239e66f31c5Sopenharmony_ci /* erase to end of line */ 240e66f31c5Sopenharmony_ci end = start + cs->si.width; 241e66f31c5Sopenharmony_ci } 242e66f31c5Sopenharmony_ci /* erase from postition of cursor */ 243e66f31c5Sopenharmony_ci start += cursor_position.X - 1; 244e66f31c5Sopenharmony_ci } else if (dir == 1) { 245e66f31c5Sopenharmony_ci /* erase to position of cursor */ 246e66f31c5Sopenharmony_ci end = start + cursor_position.X; 247e66f31c5Sopenharmony_ci if (entire_screen) { 248e66f31c5Sopenharmony_ci /* erase form beginning of screen */ 249e66f31c5Sopenharmony_ci start = cs->text; 250e66f31c5Sopenharmony_ci } 251e66f31c5Sopenharmony_ci } else if (dir == 2) { 252e66f31c5Sopenharmony_ci if (entire_screen) { 253e66f31c5Sopenharmony_ci /* erase form beginning of screen */ 254e66f31c5Sopenharmony_ci start = cs->text; 255e66f31c5Sopenharmony_ci /* erase to end of screen */ 256e66f31c5Sopenharmony_ci end = cs->text + cs->si.length; 257e66f31c5Sopenharmony_ci } else { 258e66f31c5Sopenharmony_ci /* erase to end of line */ 259e66f31c5Sopenharmony_ci end = start + cs->si.width; 260e66f31c5Sopenharmony_ci } 261e66f31c5Sopenharmony_ci } else { 262e66f31c5Sopenharmony_ci ASSERT(FALSE); 263e66f31c5Sopenharmony_ci } 264e66f31c5Sopenharmony_ci ASSERT_PTR_LT(start, end); 265e66f31c5Sopenharmony_ci ASSERT_LE(end - cs->text, cs->si.length); 266e66f31c5Sopenharmony_ci for (; start < end; start++) { 267e66f31c5Sopenharmony_ci *start = ' '; 268e66f31c5Sopenharmony_ci } 269e66f31c5Sopenharmony_ci} 270e66f31c5Sopenharmony_ci 271e66f31c5Sopenharmony_cistatic void make_expect_screen_write(struct captured_screen* cs, 272e66f31c5Sopenharmony_ci COORD cursor_position, 273e66f31c5Sopenharmony_ci const char* text) { 274e66f31c5Sopenharmony_ci /* position of cursor */ 275e66f31c5Sopenharmony_ci char* start; 276e66f31c5Sopenharmony_ci start = cs->text + cs->si.width * (cursor_position.Y - 1) + 277e66f31c5Sopenharmony_ci cursor_position.X - 1; 278e66f31c5Sopenharmony_ci size_t length = strlen(text); 279e66f31c5Sopenharmony_ci size_t remain_length = cs->si.length - (cs->text - start); 280e66f31c5Sopenharmony_ci length = length > remain_length ? remain_length : length; 281e66f31c5Sopenharmony_ci memcpy(start, text, length); 282e66f31c5Sopenharmony_ci} 283e66f31c5Sopenharmony_ci 284e66f31c5Sopenharmony_cistatic void make_expect_screen_set_attr(struct captured_screen* cs, 285e66f31c5Sopenharmony_ci COORD cursor_position, 286e66f31c5Sopenharmony_ci size_t length, 287e66f31c5Sopenharmony_ci WORD attr) { 288e66f31c5Sopenharmony_ci WORD* start; 289e66f31c5Sopenharmony_ci start = cs->attributes + cs->si.width * (cursor_position.Y - 1) + 290e66f31c5Sopenharmony_ci cursor_position.X - 1; 291e66f31c5Sopenharmony_ci size_t remain_length = cs->si.length - (cs->attributes - start); 292e66f31c5Sopenharmony_ci length = length > remain_length ? remain_length : length; 293e66f31c5Sopenharmony_ci while (length) { 294e66f31c5Sopenharmony_ci *start = attr; 295e66f31c5Sopenharmony_ci start++; 296e66f31c5Sopenharmony_ci length--; 297e66f31c5Sopenharmony_ci } 298e66f31c5Sopenharmony_ci} 299e66f31c5Sopenharmony_ci 300e66f31c5Sopenharmony_cistatic BOOL compare_screen(uv_tty_t* tty_out, 301e66f31c5Sopenharmony_ci struct captured_screen* actual, 302e66f31c5Sopenharmony_ci struct captured_screen* expect) { 303e66f31c5Sopenharmony_ci int line, col; 304e66f31c5Sopenharmony_ci BOOL result = TRUE; 305e66f31c5Sopenharmony_ci int current = 0; 306e66f31c5Sopenharmony_ci ASSERT(actual->text); 307e66f31c5Sopenharmony_ci ASSERT(actual->attributes); 308e66f31c5Sopenharmony_ci ASSERT(expect->text); 309e66f31c5Sopenharmony_ci ASSERT(expect->attributes); 310e66f31c5Sopenharmony_ci if (actual->si.length != expect->si.length) { 311e66f31c5Sopenharmony_ci return FALSE; 312e66f31c5Sopenharmony_ci } 313e66f31c5Sopenharmony_ci if (actual->si.width != expect->si.width) { 314e66f31c5Sopenharmony_ci return FALSE; 315e66f31c5Sopenharmony_ci } 316e66f31c5Sopenharmony_ci if (actual->si.height != expect->si.height) { 317e66f31c5Sopenharmony_ci return FALSE; 318e66f31c5Sopenharmony_ci } 319e66f31c5Sopenharmony_ci while (current < actual->si.length) { 320e66f31c5Sopenharmony_ci if (*(actual->text + current) != *(expect->text + current)) { 321e66f31c5Sopenharmony_ci line = current / actual->si.width + 1; 322e66f31c5Sopenharmony_ci col = current - actual->si.width * (line - 1) + 1; 323e66f31c5Sopenharmony_ci fprintf(stderr, 324e66f31c5Sopenharmony_ci "line:%d col:%d expected character '%c' but found '%c'\n", 325e66f31c5Sopenharmony_ci line, 326e66f31c5Sopenharmony_ci col, 327e66f31c5Sopenharmony_ci *(expect->text + current), 328e66f31c5Sopenharmony_ci *(actual->text + current)); 329e66f31c5Sopenharmony_ci result = FALSE; 330e66f31c5Sopenharmony_ci } 331e66f31c5Sopenharmony_ci if (*(actual->attributes + current) != *(expect->attributes + current)) { 332e66f31c5Sopenharmony_ci line = current / actual->si.width + 1; 333e66f31c5Sopenharmony_ci col = current - actual->si.width * (line - 1) + 1; 334e66f31c5Sopenharmony_ci fprintf(stderr, 335e66f31c5Sopenharmony_ci "line:%d col:%d expected attributes '%u' but found '%u'\n", 336e66f31c5Sopenharmony_ci line, 337e66f31c5Sopenharmony_ci col, 338e66f31c5Sopenharmony_ci *(expect->attributes + current), 339e66f31c5Sopenharmony_ci *(actual->attributes + current)); 340e66f31c5Sopenharmony_ci result = FALSE; 341e66f31c5Sopenharmony_ci } 342e66f31c5Sopenharmony_ci current++; 343e66f31c5Sopenharmony_ci } 344e66f31c5Sopenharmony_ci clear_screen(tty_out, &expect->si); 345e66f31c5Sopenharmony_ci free_screen(expect); 346e66f31c5Sopenharmony_ci free_screen(actual); 347e66f31c5Sopenharmony_ci return result; 348e66f31c5Sopenharmony_ci} 349e66f31c5Sopenharmony_ci 350e66f31c5Sopenharmony_cistatic void initialize_tty(uv_tty_t* tty_out) { 351e66f31c5Sopenharmony_ci int r; 352e66f31c5Sopenharmony_ci int ttyout_fd; 353e66f31c5Sopenharmony_ci /* Make sure we have an FD that refers to a tty */ 354e66f31c5Sopenharmony_ci HANDLE handle; 355e66f31c5Sopenharmony_ci 356e66f31c5Sopenharmony_ci uv_tty_set_vterm_state(UV_TTY_UNSUPPORTED); 357e66f31c5Sopenharmony_ci 358e66f31c5Sopenharmony_ci handle = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 359e66f31c5Sopenharmony_ci FILE_SHARE_READ | FILE_SHARE_WRITE, 360e66f31c5Sopenharmony_ci NULL, 361e66f31c5Sopenharmony_ci CONSOLE_TEXTMODE_BUFFER, 362e66f31c5Sopenharmony_ci NULL); 363e66f31c5Sopenharmony_ci ASSERT_PTR_NE(handle, INVALID_HANDLE_VALUE); 364e66f31c5Sopenharmony_ci 365e66f31c5Sopenharmony_ci ttyout_fd = _open_osfhandle((intptr_t) handle, 0); 366e66f31c5Sopenharmony_ci ASSERT_GE(ttyout_fd, 0); 367e66f31c5Sopenharmony_ci ASSERT_EQ(UV_TTY, uv_guess_handle(ttyout_fd)); 368e66f31c5Sopenharmony_ci r = uv_tty_init(uv_default_loop(), tty_out, ttyout_fd, 0); /* Writable. */ 369e66f31c5Sopenharmony_ci ASSERT_OK(r); 370e66f31c5Sopenharmony_ci} 371e66f31c5Sopenharmony_ci 372e66f31c5Sopenharmony_cistatic void terminate_tty(uv_tty_t* tty_out) { 373e66f31c5Sopenharmony_ci set_cursor_to_home(tty_out); 374e66f31c5Sopenharmony_ci uv_close((uv_handle_t*) tty_out, NULL); 375e66f31c5Sopenharmony_ci} 376e66f31c5Sopenharmony_ci 377e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_up) { 378e66f31c5Sopenharmony_ci uv_tty_t tty_out; 379e66f31c5Sopenharmony_ci uv_loop_t* loop; 380e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 381e66f31c5Sopenharmony_ci char buffer[1024]; 382e66f31c5Sopenharmony_ci struct screen_info si; 383e66f31c5Sopenharmony_ci 384e66f31c5Sopenharmony_ci loop = uv_default_loop(); 385e66f31c5Sopenharmony_ci 386e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 387e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 388e66f31c5Sopenharmony_ci 389e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 390e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 391e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 392e66f31c5Sopenharmony_ci 393e66f31c5Sopenharmony_ci /* cursor up one times if omitted arguments */ 394e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sA", CSI); 395e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 396e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 397e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y - 1, cursor_pos.Y); 398e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 399e66f31c5Sopenharmony_ci 400e66f31c5Sopenharmony_ci /* cursor up nth times */ 401e66f31c5Sopenharmony_ci cursor_pos_old = cursor_pos; 402e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dA", CSI, si.height / 4); 403e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 404e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 405e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y - si.height / 4, cursor_pos.Y); 406e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 407e66f31c5Sopenharmony_ci 408e66f31c5Sopenharmony_ci /* cursor up from Window top does nothing */ 409e66f31c5Sopenharmony_ci cursor_pos_old.X = 1; 410e66f31c5Sopenharmony_ci cursor_pos_old.Y = 1; 411e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 412e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sA", CSI); 413e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 414e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 415e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 416e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 417e66f31c5Sopenharmony_ci ASSERT(!is_scrolling(&tty_out, si)); 418e66f31c5Sopenharmony_ci 419e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 420e66f31c5Sopenharmony_ci 421e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 422e66f31c5Sopenharmony_ci 423e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 424e66f31c5Sopenharmony_ci return 0; 425e66f31c5Sopenharmony_ci} 426e66f31c5Sopenharmony_ci 427e66f31c5Sopenharmony_ci 428e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_down) { 429e66f31c5Sopenharmony_ci uv_tty_t tty_out; 430e66f31c5Sopenharmony_ci uv_loop_t* loop; 431e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 432e66f31c5Sopenharmony_ci char buffer[1024]; 433e66f31c5Sopenharmony_ci struct screen_info si; 434e66f31c5Sopenharmony_ci 435e66f31c5Sopenharmony_ci loop = uv_default_loop(); 436e66f31c5Sopenharmony_ci 437e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 438e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 439e66f31c5Sopenharmony_ci 440e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 441e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 442e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 443e66f31c5Sopenharmony_ci 444e66f31c5Sopenharmony_ci /* cursor down one times if omitted arguments */ 445e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sB", CSI); 446e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 447e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 448e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y + 1, cursor_pos.Y); 449e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 450e66f31c5Sopenharmony_ci 451e66f31c5Sopenharmony_ci /* cursor down nth times */ 452e66f31c5Sopenharmony_ci cursor_pos_old = cursor_pos; 453e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dB", CSI, si.height / 4); 454e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 455e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 456e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y + si.height / 4, cursor_pos.Y); 457e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 458e66f31c5Sopenharmony_ci 459e66f31c5Sopenharmony_ci /* cursor down from bottom line does nothing */ 460e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 461e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height; 462e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 463e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sB", CSI); 464e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 465e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 466e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 467e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 468e66f31c5Sopenharmony_ci ASSERT(!is_scrolling(&tty_out, si)); 469e66f31c5Sopenharmony_ci 470e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 471e66f31c5Sopenharmony_ci 472e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 473e66f31c5Sopenharmony_ci 474e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 475e66f31c5Sopenharmony_ci return 0; 476e66f31c5Sopenharmony_ci} 477e66f31c5Sopenharmony_ci 478e66f31c5Sopenharmony_ci 479e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_forward) { 480e66f31c5Sopenharmony_ci uv_tty_t tty_out; 481e66f31c5Sopenharmony_ci uv_loop_t* loop; 482e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 483e66f31c5Sopenharmony_ci char buffer[1024]; 484e66f31c5Sopenharmony_ci struct screen_info si; 485e66f31c5Sopenharmony_ci 486e66f31c5Sopenharmony_ci loop = uv_default_loop(); 487e66f31c5Sopenharmony_ci 488e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 489e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 490e66f31c5Sopenharmony_ci 491e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 492e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 493e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 494e66f31c5Sopenharmony_ci 495e66f31c5Sopenharmony_ci /* cursor forward one times if omitted arguments */ 496e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sC", CSI); 497e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 498e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 499e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 500e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X + 1, cursor_pos.X); 501e66f31c5Sopenharmony_ci 502e66f31c5Sopenharmony_ci /* cursor forward nth times */ 503e66f31c5Sopenharmony_ci cursor_pos_old = cursor_pos; 504e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dC", CSI, si.width / 4); 505e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 506e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 507e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 508e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X + si.width / 4, cursor_pos.X); 509e66f31c5Sopenharmony_ci 510e66f31c5Sopenharmony_ci /* cursor forward from end of line does nothing*/ 511e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width; 512e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 513e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 514e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sC", CSI); 515e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 516e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 517e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 518e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 519e66f31c5Sopenharmony_ci 520e66f31c5Sopenharmony_ci /* cursor forward from end of screen does nothing */ 521e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width; 522e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height; 523e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 524e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sC", CSI); 525e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 526e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 527e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 528e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 529e66f31c5Sopenharmony_ci ASSERT(!is_scrolling(&tty_out, si)); 530e66f31c5Sopenharmony_ci 531e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 532e66f31c5Sopenharmony_ci 533e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 534e66f31c5Sopenharmony_ci 535e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 536e66f31c5Sopenharmony_ci return 0; 537e66f31c5Sopenharmony_ci} 538e66f31c5Sopenharmony_ci 539e66f31c5Sopenharmony_ci 540e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_back) { 541e66f31c5Sopenharmony_ci uv_tty_t tty_out; 542e66f31c5Sopenharmony_ci uv_loop_t* loop; 543e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 544e66f31c5Sopenharmony_ci char buffer[1024]; 545e66f31c5Sopenharmony_ci struct screen_info si; 546e66f31c5Sopenharmony_ci 547e66f31c5Sopenharmony_ci loop = uv_default_loop(); 548e66f31c5Sopenharmony_ci 549e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 550e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 551e66f31c5Sopenharmony_ci 552e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 553e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 554e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 555e66f31c5Sopenharmony_ci 556e66f31c5Sopenharmony_ci /* cursor back one times if omitted arguments */ 557e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sD", CSI); 558e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 559e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 560e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 561e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X - 1, cursor_pos.X); 562e66f31c5Sopenharmony_ci 563e66f31c5Sopenharmony_ci /* cursor back nth times */ 564e66f31c5Sopenharmony_ci cursor_pos_old = cursor_pos; 565e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dD", CSI, si.width / 4); 566e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 567e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 568e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 569e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X - si.width / 4, cursor_pos.X); 570e66f31c5Sopenharmony_ci 571e66f31c5Sopenharmony_ci /* cursor back from beginning of line does nothing */ 572e66f31c5Sopenharmony_ci cursor_pos_old.X = 1; 573e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 574e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 575e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sD", CSI); 576e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 577e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 578e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 579e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); 580e66f31c5Sopenharmony_ci 581e66f31c5Sopenharmony_ci /* cursor back from top of screen does nothing */ 582e66f31c5Sopenharmony_ci cursor_pos_old.X = 1; 583e66f31c5Sopenharmony_ci cursor_pos_old.Y = 1; 584e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 585e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sD", CSI); 586e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 587e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 588e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.Y); 589e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 590e66f31c5Sopenharmony_ci ASSERT(!is_scrolling(&tty_out, si)); 591e66f31c5Sopenharmony_ci 592e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 593e66f31c5Sopenharmony_ci 594e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 595e66f31c5Sopenharmony_ci 596e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 597e66f31c5Sopenharmony_ci return 0; 598e66f31c5Sopenharmony_ci} 599e66f31c5Sopenharmony_ci 600e66f31c5Sopenharmony_ci 601e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_next_line) { 602e66f31c5Sopenharmony_ci uv_tty_t tty_out; 603e66f31c5Sopenharmony_ci uv_loop_t* loop; 604e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 605e66f31c5Sopenharmony_ci char buffer[1024]; 606e66f31c5Sopenharmony_ci struct screen_info si; 607e66f31c5Sopenharmony_ci 608e66f31c5Sopenharmony_ci loop = uv_default_loop(); 609e66f31c5Sopenharmony_ci 610e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 611e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 612e66f31c5Sopenharmony_ci 613e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 614e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 615e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 616e66f31c5Sopenharmony_ci 617e66f31c5Sopenharmony_ci /* cursor next line one times if omitted arguments */ 618e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sE", CSI); 619e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 620e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 621e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y + 1, cursor_pos.Y); 622e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 623e66f31c5Sopenharmony_ci 624e66f31c5Sopenharmony_ci /* cursor next line nth times */ 625e66f31c5Sopenharmony_ci cursor_pos_old = cursor_pos; 626e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dE", CSI, si.height / 4); 627e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 628e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 629e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y + si.height / 4, cursor_pos.Y); 630e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 631e66f31c5Sopenharmony_ci 632e66f31c5Sopenharmony_ci /* cursor next line from buttom row moves beginning of line */ 633e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 634e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height; 635e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 636e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sE", CSI); 637e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 638e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 639e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 640e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 641e66f31c5Sopenharmony_ci ASSERT(!is_scrolling(&tty_out, si)); 642e66f31c5Sopenharmony_ci 643e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 644e66f31c5Sopenharmony_ci 645e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 646e66f31c5Sopenharmony_ci 647e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 648e66f31c5Sopenharmony_ci return 0; 649e66f31c5Sopenharmony_ci} 650e66f31c5Sopenharmony_ci 651e66f31c5Sopenharmony_ci 652e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_previous_line) { 653e66f31c5Sopenharmony_ci uv_tty_t tty_out; 654e66f31c5Sopenharmony_ci uv_loop_t* loop; 655e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 656e66f31c5Sopenharmony_ci char buffer[1024]; 657e66f31c5Sopenharmony_ci struct screen_info si; 658e66f31c5Sopenharmony_ci 659e66f31c5Sopenharmony_ci loop = uv_default_loop(); 660e66f31c5Sopenharmony_ci 661e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 662e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 663e66f31c5Sopenharmony_ci 664e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 665e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 666e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 667e66f31c5Sopenharmony_ci 668e66f31c5Sopenharmony_ci /* cursor previous line one times if omitted arguments */ 669e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sF", CSI); 670e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 671e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 672e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y - 1, cursor_pos.Y); 673e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 674e66f31c5Sopenharmony_ci 675e66f31c5Sopenharmony_ci /* cursor previous line nth times */ 676e66f31c5Sopenharmony_ci cursor_pos_old = cursor_pos; 677e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dF", CSI, si.height / 4); 678e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 679e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 680e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y - si.height / 4, cursor_pos.Y); 681e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 682e66f31c5Sopenharmony_ci 683e66f31c5Sopenharmony_ci /* cursor previous line from top of screen does nothing */ 684e66f31c5Sopenharmony_ci cursor_pos_old.X = 1; 685e66f31c5Sopenharmony_ci cursor_pos_old.Y = 1; 686e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 687e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sD", CSI); 688e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 689e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 690e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.Y); 691e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 692e66f31c5Sopenharmony_ci ASSERT(!is_scrolling(&tty_out, si)); 693e66f31c5Sopenharmony_ci 694e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 695e66f31c5Sopenharmony_ci 696e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 697e66f31c5Sopenharmony_ci 698e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 699e66f31c5Sopenharmony_ci return 0; 700e66f31c5Sopenharmony_ci} 701e66f31c5Sopenharmony_ci 702e66f31c5Sopenharmony_ci 703e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_horizontal_move_absolute) { 704e66f31c5Sopenharmony_ci uv_tty_t tty_out; 705e66f31c5Sopenharmony_ci uv_loop_t* loop; 706e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 707e66f31c5Sopenharmony_ci char buffer[1024]; 708e66f31c5Sopenharmony_ci struct screen_info si; 709e66f31c5Sopenharmony_ci 710e66f31c5Sopenharmony_ci loop = uv_default_loop(); 711e66f31c5Sopenharmony_ci 712e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 713e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 714e66f31c5Sopenharmony_ci 715e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 716e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 717e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 718e66f31c5Sopenharmony_ci 719e66f31c5Sopenharmony_ci /* Move to beginning of line if omitted argument */ 720e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sG", CSI); 721e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 722e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 723e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 724e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 725e66f31c5Sopenharmony_ci 726e66f31c5Sopenharmony_ci /* Move cursor to nth character */ 727e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dG", CSI, si.width / 4); 728e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 729e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 730e66f31c5Sopenharmony_ci ASSERT_EQ(si.width / 4, cursor_pos.X); 731e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 732e66f31c5Sopenharmony_ci 733e66f31c5Sopenharmony_ci /* Moving out of screen will fit within screen */ 734e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dG", CSI, si.width + 1); 735e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 736e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 737e66f31c5Sopenharmony_ci ASSERT_EQ(si.width, cursor_pos.X); 738e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); 739e66f31c5Sopenharmony_ci 740e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 741e66f31c5Sopenharmony_ci 742e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 743e66f31c5Sopenharmony_ci 744e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 745e66f31c5Sopenharmony_ci return 0; 746e66f31c5Sopenharmony_ci} 747e66f31c5Sopenharmony_ci 748e66f31c5Sopenharmony_ci 749e66f31c5Sopenharmony_ciTEST_IMPL(tty_cursor_move_absolute) { 750e66f31c5Sopenharmony_ci uv_tty_t tty_out; 751e66f31c5Sopenharmony_ci uv_loop_t* loop; 752e66f31c5Sopenharmony_ci COORD cursor_pos; 753e66f31c5Sopenharmony_ci char buffer[1024]; 754e66f31c5Sopenharmony_ci struct screen_info si; 755e66f31c5Sopenharmony_ci 756e66f31c5Sopenharmony_ci loop = uv_default_loop(); 757e66f31c5Sopenharmony_ci 758e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 759e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 760e66f31c5Sopenharmony_ci 761e66f31c5Sopenharmony_ci cursor_pos.X = si.width / 2; 762e66f31c5Sopenharmony_ci cursor_pos.Y = si.height / 2; 763e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 764e66f31c5Sopenharmony_ci 765e66f31c5Sopenharmony_ci /* Move the cursor to home if omitted arguments */ 766e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sH", CSI); 767e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 768e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 769e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 770e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.Y); 771e66f31c5Sopenharmony_ci 772e66f31c5Sopenharmony_ci /* Move the cursor to the middle of the screen */ 773e66f31c5Sopenharmony_ci snprintf( 774e66f31c5Sopenharmony_ci buffer, sizeof(buffer), "%s%d;%df", CSI, si.height / 2, si.width / 2); 775e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 776e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 777e66f31c5Sopenharmony_ci ASSERT_EQ(si.width / 2, cursor_pos.X); 778e66f31c5Sopenharmony_ci ASSERT_EQ(si.height / 2, cursor_pos.Y); 779e66f31c5Sopenharmony_ci 780e66f31c5Sopenharmony_ci /* Moving out of screen will fit within screen */ 781e66f31c5Sopenharmony_ci snprintf( 782e66f31c5Sopenharmony_ci buffer, sizeof(buffer), "%s%d;%df", CSI, si.height / 2, si.width + 1); 783e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 784e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 785e66f31c5Sopenharmony_ci ASSERT_EQ(si.width, cursor_pos.X); 786e66f31c5Sopenharmony_ci ASSERT_EQ(si.height / 2, cursor_pos.Y); 787e66f31c5Sopenharmony_ci 788e66f31c5Sopenharmony_ci snprintf( 789e66f31c5Sopenharmony_ci buffer, sizeof(buffer), "%s%d;%df", CSI, si.height + 1, si.width / 2); 790e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 791e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 792e66f31c5Sopenharmony_ci ASSERT_EQ(si.width / 2, cursor_pos.X); 793e66f31c5Sopenharmony_ci ASSERT_EQ(si.height, cursor_pos.Y); 794e66f31c5Sopenharmony_ci ASSERT(!is_scrolling(&tty_out, si)); 795e66f31c5Sopenharmony_ci 796e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 797e66f31c5Sopenharmony_ci 798e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 799e66f31c5Sopenharmony_ci 800e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 801e66f31c5Sopenharmony_ci return 0; 802e66f31c5Sopenharmony_ci} 803e66f31c5Sopenharmony_ci 804e66f31c5Sopenharmony_ci 805e66f31c5Sopenharmony_ciTEST_IMPL(tty_hide_show_cursor) { 806e66f31c5Sopenharmony_ci uv_tty_t tty_out; 807e66f31c5Sopenharmony_ci uv_loop_t* loop; 808e66f31c5Sopenharmony_ci char buffer[1024]; 809e66f31c5Sopenharmony_ci BOOL saved_cursor_visibility; 810e66f31c5Sopenharmony_ci 811e66f31c5Sopenharmony_ci loop = uv_default_loop(); 812e66f31c5Sopenharmony_ci 813e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 814e66f31c5Sopenharmony_ci 815e66f31c5Sopenharmony_ci saved_cursor_visibility = get_cursor_visibility(&tty_out); 816e66f31c5Sopenharmony_ci 817e66f31c5Sopenharmony_ci /* Hide the cursor */ 818e66f31c5Sopenharmony_ci set_cursor_visibility(&tty_out, TRUE); 819e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s?25l", CSI); 820e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 821e66f31c5Sopenharmony_ci ASSERT(!get_cursor_visibility(&tty_out)); 822e66f31c5Sopenharmony_ci 823e66f31c5Sopenharmony_ci /* Show the cursor */ 824e66f31c5Sopenharmony_ci set_cursor_visibility(&tty_out, FALSE); 825e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s?25h", CSI); 826e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 827e66f31c5Sopenharmony_ci ASSERT(get_cursor_visibility(&tty_out)); 828e66f31c5Sopenharmony_ci 829e66f31c5Sopenharmony_ci set_cursor_visibility(&tty_out, saved_cursor_visibility); 830e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 831e66f31c5Sopenharmony_ci 832e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 833e66f31c5Sopenharmony_ci 834e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 835e66f31c5Sopenharmony_ci return 0; 836e66f31c5Sopenharmony_ci} 837e66f31c5Sopenharmony_ci 838e66f31c5Sopenharmony_ci 839e66f31c5Sopenharmony_ciTEST_IMPL(tty_erase) { 840e66f31c5Sopenharmony_ci int dir; 841e66f31c5Sopenharmony_ci uv_tty_t tty_out; 842e66f31c5Sopenharmony_ci uv_loop_t* loop; 843e66f31c5Sopenharmony_ci COORD cursor_pos; 844e66f31c5Sopenharmony_ci char buffer[1024]; 845e66f31c5Sopenharmony_ci struct captured_screen actual = {0}, expect = {0}; 846e66f31c5Sopenharmony_ci 847e66f31c5Sopenharmony_ci loop = uv_default_loop(); 848e66f31c5Sopenharmony_ci 849e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 850e66f31c5Sopenharmony_ci 851e66f31c5Sopenharmony_ci /* Erase to below if omitted argument */ 852e66f31c5Sopenharmony_ci dir = 0; 853e66f31c5Sopenharmony_ci setup_screen(&tty_out); 854e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 855e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 856e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 857e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); 858e66f31c5Sopenharmony_ci 859e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 860e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sJ", CSI); 861e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 862e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 863e66f31c5Sopenharmony_ci 864e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 865e66f31c5Sopenharmony_ci 866e66f31c5Sopenharmony_ci /* Erase to below(dir = 0) */ 867e66f31c5Sopenharmony_ci setup_screen(&tty_out); 868e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 869e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); 870e66f31c5Sopenharmony_ci 871e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 872e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); 873e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 874e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 875e66f31c5Sopenharmony_ci 876e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 877e66f31c5Sopenharmony_ci 878e66f31c5Sopenharmony_ci /* Erase to above */ 879e66f31c5Sopenharmony_ci dir = 1; 880e66f31c5Sopenharmony_ci setup_screen(&tty_out); 881e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 882e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); 883e66f31c5Sopenharmony_ci 884e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 885e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); 886e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 887e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 888e66f31c5Sopenharmony_ci 889e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 890e66f31c5Sopenharmony_ci 891e66f31c5Sopenharmony_ci /* Erase All */ 892e66f31c5Sopenharmony_ci dir = 2; 893e66f31c5Sopenharmony_ci setup_screen(&tty_out); 894e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 895e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); 896e66f31c5Sopenharmony_ci 897e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 898e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); 899e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 900e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 901e66f31c5Sopenharmony_ci 902e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 903e66f31c5Sopenharmony_ci 904e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 905e66f31c5Sopenharmony_ci 906e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 907e66f31c5Sopenharmony_ci 908e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 909e66f31c5Sopenharmony_ci return 0; 910e66f31c5Sopenharmony_ci} 911e66f31c5Sopenharmony_ci 912e66f31c5Sopenharmony_ci 913e66f31c5Sopenharmony_ciTEST_IMPL(tty_erase_line) { 914e66f31c5Sopenharmony_ci int dir; 915e66f31c5Sopenharmony_ci uv_tty_t tty_out; 916e66f31c5Sopenharmony_ci uv_loop_t* loop; 917e66f31c5Sopenharmony_ci COORD cursor_pos; 918e66f31c5Sopenharmony_ci char buffer[1024]; 919e66f31c5Sopenharmony_ci struct captured_screen actual = {0}, expect = {0}; 920e66f31c5Sopenharmony_ci 921e66f31c5Sopenharmony_ci loop = uv_default_loop(); 922e66f31c5Sopenharmony_ci 923e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 924e66f31c5Sopenharmony_ci 925e66f31c5Sopenharmony_ci /* Erase to right if omitted arguments */ 926e66f31c5Sopenharmony_ci dir = 0; 927e66f31c5Sopenharmony_ci setup_screen(&tty_out); 928e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 929e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 930e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 931e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); 932e66f31c5Sopenharmony_ci 933e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 934e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sK", CSI); 935e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 936e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 937e66f31c5Sopenharmony_ci 938e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 939e66f31c5Sopenharmony_ci 940e66f31c5Sopenharmony_ci /* Erase to right(dir = 0) */ 941e66f31c5Sopenharmony_ci setup_screen(&tty_out); 942e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 943e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); 944e66f31c5Sopenharmony_ci 945e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 946e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); 947e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 948e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 949e66f31c5Sopenharmony_ci 950e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 951e66f31c5Sopenharmony_ci 952e66f31c5Sopenharmony_ci /* Erase to Left */ 953e66f31c5Sopenharmony_ci dir = 1; 954e66f31c5Sopenharmony_ci setup_screen(&tty_out); 955e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 956e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); 957e66f31c5Sopenharmony_ci 958e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 959e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); 960e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 961e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 962e66f31c5Sopenharmony_ci 963e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 964e66f31c5Sopenharmony_ci 965e66f31c5Sopenharmony_ci /* Erase All */ 966e66f31c5Sopenharmony_ci dir = 2; 967e66f31c5Sopenharmony_ci setup_screen(&tty_out); 968e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 969e66f31c5Sopenharmony_ci make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); 970e66f31c5Sopenharmony_ci 971e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 972e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); 973e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 974e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 975e66f31c5Sopenharmony_ci 976e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 977e66f31c5Sopenharmony_ci 978e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 979e66f31c5Sopenharmony_ci 980e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 981e66f31c5Sopenharmony_ci 982e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 983e66f31c5Sopenharmony_ci return 0; 984e66f31c5Sopenharmony_ci} 985e66f31c5Sopenharmony_ci 986e66f31c5Sopenharmony_ci 987e66f31c5Sopenharmony_ciTEST_IMPL(tty_set_cursor_shape) { 988e66f31c5Sopenharmony_ci uv_tty_t tty_out; 989e66f31c5Sopenharmony_ci uv_loop_t* loop; 990e66f31c5Sopenharmony_ci DWORD saved_cursor_size; 991e66f31c5Sopenharmony_ci char buffer[1024]; 992e66f31c5Sopenharmony_ci 993e66f31c5Sopenharmony_ci loop = uv_default_loop(); 994e66f31c5Sopenharmony_ci 995e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 996e66f31c5Sopenharmony_ci 997e66f31c5Sopenharmony_ci saved_cursor_size = get_cursor_size(&tty_out); 998e66f31c5Sopenharmony_ci 999e66f31c5Sopenharmony_ci /* cursor size large if omitted arguments */ 1000e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); 1001e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s q", CSI); 1002e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1003e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_LARGE); 1004e66f31c5Sopenharmony_ci 1005e66f31c5Sopenharmony_ci /* cursor size large */ 1006e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); 1007e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s1 q", CSI); 1008e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1009e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_LARGE); 1010e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); 1011e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s2 q", CSI); 1012e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1013e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_LARGE); 1014e66f31c5Sopenharmony_ci 1015e66f31c5Sopenharmony_ci /* cursor size small */ 1016e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); 1017e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s3 q", CSI); 1018e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1019e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_SMALL); 1020e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); 1021e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s6 q", CSI); 1022e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1023e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_SMALL); 1024e66f31c5Sopenharmony_ci 1025e66f31c5Sopenharmony_ci /* Nothing occurs with arguments outside valid range */ 1026e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); 1027e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s7 q", CSI); 1028e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1029e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_MIDDLE); 1030e66f31c5Sopenharmony_ci 1031e66f31c5Sopenharmony_ci /* restore cursor size if arguments is zero */ 1032e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s0 q", CSI); 1033e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1034e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), saved_cursor_size); 1035e66f31c5Sopenharmony_ci 1036e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 1037e66f31c5Sopenharmony_ci 1038e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 1039e66f31c5Sopenharmony_ci 1040e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 1041e66f31c5Sopenharmony_ci return 0; 1042e66f31c5Sopenharmony_ci} 1043e66f31c5Sopenharmony_ci 1044e66f31c5Sopenharmony_ci 1045e66f31c5Sopenharmony_ciTEST_IMPL(tty_set_style) { 1046e66f31c5Sopenharmony_ci#if _MSC_VER >= 1920 && _MSC_VER <= 1929 1047e66f31c5Sopenharmony_ci RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " 1048e66f31c5Sopenharmony_ci "See: https://github.com/libuv/libuv/issues/3304"); 1049e66f31c5Sopenharmony_ci#else 1050e66f31c5Sopenharmony_ci 1051e66f31c5Sopenharmony_ci uv_tty_t tty_out; 1052e66f31c5Sopenharmony_ci uv_loop_t* loop; 1053e66f31c5Sopenharmony_ci COORD cursor_pos; 1054e66f31c5Sopenharmony_ci char buffer[1024]; 1055e66f31c5Sopenharmony_ci struct captured_screen actual = {0}, expect = {0}; 1056e66f31c5Sopenharmony_ci WORD fg, bg; 1057e66f31c5Sopenharmony_ci WORD fg_attrs[9][2] = {{F_BLACK, FOREGROUND_BLACK}, 1058e66f31c5Sopenharmony_ci {F_RED, FOREGROUND_RED}, 1059e66f31c5Sopenharmony_ci {F_GREEN, FOREGROUND_GREEN}, 1060e66f31c5Sopenharmony_ci {F_YELLOW, FOREGROUND_YELLOW}, 1061e66f31c5Sopenharmony_ci {F_BLUE, FOREGROUND_BLUE}, 1062e66f31c5Sopenharmony_ci {F_MAGENTA, FOREGROUND_MAGENTA}, 1063e66f31c5Sopenharmony_ci {F_CYAN, FOREGROUND_CYAN}, 1064e66f31c5Sopenharmony_ci {F_WHITE, FOREGROUND_WHITE}, 1065e66f31c5Sopenharmony_ci {F_DEFAULT, 0}}; 1066e66f31c5Sopenharmony_ci WORD bg_attrs[9][2] = {{B_DEFAULT, 0}, 1067e66f31c5Sopenharmony_ci {B_BLACK, BACKGROUND_BLACK}, 1068e66f31c5Sopenharmony_ci {B_RED, BACKGROUND_RED}, 1069e66f31c5Sopenharmony_ci {B_GREEN, BACKGROUND_GREEN}, 1070e66f31c5Sopenharmony_ci {B_YELLOW, BACKGROUND_YELLOW}, 1071e66f31c5Sopenharmony_ci {B_BLUE, BACKGROUND_BLUE}, 1072e66f31c5Sopenharmony_ci {B_MAGENTA, BACKGROUND_MAGENTA}, 1073e66f31c5Sopenharmony_ci {B_CYAN, BACKGROUND_CYAN}, 1074e66f31c5Sopenharmony_ci {B_WHITE, BACKGROUND_WHITE}}; 1075e66f31c5Sopenharmony_ci WORD attr; 1076e66f31c5Sopenharmony_ci int i, length; 1077e66f31c5Sopenharmony_ci 1078e66f31c5Sopenharmony_ci loop = uv_default_loop(); 1079e66f31c5Sopenharmony_ci 1080e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 1081e66f31c5Sopenharmony_ci 1082e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1083e66f31c5Sopenharmony_ci fg_attrs[8][1] = expect.si.default_attr & FOREGROUND_WHITE; 1084e66f31c5Sopenharmony_ci bg_attrs[0][1] = expect.si.default_attr & BACKGROUND_WHITE; 1085e66f31c5Sopenharmony_ci 1086e66f31c5Sopenharmony_ci /* Set foreground color */ 1087e66f31c5Sopenharmony_ci length = ARRAY_SIZE(fg_attrs); 1088e66f31c5Sopenharmony_ci for (i = 0; i < length; i++) { 1089e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1090e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 1091e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 1092e66f31c5Sopenharmony_ci attr = (expect.si.default_attr & ~FOREGROUND_WHITE) | fg_attrs[i][1]; 1093e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1094e66f31c5Sopenharmony_ci make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); 1095e66f31c5Sopenharmony_ci 1096e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1097e66f31c5Sopenharmony_ci snprintf( 1098e66f31c5Sopenharmony_ci buffer, sizeof(buffer), "%s%dm%s%sm", CSI, fg_attrs[i][0], HELLO, CSI); 1099e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1100e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1101e66f31c5Sopenharmony_ci 1102e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1103e66f31c5Sopenharmony_ci } 1104e66f31c5Sopenharmony_ci 1105e66f31c5Sopenharmony_ci /* Set background color */ 1106e66f31c5Sopenharmony_ci length = ARRAY_SIZE(bg_attrs); 1107e66f31c5Sopenharmony_ci for (i = 0; i < length; i++) { 1108e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1109e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 1110e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 1111e66f31c5Sopenharmony_ci attr = (expect.si.default_attr & ~BACKGROUND_WHITE) | bg_attrs[i][1]; 1112e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1113e66f31c5Sopenharmony_ci make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); 1114e66f31c5Sopenharmony_ci 1115e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1116e66f31c5Sopenharmony_ci snprintf( 1117e66f31c5Sopenharmony_ci buffer, sizeof(buffer), "%s%dm%s%sm", CSI, bg_attrs[i][0], HELLO, CSI); 1118e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1119e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1120e66f31c5Sopenharmony_ci 1121e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1122e66f31c5Sopenharmony_ci } 1123e66f31c5Sopenharmony_ci 1124e66f31c5Sopenharmony_ci /* Set foreground and background color */ 1125e66f31c5Sopenharmony_ci ASSERT_EQ(ARRAY_SIZE(fg_attrs), ARRAY_SIZE(bg_attrs)); 1126e66f31c5Sopenharmony_ci length = ARRAY_SIZE(bg_attrs); 1127e66f31c5Sopenharmony_ci for (i = 0; i < length; i++) { 1128e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1129e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 1130e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 1131e66f31c5Sopenharmony_ci attr = expect.si.default_attr & ~FOREGROUND_WHITE & ~BACKGROUND_WHITE; 1132e66f31c5Sopenharmony_ci attr |= fg_attrs[i][1] | bg_attrs[i][1]; 1133e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1134e66f31c5Sopenharmony_ci make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); 1135e66f31c5Sopenharmony_ci 1136e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1137e66f31c5Sopenharmony_ci snprintf(buffer, 1138e66f31c5Sopenharmony_ci sizeof(buffer), 1139e66f31c5Sopenharmony_ci "%s%d;%dm%s%sm", 1140e66f31c5Sopenharmony_ci CSI, 1141e66f31c5Sopenharmony_ci bg_attrs[i][0], 1142e66f31c5Sopenharmony_ci fg_attrs[i][0], 1143e66f31c5Sopenharmony_ci HELLO, 1144e66f31c5Sopenharmony_ci CSI); 1145e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1146e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1147e66f31c5Sopenharmony_ci 1148e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1149e66f31c5Sopenharmony_ci } 1150e66f31c5Sopenharmony_ci 1151e66f31c5Sopenharmony_ci /* Set foreground bright on */ 1152e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1153e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 1154e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 1155e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1156e66f31c5Sopenharmony_ci attr = expect.si.default_attr; 1157e66f31c5Sopenharmony_ci attr |= FOREGROUND_INTENSITY; 1158e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1159e66f31c5Sopenharmony_ci make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); 1160e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1161e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1162e66f31c5Sopenharmony_ci make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); 1163e66f31c5Sopenharmony_ci 1164e66f31c5Sopenharmony_ci snprintf(buffer, 1165e66f31c5Sopenharmony_ci sizeof(buffer), 1166e66f31c5Sopenharmony_ci "%s%dm%s%s%dm%s%dm%s%s%dm", 1167e66f31c5Sopenharmony_ci CSI, 1168e66f31c5Sopenharmony_ci F_INTENSITY, 1169e66f31c5Sopenharmony_ci HELLO, 1170e66f31c5Sopenharmony_ci CSI, 1171e66f31c5Sopenharmony_ci F_INTENSITY_OFF1, 1172e66f31c5Sopenharmony_ci CSI, 1173e66f31c5Sopenharmony_ci F_INTENSITY, 1174e66f31c5Sopenharmony_ci HELLO, 1175e66f31c5Sopenharmony_ci CSI, 1176e66f31c5Sopenharmony_ci F_INTENSITY_OFF2); 1177e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1178e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1179e66f31c5Sopenharmony_ci 1180e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1181e66f31c5Sopenharmony_ci 1182e66f31c5Sopenharmony_ci /* Set background bright on */ 1183e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1184e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 1185e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 1186e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1187e66f31c5Sopenharmony_ci attr = expect.si.default_attr; 1188e66f31c5Sopenharmony_ci attr |= BACKGROUND_INTENSITY; 1189e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1190e66f31c5Sopenharmony_ci make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); 1191e66f31c5Sopenharmony_ci 1192e66f31c5Sopenharmony_ci snprintf(buffer, 1193e66f31c5Sopenharmony_ci sizeof(buffer), 1194e66f31c5Sopenharmony_ci "%s%dm%s%s%dm", 1195e66f31c5Sopenharmony_ci CSI, 1196e66f31c5Sopenharmony_ci B_INTENSITY, 1197e66f31c5Sopenharmony_ci HELLO, 1198e66f31c5Sopenharmony_ci CSI, 1199e66f31c5Sopenharmony_ci B_INTENSITY_OFF); 1200e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1201e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1202e66f31c5Sopenharmony_ci 1203e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1204e66f31c5Sopenharmony_ci 1205e66f31c5Sopenharmony_ci /* Inverse */ 1206e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1207e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 1208e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 1209e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1210e66f31c5Sopenharmony_ci attr = expect.si.default_attr; 1211e66f31c5Sopenharmony_ci fg = attr & FOREGROUND_WHITE; 1212e66f31c5Sopenharmony_ci bg = attr & BACKGROUND_WHITE; 1213e66f31c5Sopenharmony_ci attr &= (~FOREGROUND_WHITE & ~BACKGROUND_WHITE); 1214e66f31c5Sopenharmony_ci attr |= COMMON_LVB_REVERSE_VIDEO; 1215e66f31c5Sopenharmony_ci attr |= fg << 4; 1216e66f31c5Sopenharmony_ci attr |= bg >> 4; 1217e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1218e66f31c5Sopenharmony_ci make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); 1219e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1220e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1221e66f31c5Sopenharmony_ci 1222e66f31c5Sopenharmony_ci snprintf(buffer, 1223e66f31c5Sopenharmony_ci sizeof(buffer), 1224e66f31c5Sopenharmony_ci "%s%dm%s%s%dm%s", 1225e66f31c5Sopenharmony_ci CSI, 1226e66f31c5Sopenharmony_ci INVERSE, 1227e66f31c5Sopenharmony_ci HELLO, 1228e66f31c5Sopenharmony_ci CSI, 1229e66f31c5Sopenharmony_ci INVERSE_OFF, 1230e66f31c5Sopenharmony_ci HELLO); 1231e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1232e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1233e66f31c5Sopenharmony_ci 1234e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1235e66f31c5Sopenharmony_ci 1236e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 1237e66f31c5Sopenharmony_ci 1238e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 1239e66f31c5Sopenharmony_ci 1240e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 1241e66f31c5Sopenharmony_ci return 0; 1242e66f31c5Sopenharmony_ci#endif 1243e66f31c5Sopenharmony_ci} 1244e66f31c5Sopenharmony_ci 1245e66f31c5Sopenharmony_ci 1246e66f31c5Sopenharmony_ciTEST_IMPL(tty_save_restore_cursor_position) { 1247e66f31c5Sopenharmony_ci uv_tty_t tty_out; 1248e66f31c5Sopenharmony_ci uv_loop_t* loop; 1249e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 1250e66f31c5Sopenharmony_ci char buffer[1024]; 1251e66f31c5Sopenharmony_ci struct screen_info si; 1252e66f31c5Sopenharmony_ci 1253e66f31c5Sopenharmony_ci loop = uv_default_loop(); 1254e66f31c5Sopenharmony_ci 1255e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 1256e66f31c5Sopenharmony_ci get_screen_info(&tty_out, &si); 1257e66f31c5Sopenharmony_ci 1258e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 1259e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 1260e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 1261e66f31c5Sopenharmony_ci 1262e66f31c5Sopenharmony_ci /* save the cursor position */ 1263e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%ss", CSI); 1264e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1265e66f31c5Sopenharmony_ci 1266e66f31c5Sopenharmony_ci cursor_pos.X = si.width / 4; 1267e66f31c5Sopenharmony_ci cursor_pos.Y = si.height / 4; 1268e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1269e66f31c5Sopenharmony_ci 1270e66f31c5Sopenharmony_ci /* restore the cursor position */ 1271e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%su", CSI); 1272e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1273e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 1274e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos.X, cursor_pos_old.X); 1275e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos.Y, cursor_pos_old.Y); 1276e66f31c5Sopenharmony_ci 1277e66f31c5Sopenharmony_ci cursor_pos_old.X = si.width / 2; 1278e66f31c5Sopenharmony_ci cursor_pos_old.Y = si.height / 2; 1279e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 1280e66f31c5Sopenharmony_ci 1281e66f31c5Sopenharmony_ci /* save the cursor position */ 1282e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s7", ESC); 1283e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1284e66f31c5Sopenharmony_ci 1285e66f31c5Sopenharmony_ci cursor_pos.X = si.width / 4; 1286e66f31c5Sopenharmony_ci cursor_pos.Y = si.height / 4; 1287e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1288e66f31c5Sopenharmony_ci 1289e66f31c5Sopenharmony_ci /* restore the cursor position */ 1290e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s8", ESC); 1291e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1292e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 1293e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos.X, cursor_pos_old.X); 1294e66f31c5Sopenharmony_ci ASSERT_EQ(cursor_pos.Y, cursor_pos_old.Y); 1295e66f31c5Sopenharmony_ci 1296e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 1297e66f31c5Sopenharmony_ci 1298e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 1299e66f31c5Sopenharmony_ci 1300e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 1301e66f31c5Sopenharmony_ci return 0; 1302e66f31c5Sopenharmony_ci} 1303e66f31c5Sopenharmony_ci 1304e66f31c5Sopenharmony_ci 1305e66f31c5Sopenharmony_ciTEST_IMPL(tty_full_reset) { 1306e66f31c5Sopenharmony_ci uv_tty_t tty_out; 1307e66f31c5Sopenharmony_ci uv_loop_t* loop; 1308e66f31c5Sopenharmony_ci char buffer[1024]; 1309e66f31c5Sopenharmony_ci struct captured_screen actual = {0}, expect = {0}; 1310e66f31c5Sopenharmony_ci COORD cursor_pos; 1311e66f31c5Sopenharmony_ci DWORD saved_cursor_size; 1312e66f31c5Sopenharmony_ci BOOL saved_cursor_visibility; 1313e66f31c5Sopenharmony_ci 1314e66f31c5Sopenharmony_ci loop = uv_default_loop(); 1315e66f31c5Sopenharmony_ci 1316e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 1317e66f31c5Sopenharmony_ci 1318e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1319e66f31c5Sopenharmony_ci setup_screen(&tty_out); 1320e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width; 1321e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height; 1322e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1323e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s%d;%dm%s", CSI, F_CYAN, B_YELLOW, HELLO); 1324e66f31c5Sopenharmony_ci saved_cursor_size = get_cursor_size(&tty_out); 1325e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, 1326e66f31c5Sopenharmony_ci saved_cursor_size == CURSOR_SIZE_LARGE ? CURSOR_SIZE_SMALL 1327e66f31c5Sopenharmony_ci : CURSOR_SIZE_LARGE); 1328e66f31c5Sopenharmony_ci saved_cursor_visibility = get_cursor_visibility(&tty_out); 1329e66f31c5Sopenharmony_ci set_cursor_visibility(&tty_out, saved_cursor_visibility ? FALSE : TRUE); 1330e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1331e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sc", ESC); 1332e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1333e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1334e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1335e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), saved_cursor_size); 1336e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_visibility(&tty_out), saved_cursor_visibility); 1337e66f31c5Sopenharmony_ci ASSERT_OK(actual.si.csbi.srWindow.Top); 1338e66f31c5Sopenharmony_ci 1339e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 1340e66f31c5Sopenharmony_ci 1341e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 1342e66f31c5Sopenharmony_ci 1343e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 1344e66f31c5Sopenharmony_ci return 0; 1345e66f31c5Sopenharmony_ci} 1346e66f31c5Sopenharmony_ci 1347e66f31c5Sopenharmony_ci 1348e66f31c5Sopenharmony_ciTEST_IMPL(tty_escape_sequence_processing) { 1349e66f31c5Sopenharmony_ci#if _MSC_VER >= 1920 && _MSC_VER <= 1929 1350e66f31c5Sopenharmony_ci RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " 1351e66f31c5Sopenharmony_ci "See: https://github.com/libuv/libuv/issues/3304"); 1352e66f31c5Sopenharmony_ci#else 1353e66f31c5Sopenharmony_ci uv_tty_t tty_out; 1354e66f31c5Sopenharmony_ci uv_loop_t* loop; 1355e66f31c5Sopenharmony_ci COORD cursor_pos, cursor_pos_old; 1356e66f31c5Sopenharmony_ci DWORD saved_cursor_size; 1357e66f31c5Sopenharmony_ci char buffer[1024]; 1358e66f31c5Sopenharmony_ci struct captured_screen actual = {0}, expect = {0}; 1359e66f31c5Sopenharmony_ci int dir; 1360e66f31c5Sopenharmony_ci 1361e66f31c5Sopenharmony_ci loop = uv_default_loop(); 1362e66f31c5Sopenharmony_ci 1363e66f31c5Sopenharmony_ci initialize_tty(&tty_out); 1364e66f31c5Sopenharmony_ci 1365e66f31c5Sopenharmony_ci /* CSI + finally byte does not output anything */ 1366e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1367e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1368e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1369e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1370e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1371e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1372e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1373e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s@%s%s~%s", CSI, HELLO, CSI, HELLO); 1374e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1375e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1376e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1377e66f31c5Sopenharmony_ci 1378e66f31c5Sopenharmony_ci /* CSI(C1) + finally byte does not output anything */ 1379e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1380e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1381e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1382e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1383e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1384e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1385e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1386e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "\xC2\x9B@%s\xC2\x9B~%s", HELLO, HELLO); 1387e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1388e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1389e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1390e66f31c5Sopenharmony_ci 1391e66f31c5Sopenharmony_ci /* CSI + intermediate byte + finally byte does not output anything */ 1392e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1393e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1394e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1395e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1396e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1397e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1398e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1399e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s @%s%s/~%s", CSI, HELLO, CSI, HELLO); 1400e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1401e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1402e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1403e66f31c5Sopenharmony_ci 1404e66f31c5Sopenharmony_ci /* CSI + parameter byte + finally byte does not output anything */ 1405e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1406e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1407e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1408e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1409e66f31c5Sopenharmony_ci snprintf(buffer, 1410e66f31c5Sopenharmony_ci sizeof(buffer), 1411e66f31c5Sopenharmony_ci "%s0@%s%s>~%s%s?~%s", 1412e66f31c5Sopenharmony_ci CSI, 1413e66f31c5Sopenharmony_ci HELLO, 1414e66f31c5Sopenharmony_ci CSI, 1415e66f31c5Sopenharmony_ci HELLO, 1416e66f31c5Sopenharmony_ci CSI, 1417e66f31c5Sopenharmony_ci HELLO); 1418e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1419e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1420e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1421e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1422e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1423e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1424e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1425e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1426e66f31c5Sopenharmony_ci 1427e66f31c5Sopenharmony_ci /* ESC Single-char control does not output anyghing */ 1428e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1429e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1430e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1431e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1432e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1433e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1434e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1435e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s @%s%s/~%s", CSI, HELLO, CSI, HELLO); 1436e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1437e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1438e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1439e66f31c5Sopenharmony_ci 1440e66f31c5Sopenharmony_ci /* Nothing is output from ESC + ^, _, P, ] to BEL or ESC \ */ 1441e66f31c5Sopenharmony_ci /* Operaging System Command */ 1442e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1443e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1444e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1445e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1446e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1447e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s]0;%s%s%s", ESC, HELLO, BEL, HELLO); 1448e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1449e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1450e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1451e66f31c5Sopenharmony_ci /* Device Control Sequence */ 1452e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1453e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1454e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1455e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1456e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1457e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%sP$m%s%s", ESC, ST, HELLO); 1458e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1459e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1460e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1461e66f31c5Sopenharmony_ci /* Privacy Message */ 1462e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1463e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1464e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1465e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1466e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1467e66f31c5Sopenharmony_ci snprintf(buffer, 1468e66f31c5Sopenharmony_ci sizeof(buffer), 1469e66f31c5Sopenharmony_ci "%s^\"%s\\\"%s\"%s%s", 1470e66f31c5Sopenharmony_ci ESC, 1471e66f31c5Sopenharmony_ci HELLO, 1472e66f31c5Sopenharmony_ci HELLO, 1473e66f31c5Sopenharmony_ci ST, 1474e66f31c5Sopenharmony_ci HELLO); 1475e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1476e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1477e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1478e66f31c5Sopenharmony_ci /* Application Program Command */ 1479e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1480e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1481e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1482e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1483e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1484e66f31c5Sopenharmony_ci snprintf(buffer, 1485e66f31c5Sopenharmony_ci sizeof(buffer), 1486e66f31c5Sopenharmony_ci "%s_\"%s%s%s\"%s%s", 1487e66f31c5Sopenharmony_ci ESC, 1488e66f31c5Sopenharmony_ci HELLO, 1489e66f31c5Sopenharmony_ci ST, 1490e66f31c5Sopenharmony_ci HELLO, 1491e66f31c5Sopenharmony_ci BEL, 1492e66f31c5Sopenharmony_ci HELLO); 1493e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1494e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1495e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1496e66f31c5Sopenharmony_ci 1497e66f31c5Sopenharmony_ci /* Ignore double escape */ 1498e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1499e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1500e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1501e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1502e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1503e66f31c5Sopenharmony_ci cursor_pos.X += strlen(HELLO); 1504e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1505e66f31c5Sopenharmony_ci snprintf(buffer, 1506e66f31c5Sopenharmony_ci sizeof(buffer), 1507e66f31c5Sopenharmony_ci "%s%s@%s%s%s~%s", 1508e66f31c5Sopenharmony_ci ESC, 1509e66f31c5Sopenharmony_ci CSI, 1510e66f31c5Sopenharmony_ci HELLO, 1511e66f31c5Sopenharmony_ci ESC, 1512e66f31c5Sopenharmony_ci CSI, 1513e66f31c5Sopenharmony_ci HELLO); 1514e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1515e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1516e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1517e66f31c5Sopenharmony_ci 1518e66f31c5Sopenharmony_ci /* Ignored if argument overflow */ 1519e66f31c5Sopenharmony_ci set_cursor_to_home(&tty_out); 1520e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s1;%dH", CSI, UINT16_MAX + 1); 1521e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1522e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 1523e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 1524e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.Y); 1525e66f31c5Sopenharmony_ci 1526e66f31c5Sopenharmony_ci /* Too many argument are ignored */ 1527e66f31c5Sopenharmony_ci cursor_pos.X = 1; 1528e66f31c5Sopenharmony_ci cursor_pos.Y = 1; 1529e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1530e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1531e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1532e66f31c5Sopenharmony_ci snprintf(buffer, 1533e66f31c5Sopenharmony_ci sizeof(buffer), 1534e66f31c5Sopenharmony_ci "%s%d;%d;%d;%d;%dm%s%sm", 1535e66f31c5Sopenharmony_ci CSI, 1536e66f31c5Sopenharmony_ci F_RED, 1537e66f31c5Sopenharmony_ci F_INTENSITY, 1538e66f31c5Sopenharmony_ci INVERSE, 1539e66f31c5Sopenharmony_ci B_CYAN, 1540e66f31c5Sopenharmony_ci B_INTENSITY_OFF, 1541e66f31c5Sopenharmony_ci HELLO, 1542e66f31c5Sopenharmony_ci CSI); 1543e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1544e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1545e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1546e66f31c5Sopenharmony_ci 1547e66f31c5Sopenharmony_ci /* In the case of DECSCUSR, the others are ignored */ 1548e66f31c5Sopenharmony_ci set_cursor_to_home(&tty_out); 1549e66f31c5Sopenharmony_ci snprintf(buffer, 1550e66f31c5Sopenharmony_ci sizeof(buffer), 1551e66f31c5Sopenharmony_ci "%s%d;%d H", 1552e66f31c5Sopenharmony_ci CSI, 1553e66f31c5Sopenharmony_ci expect.si.height / 2, 1554e66f31c5Sopenharmony_ci expect.si.width / 2); 1555e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1556e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 1557e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.X); 1558e66f31c5Sopenharmony_ci ASSERT_EQ(1, cursor_pos.Y); 1559e66f31c5Sopenharmony_ci 1560e66f31c5Sopenharmony_ci /* Invalid sequence are ignored */ 1561e66f31c5Sopenharmony_ci saved_cursor_size = get_cursor_size(&tty_out); 1562e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); 1563e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s 1q", CSI); 1564e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1565e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_MIDDLE); 1566e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s 1 q", CSI); 1567e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1568e66f31c5Sopenharmony_ci ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_MIDDLE); 1569e66f31c5Sopenharmony_ci set_cursor_size(&tty_out, saved_cursor_size); 1570e66f31c5Sopenharmony_ci 1571e66f31c5Sopenharmony_ci /* #1874 2. */ 1572e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s??25l", CSI); 1573e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1574e66f31c5Sopenharmony_ci ASSERT(get_cursor_visibility(&tty_out)); 1575e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s25?l", CSI); 1576e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1577e66f31c5Sopenharmony_ci ASSERT(get_cursor_visibility(&tty_out)); 1578e66f31c5Sopenharmony_ci cursor_pos_old.X = expect.si.width / 2; 1579e66f31c5Sopenharmony_ci cursor_pos_old.Y = expect.si.height / 2; 1580e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos_old); 1581e66f31c5Sopenharmony_ci snprintf(buffer, 1582e66f31c5Sopenharmony_ci sizeof(buffer), 1583e66f31c5Sopenharmony_ci "%s??%d;%df", 1584e66f31c5Sopenharmony_ci CSI, 1585e66f31c5Sopenharmony_ci expect.si.height / 4, 1586e66f31c5Sopenharmony_ci expect.si.width / 4); 1587e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1588e66f31c5Sopenharmony_ci get_cursor_position(&tty_out, &cursor_pos); 1589e66f31c5Sopenharmony_ci ASSERT(cursor_pos.X = cursor_pos_old.X); 1590e66f31c5Sopenharmony_ci ASSERT(cursor_pos.Y = cursor_pos_old.Y); 1591e66f31c5Sopenharmony_ci set_cursor_to_home(&tty_out); 1592e66f31c5Sopenharmony_ci 1593e66f31c5Sopenharmony_ci /* CSI 25 l does nothing (#1874 4.) */ 1594e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s25l", CSI); 1595e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1596e66f31c5Sopenharmony_ci ASSERT(get_cursor_visibility(&tty_out)); 1597e66f31c5Sopenharmony_ci 1598e66f31c5Sopenharmony_ci /* Unsupported sequences are ignored(#1874 5.) */ 1599e66f31c5Sopenharmony_ci dir = 2; 1600e66f31c5Sopenharmony_ci setup_screen(&tty_out); 1601e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1602e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1603e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s?%dJ", CSI, dir); 1604e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1605e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1606e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1607e66f31c5Sopenharmony_ci 1608e66f31c5Sopenharmony_ci /* Finally byte immedately after CSI [ are also output(#1874 1.) */ 1609e66f31c5Sopenharmony_ci cursor_pos.X = expect.si.width / 2; 1610e66f31c5Sopenharmony_ci cursor_pos.Y = expect.si.height / 2; 1611e66f31c5Sopenharmony_ci set_cursor_position(&tty_out, cursor_pos); 1612e66f31c5Sopenharmony_ci capture_screen(&tty_out, &expect); 1613e66f31c5Sopenharmony_ci make_expect_screen_write(&expect, cursor_pos, HELLO); 1614e66f31c5Sopenharmony_ci snprintf(buffer, sizeof(buffer), "%s[%s", CSI, HELLO); 1615e66f31c5Sopenharmony_ci write_console(&tty_out, buffer); 1616e66f31c5Sopenharmony_ci capture_screen(&tty_out, &actual); 1617e66f31c5Sopenharmony_ci ASSERT(compare_screen(&tty_out, &actual, &expect)); 1618e66f31c5Sopenharmony_ci 1619e66f31c5Sopenharmony_ci terminate_tty(&tty_out); 1620e66f31c5Sopenharmony_ci 1621e66f31c5Sopenharmony_ci uv_run(loop, UV_RUN_DEFAULT); 1622e66f31c5Sopenharmony_ci 1623e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 1624e66f31c5Sopenharmony_ci return 0; 1625e66f31c5Sopenharmony_ci#endif 1626e66f31c5Sopenharmony_ci} 1627e66f31c5Sopenharmony_ci 1628e66f31c5Sopenharmony_ci#else 1629e66f31c5Sopenharmony_ci 1630e66f31c5Sopenharmony_citypedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ 1631e66f31c5Sopenharmony_ci 1632e66f31c5Sopenharmony_ci#endif /* ifdef _WIN32 */ 1633