mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-03 20:22:38 +00:00
Add VT sequences input support ##windows (#16747)
* Add VT sequences input support ##windows * Fix radare2 immediately exiting when console is redirected to pipe * Hack to get viewport size under MinTTY * Fix mouse when VT input disabled and buffer scrolled * Fix line wrapping when VT output disabled * Fix build on VS2017 * Fix for comments * fix some weirdness * Fix losing echo after exiting
This commit is contained in:
parent
502b4b0f52
commit
153de56173
159
libr/cons/cons.c
159
libr/cons/cons.c
@ -134,7 +134,7 @@ static void __break_signal(int sig) {
|
||||
|
||||
static inline void __cons_write_ll(const char *buf, int len) {
|
||||
#if __WINDOWS__
|
||||
if (I.ansicon) {
|
||||
if (I.vtmode) {
|
||||
(void) write (I.fdout, buf, len);
|
||||
} else {
|
||||
if (I.fdout == 1) {
|
||||
@ -471,17 +471,21 @@ R_API void r_cons_enable_highlight(const bool enable) {
|
||||
}
|
||||
|
||||
R_API bool r_cons_enable_mouse(const bool enable) {
|
||||
#if __UNIX__
|
||||
const char *click = enable
|
||||
? "\x1b[?1000;1006;1015h"
|
||||
: "\x1b[?1001r" "\x1b[?1000l";
|
||||
#if __WINDOWS__
|
||||
if (I.vtmode == 2) {
|
||||
#endif
|
||||
const char *click = enable
|
||||
? "\x1b[?1000;1006;1015h"
|
||||
: "\x1b[?1001r"
|
||||
"\x1b[?1000l";
|
||||
// : "\x1b[?1000;1006;1015l";
|
||||
// const char *old = enable ? "\x1b[?1001s" "\x1b[?1000h" : "\x1b[?1001r" "\x1b[?1000l";
|
||||
bool enabled = I.mouse;
|
||||
I.mouse = enable;
|
||||
write (2, click, strlen (click));
|
||||
return enabled;
|
||||
#elif __WINDOWS__
|
||||
// const char *old = enable ? "\x1b[?1001s" "\x1b[?1000h" : "\x1b[?1001r" "\x1b[?1000l";
|
||||
bool enabled = I.mouse;
|
||||
I.mouse = enable;
|
||||
write (2, click, strlen (click));
|
||||
return enabled;
|
||||
#if __WINDOWS__
|
||||
}
|
||||
DWORD mode, mouse;
|
||||
HANDLE h;
|
||||
bool enabled = I.mouse;
|
||||
@ -537,7 +541,9 @@ R_API RCons *r_cons_new() {
|
||||
I.num = NULL;
|
||||
I.null = 0;
|
||||
#if __WINDOWS__
|
||||
I.ansicon = r_cons_is_ansicon ();
|
||||
I.vtmode = r_cons_is_vtcompat ();
|
||||
#else
|
||||
I.vtmode = 2;
|
||||
#endif
|
||||
#if EMSCRIPTEN
|
||||
/* do nothing here :? */
|
||||
@ -659,7 +665,7 @@ R_API void r_cons_fill_line() {
|
||||
|
||||
R_API void r_cons_clear_line(int std_err) {
|
||||
#if __WINDOWS__
|
||||
if (I.ansicon) {
|
||||
if (I.vtmode) {
|
||||
fprintf (std_err? stderr: stdout,"%s", R_CONS_CLEAR_LINE);
|
||||
} else {
|
||||
char white[1024];
|
||||
@ -962,7 +968,7 @@ R_API void r_cons_visual_flush() {
|
||||
if (!I.null) {
|
||||
/* TODO: this ifdef must go in the function body */
|
||||
#if __WINDOWS__
|
||||
if (I.ansicon) {
|
||||
if (I.vtmode) {
|
||||
r_cons_visual_write (I.context->buffer);
|
||||
} else {
|
||||
r_cons_w32_print (I.context->buffer, I.context->buffer_len, true);
|
||||
@ -997,7 +1003,7 @@ R_API void r_cons_print_fps (int col) {
|
||||
col = 12;
|
||||
}
|
||||
#ifdef __WINDOWS__
|
||||
if (I.ansicon) {
|
||||
if (I.vtmode) {
|
||||
eprintf ("\x1b[0;%dH[%d FPS] \n", w - col, fps);
|
||||
} else {
|
||||
r_cons_w32_gotoxy (2, w - col, 0);
|
||||
@ -1279,17 +1285,75 @@ R_API bool r_cons_isatty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if __WINDOWS__
|
||||
static int __xterm_get_cur_pos(int *xpos) {
|
||||
int ypos = 0;
|
||||
const char *get_pos = R_CONS_GET_CURSOR_POSITION;
|
||||
if (write (I.fdout, get_pos, sizeof (get_pos)) < 1) {
|
||||
return 0;
|
||||
}
|
||||
int ch = r_cons_readchar ();
|
||||
if (ch != 0x1b) {
|
||||
while (ch = r_cons_readchar_timeout (25)) {
|
||||
if (ch < 1) {
|
||||
return 0;
|
||||
}
|
||||
if (ch == 0x1b) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)r_cons_readchar ();
|
||||
char pos[16] = { 0 };
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof (pos); i++) {
|
||||
if ((ch = r_cons_readchar ()) == ';') {
|
||||
break;
|
||||
}
|
||||
pos[i] = ch;
|
||||
}
|
||||
ypos = atoi (pos);
|
||||
pos[0] = '\0';
|
||||
for (i = 0; i < sizeof (pos); i++) {
|
||||
if ((ch = r_cons_readchar ()) == 'R') {
|
||||
break;
|
||||
}
|
||||
pos[i] = ch;
|
||||
}
|
||||
*xpos = atoi (pos);
|
||||
|
||||
return ypos;
|
||||
}
|
||||
|
||||
static bool __xterm_get_size(void) {
|
||||
if (write (I.fdout, R_CONS_CURSOR_SAVE, sizeof (R_CONS_CURSOR_SAVE)) < 1) {
|
||||
return false;
|
||||
}
|
||||
(void)write (I.fdout, "\x1b[999;999H", sizeof ("\x1b[999;999H"));
|
||||
I.rows = __xterm_get_cur_pos (&I.columns);
|
||||
(void)write (I.fdout, R_CONS_CURSOR_RESTORE, sizeof (R_CONS_CURSOR_RESTORE));
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// XXX: if this function returns <0 in rows or cols expect MAYHEM
|
||||
R_API int r_cons_get_size(int *rows) {
|
||||
#if __WINDOWS__
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
bool ret = GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi);
|
||||
I.columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
||||
I.rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
if (!ret || (I.columns == -1 && I.rows == 0)) {
|
||||
// Stdout is probably redirected so we set default values
|
||||
I.columns = 80;
|
||||
I.rows = 23;
|
||||
if (ret) {
|
||||
I.columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
||||
I.rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
} else {
|
||||
if (I.term_xterm) {
|
||||
ret = __xterm_get_size ();
|
||||
}
|
||||
if (!ret || (I.columns == -1 && I.rows == 0)) {
|
||||
// Stdout is probably redirected so we set default values
|
||||
I.columns = 80;
|
||||
I.rows = 23;
|
||||
}
|
||||
}
|
||||
#elif EMSCRIPTEN
|
||||
I.columns = 80;
|
||||
@ -1361,11 +1425,31 @@ R_API int r_cons_get_size(int *rows) {
|
||||
}
|
||||
|
||||
#if __WINDOWS__
|
||||
R_API bool r_cons_is_ansicon(void) {
|
||||
R_API int r_cons_is_vtcompat(void) {
|
||||
DWORD major;
|
||||
DWORD minor;
|
||||
DWORD release = 0;
|
||||
bool win_support = false;
|
||||
char *wt_session = r_sys_getenv ("WT_SESSION");
|
||||
if (wt_session) {
|
||||
free (wt_session);
|
||||
return 2;
|
||||
}
|
||||
char *term = r_sys_getenv ("TERM");
|
||||
if (term) {
|
||||
if (strstr (term, "xterm")) {
|
||||
I.term_xterm = 1;
|
||||
free (term);
|
||||
return 2;
|
||||
}
|
||||
I.term_xterm = 0;
|
||||
free (term);
|
||||
}
|
||||
char *ansicon = r_sys_getenv ("ANSICON");
|
||||
if (ansicon) {
|
||||
free (ansicon);
|
||||
return 1;
|
||||
}
|
||||
bool win_support = 0;
|
||||
RSysInfo *info = r_sys_info ();
|
||||
if (info && info->version) {
|
||||
char *dot = strtok (info->version, ".");
|
||||
@ -1378,22 +1462,17 @@ R_API bool r_cons_is_ansicon(void) {
|
||||
if (major > 10
|
||||
|| (major == 10 && minor > 0)
|
||||
|| (major == 10 && minor == 0 && release >= 1703)) {
|
||||
win_support = true;
|
||||
win_support = 1;
|
||||
}
|
||||
}
|
||||
r_sys_info_free (info);
|
||||
char *ansicon = r_sys_getenv ("ANSICON");
|
||||
if (ansicon) {
|
||||
free (ansicon);
|
||||
win_support = true;
|
||||
}
|
||||
return win_support;
|
||||
}
|
||||
#endif
|
||||
|
||||
R_API void r_cons_show_cursor(int cursor) {
|
||||
#if __WINDOWS__
|
||||
if (I.ansicon) {
|
||||
if (I.vtmode) {
|
||||
#endif
|
||||
write (1, cursor ? "\x1b[?25h" : "\x1b[?25l", 6);
|
||||
#if __WINDOWS__
|
||||
@ -1446,9 +1525,17 @@ R_API void r_cons_set_raw(bool is_raw) {
|
||||
}
|
||||
#elif __WINDOWS__
|
||||
if (is_raw) {
|
||||
SetConsoleMode (h, I.term_raw);
|
||||
if (I.term_xterm) {
|
||||
r_sandbox_system ("stty raw -echo", 1);
|
||||
} else {
|
||||
SetConsoleMode (h, I.term_raw);
|
||||
}
|
||||
} else {
|
||||
SetConsoleMode (h, I.term_buf);
|
||||
if (I.term_xterm) {
|
||||
r_sandbox_system ("stty -raw echo", 1);
|
||||
} else {
|
||||
SetConsoleMode (h, I.term_buf);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#warning No raw console supported for this platform
|
||||
@ -1503,7 +1590,7 @@ R_API void r_cons_set_cup(int enable) {
|
||||
write (2, code, strlen (code));
|
||||
fflush (stdout);
|
||||
#elif __WINDOWS__
|
||||
if (I.ansicon) {
|
||||
if (I.vtmode) {
|
||||
if (enable) {
|
||||
const char *code =
|
||||
"\x1b[?1049h" // xterm
|
||||
@ -1793,7 +1880,7 @@ R_API void r_cons_cmd_help(const char *help[], bool use_color) {
|
||||
}
|
||||
|
||||
R_API void r_cons_clear_buffer(void) {
|
||||
#if __UNIX__
|
||||
write (1, "\x1b" "c\x1b[3J", 6);
|
||||
#endif
|
||||
if (I.vtmode) {
|
||||
write (1, "\x1b" "c\x1b[3J", 6);
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ static int r_line_readchar_utf8(ut8 *s, int slen) {
|
||||
|
||||
#if __WINDOWS__
|
||||
static int r_line_readchar_win(ut8 *s, int slen) { // this function handle the input in console mode
|
||||
INPUT_RECORD irInBuf;
|
||||
INPUT_RECORD irInBuf = { { 0 } };
|
||||
BOOL ret, bCtrl = FALSE;
|
||||
DWORD mode, out;
|
||||
char buf[5] = {0};
|
||||
@ -275,13 +275,17 @@ static int r_line_readchar_win(ut8 *s, int slen) { // this function handle the i
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
h = GetStdHandle (STD_INPUT_HANDLE);
|
||||
DWORD new_mode = I.vtmode == 2 ? ENABLE_VIRTUAL_TERMINAL_INPUT : 0;
|
||||
GetConsoleMode (h, &mode);
|
||||
SetConsoleMode (h, 0); // RAW
|
||||
SetConsoleMode (h, new_mode);
|
||||
do_it_again:
|
||||
bed = r_cons_sleep_begin ();
|
||||
ret = ReadConsoleInput (h, &irInBuf, 1, &out);
|
||||
if (r_cons_singleton()->term_xterm) {
|
||||
ret = ReadFile (h, buf, 1, &out, NULL);
|
||||
} else {
|
||||
ret = ReadConsoleInput (h, &irInBuf, 1, &out);
|
||||
}
|
||||
r_cons_sleep_end (bed);
|
||||
if (ret < 1) {
|
||||
return 0;
|
||||
@ -1530,12 +1534,16 @@ R_API const char *r_line_readline_cb(RLineReadCallback cb, void *user) {
|
||||
break;
|
||||
case 27: // esc-5b-41-00-00 alt/meta key
|
||||
#if __WINDOWS__
|
||||
memmove (buf, buf + 1, strlen (buf));
|
||||
if (!buf[0]) {
|
||||
buf[0] = -1;
|
||||
if (I.vtmode != 2) {
|
||||
memmove (buf, buf + 1, strlen (buf));
|
||||
if (!buf[0]) {
|
||||
buf[0] = -1;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
buf[0] = r_cons_readchar_timeout (50);
|
||||
#if __WINDOWS__
|
||||
}
|
||||
#else
|
||||
buf[0] = r_cons_readchar_timeout (50);
|
||||
#endif
|
||||
switch (buf[0]) {
|
||||
case 127: // alt+bkspace
|
||||
@ -1590,29 +1598,29 @@ R_API const char *r_line_readline_cb(RLineReadCallback cb, void *user) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#if !__WINDOWS__
|
||||
buf[1] = r_cons_readchar_timeout (50);
|
||||
if (buf[1] == -1) {
|
||||
r_cons_break_pop ();
|
||||
return NULL;
|
||||
if (I.vtmode == 2) {
|
||||
buf[1] = r_cons_readchar_timeout (50);
|
||||
if (buf[1] == -1) {
|
||||
r_cons_break_pop ();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (buf[0] == 0x5b) { // [
|
||||
switch (buf[1]) {
|
||||
case '3': // supr
|
||||
case '3': // supr
|
||||
__delete_next_char ();
|
||||
#if !__WINDOWS__
|
||||
buf[1] = r_cons_readchar ();
|
||||
if (buf[1] == -1) {
|
||||
r_cons_break_pop ();
|
||||
return NULL;
|
||||
if (I.vtmode == 2) {
|
||||
buf[1] = r_cons_readchar ();
|
||||
if (buf[1] == -1) {
|
||||
r_cons_break_pop ();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case '5': // pag up
|
||||
#if !__WINDOWS__
|
||||
buf[1] = r_cons_readchar ();
|
||||
#endif
|
||||
if (I.vtmode == 2) {
|
||||
buf[1] = r_cons_readchar ();
|
||||
}
|
||||
if (I.hud) {
|
||||
I.hud->top_entry_n -= (rows - 1);
|
||||
if (I.hud->top_entry_n < 0) {
|
||||
@ -1625,9 +1633,9 @@ R_API const char *r_line_readline_cb(RLineReadCallback cb, void *user) {
|
||||
}
|
||||
break;
|
||||
case '6': // pag down
|
||||
#if !__WINDOWS__
|
||||
buf[1] = r_cons_readchar ();
|
||||
#endif
|
||||
if (I.vtmode == 2) {
|
||||
buf[1] = r_cons_readchar ();
|
||||
}
|
||||
if (I.hud) {
|
||||
I.hud->top_entry_n += (rows - 1);
|
||||
if (I.hud->top_entry_n >= I.hud->current_entry_n) {
|
||||
@ -1693,18 +1701,21 @@ R_API const char *r_line_readline_cb(RLineReadCallback cb, void *user) {
|
||||
__move_cursor_left ();
|
||||
break;
|
||||
case 0x31: // control + arrow
|
||||
#if __WINDOWS__
|
||||
ch = buf[2];
|
||||
#else
|
||||
ch = r_cons_readchar ();
|
||||
if (ch == 0x7e) { // HOME in screen/tmux
|
||||
// corresponding END is 0x34 below (the 0x7e is ignored there)
|
||||
I.buffer.index = 0;
|
||||
break;
|
||||
if (I.vtmode == 2) {
|
||||
ch = r_cons_readchar ();
|
||||
if (ch == 0x7e) { // HOME in screen/tmux
|
||||
// corresponding END is 0x34 below (the 0x7e is ignored there)
|
||||
I.buffer.index = 0;
|
||||
break;
|
||||
}
|
||||
r_cons_readchar ();
|
||||
}
|
||||
#if __WINDOWS__
|
||||
else {
|
||||
ch = buf[2];
|
||||
}
|
||||
r_cons_readchar ();
|
||||
int fkey = ch - '0';
|
||||
#endif
|
||||
int fkey = ch - '0';
|
||||
switch (ch) {
|
||||
case 0x41:
|
||||
// first
|
||||
@ -1739,15 +1750,11 @@ R_API const char *r_line_readline_cb(RLineReadCallback cb, void *user) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#if __WINDOWS__
|
||||
// ...
|
||||
#else
|
||||
{
|
||||
if (I.vtmode == 2) {
|
||||
if (I.cb_fkey) {
|
||||
I.cb_fkey (I.user, fkey);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
r_cons_set_raw (1);
|
||||
|
@ -98,29 +98,31 @@ static bool is_arrow;
|
||||
|
||||
R_API int r_cons_arrow_to_hjkl(int ch) {
|
||||
#if __WINDOWS__
|
||||
if (is_arrow) {
|
||||
switch (ch) {
|
||||
case VK_DOWN: // key down
|
||||
ch = bCtrl ? 'J' : 'j';
|
||||
break;
|
||||
case VK_RIGHT: // key right
|
||||
ch = bCtrl ? 'L' : 'l';
|
||||
break;
|
||||
case VK_UP: // key up
|
||||
ch = bCtrl ? 'K' : 'k';
|
||||
break;
|
||||
case VK_LEFT: // key left
|
||||
ch = bCtrl ? 'H' : 'h';
|
||||
break;
|
||||
case VK_PRIOR: // key home
|
||||
ch = 'K';
|
||||
break;
|
||||
case VK_NEXT: // key end
|
||||
ch = 'J';
|
||||
break;
|
||||
if (I->vtmode != 2) {
|
||||
if (is_arrow) {
|
||||
switch (ch) {
|
||||
case VK_DOWN: // key down
|
||||
ch = bCtrl ? 'J' : 'j';
|
||||
break;
|
||||
case VK_RIGHT: // key right
|
||||
ch = bCtrl ? 'L' : 'l';
|
||||
break;
|
||||
case VK_UP: // key up
|
||||
ch = bCtrl ? 'K' : 'k';
|
||||
break;
|
||||
case VK_LEFT: // key left
|
||||
ch = bCtrl ? 'H' : 'h';
|
||||
break;
|
||||
case VK_PRIOR: // key home
|
||||
ch = 'K';
|
||||
break;
|
||||
case VK_NEXT: // key end
|
||||
ch = 'J';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return I->mouse_event && (ut8)ch == UT8_MAX ? 0 : ch;
|
||||
}
|
||||
return I->mouse_event && (ut8)ch == UT8_MAX ? 0 : ch;
|
||||
#endif
|
||||
I->mouse_event = 0;
|
||||
/* emacs */
|
||||
@ -416,14 +418,18 @@ static int __cons_readchar_w32(ut32 usec) {
|
||||
is_arrow = false;
|
||||
DWORD mode, out;
|
||||
HANDLE h;
|
||||
INPUT_RECORD irInBuf;
|
||||
INPUT_RECORD irInBuf = { { 0 } };
|
||||
CONSOLE_SCREEN_BUFFER_INFO info = { { 0 } };
|
||||
bool resize = false;
|
||||
bool click_n_drag = false;
|
||||
void *bed;
|
||||
I->mouse_event = 0;
|
||||
h = GetStdHandle (STD_INPUT_HANDLE);
|
||||
GetConsoleMode (h, &mode);
|
||||
SetConsoleMode (h, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS);
|
||||
DWORD newmode = I->vtmode == 2
|
||||
? ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
: ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS;
|
||||
SetConsoleMode (h, newmode);
|
||||
do {
|
||||
bed = r_cons_sleep_begin ();
|
||||
if (usec) {
|
||||
@ -432,8 +438,12 @@ static int __cons_readchar_w32(ut32 usec) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ret = ReadConsoleInput (h, &irInBuf, 1, &out);
|
||||
r_cons_enable_mouse (true);
|
||||
if (I->term_xterm) {
|
||||
ret = ReadFile (h, &ch, 1, &out, NULL);
|
||||
} else {
|
||||
ret = ReadConsoleInput (h, &irInBuf, 1, &out);
|
||||
}
|
||||
r_cons_sleep_end (bed);
|
||||
if (ret) {
|
||||
if (irInBuf.EventType == MOUSE_EVENT) {
|
||||
@ -453,7 +463,9 @@ static int __cons_readchar_w32(ut32 usec) {
|
||||
}
|
||||
switch (irInBuf.Event.MouseEvent.dwButtonState) {
|
||||
case FROM_LEFT_1ST_BUTTON_PRESSED:
|
||||
r_cons_set_click (irInBuf.Event.MouseEvent.dwMousePosition.X + 1, irInBuf.Event.MouseEvent.dwMousePosition.Y + 1);
|
||||
GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
|
||||
int rel_y = irInBuf.Event.MouseEvent.dwMousePosition.Y - info.srWindow.Top;
|
||||
r_cons_set_click (irInBuf.Event.MouseEvent.dwMousePosition.X + 1, rel_y + 1);
|
||||
ch = UT8_MAX;
|
||||
break;
|
||||
case RIGHTMOST_BUTTON_PRESSED:
|
||||
@ -532,7 +544,9 @@ static int __cons_readchar_w32(ut32 usec) {
|
||||
resize = false;
|
||||
}
|
||||
}
|
||||
FlushConsoleInputBuffer (h);
|
||||
if (I->vtmode != 2 && !I->term_xterm) {
|
||||
FlushConsoleInputBuffer (h);
|
||||
}
|
||||
} while (ch == 0);
|
||||
SetConsoleMode (h, mode);
|
||||
return ch;
|
||||
@ -593,10 +607,10 @@ R_API int r_cons_readchar() {
|
||||
memmove (readbuffer, readbuffer + 1, readbuffer_length);
|
||||
return ch;
|
||||
}
|
||||
r_cons_set_raw (1);
|
||||
#if __WINDOWS__
|
||||
return __cons_readchar_w32 (0);
|
||||
#else
|
||||
r_cons_set_raw (1);
|
||||
void *bed = r_cons_sleep_begin ();
|
||||
|
||||
// Blocks until either stdin has something to read or a signal happens.
|
||||
|
@ -20,7 +20,9 @@ R_API RLine *r_line_new(void) {
|
||||
I.kill_ring = r_list_newf (NULL);
|
||||
I.kill_ring_ptr = -1;
|
||||
#if __WINDOWS__
|
||||
I.ansicon = r_cons_is_ansicon ();
|
||||
I.vtmode = r_cons_is_vtcompat ();
|
||||
#else
|
||||
I.vtmode = 2;
|
||||
#endif
|
||||
if (!r_line_dietline_init ()) {
|
||||
eprintf ("error: r_line_dietline_init\n");
|
||||
|
@ -24,6 +24,10 @@ R_API void r_cons_w32_clear(void) {
|
||||
static CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
COORD startCoords;
|
||||
DWORD dummy;
|
||||
if (I->vtmode) {
|
||||
r_cons_strcat (Color_RESET R_CONS_CLEAR_SCREEN);
|
||||
return;
|
||||
}
|
||||
if (I->is_wine == 1) {
|
||||
write (1, "\033[0;0H\033[0m\033[2J", 6 + 4 + 4);
|
||||
}
|
||||
@ -50,6 +54,10 @@ R_API void r_cons_w32_gotoxy(int fd, int x, int y) {
|
||||
COORD coord;
|
||||
coord.X = x;
|
||||
coord.Y = y;
|
||||
if (I->vtmode) {
|
||||
r_cons_printf ("\x1b[%d;%dH", y, x);
|
||||
return;
|
||||
}
|
||||
if (I->is_wine == 1) {
|
||||
write (fd, "\x1b[0;0H", 6);
|
||||
}
|
||||
@ -403,7 +411,7 @@ R_API int r_cons_win_vhprintf(DWORD hdl, bool vmode, const char *fmt, va_list ap
|
||||
FILE *con = hdl == STD_OUTPUT_HANDLE ? stdout : stderr;
|
||||
if (!strchr (fmt, '%')) {
|
||||
size_t len = strlen (fmt);
|
||||
if (I->ansicon) {
|
||||
if (I->vtmode) {
|
||||
return fwrite (fmt, 1, len, con);
|
||||
}
|
||||
return r_cons_w32_hprint (hdl, fmt, len, vmode);
|
||||
@ -414,7 +422,7 @@ R_API int r_cons_win_vhprintf(DWORD hdl, bool vmode, const char *fmt, va_list ap
|
||||
char *buf = calloc (1, num_chars);
|
||||
if (buf) {
|
||||
(void)vsnprintf (buf, num_chars, fmt, ap);
|
||||
if (I->ansicon) {
|
||||
if (I->vtmode) {
|
||||
ret = fwrite (buf, 1, num_chars - 1, con);
|
||||
} else {
|
||||
ret = r_cons_w32_hprint (hdl, buf, num_chars - 1, vmode);
|
||||
|
@ -2089,26 +2089,37 @@ static bool cb_scrhighlight(void *user, void *data) {
|
||||
}
|
||||
|
||||
#if __WINDOWS__
|
||||
static bool scr_ansicon(void *user, void *data) {
|
||||
static bool scr_vtmode(void *user, void *data) {
|
||||
RConfigNode *node = (RConfigNode *) data;
|
||||
if (!strcmp (node->value, "true")) {
|
||||
if (r_str_is_true (node->value)) {
|
||||
node->i_value = 1;
|
||||
}
|
||||
r_line_singleton ()->ansicon = r_cons_singleton ()->ansicon = node->i_value;
|
||||
HANDLE streams[] = { GetStdHandle (STD_OUTPUT_HANDLE), GetStdHandle (STD_ERROR_HANDLE) };
|
||||
node->i_value = node->i_value > 2 ? 2 : node->i_value;
|
||||
r_line_singleton ()->vtmode = r_cons_singleton ()->vtmode = node->i_value;
|
||||
|
||||
DWORD mode;
|
||||
HANDLE input = GetStdHandle (STD_INPUT_HANDLE);
|
||||
GetConsoleMode (input, &mode);
|
||||
if (node->i_value == 2) {
|
||||
SetConsoleMode (input, mode & ENABLE_VIRTUAL_TERMINAL_INPUT);
|
||||
r_cons_singleton ()->term_raw = ENABLE_VIRTUAL_TERMINAL_INPUT;
|
||||
} else {
|
||||
SetConsoleMode (input, mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT);
|
||||
r_cons_singleton ()->term_raw = 0;
|
||||
}
|
||||
HANDLE streams[] = { GetStdHandle (STD_OUTPUT_HANDLE), GetStdHandle (STD_ERROR_HANDLE) };
|
||||
int i;
|
||||
if (node->i_value == 1) { // scr.ansicon=2 to show esc seqs (for debugging) if using non-ConEmu-hosted cmd.exe
|
||||
if (node->i_value > 0) {
|
||||
for (i = 0; i < R_ARRAY_SIZE (streams); i++) {
|
||||
GetConsoleMode (streams[i], &mode);
|
||||
SetConsoleMode (streams[i],
|
||||
mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < R_ARRAY_SIZE (streams); i++) {
|
||||
GetConsoleMode (streams[i], &mode);
|
||||
SetConsoleMode (streams[i],
|
||||
mode & ~ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
mode & ~ENABLE_VIRTUAL_TERMINAL_PROCESSING & ~ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -3518,8 +3529,8 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETBPREF ("scr.slow", "true", "Do slow stuff on visual mode like RFlag.get_at(true)");
|
||||
SETCB ("scr.prompt.popup", "false", &cb_scr_prompt_popup, "Show widget dropdown for autocomplete");
|
||||
#if __WINDOWS__
|
||||
SETICB ("scr.ansicon", r_cons_singleton ()->ansicon,
|
||||
&scr_ansicon, "Use ANSICON mode or not on Windows");
|
||||
SETICB ("scr.vtmode", r_cons_singleton ()->vtmode,
|
||||
&scr_vtmode, "Use VT sequences on Windows (0: Disable, 1: Output, 2: Input & Output)");
|
||||
#endif
|
||||
#if __ANDROID__
|
||||
SETBPREF ("scr.responsive", "true", "Auto-adjust Visual depending on screen (e.g. unset asm.bytes)");
|
||||
|
@ -40,6 +40,9 @@ extern "C" {
|
||||
# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||
# endif
|
||||
# ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
# define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
||||
# endif
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@ -494,7 +497,7 @@ typedef struct r_cons_t {
|
||||
#if __UNIX__
|
||||
struct termios term_raw, term_buf;
|
||||
#elif __WINDOWS__
|
||||
DWORD term_raw, term_buf;
|
||||
DWORD term_raw, term_buf, term_xterm;
|
||||
#endif
|
||||
RNum *num;
|
||||
/* Pager (like more or less) to use if the output doesn't fit on the
|
||||
@ -510,9 +513,7 @@ typedef struct r_cons_t {
|
||||
const char **vline;
|
||||
int refcnt;
|
||||
R_DEPRECATE bool newline;
|
||||
#if __WINDOWS__
|
||||
int ansicon;
|
||||
#endif
|
||||
int vtmode;
|
||||
bool flush;
|
||||
bool use_utf8; // use utf8 features
|
||||
bool use_utf8_curvy; // use utf8 curved corners
|
||||
@ -827,7 +828,7 @@ R_API int r_cons_pipe_open(const char *file, int fdn, int append);
|
||||
R_API void r_cons_pipe_close(int fd);
|
||||
|
||||
#if __WINDOWS__
|
||||
R_API bool r_cons_is_ansicon(void);
|
||||
R_API int r_cons_is_vtcompat(void);
|
||||
R_API void r_cons_w32_clear(void);
|
||||
R_API void r_cons_w32_gotoxy(int fd, int x, int y);
|
||||
R_API int r_cons_w32_print(const char *ptr, int len, bool vmode);
|
||||
@ -1070,9 +1071,7 @@ struct r_line_t {
|
||||
RLineHud *hud;
|
||||
RList *sdbshell_hist;
|
||||
RListIter *sdbshell_hist_iter;
|
||||
#if __WINDOWS__
|
||||
int ansicon;
|
||||
#endif
|
||||
int vtmode;
|
||||
}; /* RLine */
|
||||
|
||||
#ifdef R_API
|
||||
|
Loading…
x
Reference in New Issue
Block a user