Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions lib/tty/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -1167,26 +1167,6 @@ correct_key_code (int code)

/* --------------------------------------------------------------------------------------------- */

static int
getch_with_timeout (unsigned int delay_us)
{
fd_set Read_FD_Set;
int c;
struct timeval time_out;

time_out.tv_sec = delay_us / G_USEC_PER_SEC;
time_out.tv_usec = delay_us % G_USEC_PER_SEC;
tty_nodelay (TRUE);
FD_ZERO (&Read_FD_Set);
FD_SET (input_fd, &Read_FD_Set);
select (input_fd + 1, &Read_FD_Set, NULL, NULL, &time_out);
c = tty_lowlevel_getch ();
tty_nodelay (FALSE);
return c;
}

/* --------------------------------------------------------------------------------------------- */

static void
learn_store_key (GString *buffer, int c)
{
Expand Down Expand Up @@ -2139,6 +2119,26 @@ tty_getch (void)

/* --------------------------------------------------------------------------------------------- */

int
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in master, there is now an MC_TESTABLE macro, which should avoid the churn of making the function formally public.

getch_with_timeout (unsigned int delay_us)
{
fd_set Read_FD_Set;
int c;
struct timeval time_out;

time_out.tv_sec = delay_us / G_USEC_PER_SEC;
time_out.tv_usec = delay_us % G_USEC_PER_SEC;
tty_nodelay (TRUE);
FD_ZERO (&Read_FD_Set);
FD_SET (input_fd, &Read_FD_Set);
select (input_fd + 1, &Read_FD_Set, NULL, NULL, &time_out);
c = tty_lowlevel_getch ();
tty_nodelay (FALSE);
return c;
}

/* --------------------------------------------------------------------------------------------- */

char *
learn_key (void)
{
Expand Down
1 change: 1 addition & 0 deletions lib/tty/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ char *tty_keycode_to_keyname (const int keycode);
int tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block);
gboolean is_idle (void);
int tty_getch (void);
MC_MOCKABLE int getch_with_timeout (unsigned int delay_us);

/* While waiting for input, the program can select on more than one file */
typedef int (*select_fn) (int fd, void *info);
Expand Down
4 changes: 3 additions & 1 deletion lib/tty/tty-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ extern int sigwinch_pipe[2];

/*** declarations of public functions ************************************************************/

void load_terminfo_keys (void);

void tty_create_winch_pipe (void);
void tty_destroy_winch_pipe (void);

char *mc_tty_normalize_from_utf8 (const char *str);
void tty_init_xterm_support (gboolean is_xterm);
int tty_lowlevel_getch (void);
MC_MOCKABLE int tty_lowlevel_getch (void);

void tty_colorize_area (int y, int x, int rows, int cols, int color);

Expand Down
4 changes: 3 additions & 1 deletion lib/tty/tty-slang.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,11 @@ do_define_key (int code, const char *strcap)
define_sequence (code, seq, MCKEY_NOACTION);
}

/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */

static void
void
load_terminfo_keys (void)
{
int i;
Expand Down
1 change: 1 addition & 0 deletions tests/lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ terminal_SOURCES = \

tty_SOURCES = \
tty.c
tty_LDADD = $(SLANG_LIBS)

utilunix__mc_pstream_get_string_SOURCES = \
utilunix__mc_pstream_get_string.c
Expand Down
90 changes: 90 additions & 0 deletions tests/lib/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,46 @@
#include "lib/util.h"

#include "lib/tty/tty.h"
#include "lib/tty/tty-internal.h"
#include "lib/tty/key.h"

static int mock_input_buf[1000];
static int *mock_input_ptr;

static void
mock_input (const char *charinput)
{
mock_input_ptr = mock_input_buf;

while (*charinput != '\0')
*mock_input_ptr++ = (*charinput++ & 0xFF);
*mock_input_ptr = '\0';

mock_input_ptr = mock_input_buf;
}

/* @Mock */
int
tty_lowlevel_getch (void)
{
int key = *mock_input_ptr;
if (key != '\0')
{
mock_input_ptr++;
return key;
}
else
return -1;
}

/* @Mock */
int
getch_with_timeout (unsigned int delay_us)
{
(void) (delay_us);

return tty_lowlevel_getch ();
}

/* --------------------------------------------------------------------------------------------- */
/* @CapturedValue */
Expand Down Expand Up @@ -74,6 +114,7 @@ START_TEST (test_tty_check_term_non_xterm)
ck_assert_int_eq (actual_result_force_true, 1);
}
END_TEST

/* --------------------------------------------------------------------------------------------- */

START_TEST (test_tty_check_term_xterm_like)
Expand All @@ -94,6 +135,54 @@ END_TEST

/* --------------------------------------------------------------------------------------------- */

START_TEST (test_tty_get_key_code)
{
mc_global.tty.xterm_flag = TRUE;

setenv ("TERM", "xterm", 1);
init_key ();
#ifdef HAVE_SLANG
SLtt_get_terminfo ();
load_terminfo_keys ();
#endif

mock_input ("\x1b[1;2A");
ck_assert_int_eq (get_key_code (0), KEY_M_SHIFT | KEY_UP);
ck_assert_int_eq (get_key_code (0), -1);
ck_assert_int_eq (get_key_code (0), -1);

mock_input ("😊FG");
ck_assert_int_eq (get_key_code (0), 0xF0);
ck_assert_int_eq (get_key_code (0), 0x9F);
ck_assert_int_eq (get_key_code (0), 0x98);
ck_assert_int_eq (get_key_code (0), 0x8A);
ck_assert_int_eq (get_key_code (0), 'F');
ck_assert_int_eq (get_key_code (0), 'G');
ck_assert_int_eq (get_key_code (0), -1);
ck_assert_int_eq (get_key_code (0), -1);

mock_input ("ц\x1b[1;2A=5ů§a");
ck_assert_int_eq (get_key_code (0), 0xD1); // 'ц'
ck_assert_int_eq (get_key_code (0), 0x86);
ck_assert_int_eq (get_key_code (0), KEY_M_SHIFT | KEY_UP);
ck_assert_int_eq (get_key_code (0), '=');
ck_assert_int_eq (get_key_code (0), '5');
ck_assert_int_eq (get_key_code (0), 0xC5); // 'ů'
ck_assert_int_eq (get_key_code (0), 0xAF);
ck_assert_int_eq (get_key_code (0), 0xC2); // '§'
ck_assert_int_eq (get_key_code (0), 0xA7);
ck_assert_int_eq (get_key_code (0), 'a');
ck_assert_int_eq (get_key_code (0), -1);
ck_assert_int_eq (get_key_code (0), -1);

mock_input ("\x1b[u");
ck_assert_int_eq (get_key_code (0), -1);
ck_assert_int_eq (get_key_code (0), -1);
}
END_TEST

/* --------------------------------------------------------------------------------------------- */

int
main (void)
{
Expand All @@ -105,6 +194,7 @@ main (void)
tcase_add_test (tc_core, test_tty_check_term_unset);
tcase_add_test (tc_core, test_tty_check_term_non_xterm);
tcase_add_test (tc_core, test_tty_check_term_xterm_like);
tcase_add_test (tc_core, test_tty_get_key_code);
// ***********************************

return mctest_run_all (tc_core);
Expand Down