summaryrefslogtreecommitdiffstats
path: root/osdep
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2024-03-23 03:30:43 +0100
committerKacper Michajłow <kasper93@gmail.com>2024-04-07 20:18:05 +0200
commit0f85a380c381fa925dd2288a0e2fbe384dcbf0a9 (patch)
tree127bfdc24af5093370b86191d676ff0884bdcd72 /osdep
parent2f76536f6211a1b80f6eca2582bb79048ca220b1 (diff)
downloadmpv-0f85a380c381fa925dd2288a0e2fbe384dcbf0a9.tar.bz2
mpv-0f85a380c381fa925dd2288a0e2fbe384dcbf0a9.tar.xz
terminal-win: add more control codes support in non-VT mode
And skip unsupported private sequences, instead of printing them.
Diffstat (limited to 'osdep')
-rw-r--r--osdep/terminal-win.c82
1 files changed, 76 insertions, 6 deletions
diff --git a/osdep/terminal-win.c b/osdep/terminal-win.c
index dc8e10407d..238d4b95b7 100644
--- a/osdep/terminal-win.c
+++ b/osdep/terminal-win.c
@@ -285,6 +285,10 @@ int mp_console_fputs(HANDLE wstream, bstr str)
// CSI - Control Sequence Introducer
next += 2;
+ // private sequences
+ bool priv = next[0] == '?';
+ next += priv;
+
// CSI codes generally follow this syntax:
// "\033[" [ <i> (';' <i> )* ] <c>
// where <i> are integers, and <c> a single char command code.
@@ -308,18 +312,84 @@ int mp_console_fputs(HANDLE wstream, bstr str)
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(wstream, &info);
switch (code) {
- case 'K': { // erase to end of line
- COORD at = info.dwCursorPosition;
- int len = info.dwSize.X - at.X;
- FillConsoleOutputCharacterW(wstream, ' ', len, at, &(DWORD){0});
- SetConsoleCursorPosition(wstream, at);
+ case 'K': { // erase line
+ COORD cursor_pos = info.dwCursorPosition;
+ COORD at = cursor_pos;
+ int len;
+ switch (num_params ? params[0] : 0) {
+ case 1:
+ len = at.X;
+ at.X = 0;
+ break;
+ case 2:
+ len = info.dwSize.X;
+ at.X = 0;
+ break;
+ case 0:
+ default:
+ len = info.dwSize.X - at.X;
+ }
+ FillConsoleOutputCharacterW(wstream, L' ', len, at, &(DWORD){0});
+ SetConsoleCursorPosition(wstream, cursor_pos);
+ break;
+ }
+ case 'B': { // cursor down
+ info.dwCursorPosition.Y += !num_params ? 1 : params[0];
+ SetConsoleCursorPosition(wstream, info.dwCursorPosition);
break;
}
case 'A': { // cursor up
- info.dwCursorPosition.Y -= 1;
+ info.dwCursorPosition.Y -= !num_params ? 1 : params[0];
SetConsoleCursorPosition(wstream, info.dwCursorPosition);
break;
}
+ case 'J': {
+ // Only full screen clear is supported
+ if (!num_params || params[0] != 2)
+ break;
+
+ COORD top_left = {0, 0};
+ FillConsoleOutputCharacterW(wstream, L' ', info.dwSize.X * info.dwSize.Y,
+ top_left, &(DWORD){0});
+ SetConsoleCursorPosition(wstream, top_left);
+ break;
+ }
+ case 'f': {
+ if (num_params != 2)
+ break;
+ SetConsoleCursorPosition(wstream, (COORD){params[0], params[1]});
+ break;
+ }
+ case 'l': {
+ if (!priv || !num_params)
+ break;
+
+ switch (params[0]) {
+ case 25:; // hide the cursor
+ CONSOLE_CURSOR_INFO cursor_info;
+ if (!GetConsoleCursorInfo(wstream, &cursor_info))
+ break;
+ cursor_info.bVisible = FALSE;
+ SetConsoleCursorInfo(wstream, &cursor_info);
+ break;
+ }
+ break;
+ }
+ case 'h': {
+ if (!priv || !num_params)
+ break;
+
+ switch (params[0]) {
+ case 25:; // show the cursor
+ CONSOLE_CURSOR_INFO cursor_info;
+ if (!GetConsoleCursorInfo(wstream, &cursor_info))
+ break;
+ cursor_info.bVisible = TRUE;
+ SetConsoleCursorInfo(wstream, &cursor_info);
+ break;
+ }
+ break;
+ }
case 'm': { // "SGR"
short attr = info.wAttributes;
if (num_params == 0) // reset