Alexandre Julliard wrote:
Vitaly Lipatov <[EMAIL PROTECTED]> writes:
We can't get correct non latin output in utfed console with normal ncurses. As
far as I know there is some problems in normal ncurses with utf8 (multbyte
symbols)... Only ncursesw supports utf8 output correctly (and wide char)... I
am wrong?
I don't know, maybe not, curses isn't exactly a great API...
In any case, you'll need to send the rest of the code, I'd like to see
how you are using it before adding configure checks.
This patch fixs wineconsole for non latin symbols. If we have ncursesw
we use unicode functions to console output.
Index: programs/wineconsole/curses.c
===================================================================
RCS file: /home/wine/wine/programs/wineconsole/curses.c,v
retrieving revision 1.29
diff -u -p -u -r1.29 curses.c
--- programs/wineconsole/curses.c 5 Oct 2006 18:16:40 -0000 1.29
+++ programs/wineconsole/curses.c 4 Jan 2007 13:56:13 -0000
@@ -35,7 +35,9 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
-#ifdef HAVE_NCURSES_H
+#ifdef HAVE_NCURSESW_NCURSES_H
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSES_H)
# include <ncurses.h>
#elif defined(HAVE_CURSES_H)
# include <curses.h>
@@ -50,6 +52,7 @@
#include <windef.h>
#include <winbase.h>
#include <winnls.h>
+#include <winuser.h>
#include "winecon_private.h"
#include "wine/library.h"
@@ -60,9 +63,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(curses);
#define PRIVATE(data) ((struct inner_data_curse*)((data)->private))
-#if defined(HAVE_CURSES_H) || defined(HAVE_NCURSES_H)
+#if defined(HAVE_CURSES_H) || defined(HAVE_NCURSES_H) || defined(HAVE_NCURSESW_NCURSES_H)
-#ifdef HAVE_NCURSES_H
+#ifdef HAVE_LIBNCURSESW
+# define CURSES_NAME "ncursesw"
+#elif defined (HAVE_LIBNCURSES)
# define CURSES_NAME "ncurses"
#else
# define CURSES_NAME "curses"
@@ -115,7 +120,12 @@ MAKE_FUNCPTR(prefresh)
MAKE_FUNCPTR(raw)
MAKE_FUNCPTR(start_color)
MAKE_FUNCPTR(stdscr)
-MAKE_FUNCPTR(waddchnstr)
+#ifdef HAVE_LIBNCURSESW
+MAKE_FUNCPTR(wget_wch)
+MAKE_FUNCPTR(wadd_wch)
+#else
+MAKE_FUNCPTR(waddch)
+#endif
MAKE_FUNCPTR(wmove)
MAKE_FUNCPTR(wgetch)
#ifdef HAVE_MOUSEMASK
@@ -129,7 +139,9 @@ MAKE_FUNCPTR(mousemask)
static BOOL WCCURSES_bind_libcurses(void)
{
-#ifdef HAVE_NCURSES_H
+#ifdef HAVE_LIBNCURSESW
+ static const char *ncname = SONAME_LIBNCURSESW;
+#elif defined (HAVE_LIBNCURSES)
static const char *ncname = SONAME_LIBNCURSES;
#else
static const char *ncname = SONAME_LIBCURSES;
@@ -178,7 +190,12 @@ static BOOL WCCURSES_bind_libcurses(void
LOAD_FUNCPTR(raw)
LOAD_FUNCPTR(start_color)
LOAD_FUNCPTR(stdscr)
- LOAD_FUNCPTR(waddchnstr)
+#ifdef HAVE_LIBNCURSESW
+ LOAD_FUNCPTR(wget_wch)
+ LOAD_FUNCPTR(wadd_wch)
+#else
+ LOAD_FUNCPTR(waddch)
+#endif
LOAD_FUNCPTR(wmove)
LOAD_FUNCPTR(wgetch)
#ifdef HAVE_MOUSEMASK
@@ -230,9 +247,11 @@ sym_not_found:
#define raw p_raw
#define start_color p_start_color
#define stdscr (*p_stdscr)
-#define waddchnstr p_waddchnstr
+#define waddch p_waddch
#define wmove p_wmove
#define wgetch p_wgetch
+#define wget_wch p_wget_wch
+#define wadd_wch p_wadd_wch
/******************************************************************
* WCCURSES_ResizeScreenBuffer
@@ -355,18 +374,19 @@ static void WCCURSES_Refresh(const struc
unsigned int x;
int y;
CHAR_INFO* cell;
+ #ifdef HAVE_LIBNCURSESW
+ cchar_t outChar;
+ #else
+ unsigned char ch;
+ #endif
DWORD attr;
- char ch;
-
for (y = tp; y <= bm; y++)
{
cell = &data->cells[y * data->curcfg.sb_width];
for (x = 0; x < data->curcfg.sb_width; x++)
{
- WideCharToMultiByte(CP_ACP, 0, &cell[x].Char.UnicodeChar, 1,
- &ch, 1, NULL, NULL);
- attr = ((BYTE)ch < 32 || (BYTE)ch > 127) ? 32 : (BYTE)ch;
-
+ attr = A_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);
@@ -375,9 +395,19 @@ static void WCCURSES_Refresh(const struc
if (cell[x].Attributes & BACKGROUND_GREEN) attr |= COLOR_PAIR(COLOR_GREEN << 3);
if (cell[x].Attributes & FOREGROUND_INTENSITY) attr |= A_BOLD;
+
+ /* I can`t move in PRIVATE(data)->line[x] WCHAR symbols */
PRIVATE(data)->line[x] = attr;
- }
- mvwaddchnstr(PRIVATE(data)->pad, y, 0, PRIVATE(data)->line, data->curcfg.sb_width);
+ #ifdef HAVE_LIBNCURSESW
+ outChar.chars[0] =(wchar_t) cell[x].Char.UnicodeChar;
+ outChar.attr = attr;
+ mvwadd_wch(PRIVATE(data)->pad,y,x,&outChar);
+ #else
+ WideCharToMultiByte(CP_UNIXCP,0,&cell[x].Char.UnicodeChar,1,(char *)&ch,1,NULL,NULL);
+ PRIVATE(data)->line[x] |= ( ch < 32 ) ? 32 : ch;
+ mvwaddch(PRIVATE(data)->pad,y,x,PRIVATE(data)->line[x]);
+ #endif
+ }
}
WCCURSES_PosCursor(data);
@@ -433,20 +463,6 @@ static void WCCURSES_ScrollV(struct inne
}
}
-/* Ascii -> VK, generated by calling VkKeyScanA(i) */
-static int vkkeyscan_table[256] =
-{
- 0,0,0,0,0,0,0,0,8,9,0,0,0,13,0,0,0,0,0,19,145,556,0,0,0,0,0,27,0,0,0,
- 0,32,305,478,307,308,309,311,222,313,304,312,443,188,189,190,191,48,
- 49,50,51,52,53,54,55,56,57,442,186,444,187,446,447,306,321,322,323,
- 324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,
- 341,342,343,344,345,346,219,220,221,310,445,192,65,66,67,68,69,70,71,
- 72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,475,476,477,
- 448,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,0
-};
static int mapvkey_0[256] =
{
@@ -489,7 +505,7 @@ static unsigned WCCURSES_FillSimpleChar(
unsigned inchar;
unsigned numEvent = 0;
DWORD cks = 0;
-
+
switch (real_inchar)
{
case 9: inchar = real_inchar;
@@ -505,7 +521,11 @@ static unsigned WCCURSES_FillSimpleChar(
* generated otherwise, we'll have a race here. FIXME: This gives 1 sec. delay
* because curses looks for a second character.
*/
- if ((inchar = wgetch(stdscr)) != ERR)
+ #ifdef HAVE_LIBNCURSESW
+ if ((wget_wch(stdscr,(wint_t*)&inchar)) != ERR)
+ #else
+ if ((inchar = wgetch(stdscr)) != ERR)
+ #endif
{
/* we got a alt-something key... */
cks = LEFT_ALT_PRESSED;
@@ -517,11 +537,18 @@ static unsigned WCCURSES_FillSimpleChar(
inchar = real_inchar;
break;
}
- if ((inchar & ~0xFF) != 0) WINE_FIXME("What a char (%u)\n", inchar);
- vk = vkkeyscan_table[inchar];
+
+ #ifdef HAVE_LIBNCURSESW
+ ir[numEvent].Event.KeyEvent.uChar.UnicodeChar = inchar;
+ #else
+ MultiByteToWideChar(CP_UNIXCP, 0,(char*)&inchar,1,&ir[numEvent].Event.KeyEvent.uChar.UnicodeChar, 1);
+ if ((inchar & ~0xFF) != 0) WINE_FIXME("What a char (%u)\n", inchar);
+ #endif
+
+ vk = (BYTE)VkKeyScanW(ir[numEvent].Event.KeyEvent.uChar.UnicodeChar);
if (vk & 0x0100)
WCCURSES_InitComplexChar(&ir[numEvent++], 1, 0x2a, 0x10, SHIFT_PRESSED);
- if ((vk & 0x0200) || (unsigned char)real_inchar <= 26)
+ if ((vk & 0x0200) || real_inchar <= 26)
WCCURSES_InitComplexChar(&ir[numEvent++], 1, 0x1d, 0x11, LEFT_CTRL_PRESSED);
if (vk & 0x0400)
WCCURSES_InitComplexChar(&ir[numEvent++], 1, 0x38, 0x12, LEFT_ALT_PRESSED);
@@ -532,13 +559,12 @@ static unsigned WCCURSES_FillSimpleChar(
ir[numEvent].Event.KeyEvent.dwControlKeyState = cks;
if (vk & 0x0100)
ir[numEvent].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
- if ((vk & 0x0200) || (unsigned char)real_inchar <= 26)
+ if ((vk & 0x0200) || real_inchar <= 26)
ir[numEvent].Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED;
if (vk & 0x0400)
ir[numEvent].Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED;
ir[numEvent].Event.KeyEvent.wVirtualKeyCode = vk;
ir[numEvent].Event.KeyEvent.wVirtualScanCode = mapvkey_0[vk & 0x00ff]; /* VirtualKeyCodes to ScanCode */
- ir[numEvent].Event.KeyEvent.uChar.UnicodeChar = (unsigned char)inchar;
ir[numEvent + 1] = ir[numEvent];
ir[numEvent + 1].Event.KeyEvent.bKeyDown = 0;
@@ -547,7 +573,7 @@ static unsigned WCCURSES_FillSimpleChar(
if (vk & 0x0400)
WCCURSES_InitComplexChar(&ir[numEvent++], 0, 0x38, 0x12, LEFT_ALT_PRESSED);
- if ((vk & 0x0200) || (unsigned char)real_inchar <= 26)
+ if ((vk & 0x0200) || real_inchar <= 26)
WCCURSES_InitComplexChar(&ir[numEvent++], 0, 0x1d, 0x11, 0);
if (vk & 0x0100)
WCCURSES_InitComplexChar(&ir[numEvent++], 0, 0x2a, 0x10, 0);
@@ -855,7 +881,11 @@ static void WCCURSES_GetEvents(struct in
unsigned numEvent;
DWORD n;
+ #ifdef HAVE_LIBNCURSESW
+ if ((wget_wch(stdscr,(wint_t*)&inchar)) == ERR) {WINE_FIXME("Ooch. somebody beat us\n");return;}
+ #else
if ((inchar = wgetch(stdscr)) == ERR) {WINE_FIXME("Ooch. somebody beat us\n");return;}
+ #endif
WINE_TRACE("Got o%o (0x%x)\n", inchar,inchar);