summaryrefslogtreecommitdiff
path: root/src/ncurses.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-06-09 13:26:54 +0100
committerMaxime Coste <frrrwww@gmail.com>2014-06-09 13:47:36 +0100
commit052d877ee64a0002dde538ae8f9a11da54f89191 (patch)
tree07b40515cfb1456a64dd3811cc538813f83dbfa3 /src/ncurses.cc
parent732d1c3bd19405bb3144f0b56ec1d10758ab8ec5 (diff)
Safer implementation of signal handlers in ncurses.cc
On recent ncurses implementation on cygwin, the old method provoked freezes. Avoid calling ncurses functions in signal handlers. We still call an unsafe function (EventManager::force_signal)...
Diffstat (limited to 'src/ncurses.cc')
-rw-r--r--src/ncurses.cc51
1 files changed, 37 insertions, 14 deletions
diff --git a/src/ncurses.cc b/src/ncurses.cc
index 67f73951..78e96746 100644
--- a/src/ncurses.cc
+++ b/src/ncurses.cc
@@ -140,15 +140,19 @@ static void set_color(WINDOW* window, ColorPair colors)
}
}
+static sig_atomic_t resize_pending = 0;
+
void on_term_resize(int)
{
- ungetch(KEY_RESIZE);
+ resize_pending = 1;
EventManager::instance().force_signal(0);
}
+static sig_atomic_t ctrl_c_pending = 0;
+
void on_sigint(int)
{
- ungetch(CTRL('c'));
+ ctrl_c_pending = 1;
EventManager::instance().force_signal(0);
}
@@ -267,6 +271,8 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer,
const DisplayLine& status_line,
const DisplayLine& mode_line)
{
+ check_resize();
+
LineCount line_index = 0;
for (const DisplayLine& line : display_buffer.lines())
{
@@ -315,8 +321,29 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer,
m_dirty = true;
}
+void NCursesUI::check_resize()
+{
+ if (resize_pending)
+ {
+ int fd = open("/dev/tty", O_RDWR);
+ winsize ws;
+ if (ioctl(fd, TIOCGWINSZ, (void*)&ws) == 0)
+ {
+ close(fd);
+ resizeterm(ws.ws_row, ws.ws_col);
+ update_dimensions();
+ }
+ resize_pending = false;
+ }
+}
+
bool NCursesUI::is_key_available()
{
+ check_resize();
+
+ if (ctrl_c_pending)
+ return true;
+
timeout(0);
const int c = getch();
if (c != ERR)
@@ -327,6 +354,14 @@ bool NCursesUI::is_key_available()
Key NCursesUI::get_key()
{
+ check_resize();
+
+ if (ctrl_c_pending)
+ {
+ ctrl_c_pending = false;
+ return ctrl('c');
+ }
+
const int c = getch();
if (c > 0 and c < 27)
{
@@ -344,18 +379,6 @@ Key NCursesUI::get_key()
else
return Key::Escape;
}
- else if (c == KEY_RESIZE)
- {
- int fd = open("/dev/tty", O_RDWR);
- winsize ws;
- if (fd != -1 and ioctl(fd, TIOCGWINSZ, (void*)&ws) == 0)
- {
- close(fd);
- resizeterm(ws.ws_row, ws.ws_col);
- update_dimensions();
- }
- return Key::Invalid;
- }
else switch (c)
{
case KEY_BACKSPACE: case 127: return Key::Backspace;