summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac6
-rw-r--r--disk-utils/cfdisk.c110
2 files changed, 108 insertions, 8 deletions
diff --git a/configure.ac b/configure.ac
index e7c6a144d..107184bf9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -706,7 +706,11 @@ AM_CONDITIONAL([HAVE_SLANG], [test "x$have_slang" = xyes])
AS_IF([test "x$have_slang" = xyes -o "x$have_ncurses" = xyes], [
AC_CHECK_LIB([$CURSES_LIB_NAME], use_default_colors, [
AC_DEFINE(HAVE_USE_DEFAULT_COLORS, 1,
- [Define if curses library has the use_default_colors command.])
+ [Define if curses library has the use_default_colors().])
+ ])
+ AC_CHECK_LIB([$CURSES_LIB_NAME], resizeterm, [
+ AC_DEFINE(HAVE_RESIZETERM, 1,
+ [Define if curses library has the resizeterm().])
])
])
diff --git a/disk-utils/cfdisk.c b/disk-utils/cfdisk.c
index 6d3e6eb8d..b0185092a 100644
--- a/disk-utils/cfdisk.c
+++ b/disk-utils/cfdisk.c
@@ -5,6 +5,7 @@
#include <ctype.h>
#include <getopt.h>
#include <libsmartcols.h>
+#include <sys/ioctl.h>
#ifdef HAVE_SLANG_H
# include <slang.h>
@@ -76,6 +77,7 @@ static struct cfdisk_menuitem *menu_get_menuitem(struct cfdisk *cf, size_t idx);
static struct cfdisk_menuitem *menu_get_menuitem_by_key(struct cfdisk *cf, int key, size_t *idx);
static struct cfdisk_menu *menu_push(struct cfdisk *cf, struct cfdisk_menuitem *item);
static struct cfdisk_menu *menu_pop(struct cfdisk *cf);
+static void menu_refresh_size(struct cfdisk *cf);
static int ui_refresh(struct cfdisk *cf);
static void ui_warnx(const char *fmt, ...);
@@ -83,11 +85,13 @@ static void ui_warn(const char *fmt, ...);
static void ui_info(const char *fmt, ...);
static void ui_draw_menu(struct cfdisk *cf);
static int ui_menu_move(struct cfdisk *cf, int key);
+static void ui_menu_resize(struct cfdisk *cf);
static int ui_get_size(struct cfdisk *cf, const char *prompt, uintmax_t *res,
uintmax_t low, uintmax_t up);
static int ui_enabled;
+static int ui_resize;
/* menu item */
struct cfdisk_menuitem {
@@ -161,6 +165,25 @@ static int cols_init(struct cfdisk *cf)
return fdisk_get_columns(cf->cxt, 0, &cf->cols, &cf->ncols);
}
+static void resize(void)
+{
+ struct winsize ws;
+
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &ws) != -1
+ && ws.ws_row && ws.ws_col) {
+ LINES = ws.ws_row;
+ COLS = ws.ws_col;
+#if HAVE_RESIZETERM
+ resizeterm(ws.ws_row, ws.ws_col);
+#endif
+ clearok(stdscr, TRUE);
+ }
+ touchwin(stdscr);
+
+ DBG(FRONTEND, ul_debug("ui: resize refresh COLS=%d, LINES=%d", COLS, LINES));
+ ui_resize = 0;
+}
+
/* Reads partition in tree-like order from scols
*/
static int partition_from_scols(struct fdisk_table *tb,
@@ -408,6 +431,8 @@ static int ask_menu(struct fdisk_ask *ask, struct cfdisk *cf)
do {
int key = getch();
+ if (ui_resize)
+ ui_menu_resize(cf);
if (ui_menu_move(cf, key) == 0)
continue;
@@ -601,6 +626,18 @@ static void die_on_signal(int dummy __attribute__((__unused__)))
exit(EXIT_FAILURE);
}
+static void resize_on_signal(int dummy __attribute__((__unused__)))
+{
+ DBG(FRONTEND, ul_debug("resize on signal."));
+ ui_resize = 1;
+}
+
+static void menu_refresh_size(struct cfdisk *cf)
+{
+ if (cf->menu && cf->menu->nitems)
+ cf->menu->page_sz = cf->menu->nitems / (LINES - 4) ? LINES - 4 : 0;
+}
+
static void menu_update_ignore(struct cfdisk *cf)
{
char ignore[128] = { 0 };
@@ -643,7 +680,7 @@ static void menu_update_ignore(struct cfdisk *cf)
else
m->idx = 0;
- m->page_sz = m->nitems / (LINES - 4) ? LINES - 4 : 0;
+ menu_refresh_size(cf);
}
static struct cfdisk_menu *menu_push(
@@ -669,7 +706,7 @@ static struct cfdisk_menu *menu_push(
}
cf->menu = m;
- m->page_sz = m->nitems / (LINES - 4) ? LINES - 4 : 0;
+ menu_refresh_size(cf);
return m;
}
@@ -718,6 +755,9 @@ static int ui_init(struct cfdisk *cf __attribute__((__unused__)))
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
+ sa.sa_handler = resize_on_signal;
+ sigaction(SIGWINCH, &sa, NULL);
+
ui_enabled = 1;
initscr();
@@ -859,6 +899,29 @@ static void ui_draw_menuitem(struct cfdisk *cf,
mvprintw(ln, cl, vert ? " %s " : "[%s]", buf);
}
+static void ui_clean_menu(struct cfdisk *cf)
+{
+ size_t i;
+ size_t nlines;
+ struct cfdisk_menu *m = cf->menu;
+ size_t ln = menuitem_get_line(cf, 0);
+
+ if (m->vertical)
+ nlines = m->page_sz ? m->page_sz : m->nitems;
+ else
+ nlines = menuitem_get_line(cf, m->nitems);
+
+ for (i = ln; i <= ln + nlines; i++) {
+ move(i, 0);
+ clrtoeol();
+ }
+ if (m->vertical) {
+ move(ln - 1, 0);
+ clrtoeol();
+ }
+ ui_clean_hint();
+}
+
static void ui_draw_menu(struct cfdisk *cf)
{
struct cfdisk_menuitem *d;
@@ -872,6 +935,7 @@ static void ui_draw_menu(struct cfdisk *cf)
DBG(FRONTEND, ul_debug("ui: menu: draw start"));
+ ui_clean_menu(cf);
m = cf->menu;
if (m->vertical)
@@ -879,11 +943,6 @@ static void ui_draw_menu(struct cfdisk *cf)
else
nlines = menuitem_get_line(cf, m->nitems);
- for (i = ln; i <= ln + nlines; i++) {
- move(i, 0);
- clrtoeol();
- }
-
if (m->ignore_cb)
menu_update_ignore(cf);
i = 0;
@@ -973,6 +1032,9 @@ static int ui_menu_move(struct cfdisk *cf, int key)
assert(cf);
assert(cf->menu);
+ if (key == ERR)
+ return 0; /* ignore errors */
+
m = cf->menu;
DBG(FRONTEND, ul_debug("ui: menu move key >%c<.", key));
@@ -1025,6 +1087,16 @@ static int ui_menu_move(struct cfdisk *cf, int key)
return 1; /* key irrelevant for menu move */
}
+/* but don't call me from ui_run(), this is for pop-up menus only */
+static void ui_menu_resize(struct cfdisk *cf)
+{
+ resize();
+ ui_clean_menu(cf);
+ menu_refresh_size(cf);
+ ui_draw_menu(cf);
+ refresh();
+}
+
static int partition_on_page(struct cfdisk *cf, size_t i)
{
if (cf->page_sz == 0 ||
@@ -1221,6 +1293,10 @@ static ssize_t ui_get_string(struct cfdisk *cf, const char *prompt,
int c;
if ((c = getch()) == ERR) {
#endif
+ if (ui_resize) {
+ resize();
+ continue;
+ }
if (!isatty(STDIN_FILENO))
exit(2);
else
@@ -1406,6 +1482,8 @@ static struct fdisk_parttype *ui_get_parttype(struct cfdisk *cf,
do {
int key = getch();
+ if (ui_resize)
+ ui_menu_resize(cf);
if (ui_menu_move(cf, key) == 0)
continue;
@@ -1472,6 +1550,9 @@ static int ui_create_label(struct cfdisk *cf)
do {
int key = getch();
+
+ if (ui_resize)
+ ui_menu_resize(cf);
if (ui_menu_move(cf, key) == 0)
continue;
switch (key) {
@@ -1538,6 +1619,7 @@ static int ui_help(void)
mvaddstr(i, 1, _(help[i]));
ui_info(_("Press a key to continue."));
+
getch();
return 0;
}
@@ -1738,6 +1820,14 @@ static int main_menu_action(struct cfdisk *cf, int key)
return 0;
}
+static void ui_resize_refresh(struct cfdisk *cf)
+{
+ resize();
+ menu_refresh_size(cf);
+ lines_refresh(cf);
+ ui_refresh(cf);
+}
+
static int ui_run(struct cfdisk *cf)
{
int rc = 0;
@@ -1771,6 +1861,12 @@ static int ui_run(struct cfdisk *cf)
do {
int rc = 0, key = getch();
+ if (ui_resize)
+ /* Note that ncurses getch() returns ERR when interrupted
+ * by signal, but SLang does not interrupt at all. */
+ ui_resize_refresh(cf);
+ if (key == ERR)
+ continue;
if (ui_menu_move(cf, key) == 0)
continue;