[Curses] Better support for widechar (unicode) (5/5)

Peter Berg Larsen pebl at math.ku.dk
Sat Nov 29 01:30:09 CST 2003


Changelog:
- If so library libncursesw is loaded use UTF-8 instead of converting
  unicode to ascii
-------------- next part --------------
diff -ur wine-20031016/programs/wineconsole/curses.c wine-my/programs/wineconsole/curses.c
--- wine-20031016/programs/wineconsole/curses.c	2003-10-15 23:01:05.000000000 +0200
+++ wine-my/programs/wineconsole/curses.c	2003-11-14 05:20:46.000000000 +0100
@@ -127,6 +127,14 @@
 MAKE_FUNCPTR(wmove)
 MAKE_FUNCPTR(wgetch)
 MAKE_FUNCPTR(resizeterm)
+
+#ifdef HAVE_NCURSESW_NCURSES_H
+# ifndef mvwadd_wchnstr
+	MAKE_FUNCPTR(mvwadd_wchnstr)
+# endif
+ MAKE_FUNCPTR(wadd_wchnstr)
+ MAKE_FUNCPTR(wcwidth)
+#endif
 
 #undef MAKE_FUNCPTR
 
@@ -193,6 +201,17 @@
     LOAD_FUNCPTR(wmove)
     LOAD_FUNCPTR(wgetch)
     LOAD_FUNCPTR(resizeterm)
+
+#ifdef HAVE_NCURSESW_NCURSES_H
+    if (!strcmp(nc_type->name,"ncursesw"))
+    {    
+#ifndef mvwadd_wchnstr
+	LOAD_FUNCPTR(mvwadd_wchnstr)
+#endif
+	LOAD_FUNCPTR(wadd_wchnstr)
+        LOAD_FUNCPTR(wcwidth)
+    }
+#endif
 
 #undef LOAD_FUNCPTR
 
@@ -240,6 +259,12 @@
 #define wmove p_wmove
 #define wgetch p_wgetch
 #define resizeterm p_resizeterm
+
+#ifndef mvwadd_wchnstr
+#  define mvwadd_wchnstr p_mvwadd_wchnstr
+#endif
+#define wadd_wchnstr p_wadd_wchnstr
+#define wcwidth p_wcwidth
 
 /******************************************************************
  *		WCCURSES_ResizeScreenBuffer
@@ -412,6 +437,74 @@
     WCCURSES_PosCursor(data);
 }
 
+#ifdef HAVE_NCURSESW_NCURSES_H
+static void WCCURSES_Refresh_UTF8(const struct inner_data* data, int tp, int bm)
+{
+    int         x, y;
+    CHAR_INFO*	cell;
+    attr_t  attr;
+    cchar_t *cc_line = (cchar_t *)PRIVATE(data)->line;
+
+    for (y = tp; y <= bm; y++)
+    {
+	cell = &data->cells[y * data->curcfg.sb_width];
+	memset(cc_line, 0, nc_type->sizeof_char * data->curcfg.sb_width);
+
+        for (x = 0; x < data->curcfg.sb_width; x++)
+        {
+	    cc_line[x].chars[0] = cell[x].Char.UnicodeChar;
+
+	    /* FIXME: windows oddity or not all unicodes seem to be support by font/locale */
+	    if (wcwidth(cc_line[x].chars[0]) <= 0)
+	    {
+		cc_line[x].chars[0] = L'!';
+		if (cell[x].Char.UnicodeChar > 0)
+		    WINE_TRACE("Unicode 0x%x cannot be displayed\n",cell[x].Char.UnicodeChar);
+	    }
+
+	    attr = WA_NORMAL;
+	    if (cell[x].Attributes & FOREGROUND_RED)   attr |= COLOR_PAIR(COLOR_RED);
+	    if (cell[x].Attributes & FOREGROUND_BLUE)  attr |= COLOR_PAIR(COLOR_BLUE);
+            if (cell[x].Attributes & FOREGROUND_GREEN) attr |= COLOR_PAIR(COLOR_GREEN);
+            if (cell[x].Attributes & BACKGROUND_RED)   attr |= COLOR_PAIR(COLOR_RED << 3);
+            if (cell[x].Attributes & BACKGROUND_BLUE)  attr |= COLOR_PAIR(COLOR_BLUE << 3);
+            if (cell[x].Attributes & BACKGROUND_GREEN) attr |= COLOR_PAIR(COLOR_GREEN << 3);
+	    cc_line[x].attr = attr;
+	}
+        if (mvwadd_wchnstr(PRIVATE(data)->pad, y, 0, cc_line, data->curcfg.sb_width) == ERR)
+	{
+	    WINE_WARN("Error while refreshing the %d line\n",y);
+	}
+    }
+
+    WCCURSES_PosCursor(data);
+}
+
+/******************************************************************
+ *		WCCURSES_Init_UTF8
+ * FIXME: Find a good way to determine whether terminal supports unicode.
+ * http://mail.nl.linux.org/linux-utf8/2001-11/msg00073.html
+ * http://www.mail-archive.com/[email protected]/msg04341.html
+ * Select UTF-8 character set.
+ * Test abitrary chosen (5952) unicode width.
+ */
+static BOOL WCCURSES_Init_UTF8(struct inner_data* data)
+{
+    fputs("\033%G", stdout);
+    fflush(stdout);
+
+    if (wcwidth(5952) <= 0)
+    {
+	WINE_MESSAGE("Terminal or locale environment is not setup to use unicode (UTF-8). "
+		     "Falls back to ascii.\n");
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+#endif
+
 /******************************************************************
  *		WCCURSES_Scroll
  *
@@ -985,6 +1078,13 @@
 
     initscr();
 
+#ifdef HAVE_NCURSESW_NCURSES_H
+    if (!strcmp(nc_type->name,"ncursesw") && WCCURSES_Init_UTF8(data))
+    {
+	data->fnRefresh = WCCURSES_Refresh_UTF8;
+    }
+#endif
+
     /* creating the basic colors - FIXME intensity not handled yet */
     if (!has_colors())
     {


More information about the wine-patches mailing list