if USE_SLANG
sbin_PROGRAMS += cfdisk
dist_man_MANS += cfdisk.8
-cfdisk_SOURCES = cfdisk.c $(fdisk_common)
+cfdisk_SOURCES = cfdisk.c $(fdisk_common) ../lib/mbsalign.c
cfdisk_CFLAGS = $(cflags_blkid)
cfdisk_LDADD = -lslang $(ldadd_blkid)
else
#include <blkid.h>
#endif
+#ifdef HAVE_WIDECHAR
+#include <wctype.h>
+#endif
+
#include "nls.h"
#include "blkdev.h"
#include "xstrncpy.h"
#include "common.h"
#include "gpt.h"
+#include "mbsalign.h"
#ifdef __GNU__
#define DEFAULT_DEVICE "/dev/hd0"
static int
get_string(char *str, int len, char *def) {
- unsigned char c;
- int i = 0;
- int x, y;
+ size_t cells = 0, i = 0;
+ int x, y, key;
int use_def = FALSE;
+ wint_t c;
getyx(stdscr, y, x);
clrtoeol();
}
refresh();
+
+#if defined(HAVE_LIBNCURSESW) && defined(HAVE_WIDECHAR)
+ while ((key = get_wch(&c)) != ERR &&
+ c != '\r' && c != '\n' && c != KEY_ENTER) {
+#else
while ((c = getch()) != '\n' && c != CR) {
+#endif
switch (c) {
case ESC:
move(y, x);
return GS_ESCAPE;
case DEL:
case '\b':
+ case KEY_BACKSPACE:
if (i > 0) {
- str[--i] = 0;
- mvaddch(y, x+i, ' ');
- move(y, x+i);
+ cells--;
+ i = mbs_truncate(str, &cells);
+ if (i < 0)
+ return GS_ESCAPE;
+ mvaddch(y, x + cells, ' ');
+ move(y, x + cells);
} else if (use_def) {
clrtoeol();
use_def = FALSE;
putchar(BELL);
break;
default:
+#if defined(HAVE_LIBNCURSESW) && defined(HAVE_WIDECHAR)
+ if (i < len && iswprint(c)) {
+ wchar_t wc = (wchar_t) c;
+ char s[MB_CUR_MAX + 1];
+ int sz = wctomb(s, wc);
+
+ if (sz + i < len) {
+ s[sz] = '\0';
+ mvaddnstr(y, x + cells, s, sz);
+ if (use_def) {
+ clrtoeol();
+ use_def = FALSE;
+ }
+ memcpy(str + i, s, sz);
+ i += sz;
+ str[i] = '\0';
+ cells += wcwidth(wc);
+ } else
+ putchar(BELL);
+ }
+#else
if (i < len && isprint(c)) {
- mvaddch(y, x+i, c);
+ mvaddch(y, x + cells, c);
if (use_def) {
clrtoeol();
use_def = FALSE;
}
str[i++] = c;
str[i] = 0;
- } else
+ cells++;
+ }
+#endif
+ else
putchar(BELL);
}
refresh();
#endif
};
-size_t
-mbsalign (const char *src, char *dest, size_t dest_size,
- size_t *width, mbs_align_t align, int flags);
+extern size_t mbs_truncate(char *str, size_t *width);
+
+extern size_t mbsalign (const char *src, char *dest,
+ size_t dest_size, size_t *width,
+ mbs_align_t align, int flags);
}
#endif
+/* Truncate multi-byte string to @width and returns number of
+ * bytes of the new string @str, and in @width returns number
+ * of cells.
+ */
+size_t
+mbs_truncate(char *str, size_t *width)
+{
+ size_t bytes = strlen(str);
+#ifdef HAVE_WIDECHAR
+ size_t sz = mbstowcs(NULL, str, 0);
+ wchar_t *wcs = NULL;
+
+ if (sz == (size_t) -1)
+ goto done;
+
+ wcs = malloc((sz + 1) * sizeof(wchar_t));
+ if (!wcs)
+ goto done;
+
+ if (!mbstowcs(wcs, str, sz))
+ goto done;
+ *width = wc_truncate(wcs, *width);
+ bytes = wcstombs(str, wcs, bytes);
+done:
+ free(wcs);
+#else
+ if (*width < bytes)
+ bytes = *width;
+#endif
+ if (bytes >= 0)
+ str[bytes] = '\0';
+ return bytes;
+}
+
/* Write N_SPACES space characters to DEST while ensuring
nothing is written beyond DEST_END. A terminating NUL
is always added to DEST.