aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/interface-curses
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface-curses')
-rw-r--r--src/interface-curses/curses-info-popup.c32
-rw-r--r--src/interface-curses/curses-info-popup.h2
-rw-r--r--src/interface-curses/curses-utils.c16
-rw-r--r--src/interface-curses/curses-utils.h9
-rw-r--r--src/interface-curses/interface.c225
5 files changed, 163 insertions, 121 deletions
diff --git a/src/interface-curses/curses-info-popup.c b/src/interface-curses/curses-info-popup.c
index edb6e15..83d4665 100644
--- a/src/interface-curses/curses-info-popup.c
+++ b/src/interface-curses/curses-info-popup.c
@@ -73,7 +73,7 @@ teco_curses_info_popup_add(teco_curses_info_popup_t *ctx, teco_popup_entry_type_
}
static void
-teco_curses_info_popup_init_pad(teco_curses_info_popup_t *ctx, attr_t attr)
+teco_curses_info_popup_init_pad(teco_curses_info_popup_t *ctx, attr_t attr, gshort pair)
{
int pad_lines; /**! pad height */
gint pad_cols; /**! entry columns */
@@ -102,11 +102,11 @@ teco_curses_info_popup_init_pad(teco_curses_info_popup_t *ctx, attr_t attr)
ctx->pad = newpad(pad_lines, COLS - 2);
/*
- * NOTE: attr could contain A_REVERSE on monochrome terminals,
+ * NOTE: attr could contain WA_REVERSE on monochrome terminals,
* so we use foreground attributes instead of background attributes.
- * This way, we can cancel out the A_REVERSE if necessary.
+ * This way, we can cancel out the WA_REVERSE if necessary.
*/
- wattrset(ctx->pad, attr);
+ wattr_set(ctx->pad, attr, pair, NULL);
teco_curses_clrtobot(ctx->pad);
/*
@@ -161,7 +161,7 @@ teco_curses_info_popup_init_pad(teco_curses_info_popup_t *ctx, attr_t attr)
}
void
-teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr)
+teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr, gshort pair)
{
if (!ctx->length)
/* nothing to display */
@@ -171,7 +171,7 @@ teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr)
delwin(ctx->window);
if (!ctx->pad)
- teco_curses_info_popup_init_pad(ctx, attr);
+ teco_curses_info_popup_init_pad(ctx, attr, pair);
gint pad_lines = getmaxy(ctx->pad);
/*
@@ -183,15 +183,17 @@ teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr)
/* window covers message, scintilla and info windows */
ctx->window = newwin(popup_lines, 0, LINES - teco_cmdline.height - popup_lines, 0);
- wattrset(ctx->window, attr);
+ wattr_set(ctx->window, attr, pair, NULL);
- wborder(ctx->window,
- ACS_VLINE,
- ACS_VLINE, /* may be overwritten with scrollbar */
- ACS_HLINE,
- ' ', /* no bottom line */
- ACS_ULCORNER, ACS_URCORNER,
- ACS_VLINE, ACS_VLINE);
+ /*
+ * NOTE: wborder() is broken for large pair numbers, at least on ncurses.
+ */
+ waddch(ctx->window, ACS_ULCORNER);
+ whline(ctx->window, ACS_HLINE, COLS - 2);
+ mvwaddch(ctx->window, 0, COLS - 1, ACS_URCORNER);
+ mvwvline(ctx->window, 1, 0, ACS_VLINE, getmaxy(ctx->window)-1);
+ /* may be overwritten with scrollbar */
+ mvwvline(ctx->window, 1, COLS - 1, ACS_VLINE, getmaxy(ctx->window)-1);
copywin(ctx->pad, ctx->window,
ctx->pad_first_line, 0,
@@ -214,7 +216,7 @@ teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr)
* Instead, simply draw reverse blanks.
*/
wmove(ctx->window, bar_y, COLS-1);
- wattrset(ctx->window, attr ^ A_REVERSE);
+ wattr_set(ctx->window, attr ^ WA_REVERSE, pair, NULL);
wvline(ctx->window, ' ', bar_height);
}
diff --git a/src/interface-curses/curses-info-popup.h b/src/interface-curses/curses-info-popup.h
index fd923e9..898ba70 100644
--- a/src/interface-curses/curses-info-popup.h
+++ b/src/interface-curses/curses-info-popup.h
@@ -49,7 +49,7 @@ teco_curses_info_popup_init(teco_curses_info_popup_t *ctx)
void teco_curses_info_popup_add(teco_curses_info_popup_t *ctx, teco_popup_entry_type_t type,
const gchar *name, gsize name_len, gboolean highlight);
-void teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr);
+void teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr, gshort pair);
const teco_string_t *teco_curses_info_popup_getentry(teco_curses_info_popup_t *ctx, gint y, gint x);
void teco_curses_info_popup_scroll_page(teco_curses_info_popup_t *ctx);
void teco_curses_info_popup_scroll(teco_curses_info_popup_t *ctx, gint delta);
diff --git a/src/interface-curses/curses-utils.c b/src/interface-curses/curses-utils.c
index 875c332..3b25d56 100644
--- a/src/interface-curses/curses-utils.c
+++ b/src/interface-curses/curses-utils.c
@@ -53,9 +53,9 @@ teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width)
/*
* The entire background might be in reverse, especially
* on monochrome terminals.
- * In those cases, we have to __remove__ the A_REVERSE flag.
+ * In those cases, we have to __remove__ the WA_REVERSE flag.
*/
- attr_t attrs = A_NORMAL;
+ attr_t attrs = WA_NORMAL;
short pair = 0;
wattr_get(win, &attrs, &pair, NULL);
@@ -81,28 +81,28 @@ teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width)
chars_added++;
if (chars_added > max_width)
goto truncate;
- wattr_set(win, attrs ^ A_REVERSE, pair, NULL);
+ wattr_set(win, attrs ^ WA_REVERSE, pair, NULL);
waddch(win, '$');
break;
case '\r':
chars_added += 2;
if (chars_added > max_width)
goto truncate;
- wattr_set(win, attrs ^ A_REVERSE, pair, NULL);
+ wattr_set(win, attrs ^ WA_REVERSE, pair, NULL);
waddstr(win, "CR");
break;
case '\n':
chars_added += 2;
if (chars_added > max_width)
goto truncate;
- wattr_set(win, attrs ^ A_REVERSE, pair, NULL);
+ wattr_set(win, attrs ^ WA_REVERSE, pair, NULL);
waddstr(win, "LF");
break;
case '\t':
chars_added += 3;
if (chars_added > max_width)
goto truncate;
- wattr_set(win, attrs ^ A_REVERSE, pair, NULL);
+ wattr_set(win, attrs ^ WA_REVERSE, pair, NULL);
waddstr(win, "TAB");
break;
default:
@@ -110,7 +110,7 @@ teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width)
chars_added += 2;
if (chars_added > max_width)
goto truncate;
- wattr_set(win, attrs ^ A_REVERSE, pair, NULL);
+ wattr_set(win, attrs ^ WA_REVERSE, pair, NULL);
waddch(win, '^');
waddch(win, TECO_CTL_ECHO(*str));
} else {
@@ -126,7 +126,7 @@ teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width)
waddnstr(win, str, clen);
}
}
- /* restore original state of A_REVERSE */
+ /* restore original state of WA_REVERSE */
wattr_set(win, attrs, pair, NULL);
str += clen;
diff --git a/src/interface-curses/curses-utils.h b/src/interface-curses/curses-utils.h
index 97fc1cc..c6d9d8d 100644
--- a/src/interface-curses/curses-utils.h
+++ b/src/interface-curses/curses-utils.h
@@ -27,15 +27,12 @@ guint teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_
guint teco_curses_format_filename(WINDOW *win, const gchar *filename, gint max_width);
-/**
- * Add Unicode character to window.
- * This is just like wadd_wch(), but does not require wide-char APIs.
- */
+/** Add Unicode character to window. */
static inline void
teco_curses_add_wc(WINDOW *win, gunichar chr)
{
- gchar buf[6];
- waddnstr(win, buf, g_unichar_to_utf8(chr, buf));
+ wchar_t wc = chr;
+ waddnwstr(win, &wc, 1);
}
/**
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c
index 94501cb..b30e5dc 100644
--- a/src/interface-curses/interface.c
+++ b/src/interface-curses/interface.c
@@ -125,7 +125,8 @@ teco_console_ctrl_handler(DWORD type)
{
switch (type) {
case CTRL_C_EVENT:
- teco_interrupted = TRUE;
+ case CTRL_BREAK_EVENT:
+ teco_interrupted = TECO_INTERRUPTED;
return TRUE;
}
@@ -137,6 +138,7 @@ teco_console_ctrl_handler(DWORD type)
static gint teco_xterm_version(void) G_GNUC_UNUSED;
static gint teco_interface_blocking_getch(void);
+static inline gboolean teco_interface_check_key(gint key);
/**
* Get bright variant of one of the 8 standard
@@ -154,6 +156,12 @@ static gint teco_interface_blocking_getch(void);
* The 8 bright colors (if terminal supports at
* least 16 colors), else they are identical to
* the non-bright colors (default curses colors).
+ *
+ * As a consequence a light black (grey) foreground
+ * on black background might be invisible on 8 color
+ * terminals.
+ * If you add in A_BOLD, there is a good chance that
+ * the text will still become grey.
*/
#define COLOR_LBLACK COLOR_LIGHT(COLOR_BLACK)
#define COLOR_LRED COLOR_LIGHT(COLOR_RED)
@@ -232,47 +240,19 @@ static struct {
*
* Scinterm no longer initializes all color pairs for all combinations of
* the builtin foreground and background colors.
- * Since curses guarantees only 256 color pairs, we cannot do that either.
- * Instead we allocate color pairs beginnig at 128 on demand
- * (similar to what Scinterm does).
- *
- * @note Scinterm now also has scintilla_set_color_offsets(),
- * so we could use the lower 127 color pairs as well.
+ * Since curses does not guarantee any number of color pairs, we cannot do that either.
+ * Instead we allocate color pairs in the first half of
+ * color pair space on demand, while the second half is reserved to Scinterm.
*
+ * @param attr attributes to modify (for supporting monochrome terminals)
* @param fg curses foreground color
* @param bg curses background color
* @return curses color pair number
*/
static gshort
-teco_color_pair(gshort fg, gshort bg)
-{
- static gshort last_pair = 127;
-
- G_STATIC_ASSERT(sizeof(gshort)*2 <= sizeof(guint));
- gpointer key = GUINT_TO_POINTER(((guint)fg << 16) | bg);
- gpointer value = g_hash_table_lookup(teco_interface.pair_table, key);
- if (G_LIKELY(value != NULL))
- return GPOINTER_TO_UINT(value);
- init_pair(++last_pair, fg, bg);
- g_hash_table_insert(teco_interface.pair_table, key, GUINT_TO_POINTER(last_pair));
- return last_pair;
-}
-
-/**
- * Curses attribute for the color combination
- * according to the color pairs initialized by
- * Scinterm.
- * This is equivalent to Scinterm's internal term_color_attr().
- *
- * @param fg foreground color
- * @param bg background color
- * @return curses attribute
- */
-static inline attr_t
-teco_color_attr(gshort fg, gshort bg)
+teco_color_pair(attr_t *attr, gshort fg, gshort bg)
{
- if (has_colors())
- return COLOR_PAIR(teco_color_pair(fg, bg));
+ static guint next_pair = 1;
/*
* Basic support for monochrome terminals:
@@ -281,7 +261,29 @@ teco_color_attr(gshort fg, gshort bg)
* This will at least work with the terminal.tes and contrast.tes
* color schemes.
*/
- return bg != COLOR_BLACK ? A_REVERSE : 0;
+ if (!has_colors()) {
+ if (bg != COLOR_BLACK)
+ *attr |= WA_REVERSE;
+ return 0;
+ }
+
+ G_STATIC_ASSERT(sizeof(gshort)*2 <= sizeof(guint));
+ gpointer key = GUINT_TO_POINTER(((guint)fg << 8*sizeof(bg)) | bg);
+ gpointer value = g_hash_table_lookup(teco_interface.pair_table, key);
+ if (G_LIKELY(value != NULL))
+ return GPOINTER_TO_UINT(value);
+ if (G_UNLIKELY(next_pair >= COLOR_PAIRS || next_pair > G_MAXSHORT))
+ return 0;
+ init_pair(next_pair, fg, bg);
+ g_hash_table_insert(teco_interface.pair_table, key, GUINT_TO_POINTER(next_pair));
+ return next_pair++;
+}
+
+static inline gint
+teco_wattr_set(WINDOW *win, attr_t attr, gshort fg, gshort bg)
+{
+ gshort pair = teco_color_pair(&attr, fg, bg);
+ return wattr_set(win, attr, pair, NULL);
}
/**
@@ -435,7 +437,7 @@ static void teco_interface_set_window_title(const gchar *title);
static void teco_interface_draw_info(void);
void
-teco_interface_init(void)
+teco_interface_init(gint argc, gchar **argv)
{
for (guint i = 0; i < G_N_ELEMENTS(teco_interface.color_table); i++)
teco_interface.color_table[i] = -1;
@@ -449,7 +451,7 @@ teco_interface_init(void)
teco_cmdline_init();
/*
* The default INDIC_STRIKE wouldn't be visible.
- * Instead we use INDIC_SQUIGGLE, which is rendered as A_UNDERLINE.
+ * Instead we use INDIC_SQUIGGLE, which is rendered as WA_UNDERLINE.
*/
teco_cmdline_ssm(SCI_INDICSETSTYLE, INDICATOR_RUBBEDOUT, INDIC_SQUIGGLE);
/*
@@ -752,6 +754,12 @@ teco_interface_init_interactive(GError **error)
teco_interface.pair_table = g_hash_table_new(g_direct_hash, g_direct_equal);
start_color();
+ /*
+ * Scinterm uses shorts for color pairs, so G_MAXSHORT is the maximum.
+ * Some Curses implementations (NetBSD, PDCurses) may support less,
+ * but set COLOR_PAIRS accordingly.
+ */
+ scintilla_set_color_offsets(0, MIN(COLOR_PAIRS, G_MAXSHORT)/2);
/*
* On UNIX terminals, the escape key is usually
@@ -942,7 +950,7 @@ teco_interface_msg_literal(teco_msg_t type, const gchar *str, gsize len)
teco_interface_stdio_msg(type, str, len);
#endif
- short fg, bg;
+ gshort fg, bg;
fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0));
@@ -964,7 +972,7 @@ teco_interface_msg_literal(teco_msg_t type, const gchar *str, gsize len)
}
wmove(teco_interface.msg_window, 0, 0);
- wattrset(teco_interface.msg_window, teco_color_attr(fg, bg));
+ teco_wattr_set(teco_interface.msg_window, 0, fg, bg);
teco_curses_format_str(teco_interface.msg_window, str, len, -1);
teco_curses_clrtobot(teco_interface.msg_window);
}
@@ -975,11 +983,11 @@ teco_interface_msg_clear(void)
if (!teco_interface.input_pad) /* batch mode */
return;
- short fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0));
- short bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0));
+ gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0));
+ gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0));
wmove(teco_interface.msg_window, 0, 0);
- wattrset(teco_interface.msg_window, teco_color_attr(fg, bg));
+ teco_wattr_set(teco_interface.msg_window, 0, fg, bg);
teco_curses_clrtobot(teco_interface.msg_window);
}
@@ -993,25 +1001,41 @@ teco_interface_getch(gboolean widechar)
/*
* Signal that we accept input by drawing a real cursor in the message bar.
+ * FIXME: curs_set(2) would be better, but isn't always visible.
*/
wmove(teco_interface.msg_window, 0, 0);
- curs_set(1);
wrefresh(teco_interface.msg_window);
+ curs_set(1);
gchar buf[4];
gint i = 0;
gint32 cp;
do {
- cp = teco_interface_blocking_getch();
- if (cp == TECO_CTL_KEY('C'))
- teco_interrupted = TRUE;
- if (cp == TECO_CTL_KEY('C') || cp == TECO_CTL_KEY('D')) {
- cp = -1;
- break;
- }
- if (cp < 0 || cp > 0xFF)
- continue;
+ do {
+ cp = teco_interface_blocking_getch();
+ switch (cp) {
+#ifdef KEY_RESIZE
+ case KEY_RESIZE:
+ teco_interface_resize_all_windows();
+ teco_interface_refresh(FALSE);
+ /* cursor was moved by the resize */
+ wmove(teco_interface.msg_window, 0, 0);
+ wrefresh(teco_interface.msg_window);
+ break;
+#endif
+ case KEY_BACKSPACE:
+ return TECO_CTL_KEY('H');
+ case KEY_ENTER:
+ return '\n';
+ case TECO_CTL_KEY('C'):
+ teco_interrupted = TECO_INTERRUPTED;
+ /* fall through */
+ case TECO_CTL_KEY('D'):
+ /* emulates EOF on stdin */
+ return -1;
+ }
+ } while (cp < 0 || cp > 0xFF || !teco_interface_check_key(cp));
if (!widechar || !cp)
break;
@@ -1023,7 +1047,6 @@ teco_interface_getch(gboolean widechar)
i = 0;
} while (cp < 0);
- curs_set(0);
return cp;
}
@@ -1153,11 +1176,11 @@ teco_interface_draw_info(void)
* the current buffer's STYLE_DEFAULT.
* The same style is used for MSG_USER messages.
*/
- short fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0));
- short bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0));
+ gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0));
+ gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0));
wmove(teco_interface.info_window, 0, 0);
- wattrset(teco_interface.info_window, teco_color_attr(fg, bg));
+ teco_wattr_set(teco_interface.info_window, 0, fg, bg);
const gchar *info_type_str;
@@ -1726,11 +1749,13 @@ teco_interface_popup_show(gsize prefix_len)
/* batch mode */
return;
- short fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0));
- short bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0));
+ gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0));
+ gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0));
teco_interface.popup_prefix_len = prefix_len;
- teco_curses_info_popup_show(&teco_interface.popup, teco_color_attr(fg, bg));
+ attr_t attr = 0;
+ gshort pair = teco_color_pair(&attr, fg, bg);
+ teco_curses_info_popup_show(&teco_interface.popup, attr, pair);
}
void
@@ -1781,7 +1806,7 @@ teco_interface_popup_clear(void)
gboolean
teco_interface_is_interrupted(void)
{
- return teco_interrupted != FALSE;
+ return teco_interrupted == TECO_INTERRUPTED;
}
#else /* !CURSES_TTY && !PDCURSES_WINCON && !NCURSES_WIN32 */
@@ -1800,7 +1825,7 @@ teco_interface_is_interrupted(void)
{
if (!teco_interface.input_pad)
/* batch mode */
- return teco_interrupted != FALSE;
+ return teco_interrupted == TECO_INTERRUPTED;
/*
* NOTE: wgetch() is configured to be nonblocking.
@@ -1815,7 +1840,7 @@ teco_interface_is_interrupted(void)
GINT_TO_POINTER(key));
}
- return teco_interrupted != FALSE;
+ return teco_interrupted == TECO_INTERRUPTED;
}
#endif
@@ -1837,16 +1862,6 @@ teco_interface_refresh(gboolean force)
clearok(curscr, TRUE);
/*
- * Let Scinterm enable/disable the hardware cursor
- * based on the CARETSTYLE_CURSES.
- * Doing this repeatedly ensures you can change the
- * caret style interactively.
- * Also, window resizes enable the cursor on PDCurses/wincon
- * sometimes (FIXME).
- */
- curs_set(0);
-
- /*
* Info window is updated very often which is very
* costly, especially when using PDC_set_title(),
* so we redraw it here, where the overhead does
@@ -1870,6 +1885,19 @@ teco_interface_refresh(gboolean force)
*/
teco_view_update_cursor(teco_cmdline.view);
doupdate();
+
+ /*
+ * Scinterm enables/disables the hardware cursor,
+ * but only if CARETSTYLE_CURSES is used.
+ * Disabling the cursor repeatedly ensures you can change
+ * the caret style interactively.
+ * It also makes sure the cursor is reset after
+ * teco_interface_getch().
+ * Also, window resizes sometimes enable the hardware cursor on
+ * PDCurses/wincon (FIXME).
+ */
+ if (!(teco_view_ssm(teco_cmdline.view, SCI_GETCARETSTYLE, 0, 0) & CARETSTYLE_CURSES))
+ curs_set(0);
}
#if NCURSES_MOUSE_VERSION >= 2
@@ -1927,9 +1955,11 @@ teco_interface_process_mevent(MEVENT *event, GError **error)
else if (event->bstate & BUTTON_NUM(5))
teco_curses_info_popup_scroll(&teco_interface.popup, +2);
- short fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0));
- short bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0));
- teco_curses_info_popup_show(&teco_interface.popup, teco_color_attr(fg, bg));
+ gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0));
+ gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0));
+ attr_t attr = 0;
+ gshort pair = teco_color_pair(&attr, fg, bg);
+ teco_curses_info_popup_show(&teco_interface.popup, attr, pair);
return TRUE;
}
@@ -2099,7 +2129,7 @@ teco_interface_blocking_getch(void)
gint key = wgetch(teco_interface.input_pad);
teco_memory_start_limiting();
/* allow asynchronous interruptions on <CTRL/C> */
- teco_interrupted = FALSE;
+ teco_interrupted = TECO_NORMAL;
wtimeout(teco_interface.input_pad, 0);
#if defined(CURSES_TTY) || defined(PDCURSES_WINCON) || defined(NCURSES_WIN32)
noraw(); /* FIXME: necessary because of NCURSES_WIN32 bug */
@@ -2115,6 +2145,31 @@ teco_interface_blocking_getch(void)
return key;
}
+#ifdef __PDCURSES__
+
+/*
+ * Especially PDCurses/WinGUI likes to report two keypresses,
+ * e.g. for CTRL+Shift+6 (CTRL+^).
+ * Make sure we don't filter out AltGr, which may be reported as CTRL+ALT.
+ */
+static inline gboolean
+teco_interface_check_key(gint key)
+{
+ return (PDC_get_key_modifiers() &
+ (PDC_KEY_MODIFIER_CONTROL | PDC_KEY_MODIFIER_ALT)) != PDC_KEY_MODIFIER_CONTROL ||
+ TECO_IS_CTL(key);
+}
+
+#else /* __PDCURSES__ */
+
+static inline gboolean
+teco_interface_check_key(gint key)
+{
+ return TRUE;
+}
+
+#endif
+
/**
* One iteration of the event loop.
*
@@ -2220,22 +2275,10 @@ teco_interface_event_loop_iter(void)
* Control keys and keys with printable representation
*/
default:
- if (key > 0xFF)
- /* unhandled function key */
+ if (key > 0xFF || !teco_interface_check_key(key))
+ /* unhandled function key or bogus key press */
return;
-#ifdef __PDCURSES__
- /*
- * Especially PDCurses/WinGUI likes to report two keypresses,
- * e.g. for CTRL+Shift+6 (CTRL+^).
- * Make sure we don't filter out AltGr, which may be reported as CTRL+ALT.
- */
- if ((PDC_get_key_modifiers() &
- (PDC_KEY_MODIFIER_CONTROL | PDC_KEY_MODIFIER_ALT)) == PDC_KEY_MODIFIER_CONTROL &&
- !TECO_IS_CTL(key))
- return;
-#endif
-
/*
* NOTE: There's also wget_wch(), but it requires
* a widechar version of Curses.