diff -Naru wesnoth-1.8.4-org/src/menu_events.cpp wesnoth-1.8.4/src/menu_events.cpp
--- wesnoth-1.8.4-org/src/menu_events.cpp	2010-05-24 23:38:02.000000000 +0900
+++ wesnoth-1.8.4/src/menu_events.cpp	2010-09-12 19:28:00.777149000 +0900
@@ -635,6 +635,7 @@
 	textbox_info_.show(gui::TEXTBOX_MESSAGE,_("Message:"),
 		has_friends() ? is_observer() ? _("Send to observers only") : _("Send to allies only")
 					  : "", preferences::message_private(), *gui_);
+	textbox_info_.box()->activate_skk(true);
 }
 
 void menu_handler::whisper()
diff -Naru wesnoth-1.8.4-org/src/multiplayer_ui.cpp wesnoth-1.8.4/src/multiplayer_ui.cpp
--- wesnoth-1.8.4-org/src/multiplayer_ui.cpp	2010-05-01 18:40:42.000000000 +0900
+++ wesnoth-1.8.4/src/multiplayer_ui.cpp	2010-09-12 19:28:00.792150000 +0900
@@ -497,9 +497,10 @@
 {
 	//On enter, adds the current chat message to the chat textbox.
 	if((event.keysym.sym == SDLK_RETURN || event.keysym.sym == SDLK_KP_ENTER) && !entry_textbox_.text().empty()) {
-
-		chat_handler::do_speak(entry_textbox_.text());
-		entry_textbox_.clear();
+		if (entry_textbox_.decide_skk()) {
+			chat_handler::do_speak(entry_textbox_.text());
+			entry_textbox_.clear();
+		}
 	// nick tab-completion
 	} else if(event.keysym.sym == SDLK_TAB ) {
 		std::string text = entry_textbox_.text();
diff -Naru wesnoth-1.8.4-org/src/play_controller.cpp wesnoth-1.8.4/src/play_controller.cpp
--- wesnoth-1.8.4-org/src/play_controller.cpp	2010-04-19 14:30:56.000000000 +0900
+++ wesnoth-1.8.4/src/play_controller.cpp	2010-09-12 19:28:00.784150000 +0900
@@ -894,7 +894,8 @@
 	} else if(event.key.keysym.sym == SDLK_TAB) {
 		menu_handler_.get_textbox().tab(teams_, units_, *gui_);
 	} else if(event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == SDLK_KP_ENTER) {
-		enter_textbox();
+		if (menu_handler_.get_textbox().box()->decide_skk())
+			enter_textbox();
 	}
 }
 
diff -Naru wesnoth-1.8.4-org/src/widgets/textbox.cpp wesnoth-1.8.4/src/widgets/textbox.cpp
--- wesnoth-1.8.4-org/src/widgets/textbox.cpp	2010-04-23 22:57:22.000000000 +0900
+++ wesnoth-1.8.4/src/widgets/textbox.cpp	2010-09-12 19:49:09.574720000 +0900
@@ -21,6 +21,26 @@
 #include "log.hpp"
 #include "video.hpp"
 
+#define NOATOM
+#define NOGDI
+#define NOGDICAPMASKS
+#define NOMETAFILE
+#define NOMINMAX
+#define NOMSG
+#define NOOPENFILE
+#define NORASTEROPS
+#define NOSCROLL
+#define NOSOUND
+#define NOSYSMETRICS
+#define NOTEXTMETRIC
+#define NOWH
+#define NOCOMM
+#define NOKANJI
+#define NOCRYPT
+#define NOMCX
+#include <windows.h>
+#include "sdlskk.h"
+
 static lg::log_domain log_display("display");
 #define WRN_DP LOG_STREAM(warn, log_display)
 #define DBG_G LOG_STREAM(debug, lg::general)
@@ -46,10 +66,25 @@
 	set_measurements(width, font::get_max_height(font_size));
 	set_scroll_rate(font::get_max_height(font_size) / 2);
 	update_text_cache(true);
+
+	skk_font = TTF_OpenFont("sdlskk_ttf", font_size);
+	SDLSKK_set_encoding(SDLSKK_UTF8);
+	skk_dict = SDLSKK_Dict_new();
+	SDLSKK_Dict_load(skk_dict, "sdlskk_jisyo", 0);
+	skk_table = SDLSKK_RomKanaRuleTable_new("sdlskk_rule_table");
+	skk_keybind = SDLSKK_Keybind_new();
+	SDLSKK_Keybind_set_default_key(skk_keybind);
+	skk_context = SDLSKK_Context_new(skk_dict, skk_table, skk_keybind, 0);
+	skk_active = false;
 }
 
 textbox::~textbox()
 {
+	SDLSKK_Context_delete(skk_context);
+	SDLSKK_RomKanaRuleTable_delete(skk_table);
+	SDLSKK_Dict_delete_all(skk_dict);
+	SDLSKK_Keybind_delete(skk_keybind);
+	TTF_CloseFont(skk_font);
 }
 
 void textbox::set_inner_location(SDL_Rect const &rect)
@@ -125,6 +160,8 @@
 	set_dirty(true);
 	update_text_cache(true);
 	handle_text_changed(text_);
+	SDLSKK_Context_clear(skk_context);
+	skk_active = false;
 }
 
 void textbox::draw_cursor(int pos, CVideo &video) const
@@ -192,6 +229,25 @@
 	draw_cursor((cursor_pos_ == 0 ? 0 : cursor_pos_ - 1), video());
 
 	update_rect(loc);
+
+	if (skk_active) {
+		SDL_Color skk_color = { 0x01, 0x01, 0x01, 0 };
+		surface skk_surf = SDLSKK_Context_render_display_str(skk_context, skk_font, skk_color);
+
+		SDL_Rect rc;
+		SDL_GetClipRect(skk_surf, &rc);
+
+		surface skk_surf_painted = create_compatible_surface(surf, rc.w, rc.h);
+		SDL_FillRect(skk_surf_painted, NULL, SDL_MapRGB(skk_surf_painted->format, 0x40, 0xe0, 0xd0));
+		SDL_BlitSurface(skk_surf, NULL, skk_surf_painted, NULL);
+		skk_surf = skk_surf_painted;
+
+		int cur = is_selection() ? std::min<int>(selstart_,selend_) : cursor_;
+		rc.x = loc.x + text_pos_ + char_x_[cur];
+		rc.y = loc.y + yscroll_ + char_y_[cur];
+
+		SDL_BlitSurface(skk_surf, NULL, surf, &rc);
+	}
 }
 
 void textbox::set_editable(bool value)
@@ -368,6 +424,44 @@
 	return false;
 }
 
+bool textbox::is_empty_skk()
+{
+	if (skk_active)
+	{
+		if (SDLSKK_Context_get_basic_mode(skk_context))
+		{
+			char buf[1024];
+			if (*SDLSKK_Context_get_str(skk_context, buf, sizeof(buf)) == 0)
+				return true;
+		}
+		return false;
+	}
+	return true;
+}
+
+bool textbox::decide_skk()
+{
+	if (!is_empty_skk())
+	{
+		SDL_Event event;
+		event.key.type = SDL_KEYDOWN;
+		event.key.keysym.sym = SDLK_RETURN;
+		handle_event(event);
+		return false;
+	}
+	return true;
+}
+
+void textbox::activate_skk(bool active)
+{
+	if (skk_active != active)
+	{
+		if (skk_active)
+			SDLSKK_Context_clear(skk_context);
+		skk_active = active;
+	}
+}
+
 void textbox::handle_event(const SDL_Event& event)
 {
 	scrollarea::handle_event(event);
@@ -458,6 +552,55 @@
 
 	const int c = key.sym;
 	const int old_cursor = cursor_;
+	bool ate = false;
+
+	if (c == SDLK_SPACE && (modifiers & KMOD_SHIFT)) {
+		activate_skk(!skk_active);
+		ate = true;
+	} else if (skk_active) {
+		if (is_empty_skk() && (c == SDLK_UP || c == SDLK_DOWN || c == SDLK_LEFT || c == SDLK_RIGHT ||
+		   c == SDLK_DELETE || c == SDLK_BACKSPACE || c == SDLK_END || c == SDLK_HOME ||
+		   c == SDLK_PAGEUP || c == SDLK_PAGEDOWN ||
+		   ((c == SDLK_e || c == SDLK_a || c == SDLK_u || c == SDLK_v || c == SDLK_c) && (modifiers & KMOD_CTRL))  )) {
+		} else {
+			if (c == SDLK_RETURN || c == SDLK_KP_ENTER) {
+				if (!SDLSKK_Context_get_basic_mode(skk_context))
+					SDLSKK_Context_input_key(skk_context, 'q');
+
+				char buf[1024];
+				SDLSKK_Context_get_str(skk_context, buf, sizeof(buf));
+
+				int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
+				if (wlen != 0) {
+					wchar_t* wc = new wchar_t[wlen];
+					if (wc != NULL) {
+						if (MultiByteToWideChar(CP_UTF8, 0, buf, -1, wc, wlen) != 0) {
+							if (is_selection())
+								erase_selection();
+
+							wlen--;
+							if (text_.size() + wlen <= max_size_) {
+								changed = true;
+								for (int i = 0; i < wlen; i++)
+								{
+									text_.insert(text_.begin() + cursor_, wc[i]);
+									++cursor_;
+								}
+							}
+						}
+						delete[] wc;
+					}
+				}
+
+				SDLSKK_Context_clear(skk_context);
+			} else {
+				SDLSKK_Context_input_event(skk_context, (SDL_Event*)&event);
+			}
+			ate = true;
+		}
+	}
+
+	if (!ate) {
 
 	if(c == SDLK_LEFT && cursor_ > 0)
 		--cursor_;
@@ -566,6 +709,8 @@
 		}
 	}
 
+	} // if (!ate) {
+
 	if(is_selection() && (selend_ != cursor_))
 		selstart_ = selend_ = -1;
 
diff -Naru wesnoth-1.8.4-org/src/widgets/textbox.hpp wesnoth-1.8.4/src/widgets/textbox.hpp
--- wesnoth-1.8.4-org/src/widgets/textbox.hpp	2010-04-23 22:57:22.000000000 +0900
+++ wesnoth-1.8.4/src/widgets/textbox.hpp	2010-09-12 19:28:00.210117000 +0900
@@ -22,6 +22,7 @@
 #include "scrollarea.hpp"
 
 #include "SDL.h"
+#include "sdlskk.h"
 
 namespace gui {
 
@@ -43,6 +44,10 @@
 
 	void set_wrap(bool val);
 
+	bool is_empty_skk();
+	bool decide_skk();
+	void activate_skk(bool active);
+
 protected:
 	virtual void draw_contents();
 	virtual void set_inner_location(SDL_Rect const &);
@@ -82,6 +87,13 @@
 	double alpha_;
 	double alpha_focus_;
 
+	SDLSKK_Context* skk_context;
+	SDLSKK_RomKanaRuleTable* skk_table;
+	SDLSKK_Dictionary* skk_dict;
+	SDLSKK_Keybind* skk_keybind;
+	TTF_Font* skk_font;
+	bool skk_active;
+
 	void handle_event(const SDL_Event& event);
 
 	void draw_cursor(int pos, CVideo &video) const;
