diff --git a/irrlicht/include/IOSOperator.h b/irrlicht/include/IOSOperator.h
index b5c6236..b2e864a 100644
--- a/irrlicht/include/IOSOperator.h
+++ b/irrlicht/include/IOSOperator.h
@@ -26,11 +26,11 @@ public:
 	}
 
 	//! Copies text to the clipboard
-	virtual void copyToClipboard(const c8* text) const = 0;
+	virtual void copyToClipboard(const c16* text) const = 0;
 
 	//! Get text from the clipboard
 	/** \return Returns 0 if no string is in there. */
-	virtual const c8* getTextFromClipboard() const = 0;
+	virtual const c16* getTextFromClipboard() const = 0;
 
 	//! Get the processor speed in megahertz
 	/** \param MHz The integer variable to store the speed in.
diff --git a/irrlicht/include/IrrCompileConfig.h b/irrlicht/include/IrrCompileConfig.h
index c2c5d12..7c44f0c 100644
--- a/irrlicht/include/IrrCompileConfig.h
+++ b/irrlicht/include/IrrCompileConfig.h
@@ -233,7 +233,9 @@ you will not be able to use anything provided by the GUI Environment, including
 disable this feature, the engine behave as before (ansi). This is currently only supported
 for Windows based systems. You also have to set #define UNICODE for this to compile.
 */
-//#define _IRR_WCHAR_FILESYSTEM
+#if defined(_IRR_WINDOWS_) && (defined(_UNICODE) || defined(UNICODE))
+#define _IRR_WCHAR_FILESYSTEM
+#endif
 #ifdef NO_IRR_WCHAR_FILESYSTEM
 #undef _IRR_WCHAR_FILESYSTEM
 #endif
diff --git a/irrlicht/include/Keycodes.h b/irrlicht/include/Keycodes.h
index e56eca1..57ab312 100644
--- a/irrlicht/include/Keycodes.h
+++ b/irrlicht/include/Keycodes.h
@@ -89,7 +89,7 @@ namespace irr
 		KEY_KEY_X            = 0x58,  // X key
 		KEY_KEY_Y            = 0x59,  // Y key
 		KEY_KEY_Z            = 0x5A,  // Z key
-		KEY_LWIN             = 0x5B,  // Left Windows key (Microsoft® Natural® keyboard)
+		KEY_LWIN             = 0x5B,  // Left Windows key (MicrosoftÂ® NaturalÂ® keyboard)
 		KEY_RWIN             = 0x5C,  // Right Windows key (Natural keyboard)
 		KEY_APPS             = 0x5D,  // Applications key (Natural keyboard)
 		KEY_SLEEP            = 0x5F,  // Computer Sleep key
diff --git a/irrlicht/include/irrTypes.h b/irrlicht/include/irrTypes.h
index cfeaf84..a656631 100644
--- a/irrlicht/include/irrTypes.h
+++ b/irrlicht/include/irrTypes.h
@@ -48,7 +48,9 @@ typedef __int16			s16;
 typedef signed short		s16;
 #endif
 
-
+//! 16 bit character variable.
+/** This is a typedef for wchar_t, it ensures portability of the engine. */
+typedef wchar_t			c16;
 
 //! 32 bit unsigned variable.
 /** This is a typedef for unsigned int, it ensures portability of the engine. */
diff --git a/irrlicht/src/CGUIEditBox.cpp b/irrlicht/src/CGUIEditBox.cpp
index f33b5a2..8375444 100644
--- a/irrlicht/src/CGUIEditBox.cpp
+++ b/irrlicht/src/CGUIEditBox.cpp
@@ -287,7 +287,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
 				const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
 				const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
 
-				core::stringc s;
+				core::stringw s;
 				s = Text.subString(realmbgn, realmend - realmbgn).c_str();
 				Operator->copyToClipboard(s.c_str());
 			}
@@ -300,7 +300,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
 				const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
 
 				// copy
-				core::stringc sc;
+				core::stringw sc;
 				sc = Text.subString(realmbgn, realmend - realmbgn).c_str();
 				Operator->copyToClipboard(sc.c_str());
 
@@ -330,16 +330,10 @@ bool CGUIEditBox::processKey(const SEvent& event)
 				const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
 
 				// add new character
-				const c8* p = Operator->getTextFromClipboard();
+				const c16* p = Operator->getTextFromClipboard();
 				if (p)
 				{
-					// TODO: we should have such a function in core::string
-					size_t lenOld = strlen(p);
-					wchar_t *ws = new wchar_t[lenOld + 1];
-					size_t len = mbstowcs(ws,p,lenOld);
-					ws[len] = 0;
-					irr::core::stringw widep(ws);
-					delete[] ws;
+					irr::core::stringw widep(p);
 
 					if (MarkBegin == MarkEnd)
 					{
diff --git a/irrlicht/src/CIrrDeviceWin32.cpp b/irrlicht/src/CIrrDeviceWin32.cpp
index f96c178..2e7a9ee 100644
--- a/irrlicht/src/CIrrDeviceWin32.cpp
+++ b/irrlicht/src/CIrrDeviceWin32.cpp
@@ -20,6 +20,8 @@
 #include "COSOperator.h"
 #include "dimension2d.h"
 #include "IGUISpriteBank.h"
+#include "IGUIEnvironment.h"
+#include "IGUIElement.h"
 #include <winuser.h>
 #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
 #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
@@ -749,6 +751,26 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 		return 0;
 	}
 
+	{
+		dev = getDeviceFromHWnd(hWnd);
+		if (dev)
+		{
+			irr::gui::IGUIElement* ele = dev->getGUIEnvironment()->getFocus();
+			if (!ele || (ele->getType() != irr::gui::EGUIET_EDIT_BOX) || !ele->isEnabled())
+			{
+				HIMC hIMC = ImmGetContext(hWnd);
+				if (hIMC)
+				{
+					ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+					ImmReleaseContext(hWnd, hIMC);
+				}
+				ImmAssociateContextEx(hWnd, NULL, 0);
+			}
+			else
+				ImmAssociateContextEx(hWnd, NULL, IACE_DEFAULT);
+		}
+	}
+
 	switch (message)
 	{
 	case WM_PAINT:
@@ -773,22 +795,21 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 			event.KeyInput.Key = (irr::EKEY_CODE)wParam;
 			event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN);
 
-			const UINT MY_MAPVK_VSC_TO_VK_EX = 3; // MAPVK_VSC_TO_VK_EX should be in SDK according to MSDN, but isn't in mine.
 			if ( event.KeyInput.Key == irr::KEY_SHIFT )
 			{
 				// this will fail on systems before windows NT/2000/XP, not sure _what_ will return there instead.
-				event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX );
+				event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MAPVK_VSC_TO_VK_EX );
 			}
 			if ( event.KeyInput.Key == irr::KEY_CONTROL )
 			{
-				event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX );
+				event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MAPVK_VSC_TO_VK_EX );
 				// some keyboards will just return LEFT for both - left and right keys. So also check extend bit.
 				if (lParam & 0x1000000)
 					event.KeyInput.Key = irr::KEY_RCONTROL;
 			}
 			if ( event.KeyInput.Key == irr::KEY_MENU )
 			{
-				event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX );
+				event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MAPVK_VSC_TO_VK_EX );
 				if (lParam & 0x1000000)
 					event.KeyInput.Key = irr::KEY_RMENU;
 			}
@@ -904,6 +925,53 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 		KEYBOARD_INPUT_HKL = GetKeyboardLayout(0);
 		KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) );
 		return 0;
+
+	case WM_IME_STARTCOMPOSITION:
+		{
+			dev = getDeviceFromHWnd(hWnd);
+			irr::gui::IGUIElement* ele = dev->getGUIEnvironment()->getFocus();
+			if (!ele)
+				break;
+			irr::core::position2di pos = ele->getAbsolutePosition().UpperLeftCorner;
+			COMPOSITIONFORM CompForm = { CFS_POINT, { pos.X, pos.Y + ele->getAbsolutePosition().getHeight() } };
+			HIMC hIMC = ImmGetContext(hWnd);
+			ImmSetCompositionWindow(hIMC, &CompForm);
+			ImmReleaseContext(hWnd, hIMC);
+		}
+		break;
+
+	case WM_IME_CHAR:
+		event.EventType = irr::EET_KEY_INPUT_EVENT;
+		event.KeyInput.PressedDown = true;
+#ifdef _UNICODE
+		event.KeyInput.Char = wParam;
+#else
+		BYTE ch[3];
+		if(wParam >> 8) {
+			ch[0] = wParam >> 8;
+			ch[1] = wParam & 0xff;
+			ch[2] = 0;
+		} else {
+			ch[0] = wParam;
+			ch[1] = 0;
+		}
+		WORD unicodeChar;
+		MultiByteToWideChar(
+			KEYBOARD_INPUT_CODEPAGE,
+			MB_PRECOMPOSED, // default
+			(LPCSTR)ch,
+			sizeof(wParam),
+			(WCHAR*)&unicodeChar,
+			1);
+		event.KeyInput.Char = unicodeChar;
+#endif
+		event.KeyInput.Key = irr::KEY_ACCEPT;
+		event.KeyInput.Shift = 0;
+		event.KeyInput.Control = 0;
+		dev = getDeviceFromHWnd(hWnd);
+		if (dev)
+			dev->postEventFromUser(event);
+		return 0;
 	}
 	return DefWindowProc(hWnd, message, wParam, lParam);
 }
@@ -1797,8 +1865,8 @@ void CIrrDeviceWin32::handleSystemMessages()
 
 	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
 	{
-		// No message translation because we don't use WM_CHAR and it would conflict with our
-		// deadkey handling.
+		// conflict with deadkey handling.
+		TranslateMessage(&msg);
 
 		if (ExternalWindow && msg.hwnd == HWnd)
 			WndProc(HWnd, msg.message, msg.wParam, msg.lParam);
diff --git a/irrlicht/src/COSOperator.cpp b/irrlicht/src/COSOperator.cpp
index 90e644d..1856c04 100644
--- a/irrlicht/src/COSOperator.cpp
+++ b/irrlicht/src/COSOperator.cpp
@@ -52,9 +52,9 @@ const core::stringc& COSOperator::getOperatingSystemVersion() const
 
 
 //! copies text to the clipboard
-void COSOperator::copyToClipboard(const c8* text) const
+void COSOperator::copyToClipboard(const c16* text) const
 {
-	if (strlen(text)==0)
+	if (wcslen(text)==0)
 		return;
 
 // Windows version
@@ -66,15 +66,15 @@ void COSOperator::copyToClipboard(const c8* text) const
 	EmptyClipboard();
 
 	HGLOBAL clipbuffer;
-	char * buffer;
+	wchar_t * buffer;
 
-	clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text)+1);
-	buffer = (char*)GlobalLock(clipbuffer);
+	clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(wchar_t) * (wcslen(text) + 1));
+	buffer = (wchar_t*)GlobalLock(clipbuffer);
 
-	strcpy(buffer, text);
+	wcscpy(buffer, text);
 
 	GlobalUnlock(clipbuffer);
-	SetClipboardData(CF_TEXT, clipbuffer);
+	SetClipboardData(CF_UNICODETEXT, clipbuffer);
 	CloseClipboard();
 
 // MacOSX version
@@ -93,7 +93,7 @@ void COSOperator::copyToClipboard(const c8* text) const
 
 //! gets text from the clipboard
 //! \return Returns 0 if no string is in there.
-const c8* COSOperator::getTextFromClipboard() const
+const c16* COSOperator::getTextFromClipboard() const
 {
 #if defined(_IRR_XBOX_PLATFORM_)
 		return 0;
@@ -101,10 +101,10 @@ const c8* COSOperator::getTextFromClipboard() const
 	if (!OpenClipboard(NULL))
 		return 0;
 
-	char * buffer = 0;
+	wchar_t * buffer = 0;
 
-	HANDLE hData = GetClipboardData( CF_TEXT );
-	buffer = (char*)GlobalLock( hData );
+	HANDLE hData = GetClipboardData( CF_UNICODETEXT );
+	buffer = (wchar_t*)GlobalLock( hData );
 	GlobalUnlock( hData );
 	CloseClipboard();
 	return buffer;
diff --git a/irrlicht/src/COSOperator.h b/irrlicht/src/COSOperator.h
index 3f633da..c0712df 100644
--- a/irrlicht/src/COSOperator.h
+++ b/irrlicht/src/COSOperator.h
@@ -27,11 +27,11 @@ public:
 	virtual const core::stringc& getOperatingSystemVersion() const;
 
 	//! copies text to the clipboard
-	virtual void copyToClipboard(const c8* text) const;
+	virtual void copyToClipboard(const c16* text) const;
 
 	//! gets text from the clipboard
 	//! \return Returns 0 if no string is in there.
-	virtual const c8* getTextFromClipboard() const;
+	virtual const c16* getTextFromClipboard() const;
 
 	//! gets the processor speed in megahertz
 	//! \param Mhz:
