2014-11-19 21:25:17 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2014 - pancake */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
#include <r_cons.h>
|
|
|
|
#include <string.h>
|
2015-01-26 16:55:12 +00:00
|
|
|
#if __WINDOWS__ && !__CYGWIN__ && !MINGW32
|
2015-01-14 22:31:29 +00:00
|
|
|
#include <conio.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define I r_cons_singleton()
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2015-01-26 16:55:12 +00:00
|
|
|
#if 0
|
2012-02-01 01:22:43 +00:00
|
|
|
//__UNIX__
|
|
|
|
#include <poll.h>
|
|
|
|
static int is_fd_ready(int fd) {
|
|
|
|
fd_set rfds;
|
|
|
|
struct timeval tv;
|
|
|
|
if (fd==-1)
|
|
|
|
return 0;
|
|
|
|
FD_ZERO (&rfds);
|
|
|
|
FD_SET (fd, &rfds);
|
|
|
|
tv.tv_sec = 0;
|
|
|
|
tv.tv_usec = 1;
|
|
|
|
if (select (1, &rfds, NULL, NULL, &tv) == -1)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
return !FD_ISSET (0, &rfds);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-11-19 21:25:17 +00:00
|
|
|
R_API int r_cons_controlz(int ch) {
|
|
|
|
#if __UNIX__
|
|
|
|
if (ch == 0x1a) {
|
|
|
|
r_cons_set_raw (0);
|
|
|
|
r_cons_show_cursor (1);
|
|
|
|
r_sys_stop ();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
2010-02-21 19:21:36 +00:00
|
|
|
R_API int r_cons_arrow_to_hjkl(int ch) {
|
2015-02-10 23:13:04 +00:00
|
|
|
I->mouse_event = 0;
|
2014-11-20 00:39:52 +00:00
|
|
|
/* emacs */
|
|
|
|
switch ((ut8)ch) {
|
|
|
|
case 0xc3: r_cons_readchar(); ch='K'; break; // emacs repag (alt + v)
|
|
|
|
case 0x16: ch='J'; break; // emacs avpag (ctrl + v)
|
|
|
|
case 0x10: ch='k'; break; // emacs up (ctrl + p)
|
|
|
|
case 0x0e: ch='j'; break; // emacs down (ctrl + n)
|
|
|
|
case 0x06: ch='l'; break; // emacs right (ctrl + f)
|
|
|
|
case 0x02: ch='h'; break; // emacs left (ctrl + b)
|
|
|
|
}
|
2014-10-06 00:36:22 +00:00
|
|
|
if (ch != 0x1b)
|
|
|
|
return ch;
|
|
|
|
ch = r_cons_readchar ();
|
|
|
|
if (!ch) return 0;
|
|
|
|
switch (ch) {
|
|
|
|
case 0x1b:
|
|
|
|
ch = 'q'; // XXX: must be 0x1b (R_CONS_KEY_ESC)
|
|
|
|
break;
|
|
|
|
case 0x4f: // function keys from f1 to f4
|
|
|
|
ch = r_cons_readchar ();
|
|
|
|
ch = 0xf1 + (ch&0xf);
|
|
|
|
break;
|
|
|
|
case '[': // function keys (2)
|
2010-02-28 14:16:02 +00:00
|
|
|
ch = r_cons_readchar ();
|
2011-06-05 18:36:22 +00:00
|
|
|
switch (ch) {
|
2014-10-06 00:36:22 +00:00
|
|
|
case '[':
|
2011-06-05 18:36:22 +00:00
|
|
|
ch = r_cons_readchar ();
|
2014-10-06 00:36:22 +00:00
|
|
|
switch (ch) {
|
|
|
|
case '2': ch = R_CONS_KEY_F11; break;
|
|
|
|
case 'A': ch = R_CONS_KEY_F1; break;
|
|
|
|
case 'B': ch = R_CONS_KEY_F2; break;
|
|
|
|
case 'C': ch = R_CONS_KEY_F3; break;
|
|
|
|
case 'D': ch = R_CONS_KEY_F4; break;
|
|
|
|
}
|
2011-06-05 18:36:22 +00:00
|
|
|
break;
|
2014-10-06 00:36:22 +00:00
|
|
|
case '2':
|
2010-02-28 13:49:26 +00:00
|
|
|
ch = r_cons_readchar ();
|
2010-02-28 14:16:02 +00:00
|
|
|
switch (ch) {
|
2014-10-06 00:36:22 +00:00
|
|
|
case 0x7e:
|
|
|
|
ch = R_CONS_KEY_F12;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r_cons_readchar ();
|
2011-06-05 18:36:22 +00:00
|
|
|
switch (ch) {
|
2014-10-06 00:36:22 +00:00
|
|
|
case '0': ch = R_CONS_KEY_F9; break;
|
|
|
|
case '1': ch = R_CONS_KEY_F10; break;
|
|
|
|
case '3': ch = R_CONS_KEY_F11; break;
|
2011-06-05 18:36:22 +00:00
|
|
|
}
|
|
|
|
break;
|
2014-10-06 00:36:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '1':
|
|
|
|
ch = r_cons_readchar ();
|
|
|
|
switch (ch) {
|
|
|
|
case ':': // arrow+shift
|
|
|
|
ch = r_cons_readchar ();
|
2011-06-05 18:36:22 +00:00
|
|
|
ch = r_cons_readchar ();
|
|
|
|
switch (ch) {
|
2014-10-06 00:36:22 +00:00
|
|
|
case 'A': ch = 'K'; break;
|
|
|
|
case 'B': ch = 'J'; break;
|
|
|
|
case 'C': ch = 'L'; break;
|
|
|
|
case 'D': ch = 'H'; break;
|
2011-06-05 18:36:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
/*
|
2014-10-06 00:36:22 +00:00
|
|
|
case '1': ch = R_CONS_KEY_F1; break;
|
|
|
|
case '2': ch = R_CONS_KEY_F2; break;
|
|
|
|
case '3': ch = R_CONS_KEY_F3; break;
|
|
|
|
case '4': ch = R_CONS_KEY_F4; break;
|
2011-06-05 18:36:22 +00:00
|
|
|
*/
|
2014-10-06 00:36:22 +00:00
|
|
|
case '5':
|
|
|
|
r_cons_readchar ();
|
|
|
|
ch = 0xf5;
|
2011-06-05 18:36:22 +00:00
|
|
|
break;
|
2014-10-06 00:36:22 +00:00
|
|
|
case '6':
|
|
|
|
r_cons_readchar ();
|
|
|
|
ch = 0xf7;
|
|
|
|
break;
|
|
|
|
case '7':
|
|
|
|
r_cons_readchar ();
|
|
|
|
ch = 0xf6;
|
|
|
|
break;
|
|
|
|
case '8':
|
|
|
|
r_cons_readchar ();
|
|
|
|
ch = 0xf7;
|
|
|
|
break;
|
|
|
|
case '9':
|
|
|
|
r_cons_readchar ();
|
|
|
|
ch = 0xf8;
|
|
|
|
break;
|
|
|
|
} // F9-F12 not yet supported!!
|
2011-06-05 18:36:22 +00:00
|
|
|
break;
|
2014-10-06 00:36:22 +00:00
|
|
|
case '5': ch='K'; break; // repag
|
|
|
|
case '6': ch='J'; break; // avpag
|
|
|
|
case 'A': ch='k'; break; // up
|
|
|
|
case 'B': ch='j'; break; // down
|
|
|
|
case 'C': ch='l'; break; // right
|
|
|
|
case 'D': ch='h'; break; // left
|
|
|
|
case 'M': // Mouse events
|
|
|
|
ch = r_cons_readchar ();
|
|
|
|
/* Skip the x/y coordinates */
|
|
|
|
(void)r_cons_readchar();
|
|
|
|
(void)r_cons_readchar();
|
|
|
|
if (ch==0x20) {
|
|
|
|
// click
|
|
|
|
r_cons_enable_mouse (R_FALSE);
|
|
|
|
ch = 0;
|
|
|
|
//r_cons_enable_mouse (R_TRUE);
|
|
|
|
} else
|
|
|
|
if (ch >= 64 + 32) {
|
|
|
|
/* Grab wheel events only */
|
2015-02-10 23:13:04 +00:00
|
|
|
I->mouse_event = 1;
|
2014-10-06 00:36:22 +00:00
|
|
|
ch = "kj"[(ch - (64 + 32))&1];
|
|
|
|
} else {
|
|
|
|
// temporary disable the mouse wheel to allow select
|
|
|
|
r_cons_enable_mouse (R_FALSE);
|
|
|
|
(void)r_cons_readchar ();
|
|
|
|
ch = 0;
|
|
|
|
}
|
2010-01-30 13:02:53 +00:00
|
|
|
}
|
2014-10-06 00:36:22 +00:00
|
|
|
break;
|
2010-01-30 13:02:53 +00:00
|
|
|
}
|
|
|
|
return ch;
|
|
|
|
}
|
2010-01-09 01:05:04 +00:00
|
|
|
|
2014-03-01 23:31:35 +00:00
|
|
|
|
2009-04-07 11:28:22 +00:00
|
|
|
// XXX no control for max length here?!?!
|
2010-02-21 19:21:36 +00:00
|
|
|
R_API int r_cons_fgets(char *buf, int len, int argc, const char **argv) {
|
2014-03-01 23:31:35 +00:00
|
|
|
#define RETURN(x) { ret=x; goto beach; }
|
2010-02-21 19:21:36 +00:00
|
|
|
RCons *cons = r_cons_singleton ();
|
2014-03-01 23:31:35 +00:00
|
|
|
int ret = 0, color = cons->pal.input && *cons->pal.input;
|
2014-09-04 09:06:11 +00:00
|
|
|
#if 0
|
2014-03-01 23:31:35 +00:00
|
|
|
int mouse = r_cons_enable_mouse (R_FALSE);
|
|
|
|
r_cons_enable_mouse (R_FALSE);
|
|
|
|
r_cons_flush ();
|
2014-09-04 09:06:11 +00:00
|
|
|
#endif
|
2014-03-03 01:01:40 +00:00
|
|
|
if (cons->user_fgets) {
|
2014-03-01 23:31:35 +00:00
|
|
|
RETURN (cons->user_fgets (buf, len));
|
2014-03-03 01:01:40 +00:00
|
|
|
}
|
2010-02-28 14:16:02 +00:00
|
|
|
*buf = '\0';
|
|
|
|
fflush (cons->fdin);
|
2013-05-22 02:22:49 +00:00
|
|
|
if (color) {
|
2013-09-29 23:14:04 +00:00
|
|
|
const char *p = cons->pal.input;
|
2014-03-01 23:31:35 +00:00
|
|
|
int len = p? strlen (p): 0;
|
2013-09-29 23:14:04 +00:00
|
|
|
if (len>0)
|
|
|
|
fwrite (p, len, 1, stdout);
|
2013-05-22 02:22:49 +00:00
|
|
|
fflush (stdout);
|
|
|
|
}
|
|
|
|
if (fgets (buf, len, cons->fdin) == NULL) {
|
|
|
|
if (color) {
|
|
|
|
printf (Color_RESET);
|
|
|
|
fflush (stdout);
|
|
|
|
}
|
2014-03-01 23:31:35 +00:00
|
|
|
RETURN (-1);
|
2013-05-22 02:22:49 +00:00
|
|
|
}
|
|
|
|
if (feof (cons->fdin)) {
|
|
|
|
if (color) printf (Color_RESET);
|
2014-03-01 23:31:35 +00:00
|
|
|
RETURN (-2);
|
2013-05-22 02:22:49 +00:00
|
|
|
}
|
2010-02-28 14:16:02 +00:00
|
|
|
buf[strlen (buf)-1] = '\0';
|
2013-05-22 02:22:49 +00:00
|
|
|
if (color) printf (Color_RESET);
|
2014-03-01 23:31:35 +00:00
|
|
|
ret = strlen (buf);
|
|
|
|
beach:
|
2014-09-04 09:06:11 +00:00
|
|
|
//r_cons_enable_mouse (mouse);
|
2014-03-01 23:31:35 +00:00
|
|
|
return ret;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-28 14:16:02 +00:00
|
|
|
R_API void r_cons_any_key() {
|
2010-01-30 13:02:53 +00:00
|
|
|
r_cons_strcat ("\n--press any key--\n");
|
|
|
|
r_cons_flush ();
|
|
|
|
r_cons_readchar ();
|
|
|
|
//r_cons_strcat ("\x1b[2J\x1b[0;0H"); // wtf?
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2015-01-26 16:55:12 +00:00
|
|
|
#if __WINDOWS__ && !__CYGWIN__ && !MINGW32
|
2015-01-14 22:31:29 +00:00
|
|
|
static char getwinkey() {
|
|
|
|
char i=0;
|
|
|
|
int res=0;
|
|
|
|
for(i=8; i <= 255; i++) {
|
|
|
|
res = GetAsyncKeyState (i);
|
|
|
|
if (res & 0x7FFF) {
|
|
|
|
switch (i) {
|
|
|
|
case 33: return 'K';
|
|
|
|
case 34: return 'J';
|
|
|
|
case 37: return 'h';
|
|
|
|
case 38: return 'k';
|
|
|
|
case 39: return 'l';
|
|
|
|
case 40: return 'j';
|
|
|
|
default:
|
|
|
|
if (i>=0x30 && i<=0x5a)
|
|
|
|
return '1';
|
|
|
|
else return '2';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return '2';
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2010-02-28 14:16:02 +00:00
|
|
|
R_API int r_cons_readchar() {
|
2009-02-05 21:08:46 +00:00
|
|
|
char buf[2];
|
2014-11-19 21:25:17 +00:00
|
|
|
buf[0] = -1;
|
2015-01-26 16:55:12 +00:00
|
|
|
#if __WINDOWS__ && !__CYGWIN__ && !MINGW32
|
2009-02-05 21:08:46 +00:00
|
|
|
BOOL ret;
|
2010-01-30 13:02:53 +00:00
|
|
|
DWORD out;
|
2011-11-29 08:46:41 +00:00
|
|
|
DWORD mode;
|
2015-01-14 22:31:29 +00:00
|
|
|
char b;
|
2010-06-27 20:14:06 +00:00
|
|
|
HANDLE h = GetStdHandle (STD_INPUT_HANDLE);
|
2010-01-30 13:02:53 +00:00
|
|
|
GetConsoleMode (h, &mode);
|
|
|
|
SetConsoleMode (h, 0); // RAW
|
2015-01-14 22:31:29 +00:00
|
|
|
ignore:
|
|
|
|
if (!I->is_wine) {
|
|
|
|
while (!_kbhit ());
|
|
|
|
b = getwinkey ();
|
|
|
|
if (b=='2')
|
|
|
|
goto ignore;
|
|
|
|
else if (b=='1')
|
|
|
|
ret = ReadConsole (h, buf, 1, &out, NULL);
|
|
|
|
else {
|
|
|
|
buf[0]=b;
|
|
|
|
ret=1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = ReadConsole (h, buf, 1, &out, NULL);
|
|
|
|
}
|
|
|
|
FlushConsoleInputBuffer(h);
|
2009-02-05 21:08:46 +00:00
|
|
|
if (!ret)
|
|
|
|
return -1;
|
2010-01-30 13:02:53 +00:00
|
|
|
SetConsoleMode (h, mode);
|
2009-02-05 21:08:46 +00:00
|
|
|
#else
|
2010-01-30 13:02:53 +00:00
|
|
|
r_cons_set_raw (1);
|
|
|
|
if (read (0, buf, 1)==-1)
|
2009-02-05 21:08:46 +00:00
|
|
|
return -1;
|
2010-01-30 13:02:53 +00:00
|
|
|
r_cons_set_raw (0);
|
2009-02-05 21:08:46 +00:00
|
|
|
#endif
|
2014-11-19 21:25:17 +00:00
|
|
|
return r_cons_controlz (buf[0]);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-02-28 13:49:26 +00:00
|
|
|
|
|
|
|
R_API int r_cons_yesno(int def, const char *fmt, ...) {
|
|
|
|
va_list ap;
|
|
|
|
int key = def;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
vfprintf (stderr, fmt, ap);
|
|
|
|
va_end (ap);
|
|
|
|
fflush (stderr);
|
|
|
|
r_cons_set_raw (1);
|
2014-04-30 22:54:48 +00:00
|
|
|
(void)read (0, &key, 1);
|
2010-02-28 13:49:26 +00:00
|
|
|
write (2, "\n", 1);
|
|
|
|
if (key == 'Y')
|
|
|
|
key = 'y';
|
2013-07-24 07:00:10 +00:00
|
|
|
r_cons_set_raw (0);
|
2010-02-28 14:16:02 +00:00
|
|
|
if (key=='\n' || key=='\r')
|
2010-02-28 13:49:26 +00:00
|
|
|
key = def;
|
|
|
|
return key=='y';
|
|
|
|
}
|