r540 - trunk
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Mon Mar 3 02:01:54 EST 2008
Author: icculus
Date: 2008-03-03 02:01:54 -0500 (Mon, 03 Mar 2008)
New Revision: 540
Modified:
trunk/CMakeLists.txt
trunk/gui_ncurses.c
trunk/universal.h
Log:
Fixed Unicode output in gui_ncurses.c, so ./mojosetup --locale=ru doesn't
dump ASCII crapola to your terminal anymore.
Modified: trunk/CMakeLists.txt
===================================================================
--- trunk/CMakeLists.txt 2008-03-02 06:37:37 UTC (rev 539)
+++ trunk/CMakeLists.txt 2008-03-03 07:01:54 UTC (rev 540)
@@ -358,10 +358,10 @@
IF(MOJOSETUP_GUI_NCURSES_STATIC)
ADD_DEFINITIONS(-DGUI_STATIC_LINK_NCURSES=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} gui_ncurses.c)
- SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} -lncurses) # !!! FIXME
+ SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} -lncursesw) # !!! FIXME
ELSE(MOJOSETUP_GUI_NCURSES_STATIC)
MOJOSETUP_ADD_LIBRARY(mojosetupgui_ncurses gui_ncurses.c)
- TARGET_LINK_LIBRARIES(mojosetupgui_ncurses "-lncurses") # !!! FIXME
+ TARGET_LINK_LIBRARIES(mojosetupgui_ncurses "-lncursesw") # !!! FIXME
ENDIF(MOJOSETUP_GUI_NCURSES_STATIC)
ENDIF(MOJOSETUP_GUI_NCURSES)
ENDIF(NOT MACOSX)
Modified: trunk/gui_ncurses.c
===================================================================
--- trunk/gui_ncurses.c 2008-03-02 06:37:37 UTC (rev 539)
+++ trunk/gui_ncurses.c 2008-03-03 07:01:54 UTC (rev 540)
@@ -21,7 +21,8 @@
#include <unistd.h>
#include <ctype.h>
-#include <curses.h>
+#include <ncursesw/curses.h>
+#include <locale.h>
// This was built to look roughly like dialog(1), but it's not nearly as
// robust. Also, I didn't use any of dialog's code, as it is GPL/LGPL,
@@ -37,6 +38,14 @@
// Pradeep Padala's ncurses HOWTO was very helpful in teaching me curses
// quickly: http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/index.html
+// !!! FIXME: this should all be UTF-8 and Unicode clean with ncursesw, but
+// !!! FIXME: it relies on the terminal accepting UTF-8 output (we don't
+// !!! FIXME: attempt to convert) and assumes all characters fit in one
+// !!! FIXME: column, which they don't necessarily for some Asian languages,
+// !!! FIXME: etc. I'm not sure how to properly figure out column width, if
+// !!! FIXME: it's possible at all, but for that, you should probably
+// !!! FIXME: go to a proper GUI plugin like GTK+ anyhow.
+
typedef enum
{
MOJOCOLOR_BACKGROUND=1,
@@ -53,11 +62,13 @@
} MojoColor;
-static int strcells(const char *str)
+static int strchars(const char *str)
{
- // !!! FIXME: how to know how many _cells_ UTF-8 strings take in cursesw?
- return (int) strlen(str);
-} // strcells
+ int retval = 0;
+ while (utf8codepoint(&str))
+ retval++;
+ return retval;
+} // strchars
typedef struct
@@ -89,7 +100,7 @@
// !!! FIXME: cut and pasted in gui_stdio.c, too...fix bugs in both copies!
// !!! FIXME: (or move this somewhere else...)
-// !!! FIXME: this is not really Unicode friendly...
+// !!! FIXME: this handles Unicode, but assumes each glyph takes one column.
static char **splitText(char *text, int *_count, int *_w)
{
int i;
@@ -102,53 +113,63 @@
*_count = *_w = 0;
while (*text)
{
+ const char *utf8text = text;
+ uint32 ch = 0;
int pos = 0;
int furthest = 0;
- for (i = 0; (text[i]) && (i < (scrw-4)); i++)
+ for (i = 0; ((ch = utf8codepoint(&utf8text)) && (i < (scrw-4))); i++)
{
- const int ch = text[i];
if ((ch == '\r') || (ch == '\n'))
{
+ char *endptr = (char *) utf8text;
+ const char nextbyte = *utf8text;
count++;
retval = (char **) xrealloc(retval, count * sizeof (char *));
- text[i] = '\0';
+ *endptr = '\0';
retval[count-1] = xstrdup(text);
- text += i;
- *text = ch;
- if ((ch == '\r') && (text[1] == '\n'))
- text++;
- text++;
+ *endptr = nextbyte;
+ if ((ch == '\r') && (nextbyte == '\n')) // DOS endlines!
+ utf8text++; // skip it.
+ text = (char *) utf8text; // update to start of new line.
if (i > w)
w = i;
i = -1; // will be zero on next iteration...
} // if
- else if (isspace(ch))
+ else if ((ch == ' ') || (ch == '\t'))
{
furthest = i;
} // else if
} // for
// line overflow or end of stream...
- pos = (text[i]) ? furthest : i;
- if ((text[i]) && (furthest == 0)) // uhoh, no split at all...hack it.
+ pos = (ch) ? furthest : i;
+ if ((ch) && (furthest == 0)) // uhoh, no split at all...hack it.
{
- // !!! FIXME: might be chopping in the middle of a UTF-8 seq.
- pos = strlen(text);
- if (pos > scrw-4)
+ pos = strchars(text);
+ if (pos > scrw-4) // too big, have to chop a string in the middle.
pos = scrw-4;
} // if
if (pos > 0)
{
- char ch = text[pos];
+ char *endptr = NULL;
+ int j = 0;
+ char tmpch = 0;
+
+ utf8text = text; // adjust pointer by redecoding from start...
+ for (j = 0; j < pos; j++)
+ utf8codepoint(&utf8text);
+
+ endptr = (char *) utf8text;
+ tmpch = *utf8text;
count++;
retval = (char **) xrealloc(retval, count * sizeof (char*));
- text[pos] = '\0';
+ *endptr = '\0';
retval[count-1] = xstrdup(text);
- text += pos;
- *text = ch;
+ text = (char *) utf8text;
+ *endptr = tmpch;
if (pos > w)
w = pos;
} // if
@@ -255,7 +276,7 @@
else
break; // we're good, get out.
- len = strcells(msg);
+ len = strchars(msg);
y = scrh / 2;
x = ((scrw - len) / 2);
@@ -314,7 +335,7 @@
retval->textlines = splitText(retval->text, &retval->textlinecount, &w);
- len = strcells(title);
+ len = strchars(title);
if (len > scrw-4)
{
len = scrw-4;
@@ -327,7 +348,7 @@
if (bcount > 0)
{
for (i = 0; i < bcount; i++)
- buttonsw += strcells(buttons[i]) + 5; // '<', ' ', ' ', '>', ' '
+ buttonsw += strchars(buttons[i]) + 5; // '<', ' ', ' ', '>', ' '
if (buttonsw > w)
w = buttonsw;
// !!! FIXME: what if these overflow the screen?
@@ -369,7 +390,7 @@
wmove(win, h-1, w-1);
waddch(win, ACS_LRCORNER | COLOR_PAIR(MOJOCOLOR_BORDERBOTTOM));
- len = strcells(retval->title);
+ len = strchars(retval->title);
wmove(win, 0, ((w-len)/2)-1);
wattron(win, COLOR_PAIR(MOJOCOLOR_BORDERTITLE) | A_BOLD);
waddch(win, ' ');
@@ -386,7 +407,7 @@
whline(win, ACS_HLINE | A_BOLD | COLOR_PAIR(MOJOCOLOR_BORDERTOP), w-2);
for (i = 0; i < bcount; i++)
{
- len = strcells(buttons[i]) + 4;
+ len = strchars(buttons[i]) + 4;
buttonx -= len+1;
win = retval->buttons[i] = newwin(1, len, buttony, buttonx);
keypad(win, TRUE);
@@ -625,6 +646,7 @@
static boolean MojoGui_ncurses_init(void)
{
+ setlocale(LC_CTYPE, ""); // !!! FIXME: we assume you have a UTF-8 terminal.
if (initscr() == NULL)
{
logInfo("ncurses: initscr() failed, use another UI.");
@@ -1441,7 +1463,7 @@
{
int cells = (int) ( ((double) w) * (((double) percent) / 100.0) );
snprintf(buf, w+1, "%d%%", percent);
- mvwaddstr(win, h-3, ((w+2) - strcells(buf)) / 2, buf);
+ mvwaddstr(win, h-3, ((w+2) - strchars(buf)) / 2, buf);
mvwchgat(win, h-3, 1, cells, A_BOLD, MOJOCOLOR_DONE, NULL);
mvwchgat(win, h-3, 1+cells, w-cells, A_BOLD, MOJOCOLOR_TODO, NULL);
} // else
@@ -1451,7 +1473,7 @@
if (snprintf(buf, w+1, "%s", item) > (w-4))
strcpy((buf+w)-4, "..."); // !!! FIXME: Unicode problem.
mvwhline(win, h-2, 1, ' ', w);
- mvwaddstr(win, h-2, ((w+2) - strcells(buf)) / 2, buf);
+ mvwaddstr(win, h-2, ((w+2) - strchars(buf)) / 2, buf);
free(buf);
wrefresh(win);
Modified: trunk/universal.h
===================================================================
--- trunk/universal.h 2008-03-02 06:37:37 UTC (rev 539)
+++ trunk/universal.h 2008-03-03 07:01:54 UTC (rev 540)
@@ -100,7 +100,7 @@
#define UNICODE_BOGUS_CHAR_VALUE 0xFFFFFFFF
#define UNICODE_BOGUS_CHAR_CODEPOINT '?'
// !!! FIXME: document me!
-uint32 utf8codepoint(const char **_str);
+uint32 utf8codepoint(const char **str);
// Format a string, sort of (but not exactly!) like sprintf().
More information about the mojosetup-commits
mailing list