And skip unsupported private sequences, instead of printing them.
Unified · Split
| @@ -285,6 +285,10 @@ int mp_console_fputs(HANDLE wstream, bstr str) · 284 unmodified lines | |||
| 285 | // CSI - Control Sequence Introducer | 285 | // CSI - Control Sequence Introducer |
| 286 | next += 2; | 286 | next += 2; |
| 287 | 287 | ||
| 288 | // private sequences | ||
| 289 | bool priv = next[0] == '?'; | ||
| 290 | next += priv; | ||
| 291 | |||
| 288 | // CSI codes generally follow this syntax: | 292 | // CSI codes generally follow this syntax: |
| 289 | // "\033[" [ <i> (';' <i> )* ] <c> | 293 | // "\033[" [ <i> (';' <i> )* ] <c> |
| 290 | // where <i> are integers, and <c> a single char command code. | 294 | // where <i> are integers, and <c> a single char command code. |
| @@ -308,18 +312,84 @@ int mp_console_fputs(HANDLE wstream, bstr str) · 17 unmodified lines | |||
| 308 | CONSOLE_SCREEN_BUFFER_INFO info; | 312 | CONSOLE_SCREEN_BUFFER_INFO info; |
| 309 | GetConsoleScreenBufferInfo(wstream, &info); | 313 | GetConsoleScreenBufferInfo(wstream, &info); |
| 310 | switch (code) { | 314 | switch (code) { |
| 311 | case 'K': { // erase to end of line | 315 | case 'K': { // erase line |
| 312 | COORD at = info.dwCursorPosition; | 316 | COORD cursor_pos = info.dwCursorPosition; |
| 313 | int len = info.dwSize.X - at.X; | 317 | COORD at = cursor_pos; |
| 314 | FillConsoleOutputCharacterW(wstream, ' ', len, at, &(DWORD){0}); | 318 | int len; |
| 315 | SetConsoleCursorPosition(wstream, at); | 319 | switch (num_params ? params[0] : 0) { |
| 320 | case 1: | ||
| 321 | len = at.X; | ||
| 322 | at.X = 0; | ||
| 323 | break; | ||
| 324 | case 2: | ||
| 325 | len = info.dwSize.X; | ||
| 326 | at.X = 0; | ||
| 327 | break; | ||
| 328 | case 0: | ||
| 329 | default: | ||
| 330 | len = info.dwSize.X - at.X; | ||
| 331 | } | ||
| 332 | FillConsoleOutputCharacterW(wstream, L' ', len, at, &(DWORD){0}); | ||
| 333 | SetConsoleCursorPosition(wstream, cursor_pos); | ||
| 334 | break; | ||
| 335 | } | ||
| 336 | case 'B': { // cursor down | ||
| 337 | info.dwCursorPosition.Y += !num_params ? 1 : params[0]; | ||
| 338 | SetConsoleCursorPosition(wstream, info.dwCursorPosition); | ||
| 316 | break; | 339 | break; |
| 317 | } | 340 | } |
| 318 | case 'A': { // cursor up | 341 | case 'A': { // cursor up |
| 319 | info.dwCursorPosition.Y -= 1; | 342 | info.dwCursorPosition.Y -= !num_params ? 1 : params[0]; |
| 320 | SetConsoleCursorPosition(wstream, info.dwCursorPosition); | 343 | SetConsoleCursorPosition(wstream, info.dwCursorPosition); |
| 321 | break; | 344 | break; |
| 322 | } | 345 | } |
| 346 | case 'J': { | ||
| 347 | // Only full screen clear is supported | ||
| 348 | if (!num_params || params[0] != 2) | ||
| 349 | break; | ||
| 350 | |||
| 351 | COORD top_left = {0, 0}; | ||
| 352 | FillConsoleOutputCharacterW(wstream, L' ', info.dwSize.X * info.dwSize.Y, | ||
| 353 | top_left, &(DWORD){0}); | ||
| 354 | SetConsoleCursorPosition(wstream, top_left); | ||
| 355 | break; | ||
| 356 | } | ||
| 357 | case 'f': { | ||
| 358 | if (num_params != 2) | ||
| 359 | break; | ||
| 360 | SetConsoleCursorPosition(wstream, (COORD){params[0], params[1]}); | ||
| 361 | break; | ||
| 362 | } | ||
| 363 | case 'l': { | ||
| 364 | if (!priv || !num_params) | ||
| 365 | break; | ||
| 366 | |||
| 367 | switch (params[0]) { | ||
| 368 | case 25:; // hide the cursor | ||
| 369 | CONSOLE_CURSOR_INFO cursor_info; | ||
| 370 | if (!GetConsoleCursorInfo(wstream, &cursor_info)) | ||
| 371 | break; | ||
| 372 | cursor_info.bVisible = FALSE; | ||
| 373 | SetConsoleCursorInfo(wstream, &cursor_info); | ||
| 374 | break; | ||
| 375 | } | ||
| 376 | break; | ||
| 377 | } | ||
| 378 | case 'h': { | ||
| 379 | if (!priv || !num_params) | ||
| 380 | break; | ||
| 381 | |||
| 382 | switch (params[0]) { | ||
| 383 | case 25:; // show the cursor | ||
| 384 | CONSOLE_CURSOR_INFO cursor_info; | ||
| 385 | if (!GetConsoleCursorInfo(wstream, &cursor_info)) | ||
| 386 | break; | ||
| 387 | cursor_info.bVisible = TRUE; | ||
| 388 | SetConsoleCursorInfo(wstream, &cursor_info); | ||
| 389 | break; | ||
| 390 | } | ||
| 391 | break; | ||
| 392 | } | ||
| 323 | case 'm': { // "SGR" | 393 | case 'm': { // "SGR" |
| 324 | short attr = info.wAttributes; | 394 | short attr = info.wAttributes; |
| 325 | if (num_params == 0) // reset | 395 | if (num_params == 0) // reset |