Avoid flicker while resizing

This commit is contained in:
Přemysl Eric Janouch 2014-10-15 00:51:05 +02:00
parent b352a0fc8d
commit b8dc6bb3cc
5 changed files with 51 additions and 9 deletions

View File

@ -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)

View File

@ -9,6 +9,7 @@
#define GETTEXT_DIRNAME "${CMAKE_INSTALL_PREFIX}/share/locale"
#cmakedefine HAVE_WCWIDTH
#cmakedefine HAVE_RESIZE_TERM
#endif /* ! CONFIG_H */

View File

@ -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;
}

View File

@ -20,7 +20,16 @@
#include <glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <errno.h>
#include <curses.h>
#include <termios.h>
#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#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
}

View File

@ -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 */