From b8dc6bb3cc2554f0fbadf37b0178f22e0766df2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Wed, 15 Oct 2014 00:51:05 +0200 Subject: [PATCH] Avoid flicker while resizing --- CMakeLists.txt | 11 +++++++---- config.h.in | 1 + src/sdtui.c | 7 ++----- src/utils.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/utils.h | 1 + 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9612bfe..813d86c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,10 +20,6 @@ set (project_VERSION "${project_VERSION_MAJOR}") set (project_VERSION "${project_VERSION}.${project_VERSION_MINOR}") set (project_VERSION "${project_VERSION}.${project_VERSION_PATCH}") -# Configuration -include (CheckFunctionExists) -CHECK_FUNCTION_EXISTS ("wcwidth" HAVE_WCWIDTH) - # Dependencies find_package (ZLIB REQUIRED) find_package (PkgConfig REQUIRED) @@ -46,6 +42,13 @@ endif (USE_SYSTEM_TERMO) include_directories (${ZLIB_INCLUDE_DIRS} ${dependencies_INCLUDE_DIRS} ${Termo_INCLUDE_DIRS}) +# Configuration +include (CheckFunctionExists) +CHECK_FUNCTION_EXISTS ("wcwidth" HAVE_WCWIDTH) + +set (CMAKE_REQUIRED_LIBRARIES ${dependencies_LIBRARIES}) +CHECK_FUNCTION_EXISTS ("resize_term" HAVE_RESIZE_TERM) + # Localization find_package (Gettext REQUIRED) file (GLOB project_PO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/po/*.po) diff --git a/config.h.in b/config.h.in index a5fd1be..f125acb 100644 --- a/config.h.in +++ b/config.h.in @@ -9,6 +9,7 @@ #define GETTEXT_DIRNAME "${CMAKE_INSTALL_PREFIX}/share/locale" #cmakedefine HAVE_WCWIDTH +#cmakedefine HAVE_RESIZE_TERM #endif /* ! CONFIG_H */ diff --git a/src/sdtui.c b/src/sdtui.c index b09de99..3dbcb03 100644 --- a/src/sdtui.c +++ b/src/sdtui.c @@ -43,6 +43,7 @@ #include "config.h" #include "stardict.h" +#include "utils.h" #define CTRL_KEY(x) ((x) - 'A' + 1) @@ -1186,11 +1187,7 @@ process_winch_input (GIOChannel *source, char c; read (g_io_channel_unix_get_fd (source), &c, 1); - // TODO: look for resizeterm() and use it if available for flicker-free - // resize; endwin() escapes curses mode. - endwin (); - refresh (); - + update_curses_terminal_size (); app_process_resize (app); return TRUE; } diff --git a/src/utils.c b/src/utils.c index 8636778..ebbd4a9 100644 --- a/src/utils.c +++ b/src/utils.c @@ -20,7 +20,16 @@ #include #include +#include +#include +#include +#include +#ifndef TIOCGWINSZ +#include +#endif // ! TIOCGWINSZ + +#include "config.h" #include "utils.h" @@ -61,3 +70,34 @@ stream_read_string (GDataInputStream *dis, GError **error) return s; } + +static bool +xstrtoul (unsigned long *out, const char *s, int base) +{ + char *end; + errno = 0; + *out = strtoul (s, &end, base); + return errno == 0 && !*end && end != s; +} + +// Didn't want to have this ugly piece of code in the main source file; +// the standard endwin/refresh sequence makes the terminal flicker. +void +update_curses_terminal_size (void) +{ +#if defined (HAVE_RESIZE_TERM) && defined (TIOCGWINSZ) + struct winsize size; + if (!ioctl (STDOUT_FILENO, TIOCGWINSZ, (char *) &size)) + { + char *row = getenv ("LINES"); + char *col = getenv ("COLUMNS"); + unsigned long tmp; + resize_term ( + (row && xstrtoul (&tmp, row, 10)) ? tmp : size.ws_row, + (col && xstrtoul (&tmp, col, 10)) ? tmp : size.ws_col); + } +#else // HAVE_RESIZE_TERM && TIOCGWINSZ + endwin (); + refresh (); +#endif // HAVE_RESIZE_TERM && TIOCGWINSZ +} diff --git a/src/utils.h b/src/utils.h index 61c108e..c3bdd84 100644 --- a/src/utils.h +++ b/src/utils.h @@ -40,5 +40,6 @@ gboolean stream_read_all (GByteArray *ba, GInputStream *is, GError **error); gchar *stream_read_string (GDataInputStream *dis, GError **error); +void update_curses_terminal_size (void); #endif /* ! UTILS_H */