Convert WND.text field to Unicode.
Add new key to wine.ini in the section [x11drv] - TextCP, which means
code page used for texts passed to X.
Accordingly fix handlers of WM_SETTEXT/WM_GETTEXT.

diff --git a/controls/button.c b/controls/button.c
index afeafe1..51bd46c 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -15,7 +15,7 @@
 #include "tweak.h"
 
 static void PaintGrayOnGray( HDC hDC,HFONT hFont,RECT *rc,
-			     char *text, UINT format );
+			     LPCWSTR text, UINT format );
 
 static void PB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void CB_Paint( WND *wndPtr, HDC hDC, WORD action );
@@ -222,7 +222,7 @@
         return DefWindowProcA( hWnd, uMsg, wParam, lParam );
 
     case WM_SETTEXT:
-        DEFWND_SetText( wndPtr, (LPCSTR)lParam );
+        DEFWND_SetTextA( wndPtr, (LPCSTR)lParam );
 	if( wndPtr->dwStyle & WS_VISIBLE )
             PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
         return 0;
@@ -489,7 +489,7 @@
             SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
                                  GetSysColor(COLOR_GRAYTEXT) :
                                  GetSysColor(COLOR_BTNTEXT) );
-            DrawTextA( hDC, wndPtr->text, -1, &rc,
+            DrawTextW( hDC, wndPtr->text, -1, &rc,
                          DT_SINGLELINE | DT_CENTER | DT_VCENTER );
             /* do we have the focus?
 	     * Win9x draws focus last with a size prop. to the button
@@ -500,7 +500,7 @@
                 RECT r = { 0, 0, 0, 0 };
                 INT xdelta, ydelta;
 
-                DrawTextA( hDC, wndPtr->text, -1, &r,
+                DrawTextW( hDC, wndPtr->text, -1, &r,
                              DT_SINGLELINE | DT_CALCRECT );
                 xdelta = ((rc.right - rc.left) - (r.right - r.left) - 1) / 2;
                 ydelta = ((rc.bottom - rc.top) - (r.bottom - r.top) - 1) / 2;
@@ -619,7 +619,7 @@
  *   function ignores the CACHE_GetPattern funcs.
  */
 
-void PaintGrayOnGray(HDC hDC,HFONT hFont,RECT *rc,char *text,
+void PaintGrayOnGray(HDC hDC, HFONT hFont, RECT *rc, LPCWSTR text,
 			UINT format)
 {
 /*  This is the standard gray on gray pattern:
@@ -636,7 +636,7 @@
     RECT rect,rc2;
 
     rect=*rc;
-    DrawTextA( hDC, text, -1, &rect, DT_SINGLELINE | DT_CALCRECT);
+    DrawTextW( hDC, text, -1, &rect, DT_SINGLELINE | DT_CALCRECT);
     /* now text width and height are in rect.right and rect.bottom */
     rc2=rect;
     rect.left = rect.top = 0; /* drawing pos in hdcMem */
@@ -647,7 +647,7 @@
     PatBlt( hdcMem,0,0,rect.right,rect.bottom,WHITENESS);
       /* will be overwritten by DrawText, but just in case */
     if (hFont) SelectObject( hdcMem, hFont);
-    DrawTextA( hdcMem, text, -1, &rc2, DT_SINGLELINE);  
+    DrawTextW( hdcMem, text, -1, &rc2, DT_SINGLELINE);
       /* After draw: foreground = 0 bits, background = 1 bits */
     hBr = SelectObject( hdcMem, CreatePatternBrush(hbm) );
     DeleteObject( hbm );
@@ -717,7 +717,7 @@
 
       /* Draw the check-box bitmap */
 
-    if (wndPtr->text) textlen = strlen( wndPtr->text );
+    if (wndPtr->text) textlen = lstrlenW( wndPtr->text );
     if (action == ODA_DRAWENTIRE || action == ODA_SELECT)
     { 
         if( TWEAK_WineLook == WIN31_LOOK )
@@ -792,7 +792,7 @@
 	  } else {
             if (wndPtr->dwStyle & WS_DISABLED)
                 SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
-            DrawTextA( hDC, wndPtr->text, textlen, &rtext,
+            DrawTextW( hDC, wndPtr->text, textlen, &rtext,
 			 DT_SINGLELINE | DT_VCENTER );
 	  }
         }
@@ -805,7 +805,7 @@
 
         SetRectEmpty(&rbox);
         if( textlen )
-            DrawTextA( hDC, wndPtr->text, textlen, &rbox,
+            DrawTextW( hDC, wndPtr->text, textlen, &rbox,
 			 DT_SINGLELINE | DT_CALCRECT );
         textlen = rbox.bottom - rbox.top;
         delta = ((rtext.bottom - rtext.top) - textlen)/2;
@@ -884,7 +884,7 @@
         if (wndPtr->dwStyle & WS_DISABLED)
             SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
         rc.left += 10;
-        DrawTextA( hDC, wndPtr->text, -1, &rc, DT_SINGLELINE | DT_NOCLIP );
+        DrawTextW( hDC, wndPtr->text, -1, &rc, DT_SINGLELINE | DT_NOCLIP );
     }
 }
 
diff --git a/controls/icontitle.c b/controls/icontitle.c
index 9e657b7..1e9fe27 100644
--- a/controls/icontitle.c
+++ b/controls/icontitle.c
@@ -15,8 +15,6 @@
 #include "desktop.h"
 #include "heap.h"
 
-static  LPCSTR	emptyTitleText = "<...>";
-
 	BOOL	bMultiLineTitle;
 	HFONT	hIconTitleFont;
 
@@ -66,13 +64,14 @@
  */
 static BOOL ICONTITLE_GetTitlePos( WND* wnd, LPRECT lpRect )
 {
-    LPSTR str;
-    int length = lstrlenA( wnd->owner->text );
+    static WCHAR emptyTitleText[] = {'<','.','.','.','>',0};
+    LPWSTR str;
+    int length = lstrlenW( wnd->owner->text );
 
     if( length )
     {
 	str = HeapAlloc( GetProcessHeap(), 0, length + 1 );
-	lstrcpyA( str, wnd->owner->text );
+	lstrcpyW( str, wnd->owner->text );
 	while( str[length - 1] == ' ' ) /* remove trailing spaces */
 	{ 
 	    str[--length] = '\0';
@@ -85,8 +84,8 @@
     }
     if( !length ) 
     {
-	str = (LPSTR)emptyTitleText;
-	length = lstrlenA( str );
+	str = emptyTitleText;
+	length = lstrlenW( str );
     }
 
     if( str )
@@ -100,7 +99,7 @@
 		       GetSystemMetrics(SM_CXBORDER) * 2,
 		       GetSystemMetrics(SM_CYBORDER) * 2 );
 
-	    DrawTextA( hDC, str, length, lpRect, DT_CALCRECT |
+	    DrawTextW( hDC, str, length, lpRect, DT_CALCRECT |
 			 DT_CENTER | DT_NOPREFIX | DT_WORDBREAK |
 			 (( bMultiLineTitle ) ? 0 : DT_SINGLELINE) );
 
diff --git a/controls/static.c b/controls/static.c
index 7cb56a5..f054522 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -271,7 +271,7 @@
         else if (style == SS_BITMAP) 
             STATIC_SetBitmap(wndPtr,STATIC_LoadBitmap(wndPtr,(LPCSTR)lParam ));
 	else
-            DEFWND_SetText( wndPtr, (LPCSTR)lParam );
+            DEFWND_SetTextA( wndPtr, (LPCSTR)lParam );
         InvalidateRect( hWnd, NULL, FALSE );
         break;
 
@@ -417,7 +417,7 @@
     if (!IsWindowEnabled(wndPtr->hwndSelf))
    	SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
 
-    if (wndPtr->text) DrawTextA( hdc, wndPtr->text, -1, &rc, wFormat );
+    if (wndPtr->text) DrawTextW( hdc, wndPtr->text, -1, &rc, wFormat );
 }
 
 static void STATIC_PaintRectfn( WND *wndPtr, HDC hdc )
diff --git a/include/mdi.h b/include/mdi.h
index 3b22a2f..ee501df 100644
--- a/include/mdi.h
+++ b/include/mdi.h
@@ -36,7 +36,7 @@
     HWND      hwndActiveChild;
     HMENU     hWindowMenu;
     UINT      idFirstChild;
-    LPSTR       frameTitle;
+    LPWSTR    frameTitle;
     UINT      nTotalCreated;
     UINT      mdiFlags;
     UINT      sbRecalc;   /* SB_xxx flags for scrollbar fixup */
diff --git a/include/ttydrv.h b/include/ttydrv.h
index 142f89a..b89a9da 100644
--- a/include/ttydrv.h
+++ b/include/ttydrv.h
@@ -193,7 +193,7 @@
 extern struct tagWND *TTYDRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent);
 extern void TTYDRV_WND_ForceWindowRaise(struct tagWND *pWnd);
 extern void TTYDRV_WND_SetWindowPos(struct tagWND *wndPtr, const struct tagWINDOWPOS *winpos, BOOL bSMC_SETXPOS);
-extern void TTYDRV_WND_SetText(struct tagWND *wndPtr, LPCSTR text);
+extern void TTYDRV_WND_SetText(struct tagWND *wndPtr, LPCWSTR text);
 extern void TTYDRV_WND_SetFocus(struct tagWND *wndPtr);
 extern void TTYDRV_WND_PreSizeMove(struct tagWND *wndPtr);
 extern void TTYDRV_WND_PostSizeMove(struct tagWND *wndPtr);
diff --git a/include/win.h b/include/win.h
index 3566d61..1e954ab 100644
--- a/include/win.h
+++ b/include/win.h
@@ -71,7 +71,7 @@
     HINSTANCE    hInstance;     /* Window hInstance (from CreateWindow) */
     RECT         rectClient;    /* Client area rel. to parent client area */
     RECT         rectWindow;    /* Whole window rel. to parent client area */
-    LPSTR          text;          /* Window text */
+    LPWSTR        text;           /* Window text */
     void          *pVScroll;      /* Vertical scroll-bar info */
     void          *pHScroll;      /* Horizontal scroll-bar info */
     void          *pProp;         /* Pointer to properties list */
@@ -123,7 +123,7 @@
     WND*   (*pSetParent)(WND *, WND *);
     void   (*pForceWindowRaise)(WND *);
     void   (*pSetWindowPos)(WND *, const WINDOWPOS *, BOOL);
-    void   (*pSetText)(WND *, LPCSTR);
+    void   (*pSetText)(WND *, LPCWSTR);
     void   (*pSetFocus)(WND *);
     void   (*pPreSizeMove)(WND *);
     void   (*pPostSizeMove)(WND *);
@@ -202,7 +202,8 @@
 extern void CARET_GetRect(LPRECT lprc);  /* windows/caret.c */
 
 extern BOOL16 DRAG_QueryUpdate( HWND, SEGPTR, BOOL );
-extern void DEFWND_SetText( WND *wndPtr, LPCSTR text );
+extern void DEFWND_SetTextA( WND *wndPtr, LPCSTR text );
+extern void DEFWND_SetTextW( WND *wndPtr, LPCWSTR text );
 extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT16 ctlType );     /* windows/defwnd.c */
 
 extern void PROPERTY_RemoveWindowProps( WND *pWnd );  		      /* windows/property.c */
diff --git a/include/x11drv.h b/include/x11drv.h
index ccbd4ec..d4a50f3 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -422,7 +422,7 @@
 extern struct tagWND *X11DRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent);
 extern void X11DRV_WND_ForceWindowRaise(struct tagWND *pWnd);
 extern void X11DRV_WND_SetWindowPos(struct tagWND *wndPtr, const struct tagWINDOWPOS *winpos, BOOL bSMC_SETXPOS);
-extern void X11DRV_WND_SetText(struct tagWND *wndPtr, LPCSTR text);
+extern void X11DRV_WND_SetText(struct tagWND *wndPtr, LPCWSTR text);
 extern void X11DRV_WND_SetFocus(struct tagWND *wndPtr);
 extern void X11DRV_WND_PreSizeMove(struct tagWND *wndPtr);
 extern void X11DRV_WND_PostSizeMove(struct tagWND *wndPtr);
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 11fd6b9..2ef135e 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -20,9 +20,11 @@
 #include "cache.h"
 #include "windef.h"
 #include "wingdi.h"
+#include "winnls.h"
+#include "wine/unicode.h"
 #include "wine/winuser16.h"
 
-DEFAULT_DEBUG_CHANNEL(win)
+DEFAULT_DEBUG_CHANNEL(win);
 
   /* bits in the dwKeyData */
 #define KEYDATA_ALT 		0x2000
@@ -56,15 +58,45 @@
 
 
 /***********************************************************************
- *           DEFWND_SetText
+ *           DEFWND_SetTextA
  *
  * Set the window text.
  */
-void DEFWND_SetText( WND *wndPtr, LPCSTR text )
+void DEFWND_SetTextA( WND *wndPtr, LPCSTR text )
 {
+    int count;
+
     if (!text) text = "";
-    if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
-    wndPtr->text = HEAP_strdupA( SystemHeap, 0, text );    
+    count = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
+
+    if (wndPtr->text) HeapFree(SystemHeap, 0, wndPtr->text);
+    if ((wndPtr->text = HeapAlloc(SystemHeap, 0, count * sizeof(WCHAR))))
+        MultiByteToWideChar( CP_ACP, 0, text, -1, wndPtr->text, count );
+    else
+        ERR("Not enough memory for window text");
+
+    wndPtr->pDriver->pSetText(wndPtr, wndPtr->text);
+}
+
+/***********************************************************************
+ *           DEFWND_SetTextW
+ *
+ * Set the window text.
+ */
+void DEFWND_SetTextW( WND *wndPtr, LPCWSTR text )
+{
+    static const WCHAR empty_string[] = {0};
+    int count;
+
+    if (!text) text = empty_string;
+    count = strlenW(text) + 1;
+
+    if (wndPtr->text) HeapFree(SystemHeap, 0, wndPtr->text);
+    if ((wndPtr->text = HeapAlloc(SystemHeap, 0, count * sizeof(WCHAR))))
+	lstrcpyW( wndPtr->text, text );
+    else
+        ERR("Not enough memory for window text");
+
     wndPtr->pDriver->pSetText(wndPtr, wndPtr->text);
 }
 
@@ -336,7 +368,7 @@
 	return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
 	
     case WM_GETTEXTLENGTH:
-        if (wndPtr->text) return (LRESULT)strlen(wndPtr->text);
+        if (wndPtr->text) return (LRESULT)strlenW(wndPtr->text);
         return 0;
 
     case WM_SETCURSOR:
@@ -512,7 +544,7 @@
 	{
 	    CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
 	    if (cs->lpszName)
-		DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(cs->lpszName) );
+		DEFWND_SetTextA( wndPtr, (LPCSTR)PTR_SEG_TO_LIN(cs->lpszName) );
 	    result = 1;
 	}
         break;
@@ -541,13 +573,13 @@
     case WM_GETTEXT:
         if (wParam && wndPtr->text)
         {
-            lstrcpynA( (LPSTR)PTR_SEG_TO_LIN(lParam), wndPtr->text, wParam );
+            lstrcpynWtoA( (LPSTR)PTR_SEG_TO_LIN(lParam), wndPtr->text, wParam );
             result = (LRESULT)strlen( (LPSTR)PTR_SEG_TO_LIN(lParam) );
         }
         break;
 
     case WM_SETTEXT:
-	DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
+	DEFWND_SetTextA( wndPtr, (LPCSTR)PTR_SEG_TO_LIN(lParam) );
 	if( wndPtr->dwStyle & WS_CAPTION ) NC_HandleNCPaint( hwnd , (HRGN)1 );
         break;
 
@@ -580,7 +612,7 @@
     case WM_NCCREATE:
 	{
 	    CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
-	    if (cs->lpszName) DEFWND_SetText( wndPtr, cs->lpszName );
+	    if (cs->lpszName) DEFWND_SetTextA( wndPtr, cs->lpszName );
 	    result = 1;
 	}
         break;
@@ -604,13 +636,13 @@
     case WM_GETTEXT:
         if (wParam && wndPtr->text)
         {
-            lstrcpynA( (LPSTR)lParam, wndPtr->text, wParam );
+            lstrcpynWtoA( (LPSTR)lParam, wndPtr->text, wParam );
             result = (LRESULT)strlen( (LPSTR)lParam );
         }
         break;
 
     case WM_SETTEXT:
-	DEFWND_SetText( wndPtr, (LPSTR)lParam );
+	DEFWND_SetTextA( wndPtr, (LPCSTR)lParam );
 	NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
         break;
 
@@ -640,45 +672,37 @@
     WPARAM wParam,  /* [in] first message parameter */
     LPARAM lParam )   /* [in] second message parameter */
 {
-    LRESULT result;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    LRESULT result = 0;
 
+    if (!wndPtr) return 0;
     switch(msg)
     {
     case WM_NCCREATE:
 	{
 	    CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
-	    if (cs->lpszName)
-            {
-                WND *wndPtr = WIN_FindWndPtr( hwnd );
-                LPSTR str = HEAP_strdupWtoA(GetProcessHeap(), 0, cs->lpszName);
-                DEFWND_SetText( wndPtr, str );
-                HeapFree( GetProcessHeap(), 0, str );
-                WIN_ReleaseWndPtr(wndPtr);
-            }
+	    if (cs->lpszName) DEFWND_SetTextW( wndPtr, cs->lpszName );
 	    result = 1;
 	}
         break;
 
     case WM_GETTEXT:
+        if (wParam && wndPtr->text)
         {
-            LPSTR str = HeapAlloc( GetProcessHeap(), 0, wParam );
-            result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)str );
-            lstrcpynAtoW( (LPWSTR)lParam, str, wParam );
-            HeapFree( GetProcessHeap(), 0, str );
+            lstrcpynW( (LPWSTR)lParam, wndPtr->text, wParam );
+            result = strlenW( (LPWSTR)lParam );
         }
         break;
 
     case WM_SETTEXT:
-        {
-            LPSTR str = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPWSTR)lParam );
-            result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)str );
-            HeapFree( GetProcessHeap(), 0, str );
-        }
+        DEFWND_SetTextW( wndPtr, (LPCWSTR)lParam );
+	NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
         break;
 
     default:
         result = DefWindowProcA( hwnd, msg, wParam, lParam );
         break;
     }
+    WIN_ReleaseWndPtr(wndPtr);
     return result;
 }
diff --git a/windows/dialog.c b/windows/dialog.c
index e3a72ae..2d206bd 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -16,6 +16,7 @@
 #include "windowsx.h"
 #include "wine/winuser16.h"
 #include "wine/winbase16.h"
+#include "wine/unicode.h"
 #include "dialog.h"
 #include "drive.h"
 #include "heap.h"
@@ -1182,15 +1183,16 @@
                      (wndPtr->text!=NULL))
                 {
                     /* find the accelerator key */
-                    LPSTR p = wndPtr->text - 2;
+                    LPWSTR p = wndPtr->text - 2;
                     do
                     {
-                        p = strchr( p + 2, '&' );
+                        p = strchrW( p + 2, '&' );
                     }
                     while (p != NULL && p[1] == '&');
 
                     /* and check if it's the one we're looking for */
-                    if (p != NULL && toupper( p[1] ) == toupper( vKey ) )
+		    /* FIXME: convert vKey to unicode */
+                    if (p != NULL && toupperW( p[1] ) == (WCHAR)toupper( vKey ) )
                     {
                         if ((dlgCode & DLGC_STATIC) || 
                             (wndPtr->dwStyle & 0x0f) == BS_GROUPBOX )
diff --git a/windows/mdi.c b/windows/mdi.c
index 3d5cabf..ed19649 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -93,7 +93,7 @@
 static HBITMAP16 hBmpRestore = 0;
 
 /* ----------------- declarations ----------------- */
-static void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCSTR);
+static void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCWSTR);
 static BOOL MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND);
 static BOOL MDI_RestoreFrameMenu(WND *, HWND);
 
@@ -128,11 +128,12 @@
  */
 static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND hWndChild )
 {
-    char            buffer[128];
+    WCHAR           buffer[128];
+    static const WCHAR format[] = {'%','d',' ',0};
     MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
     WND            *wndPtr     = WIN_FindWndPtr(hWndChild);
-    UINT	    n          = sprintf(buffer, "%d ",
-				 wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
+    UINT	    n          = wsprintfW(buffer, format,
+                                           wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
     BOOL	    bRet	    = 0;
 
     if( !clientInfo->hWindowMenu )
@@ -141,10 +142,10 @@
         goto END;
     }
 
-    if (wndPtr->text) lstrcpynA(buffer + n, wndPtr->text, sizeof(buffer) - n );
+    if (wndPtr->text) lstrcpynW(buffer + n, wndPtr->text, sizeof(buffer)/sizeof(WCHAR) - n );
 
     n    = GetMenuState(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); 
-    bRet = ModifyMenuA(clientInfo->hWindowMenu , wndPtr->wIDmenu, 
+    bRet = ModifyMenuW(clientInfo->hWindowMenu , wndPtr->wIDmenu, 
                       MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu, buffer );
     CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED);
 END:
@@ -157,7 +158,8 @@
  */
 static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
 {
-    char    	 buffer[128];
+    WCHAR    	 buffer[128];
+    static const WCHAR format[] = {'&','%','d',' ',0};
     MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
     WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
     UINT	 index      = 0,id,n;
@@ -190,15 +192,15 @@
 	/* set correct id */
 	tmpWnd->wIDmenu--;
 
-	n = sprintf(buffer, "&%d ",index - clientInfo->idFirstChild);
+	n = wsprintfW(buffer, format ,index - clientInfo->idFirstChild);
 	if (tmpWnd->text)
-            lstrcpynA(buffer + n, tmpWnd->text, sizeof(buffer) - n );	
+            lstrcpynW(buffer + n, tmpWnd->text, sizeof(buffer)/sizeof(WCHAR) - n );	
 
 	/*  change menu if the current child is to be shown in the 
          *  "Windows" menu
          */
         if (index <= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT) 
-	ModifyMenuA(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
+	ModifyMenuW(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
                       index - 1 , buffer ); 
         WIN_ReleaseWndPtr(tmpWnd);
     }
@@ -1105,13 +1107,13 @@
  * Note: lpTitle can be NULL
  */
 static void MDI_UpdateFrameText( WND *frameWnd, HWND hClient,
-                                 BOOL repaint, LPCSTR lpTitle )
+                                 BOOL repaint, LPCWSTR lpTitle )
 {
-    char   lpBuffer[MDI_MAXTITLELENGTH+1];
+    WCHAR   lpBuffer[MDI_MAXTITLELENGTH+1];
     WND*   clientWnd = WIN_FindWndPtr(hClient);
     MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra;
 
-    TRACE("repaint %i, frameText %s\n", repaint, (lpTitle)?lpTitle:"NULL");
+    TRACE("repaint %i, frameText %s\n", repaint, (lpTitle)?debugstr_w(lpTitle):"NULL");
 
     if (!clientWnd)
            return;
@@ -1126,7 +1128,7 @@
     if (lpTitle) 
     {
 	if (ci->frameTitle) HeapFree( SystemHeap, 0, ci->frameTitle );
-	ci->frameTitle = HEAP_strdupA( SystemHeap, 0, lpTitle );
+	ci->frameTitle = HEAP_strdupW( SystemHeap, 0, lpTitle );
     }
 
     if (ci->frameTitle)
@@ -1137,32 +1139,33 @@
 	{
 	    /* combine frame title and child title if possible */
 
-	    LPCSTR lpBracket  = " - [";
-	    int	i_frame_text_length = strlen(ci->frameTitle);
-	    int	i_child_text_length = strlen(childWnd->text);
+	    static const WCHAR lpBracket[]  = {' ','-',' ','[',0};
+	    static const WCHAR lpBracket2[]  = {']',0};
+	    int	i_frame_text_length = lstrlenW(ci->frameTitle);
+	    int	i_child_text_length = lstrlenW(childWnd->text);
 
-	    lstrcpynA( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);
+	    lstrcpynW( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);
 
 	    if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
             {
-		strcat( lpBuffer, lpBracket );
+		lstrcatW( lpBuffer, lpBracket );
 
 		if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
 		{
-		    strcat( lpBuffer, childWnd->text );
-		    strcat( lpBuffer, "]" );
+		    lstrcatW( lpBuffer, childWnd->text );
+		    lstrcatW( lpBuffer, lpBracket2 );
 		}
 		else
 		{
-		    lstrcpynA( lpBuffer + i_frame_text_length + 4, 
+		    lstrcpynW( lpBuffer + i_frame_text_length + 4, 
 				 childWnd->text, MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
-		    strcat( lpBuffer, "]" );
+		    lstrcatW( lpBuffer, lpBracket2 );
 		}
 	    }
 	}
 	else
 	{
-            lstrcpynA(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH+1 );
+            lstrcpynW(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH+1 );
 	}
         WIN_ReleaseWndPtr(childWnd);
 
@@ -1170,7 +1173,7 @@
     else
 	lpBuffer[0] = '\0';
 
-    DEFWND_SetText( frameWnd, lpBuffer );
+    DEFWND_SetTextW( frameWnd, lpBuffer );
     if( repaint == MDI_REPAINTFRAME)
 	SetWindowPos( frameWnd->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED |
 			SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
@@ -1486,11 +1489,15 @@
 	    break;
 
 	  case WM_SETTEXT:
-            wndPtr = WIN_FindWndPtr(hwnd);
-            MDI_UpdateFrameText(wndPtr, hwndMDIClient,
-				      MDI_REPAINTFRAME, 
-			             (LPCSTR)PTR_SEG_TO_LIN(lParam));
-            WIN_ReleaseWndPtr(wndPtr);
+            {
+                LPWSTR text = HEAP_strdupAtoW( GetProcessHeap(), 0, 
+                                               (LPCSTR)PTR_SEG_TO_LIN(lParam) );
+                wndPtr = WIN_FindWndPtr(hwnd);
+                MDI_UpdateFrameText(wndPtr, hwndMDIClient,
+                                    MDI_REPAINTFRAME, text );
+                WIN_ReleaseWndPtr(wndPtr);
+                HeapFree( GetProcessHeap(), 0, text );
+            }
 	    return 0;
 	
 	  case WM_SETFOCUS:
@@ -2329,9 +2336,9 @@
                    if (pWnd->wIDmenu == ci->idFirstChild + i)
                        break;
 
-               SendMessageA(hListBox, LB_ADDSTRING, 0, (LPARAM) pWnd->text);
+               SendMessageW(hListBox, LB_ADDSTRING, 0, (LPARAM) pWnd->text);
                SendMessageA(hListBox, LB_SETITEMDATA, i, (LPARAM) pWnd);
-               length = strlen(pWnd->text);
+               length = lstrlenW(pWnd->text);
                WIN_ReleaseWndPtr(pWnd);
 
                if (length > widest)
diff --git a/windows/spy.c b/windows/spy.c
index eefc323..4d2d351 100644
--- a/windows/spy.c
+++ b/windows/spy.c
@@ -811,27 +811,22 @@
     {
 	INT n = sizeof(wnd_buffer) - 6;
 	LPSTR p = wnd_buffer;
-	LPSTR src;
-	
         char  postfix;
 	
 	if( pWnd->text && pWnd->text[0] != '\0' )
 	{
-	    src = pWnd->text;
+	    LPWSTR src = pWnd->text;
 	    *(p++) = postfix = '\"';
 	    while ((n-- > 1) && *src) *p++ = *src++;
+            if( *src ) for( n = 0; n < 3; n++ ) *(p++)='.';
 	}
 	else /* get class name */
 	{
-	    INT len;
-
 	    *(p++)='{';
 	    GlobalGetAtomNameA((ATOM) GetClassWord(pWnd->hwndSelf, GCW_ATOM), p, n + 1);
-	    src = p += (len = lstrlenA(p));
-	    if( len >= n ) src = wnd_buffer;	/* something nonzero */
+	    p += strlen(p);
 	    postfix = '}';
 	}
-	if( *src ) for( n = 0; n < 3; n++ ) *(p++)='.';
 	*(p++) = postfix;
 	*(p++) = '\0';
         WIN_ReleaseWndPtr(pWnd);
diff --git a/windows/ttydrv/wnd.c b/windows/ttydrv/wnd.c
index 057968a..7c55553 100644
--- a/windows/ttydrv/wnd.c
+++ b/windows/ttydrv/wnd.c
@@ -160,9 +160,9 @@
 /*****************************************************************
  *		TTYDRV_WND_SetText
  */
-void TTYDRV_WND_SetText(WND *wndPtr, LPCSTR text)
+void TTYDRV_WND_SetText(WND *wndPtr, LPCWSTR text)
 {
-  FIXME("(%p, %s): stub\n", wndPtr, debugstr_a(text));
+  FIXME("(%p, %s): stub\n", wndPtr, debugstr_w(text));
 }
 
 /*****************************************************************
diff --git a/windows/win.c b/windows/win.c
index dce2b1a..0e28e2a 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -238,7 +238,7 @@
              ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
              ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
              ptr->dwStyle, ptr->dwExStyle, (UINT)ptr->winproc,
-             ptr->text ? ptr->text : "",
+             ptr->text ? debugstr_w(ptr->text) : "",
              ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
              ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
              ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
@@ -288,7 +288,7 @@
         DPRINTF( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
                  (DWORD)ptr, ptr->hmemTaskQ, className,
                  (UINT)ptr->dwStyle, (UINT)ptr->winproc,
-                 ptr->text?ptr->text:"<null>");
+                 ptr->text ? debugstr_w(ptr->text) : "<null>");
         
         if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
         WIN_UpdateWndPtr(&ptr,ptr->next);
@@ -1506,7 +1506,7 @@
  * Implementation of FindWindow() and FindWindowEx().
  */
 static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
-                              LPCSTR title )
+                              LPCWSTR title )
 {
     WND *pWnd;
     HWND retvalue;
@@ -1556,7 +1556,7 @@
             retvalue = pWnd->hwndSelf;
             goto end;
         }
-        if (pWnd->text && !strcmp( pWnd->text, title ))
+        if (pWnd->text && !lstrcmpW( pWnd->text, title ))
         {
             retvalue = pWnd->hwndSelf;
             goto end;
@@ -1606,6 +1606,8 @@
                                LPCSTR className, LPCSTR title )
 {
     ATOM atom = 0;
+    LPWSTR buffer;
+    HWND hwnd;
 
     if (className)
     {
@@ -1617,7 +1619,11 @@
             return 0;
         }
     }
-    return WIN_FindWindow( parent, child, atom, title );
+
+    buffer = HEAP_strdupAtoW( GetProcessHeap(), 0, title );
+    hwnd = WIN_FindWindow( parent, child, atom, buffer );
+    HeapFree( GetProcessHeap(), 0, buffer );
+    return hwnd;
 }
 
 
@@ -1628,8 +1634,6 @@
                                LPCWSTR className, LPCWSTR title )
 {
     ATOM atom = 0;
-    char *buffer;
-    HWND hwnd;
 
     if (className)
     {
@@ -1641,10 +1645,7 @@
             return 0;
         }
     }
-    buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
-    hwnd = WIN_FindWindow( parent, child, atom, buffer );
-    HeapFree( GetProcessHeap(), 0, buffer );
-    return hwnd;
+    return WIN_FindWindow( parent, child, atom, title );
 }
 
 
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index a8ae0e5..3c19b6d 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -28,6 +28,7 @@
 #include "class.h"
 #include "x11drv.h"
 #include "wingdi.h"
+#include "winnls.h"
 #include "wine/winuser16.h"
 
 DEFAULT_DEBUG_CHANNEL(win);
@@ -656,13 +657,33 @@
 /*****************************************************************
  *		X11DRV_WND_SetText
  */
-void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text)
+void X11DRV_WND_SetText(WND *wndPtr, LPCWSTR text)
 {   
-  if (!X11DRV_WND_GetXWindow(wndPtr))
-    return;
+    UINT count;
+    char *buffer;
+    static UINT text_cp = (UINT)-1;
+    Window win;
 
-  TSXStoreName( display, X11DRV_WND_GetXWindow(wndPtr), text );
-  TSXSetIconName( display, X11DRV_WND_GetXWindow(wndPtr), text );
+    if (!(win = X11DRV_WND_GetXWindow(wndPtr))) return;
+
+    if(text_cp == (UINT)-1)
+    {
+	text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP);
+	TRACE("text_cp = %u\n", text_cp);
+    }
+
+    /* allocate new buffer for window text */
+    count = WideCharToMultiByte(text_cp, 0, text, -1, NULL, 0, NULL, NULL);
+    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WCHAR) )))
+    {
+	ERR("Not enough memory for window text\n");
+	return;
+    }
+    WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL);
+
+    TSXStoreName( display, win, buffer );
+    TSXSetIconName( display, win, buffer );
+    HeapFree( GetProcessHeap(), 0, buffer );
 }
 
 /*****************************************************************
diff --git a/wine.ini b/wine.ini
index e2cdfac..65d29bf 100644
--- a/wine.ini
+++ b/wine.ini
@@ -110,6 +110,9 @@
 ; Create the desktop window with a double-buffered visual
 ; (useful to play OpenGL games)
 DesktopDoubleBuffered = N
+; Code page used for captions in managed mode
+; 0 means default ANSI code page (CP_ACP == 0)
+TextCP=0
 
 [fonts]
 ;Read documentation/fonts before adding aliases