summaryrefslogtreecommitdiff
path: root/japanese
diff options
context:
space:
mode:
authorDaichi GOTO <daichi@FreeBSD.org>2012-05-22 05:19:40 +0000
committerDaichi GOTO <daichi@FreeBSD.org>2012-05-22 05:19:40 +0000
commitf7d8f112e92ffc89aa2f838ccd0e4c48b0e3c755 (patch)
treee3d3c5f9265884ab907230699cb426303b37385b /japanese
parent- Update to 0.11 (diff)
Added fcitx-mozc support
PR: 167860, 166711 Submitted by: Zhihao Yuan <lichray@gmail.com>
Notes
Notes: svn path=/head/; revision=297158
Diffstat (limited to 'japanese')
-rw-r--r--japanese/mozc-server/Makefile67
-rw-r--r--japanese/mozc-server/files/patch-base_base.gyp4
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_eim.cc141
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.conf13
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.desc10
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx.gyp110
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx_config.h32
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.cc584
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.h117
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.cc525
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.h153
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_gen_fcitx_mozc_i18n.sh14
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_mozc.conf10
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.cc177
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.h139
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.cc284
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.h96
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_po_Messages.sh36
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_po_fcitx-mozc.pot81
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_po_ja.po84
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_po_zh_CN.po82
-rw-r--r--japanese/mozc-server/files/patch-unix_fcitx_po_zh_TW.po85
22 files changed, 2838 insertions, 6 deletions
diff --git a/japanese/mozc-server/Makefile b/japanese/mozc-server/Makefile
index 1e9feda16120..34b540b9d9b3 100644
--- a/japanese/mozc-server/Makefile
+++ b/japanese/mozc-server/Makefile
@@ -7,7 +7,7 @@
PORTNAME= mozc
PORTVERSION= 1.5.1053.102
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= japanese
MASTER_SITES= ${MASTER_SITE_GOOGLE_CODE}
PKGNAMEPREFIX?= ja-
@@ -58,7 +58,6 @@ BUILD_MODE= Release
.endif
LOCALBASE_REPLACE_FILES= \
- build_mozc.py \
gyp/common.gypi \
unix/ibus/gen_mozc_xml.py \
unix/ibus/mozc.xml \
@@ -78,7 +77,7 @@ BUILD_CMD= ${SETENV} ${MAKE_ENV} ${GMAKE}
BUILD_MOZC_CMD= cd ${BUILD_WRKSRC} && \
${SETENV} BUILD_COMMAND="${WRKSRC}/mozcmake" \
PYTHONPATH=${WRKSRC}/third_party/gyp/local/lib/python${PYTHON_VER}/site-packages \
- MOZC_SERVER_DIRECTORY="${PREFIX}/bin" GYP_DEFINES="use_libprotobuf=1" \
+ GYP_DEFINES="use_libprotobuf=1" \
${PYTHON_CMD} build_mozc.py
BUILD_GYP_CMD= cd ${WRKSRC}/third_party/gyp && ${SETENV} ${MAKE_ENV} ${PYTHON_CMD} ${PYSETUP}
@@ -95,7 +94,8 @@ pre-build:
${BUILD_GYP_CMD} ${PYDISTUTILS_CONFIGURE_TARGET} ${PYDISTUTILS_CONFIGUREARGS}
${BUILD_GYP_CMD} ${PYDISTUTILS_BUILD_TARGET} ${PYDISTUTILS_BUILDARGS}
${BUILD_GYP_CMD} ${PYDISTUTILS_INSTALL_TARGET} --prefix=${WRKSRC}/third_party/gyp/local
- ${BUILD_MOZC_CMD} gyp --gypdir=${WRKSRC}/third_party/gyp/local/bin --channel_dev=0
+ ${BUILD_MOZC_CMD} gyp --gypdir=${WRKSRC}/third_party/gyp/local/bin \
+ --server_dir="${PREFIX}/bin" --channel_dev=0
${BUILD_MOZC_CMD} build_tools -c ${BUILD_MODE}
# mozc_server
@@ -227,6 +227,65 @@ do-install-scim_mozc:
${DATADIR}/icons/scim-mozc.png
.endif
+# fcitx_mozc
+.if ${BUILD_MOZC_LIST:Mfcitx_mozc} == "fcitx_mozc"
+LIB_DEPENDS+= fcitx-config.4:${PORTSDIR}/chinese/fcitx
+RUN_DEPENDS+= mozc_server:${PORTSDIR}/japanese/mozc-server \
+ mozc_tool:${PORTSDIR}/japanese/mozc-tool \
+ mozc_server_start:${PORTSDIR}/japanese/mozc-additions
+
+PLIST_FILES+= lib/fcitx/fcitx-mozc.so \
+ share/fcitx/addon/fcitx-mozc.conf \
+ share/fcitx/inputmethod/mozc.conf \
+ ${DATADIR_REL}/icon/mozc.png \
+ ${DATADIR_REL}/icon/mozc-alpha_full.png \
+ ${DATADIR_REL}/icon/mozc-alpha_half.png \
+ ${DATADIR_REL}/icon/mozc-direct.png \
+ ${DATADIR_REL}/icon/mozc-hiragana.png \
+ ${DATADIR_REL}/icon/mozc-katakana_full.png \
+ ${DATADIR_REL}/icon/mozc-katakana_half.png \
+ ${DATADIR_REL}/icon/mozc-dictionary.png \
+ ${DATADIR_REL}/icon/mozc-properties.png \
+ ${DATADIR_REL}/icon/mozc-tool.png \
+ share/locale/ja/LC_MESSAGES/fcitx-mozc.mo \
+ share/locale/zh_CN/LC_MESSAGES/fcitx-mozc.mo \
+ share/locale/zh_TW/LC_MESSAGES/fcitx-mozc.mo
+PLIST_DIRS+= ${DATADIR_REL}/icon ${DATADIR_REL}
+
+do-build-fcitx_mozc:
+ ${BUILD_MOZC_CMD} build -c ${BUILD_MODE} unix/fcitx/fcitx.gyp:fcitx-mozc
+
+do-install-fcitx_mozc:
+ ${MKDIR} \
+ ${PREFIX}/lib/fcitx \
+ ${PREFIX}/share/fcitx/addon \
+ ${PREFIX}/share/fcitx/inputmethod
+ ${INSTALL_LIB} \
+ ${WRKSRC}/out_linux/${BUILD_MODE}/fcitx-mozc.so \
+ ${PREFIX}/lib/fcitx/fcitx-mozc.so
+ ${INSTALL_DATA} \
+ ${WRKSRC}/unix/fcitx/fcitx-mozc.conf \
+ ${PREFIX}/share/fcitx/addon/fcitx-mozc.conf
+ ${INSTALL_DATA} \
+ ${WRKSRC}/unix/fcitx/mozc.conf \
+ ${PREFIX}/share/fcitx/inputmethod/mozc.conf
+ ${MKDIR} ${DATADIR}/icon
+.for F in ui-alpha_full ui-alpha_half ui-dictionary ui-direct \
+ ui-hiragana ui-katakana_full ui-katakana_half ui-properties ui-tool
+ @${INSTALL_DATA} \
+ ${WRKSRC}/data/images/unix/${F}.png \
+ ${DATADIR}/icon/${F:S/^ui-/mozc-/}.png
+.endfor
+ @${INSTALL_DATA} \
+ ${WRKSRC}/data/images/product_icon_32bpp-128.png \
+ ${DATADIR}/icon/mozc.png
+.for L in ja zh_CN zh_TW
+ @${INSTALL_DATA} \
+ ${WRKSRC}/out_linux/${BUILD_MODE}/obj/gen/unix/fcitx/po/${L}.mo \
+ ${PREFIX}/share/locale/${L}/LC_MESSAGES/fcitx-mozc.mo
+.endfor
+.endif
+
# mozc-el
.if ${BUILD_MOZC_LIST:Mmozc-el} == "mozc-el"
CATEGORIES+= editors elisp
diff --git a/japanese/mozc-server/files/patch-base_base.gyp b/japanese/mozc-server/files/patch-base_base.gyp
index 50ab433bc0ef..ed14cf8738db 100644
--- a/japanese/mozc-server/files/patch-base_base.gyp
+++ b/japanese/mozc-server/files/patch-base_base.gyp
@@ -1,5 +1,5 @@
---- base/base.gyp.orig 2012-04-26 15:05:41.000000000 +0900
-+++ base/base.gyp 2012-05-02 00:42:12.000000000 +0900
+--- base/base.gyp.orig 2012-05-01 12:21:08.063691925 +0900
++++ base/base.gyp 2012-05-02 13:23:38.254552162 +0900
@@ -228,20 +228,20 @@
}],
['OS=="linux" and target_platform!="Android"', {
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_eim.cc b/japanese/mozc-server/files/patch-unix_fcitx_eim.cc
new file mode 100644
index 000000000000..47a206a41067
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_eim.cc
@@ -0,0 +1,141 @@
+--- unix/fcitx/eim.cc.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/eim.cc 2012-05-22 13:42:56.597828244 +0900
+@@ -0,0 +1,138 @@
++/***************************************************************************
++ * Copyright (C) 2012~2012 by CSSlayer *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
++ ***************************************************************************/
++
++#include <fcitx/instance.h>
++#include <fcitx/ime.h>
++#include <fcitx/hook.h>
++#include <fcitx-config/xdg.h>
++#include "fcitx_mozc.h"
++#include "mozc_connection.h"
++#include "mozc_response_parser.h"
++
++typedef struct _FcitxMozcState {
++ mozc::fcitx::FcitxMozc* mozc;
++} FcitxMozcState;
++
++
++static void* FcitxMozcCreate(FcitxInstance* instance);
++static void FcitxMozcDestroy(void *arg);
++static boolean FcitxMozcInit(void *arg); /**< FcitxMozcInit */
++static void FcitxMozcResetIM(void *arg); /**< FcitxMozcResetIM */
++static void FcitxMozcReset(void *arg); /**< FcitxMozcResetIM */
++static INPUT_RETURN_VALUE FcitxMozcDoInput(void *arg, FcitxKeySym, unsigned int); /**< FcitxMozcDoInput */
++static void FcitxMozcSave(void *arg); /**< FcitxMozcSave */
++static void FcitxMozcReloadConfig(void *arg); /**< FcitxMozcReloadConfig */
++
++extern "C" {
++
++FCITX_EXPORT_API
++FcitxIMClass ime = {
++ FcitxMozcCreate,
++ FcitxMozcDestroy
++};
++FCITX_EXPORT_API
++int ABI_VERSION = FCITX_ABI_VERSION;
++
++}
++
++static void* FcitxMozcCreate(FcitxInstance* instance)
++{
++ FcitxMozcState* mozcState = (FcitxMozcState*) fcitx_utils_malloc0(sizeof(FcitxMozcState));
++ bindtextdomain("fcitx-keyboard", LOCALEDIR);
++
++ mozcState->mozc = new mozc::fcitx::FcitxMozc(
++ instance,
++ mozc::fcitx::MozcConnection::CreateMozcConnection(),
++ new mozc::fcitx::MozcResponseParser
++ );
++
++ mozcState->mozc->SetCompositionMode(mozc::commands::HIRAGANA);
++
++ FcitxIMEventHook hk;
++ hk.arg = mozcState;
++ hk.func = FcitxMozcReset;
++
++ FcitxInstanceRegisterResetInputHook(instance, hk);
++
++ FcitxInstanceRegisterIM(instance,
++ mozcState,
++ "mozc",
++ "Mozc",
++ mozcState->mozc->GetIconFile("mozc.png").c_str(),
++ FcitxMozcInit,
++ FcitxMozcResetIM,
++ FcitxMozcDoInput,
++ NULL,
++ NULL,
++ FcitxMozcSave,
++ FcitxMozcReloadConfig,
++ NULL,
++ 5,
++ "ja"
++ );
++
++ return mozcState;
++}
++
++static void FcitxMozcDestroy(void *arg)
++{
++ FcitxMozcState* mozcState = (FcitxMozcState*) arg;
++ delete mozcState->mozc;
++ free(mozcState);
++}
++
++INPUT_RETURN_VALUE FcitxMozcDoInput(void* arg, FcitxKeySym sym, unsigned int state)
++{
++ FcitxMozcState* mozcState = (FcitxMozcState*) arg;
++ bool result = mozcState->mozc->process_key_event(sym, state);
++ if (!result)
++ return IRV_TO_PROCESS;
++ else
++ return IRV_DISPLAY_CANDWORDS;
++}
++
++boolean FcitxMozcInit(void* arg)
++{
++ FcitxMozcState* mozcState = (FcitxMozcState*) arg;
++ mozcState->mozc->init();
++ return true;
++}
++
++void FcitxMozcReloadConfig(void* arg)
++{
++
++}
++
++void FcitxMozcSave(void* arg)
++{
++ FCITX_UNUSED(arg);
++}
++
++void FcitxMozcResetIM(void* arg)
++{
++ FcitxMozcState* mozcState = (FcitxMozcState*) arg;
++ mozcState->mozc->resetim();
++}
++
++void FcitxMozcReset(void* arg)
++{
++ FcitxMozcState* mozcState = (FcitxMozcState*) arg;
++ mozcState->mozc->reset();
++
++}
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.conf b/japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.conf
new file mode 100644
index 000000000000..0abcb776d142
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.conf
@@ -0,0 +1,13 @@
+--- unix/fcitx/fcitx-mozc.conf.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx-mozc.conf 2012-05-22 13:42:56.598827812 +0900
+@@ -0,0 +1,10 @@
++[Addon]
++Name=fcitx-mozc
++GeneralName=Mozc
++Comment=Mozc support for Fcitx
++Category=InputMethod
++Enabled=True
++Library=fcitx-mozc.so
++Type=SharedLibrary
++SubConfig=
++IMRegisterMethod=ConfigFile
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.desc b/japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.desc
new file mode 100644
index 000000000000..128d9639917d
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx-mozc.desc
@@ -0,0 +1,10 @@
+--- unix/fcitx/fcitx-mozc.desc.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx-mozc.desc 2012-05-22 13:42:56.598827812 +0900
+@@ -0,0 +1,6 @@
++[Mozc/KeyboardLayout]
++Type=Enum
++Enum0=Japanese
++Enum1=America
++DefaultValue=Japanese
++Description=Keyboard layout while using Mozc
+\ No newline at end of file
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx.gyp b/japanese/mozc-server/files/patch-unix_fcitx_fcitx.gyp
new file mode 100644
index 000000000000..6428b8ea1873
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx.gyp
@@ -0,0 +1,110 @@
+--- unix/fcitx/fcitx.gyp.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx.gyp 2012-05-22 13:42:56.598827812 +0900
+@@ -0,0 +1,107 @@
++#
++# Copyright (c) 2010-2012 fcitx Project http://code.google.com/p/fcitx/
++#
++# All rights reserved.
++#
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions
++# are met:
++# 1. Redistributions of source code must retain the above copyright
++# notice, this list of conditions and the following disclaimer.
++# 2. Redistributions in binary form must reproduce the above copyright
++# notice, this list of conditions and the following disclaimer in the
++# documentation and/or other materials provided with the distribution.
++# 3. Neither the name of authors nor the names of its contributors
++# may be used to endorse or promote products derived from this software
++# without specific prior written permission.
++#
++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
++# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
++# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++# SUCH DAMAGE.
++#
++
++{
++ 'variables': {
++ 'relative_dir': 'unix/fcitx',
++ 'gen_out_dir': '<(SHARED_INTERMEDIATE_DIR)/<(relative_dir)',
++ 'pkg_config_libs': [
++ 'fcitx',
++ 'fcitx-config',
++ 'fcitx-utils',
++ ],
++ 'fcitx_dep_include_dirs': [
++ ],
++ 'fcitx_dependencies': [
++ '../../base/base.gyp:base',
++ '../../client/client.gyp:client',
++ '../../ipc/ipc.gyp:ipc',
++ '../../session/session_base.gyp:ime_switch_util',
++ '../../session/session_base.gyp:session_protocol',
++ ],
++ 'fcitx_defines': [
++ 'LOCALEDIR="<!@(fcitx4-config --prefix)/share/locale/"',
++ ]
++ },
++ 'targets': [
++ {
++ 'target_name': 'gen_fcitx_mozc_i18n',
++ 'type': 'none',
++ 'actions': [
++ {
++ 'action_name': 'gen_fcitx_mozc_i18n',
++ 'inputs': [
++ './gen_fcitx_mozc_i18n.sh'
++ ],
++ 'outputs': [
++ '<(gen_out_dir)/po/zh_CN.mo',
++ '<(gen_out_dir)/po/zh_TW.mo',
++ '<(gen_out_dir)/po/ja.mo',
++ ],
++ 'action': [
++ 'sh',
++ './gen_fcitx_mozc_i18n.sh',
++ '<(gen_out_dir)/po',
++ ],
++ }],
++ },
++ {
++ 'target_name': 'fcitx-mozc',
++ 'product_prefix': '',
++ 'type': 'loadable_module',
++ 'sources': [
++ 'fcitx_mozc.cc',
++ 'fcitx_key_translator.cc',
++ 'mozc_connection.cc',
++ 'mozc_response_parser.cc',
++ 'eim.cc',
++ ],
++ 'dependencies': [
++ '<@(fcitx_dependencies)',
++ 'gen_fcitx_mozc_i18n',
++ ],
++ 'cflags': [
++ '<!@(pkg-config --cflags <@(pkg_config_libs))',
++ ],
++ 'include_dirs': [
++ '<@(fcitx_dep_include_dirs)',
++ ],
++ 'libraries': [
++ '<!@(pkg-config --libs-only-l <@(pkg_config_libs))',
++ ],
++ 'ldflags': [
++ '<!@(pkg-config --libs-only-L <@(pkg_config_libs))',
++ ],
++ 'defines': [
++ '<@(fcitx_defines)',
++ ],
++ },
++ ],
++}
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx_config.h b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_config.h
new file mode 100644
index 000000000000..afa29efe9c48
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_config.h
@@ -0,0 +1,32 @@
+--- unix/fcitx/fcitx_config.h.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx_config.h 2012-05-22 13:42:56.599827660 +0900
+@@ -0,0 +1,28 @@
++/***************************************************************************
++ * Copyright (C) 2012~2012 by CSSlayer *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
++ ***************************************************************************/
++
++#ifndef MOZC_UNIX_FCITX_FCITX_CONFIG_H_
++#define MOZC_UNIX_FCITX_FCITX_CONFIG_H_
++
++typedef enum _FcitxMozcLayout {
++ FcitxMozcLayout_Japanese,
++ FcitxMozcLayout_America,
++} FcitxMozcLayout;
++
++#endif
+\ No newline at end of file
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.cc b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.cc
new file mode 100644
index 000000000000..3d3028cfa751
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.cc
@@ -0,0 +1,584 @@
+--- unix/fcitx/fcitx_key_translator.cc.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx_key_translator.cc 2012-05-22 13:42:56.601828473 +0900
+@@ -0,0 +1,581 @@
++/***************************************************************************
++ * Copyright (C) 2012~2012 by CSSlayer *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
++ ***************************************************************************/
++
++#include "unix/fcitx/fcitx_key_translator.h"
++
++#include "base/logging.h"
++#include <fcitx/ime.h>
++
++namespace {
++
++const FcitxKeySym modifier_keys[] = {
++ FcitxKey_Alt_L,
++ FcitxKey_Alt_R,
++ FcitxKey_Caps_Lock,
++ FcitxKey_Control_L,
++ FcitxKey_Control_R,
++ FcitxKey_Hyper_L,
++ FcitxKey_Hyper_R,
++ FcitxKey_Meta_L,
++ FcitxKey_Meta_R,
++ FcitxKey_Shift_L,
++ FcitxKey_Shift_Lock,
++ FcitxKey_Shift_R,
++ FcitxKey_Super_L,
++ FcitxKey_Super_R,
++};
++
++const struct SpecialKeyMap {
++ FcitxKeySym from;
++ mozc::commands::KeyEvent::SpecialKey to;
++} sp_key_map[] = {
++ {FcitxKey_space, mozc::commands::KeyEvent::SPACE},
++ {FcitxKey_Return, mozc::commands::KeyEvent::ENTER},
++ {FcitxKey_Left, mozc::commands::KeyEvent::LEFT},
++ {FcitxKey_Right, mozc::commands::KeyEvent::RIGHT},
++ {FcitxKey_Up, mozc::commands::KeyEvent::UP},
++ {FcitxKey_Down, mozc::commands::KeyEvent::DOWN},
++ {FcitxKey_Escape, mozc::commands::KeyEvent::ESCAPE},
++ {FcitxKey_Delete, mozc::commands::KeyEvent::DEL},
++ {FcitxKey_BackSpace, mozc::commands::KeyEvent::BACKSPACE},
++ {FcitxKey_Insert, mozc::commands::KeyEvent::INSERT},
++ {FcitxKey_Henkan, mozc::commands::KeyEvent::HENKAN},
++ {FcitxKey_Muhenkan, mozc::commands::KeyEvent::MUHENKAN},
++ {FcitxKey_Hiragana, mozc::commands::KeyEvent::KANA},
++ // FcitxKey_Hiragana_Katakana requires special treatment.
++ // See FcitxKeyTranslator::NormalizeHiraganaKatakanaKeyWithShift.
++ {FcitxKey_Hiragana_Katakana, mozc::commands::KeyEvent::KANA},
++ {FcitxKey_Katakana, mozc::commands::KeyEvent::KATAKANA},
++ {FcitxKey_Eisu_toggle, mozc::commands::KeyEvent::EISU},
++ {FcitxKey_Home, mozc::commands::KeyEvent::HOME},
++ {FcitxKey_End, mozc::commands::KeyEvent::END},
++ {FcitxKey_Tab, mozc::commands::KeyEvent::TAB},
++ {FcitxKey_F1, mozc::commands::KeyEvent::F1},
++ {FcitxKey_F2, mozc::commands::KeyEvent::F2},
++ {FcitxKey_F3, mozc::commands::KeyEvent::F3},
++ {FcitxKey_F4, mozc::commands::KeyEvent::F4},
++ {FcitxKey_F5, mozc::commands::KeyEvent::F5},
++ {FcitxKey_F6, mozc::commands::KeyEvent::F6},
++ {FcitxKey_F7, mozc::commands::KeyEvent::F7},
++ {FcitxKey_F8, mozc::commands::KeyEvent::F8},
++ {FcitxKey_F9, mozc::commands::KeyEvent::F9},
++ {FcitxKey_F10, mozc::commands::KeyEvent::F10},
++ {FcitxKey_F11, mozc::commands::KeyEvent::F11},
++ {FcitxKey_F12, mozc::commands::KeyEvent::F12},
++ {FcitxKey_F13, mozc::commands::KeyEvent::F13},
++ {FcitxKey_F14, mozc::commands::KeyEvent::F14},
++ {FcitxKey_F15, mozc::commands::KeyEvent::F15},
++ {FcitxKey_F16, mozc::commands::KeyEvent::F16},
++ {FcitxKey_F17, mozc::commands::KeyEvent::F17},
++ {FcitxKey_F18, mozc::commands::KeyEvent::F18},
++ {FcitxKey_F19, mozc::commands::KeyEvent::F19},
++ {FcitxKey_F20, mozc::commands::KeyEvent::F20},
++ {FcitxKey_F21, mozc::commands::KeyEvent::F21},
++ {FcitxKey_F22, mozc::commands::KeyEvent::F22},
++ {FcitxKey_F23, mozc::commands::KeyEvent::F23},
++ {FcitxKey_F24, mozc::commands::KeyEvent::F24},
++ {FcitxKey_Page_Up, mozc::commands::KeyEvent::PAGE_UP},
++ {FcitxKey_Page_Down, mozc::commands::KeyEvent::PAGE_DOWN},
++
++ // Keypad (10-key).
++ {FcitxKey_KP_0, mozc::commands::KeyEvent::NUMPAD0},
++ {FcitxKey_KP_1, mozc::commands::KeyEvent::NUMPAD1},
++ {FcitxKey_KP_2, mozc::commands::KeyEvent::NUMPAD2},
++ {FcitxKey_KP_3, mozc::commands::KeyEvent::NUMPAD3},
++ {FcitxKey_KP_4, mozc::commands::KeyEvent::NUMPAD4},
++ {FcitxKey_KP_5, mozc::commands::KeyEvent::NUMPAD5},
++ {FcitxKey_KP_6, mozc::commands::KeyEvent::NUMPAD6},
++ {FcitxKey_KP_7, mozc::commands::KeyEvent::NUMPAD7},
++ {FcitxKey_KP_8, mozc::commands::KeyEvent::NUMPAD8},
++ {FcitxKey_KP_9, mozc::commands::KeyEvent::NUMPAD9},
++ {FcitxKey_KP_Equal, mozc::commands::KeyEvent::EQUALS}, // [=]
++ {FcitxKey_KP_Multiply, mozc::commands::KeyEvent::MULTIPLY}, // [*]
++ {FcitxKey_KP_Add, mozc::commands::KeyEvent::ADD}, // [+]
++ {FcitxKey_KP_Separator, mozc::commands::KeyEvent::SEPARATOR}, // enter
++ {FcitxKey_KP_Subtract, mozc::commands::KeyEvent::SUBTRACT}, // [-]
++ {FcitxKey_KP_Decimal, mozc::commands::KeyEvent::DECIMAL}, // [.]
++ {FcitxKey_KP_Divide, mozc::commands::KeyEvent::DIVIDE}, // [/]
++ {FcitxKey_KP_Space, mozc::commands::KeyEvent::SPACE},
++ {FcitxKey_KP_Tab, mozc::commands::KeyEvent::TAB},
++ {FcitxKey_KP_Enter, mozc::commands::KeyEvent::ENTER},
++ {FcitxKey_KP_Home, mozc::commands::KeyEvent::HOME},
++ {FcitxKey_KP_Left, mozc::commands::KeyEvent::LEFT},
++ {FcitxKey_KP_Up, mozc::commands::KeyEvent::UP},
++ {FcitxKey_KP_Right, mozc::commands::KeyEvent::RIGHT},
++ {FcitxKey_KP_Down, mozc::commands::KeyEvent::DOWN},
++ {FcitxKey_KP_Page_Up, mozc::commands::KeyEvent::PAGE_UP},
++ {FcitxKey_KP_Page_Down, mozc::commands::KeyEvent::PAGE_DOWN},
++ {FcitxKey_KP_End, mozc::commands::KeyEvent::END},
++ {FcitxKey_KP_Delete, mozc::commands::KeyEvent::DEL},
++ {FcitxKey_KP_Insert, mozc::commands::KeyEvent::INSERT},
++
++ // Shift+TAB.
++ {FcitxKey_ISO_Left_Tab, mozc::commands::KeyEvent::TAB},
++
++ // - FcitxKey_Kana_Lock? FcitxKey_Kana_Shift?
++};
++
++const struct SpecialAsciiMap {
++ uint32 from;
++ uint32 to;
++} sp_ascii_map[] = {
++ {FcitxKey_KP_Equal, '='},
++};
++
++const struct KanaMap {
++ uint32 keysym;
++ const char *kana;
++} kKanaMapJp[] = {
++ { '1' , "\xe3\x81\xac" }, // "ぬ"
++ { '!' , "\xe3\x81\xac" }, // "ぬ"
++ { '2' , "\xe3\x81\xb5" }, // "ふ"
++ { '\"', "\xe3\x81\xb5" }, // "ふ"
++ { '3' , "\xe3\x81\x82" }, // "あ"
++ { '#' , "\xe3\x81\x81" }, // "ぁ"
++ { '4' , "\xe3\x81\x86" }, // "う"
++ { '$' , "\xe3\x81\x85" }, // "ぅ"
++ { '5' , "\xe3\x81\x88" }, // "え"
++ { '%' , "\xe3\x81\x87" }, // "ぇ"
++ { '6' , "\xe3\x81\x8a" }, // "お"
++ { '&' , "\xe3\x81\x89" }, // "ぉ"
++ { '7' , "\xe3\x82\x84" }, // "や"
++ { '\'', "\xe3\x82\x83" }, // "ゃ"
++ { '8' , "\xe3\x82\x86" }, // "ゆ"
++ { '(' , "\xe3\x82\x85" }, // "ゅ"
++ { '9' , "\xe3\x82\x88" }, // "よ"
++ { ')' , "\xe3\x82\x87" }, // "ょ"
++ { '0' , "\xe3\x82\x8f" }, // "わ"
++ // Shift+0 is usually mapped to tilde by XKB.
++ { '-' , "\xe3\x81\xbb" }, // "ほ"
++ { '=' , "\xe3\x81\xbb" }, // "ほ"
++ { '^' , "\xe3\x81\xb8" }, // "へ"
++ { '~' , "\xe3\x82\x92" }, // "を"
++ { '|' , "\xe3\x83\xbc" }, // "ー"
++ { 'q' , "\xe3\x81\x9f" }, // "た"
++ { 'Q' , "\xe3\x81\x9f" }, // "た"
++ { 'w' , "\xe3\x81\xa6" }, // "て"
++ { 'W' , "\xe3\x81\xa6" }, // "て"
++ { 'e' , "\xe3\x81\x84" }, // "い"
++ { 'E' , "\xe3\x81\x83" }, // "ぃ"
++ { 'r' , "\xe3\x81\x99" }, // "す"
++ { 'R' , "\xe3\x81\x99" }, // "す"
++ { 't' , "\xe3\x81\x8b" }, // "か"
++ { 'T' , "\xe3\x81\x8b" }, // "か"
++ { 'y' , "\xe3\x82\x93" }, // "ん"
++ { 'Y' , "\xe3\x82\x93" }, // "ん"
++ { 'u' , "\xe3\x81\xaa" }, // "な"
++ { 'U' , "\xe3\x81\xaa" }, // "な"
++ { 'i' , "\xe3\x81\xab" }, // "に"
++ { 'I' , "\xe3\x81\xab" }, // "に"
++ { 'o' , "\xe3\x82\x89" }, // "ら"
++ { 'O' , "\xe3\x82\x89" }, // "ら"
++ { 'p' , "\xe3\x81\x9b" }, // "せ"
++ { 'P' , "\xe3\x81\x9b" }, // "せ"
++ { '@' , "\xe3\x82\x9b" }, // "゛"
++ { '`' , "\xe3\x82\x9b" }, // "゛"
++ { '[' , "\xe3\x82\x9c" }, // "゜"
++ { '{' , "\xe3\x80\x8c" }, // "「"
++ { 'a' , "\xe3\x81\xa1" }, // "ち"
++ { 'A' , "\xe3\x81\xa1" }, // "ち"
++ { 's' , "\xe3\x81\xa8" }, // "と"
++ { 'S' , "\xe3\x81\xa8" }, // "と"
++ { 'd' , "\xe3\x81\x97" }, // "し"
++ { 'D' , "\xe3\x81\x97" }, // "し"
++ { 'f' , "\xe3\x81\xaf" }, // "は"
++ { 'F' , "\xe3\x81\xaf" }, // "は"
++ { 'g' , "\xe3\x81\x8d" }, // "き"
++ { 'G' , "\xe3\x81\x8d" }, // "き"
++ { 'h' , "\xe3\x81\x8f" }, // "く"
++ { 'H' , "\xe3\x81\x8f" }, // "く"
++ { 'j' , "\xe3\x81\xbe" }, // "ま"
++ { 'J' , "\xe3\x81\xbe" }, // "ま"
++ { 'k' , "\xe3\x81\xae" }, // "の"
++ { 'K' , "\xe3\x81\xae" }, // "の"
++ { 'l' , "\xe3\x82\x8a" }, // "り"
++ { 'L' , "\xe3\x82\x8a" }, // "り"
++ { ';' , "\xe3\x82\x8c" }, // "れ"
++ { '+' , "\xe3\x82\x8c" }, // "れ"
++ { ':' , "\xe3\x81\x91" }, // "け"
++ { '*' , "\xe3\x81\x91" }, // "け"
++ { ']' , "\xe3\x82\x80" }, // "む"
++ { '}' , "\xe3\x80\x8d" }, // "」"
++ { 'z' , "\xe3\x81\xa4" }, // "つ"
++ { 'Z' , "\xe3\x81\xa3" }, // "っ"
++ { 'x' , "\xe3\x81\x95" }, // "さ"
++ { 'X' , "\xe3\x81\x95" }, // "さ"
++ { 'c' , "\xe3\x81\x9d" }, // "そ"
++ { 'C' , "\xe3\x81\x9d" }, // "そ"
++ { 'v' , "\xe3\x81\xb2" }, // "ひ"
++ { 'V' , "\xe3\x81\xb2" }, // "ひ"
++ { 'b' , "\xe3\x81\x93" }, // "こ"
++ { 'B' , "\xe3\x81\x93" }, // "こ"
++ { 'n' , "\xe3\x81\xbf" }, // "み"
++ { 'N' , "\xe3\x81\xbf" }, // "み"
++ { 'm' , "\xe3\x82\x82" }, // "も"
++ { 'M' , "\xe3\x82\x82" }, // "も"
++ { ',' , "\xe3\x81\xad" }, // "ね"
++ { '<' , "\xe3\x80\x81" }, // "、"
++ { '.' , "\xe3\x82\x8b" }, // "る"
++ { '>' , "\xe3\x80\x82" }, // "。"
++ { '/' , "\xe3\x82\x81" }, // "め"
++ { '?' , "\xe3\x83\xbb" }, // "・"
++ { '_' , "\xe3\x82\x8d" }, // "ろ"
++ // A backslash is handled in a special way because it is input by
++ // two different keys (the one next to Backslash and the one next
++ // to Right Shift).
++ { '\\', "" },
++}, kKanaMapUs[] = {
++ { '`' , "\xe3\x82\x8d" }, // "ろ" - Different from the Jp mapping.
++ { '~' , "\xe3\x82\x8d" }, // "ろ" - Different from the Jp mapping.
++ { '1' , "\xe3\x81\xac" }, // "ぬ"
++ { '!' , "\xe3\x81\xac" }, // "ぬ"
++ { '2' , "\xe3\x81\xb5" }, // "ふ"
++ { '@' , "\xe3\x81\xb5" }, // "ふ"
++ { '3' , "\xe3\x81\x82" }, // "あ"
++ { '#' , "\xe3\x81\x81" }, // "ぁ"
++ { '4' , "\xe3\x81\x86" }, // "う"
++ { '$' , "\xe3\x81\x85" }, // "ぅ"
++ { '5' , "\xe3\x81\x88" }, // "え"
++ { '%' , "\xe3\x81\x87" }, // "ぇ"
++ { '6' , "\xe3\x81\x8a" }, // "お"
++ { '^' , "\xe3\x81\x89" }, // "ぉ"
++ { '7' , "\xe3\x82\x84" }, // "や"
++ { '&' , "\xe3\x82\x83" }, // "ゃ"
++ { '8' , "\xe3\x82\x86" }, // "ゆ"
++ { '*' , "\xe3\x82\x85" }, // "ゅ"
++ { '9' , "\xe3\x82\x88" }, // "よ"
++ { '(' , "\xe3\x82\x87" }, // "ょ"
++ { '0' , "\xe3\x82\x8f" }, // "わ"
++ { ')' , "\xe3\x82\x92" }, // "を"
++ { '-' , "\xe3\x81\xbb" }, // "ほ"
++ { '_' , "\xe3\x83\xbc" }, // "ー" - Different from the Jp mapping.
++ { '=' , "\xe3\x81\xb8" }, // "へ"
++ { '+' , "\xe3\x81\xb8" }, // "へ"
++ { 'q' , "\xe3\x81\x9f" }, // "た"
++ { 'Q' , "\xe3\x81\x9f" }, // "た"
++ { 'w' , "\xe3\x81\xa6" }, // "て"
++ { 'W' , "\xe3\x81\xa6" }, // "て"
++ { 'e' , "\xe3\x81\x84" }, // "い"
++ { 'E' , "\xe3\x81\x83" }, // "ぃ"
++ { 'r' , "\xe3\x81\x99" }, // "す"
++ { 'R' , "\xe3\x81\x99" }, // "す"
++ { 't' , "\xe3\x81\x8b" }, // "か"
++ { 'T' , "\xe3\x81\x8b" }, // "か"
++ { 'y' , "\xe3\x82\x93" }, // "ん"
++ { 'Y' , "\xe3\x82\x93" }, // "ん"
++ { 'u' , "\xe3\x81\xaa" }, // "な"
++ { 'U' , "\xe3\x81\xaa" }, // "な"
++ { 'i' , "\xe3\x81\xab" }, // "に"
++ { 'I' , "\xe3\x81\xab" }, // "に"
++ { 'o' , "\xe3\x82\x89" }, // "ら"
++ { 'O' , "\xe3\x82\x89" }, // "ら"
++ { 'p' , "\xe3\x81\x9b" }, // "せ"
++ { 'P' , "\xe3\x81\x9b" }, // "せ"
++ { '[' , "\xe3\x82\x9b" }, // "゛"
++ { '{' , "\xe3\x82\x9b" }, // "゛"
++ { ']' , "\xe3\x82\x9c" }, // "゜"
++ { '}' , "\xe3\x80\x8c" }, // "「"
++ { '\\', "\xe3\x82\x80" }, // "む" - Different from the Jp mapping.
++ { '|' , "\xe3\x80\x8d" }, // "」" - Different from the Jp mapping.
++ { 'a' , "\xe3\x81\xa1" }, // "ち"
++ { 'A' , "\xe3\x81\xa1" }, // "ち"
++ { 's' , "\xe3\x81\xa8" }, // "と"
++ { 'S' , "\xe3\x81\xa8" }, // "と"
++ { 'd' , "\xe3\x81\x97" }, // "し"
++ { 'D' , "\xe3\x81\x97" }, // "し"
++ { 'f' , "\xe3\x81\xaf" }, // "は"
++ { 'F' , "\xe3\x81\xaf" }, // "は"
++ { 'g' , "\xe3\x81\x8d" }, // "き"
++ { 'G' , "\xe3\x81\x8d" }, // "き"
++ { 'h' , "\xe3\x81\x8f" }, // "く"
++ { 'H' , "\xe3\x81\x8f" }, // "く"
++ { 'j' , "\xe3\x81\xbe" }, // "ま"
++ { 'J' , "\xe3\x81\xbe" }, // "ま"
++ { 'k' , "\xe3\x81\xae" }, // "の"
++ { 'K' , "\xe3\x81\xae" }, // "の"
++ { 'l' , "\xe3\x82\x8a" }, // "り"
++ { 'L' , "\xe3\x82\x8a" }, // "り"
++ { ';' , "\xe3\x82\x8c" }, // "れ"
++ { ':' , "\xe3\x82\x8c" }, // "れ"
++ { '\'', "\xe3\x81\x91" }, // "け"
++ { '\"', "\xe3\x81\x91" }, // "け"
++ { 'z' , "\xe3\x81\xa4" }, // "つ"
++ { 'Z' , "\xe3\x81\xa3" }, // "っ"
++ { 'x' , "\xe3\x81\x95" }, // "さ"
++ { 'X' , "\xe3\x81\x95" }, // "さ"
++ { 'c' , "\xe3\x81\x9d" }, // "そ"
++ { 'C' , "\xe3\x81\x9d" }, // "そ"
++ { 'v' , "\xe3\x81\xb2" }, // "ひ"
++ { 'V' , "\xe3\x81\xb2" }, // "ひ"
++ { 'b' , "\xe3\x81\x93" }, // "こ"
++ { 'B' , "\xe3\x81\x93" }, // "こ"
++ { 'n' , "\xe3\x81\xbf" }, // "み"
++ { 'N' , "\xe3\x81\xbf" }, // "み"
++ { 'm' , "\xe3\x82\x82" }, // "も"
++ { 'M' , "\xe3\x82\x82" }, // "も"
++ { ',' , "\xe3\x81\xad" }, // "ね"
++ { '<' , "\xe3\x80\x81" }, // "、"
++ { '.' , "\xe3\x82\x8b" }, // "る"
++ { '>' , "\xe3\x80\x82" }, // "。"
++ { '/' , "\xe3\x82\x81" }, // "め"
++ { '?' , "\xe3\x83\xbb" }, // "・"
++};
++
++} // namespace
++
++static inline char get_ascii_code(FcitxKeySym sym)
++{
++ if (sym >= FcitxKey_space && sym <= FcitxKey_asciitilde)
++ return (char) (sym & 0xff);
++
++ if (sym >= FcitxKey_KP_0 && sym <= FcitxKey_KP_9)
++ return (char) ((sym - FcitxKey_KP_0 + FcitxKey_0) & 0xff);
++
++ if (sym == FcitxKey_Return)
++ return 0x0d;
++ if (sym == FcitxKey_Linefeed)
++ return 0x0a;
++ if (sym == FcitxKey_Tab)
++ return 0x09;
++ if (sym == FcitxKey_BackSpace)
++ return 0x08;
++ if (sym == FcitxKey_Escape)
++ return 0x1b;
++
++ return 0;
++}
++
++namespace mozc {
++
++namespace fcitx {
++
++KeyTranslator::KeyTranslator() {
++ InitializeKeyMaps();
++ input = 0;
++ layout = FcitxMozcLayout_Japanese;
++}
++
++KeyTranslator::~KeyTranslator() {
++}
++
++void KeyTranslator::Translate(
++ FcitxKeySym origsym, unsigned int origstate, mozc::config::Config::PreeditMethod method,
++ mozc::commands::KeyEvent *out_event) const {
++ FcitxKeySym sym;
++ unsigned int state;
++ NormalizeHiraganaKatakanaKeyWithShift(origsym, origstate, &sym, &state);
++ DCHECK(CanConvert(sym, state));
++ if (!CanConvert(sym, state)) {
++ LOG(ERROR) << "Can't handle the key: " << sym;
++ return;
++ }
++ DCHECK(out_event);
++ if (!out_event) {
++ return;
++ }
++ out_event->Clear();
++
++
++ if ((state & FcitxKeyState_Ctrl) != 0) {
++ out_event->add_modifier_keys(mozc::commands::KeyEvent::CTRL);
++ }
++ if ((state & FcitxKeyState_Alt) != 0) {
++ out_event->add_modifier_keys(mozc::commands::KeyEvent::ALT);
++ }
++ if (!IsAscii(sym, state) && (state & FcitxKeyState_Shift) != 0) {
++ out_event->add_modifier_keys(mozc::commands::KeyEvent::SHIFT);
++ }
++
++ mozc::commands::KeyEvent::SpecialKey sp_key;
++ uint32 sp_ascii;
++ string key_string;
++
++ if (IsSpecialKey(sym, state, &sp_key)) {
++ out_event->set_special_key(sp_key);
++ } else if (IsSpecialAscii(sym, state, &sp_ascii)) {
++ out_event->set_key_code(sp_ascii);
++ } else if (method == mozc::config::Config::KANA &&
++ IsKanaAvailable(sym, state, &key_string)) {
++ DCHECK(IsAscii(sym, state));
++ out_event->set_key_code(get_ascii_code(sym));
++ out_event->set_key_string(key_string);
++ } else {
++ DCHECK(IsAscii(sym, state));
++ out_event->set_key_code(get_ascii_code(sym));
++ }
++ return;
++}
++
++void KeyTranslator::TranslateClick(
++ int32 unique_id, mozc::commands::SessionCommand *out_command) const {
++ DCHECK(out_command);
++ if (out_command) {
++ out_command->set_type(mozc::commands::SessionCommand::SELECT_CANDIDATE);
++ out_command->set_id(unique_id);
++ }
++ return;
++}
++
++bool KeyTranslator::CanConvert(FcitxKeySym sym, unsigned int state) const {
++ if (IsModifierKey(sym, state)) {
++ VLOG(1) << "modifier key";
++ return false;
++ }
++ if (IsAscii(sym, state) || IsSpecialKey(sym, state, NULL) || IsSpecialAscii(sym, state, NULL)) {
++ return true;
++ }
++
++ char buf[64];
++ ::snprintf(
++ buf, sizeof(buf), "Key code Mozc doesn't know (0x%08x).", sym);
++ LOG(ERROR) << buf;
++ return false;
++}
++
++void KeyTranslator::InitializeKeyMaps() {
++ for (int i = 0; i < arraysize(sp_key_map); ++i) {
++ CHECK(special_key_map_.insert(make_pair(sp_key_map[i].from,
++ sp_key_map[i].to)).second);
++ }
++ for (int i = 0; i < arraysize(sp_ascii_map); ++i) {
++ CHECK(special_ascii_map_.insert(make_pair(sp_ascii_map[i].from,
++ sp_ascii_map[i].to)).second);
++ }
++ for (int i = 0; i < arraysize(modifier_keys); ++i) {
++ CHECK(modifier_keys_.insert(modifier_keys[i]).second);
++ }
++ for (int i = 0; i < arraysize(kKanaMapJp); ++i) {
++ CHECK(kana_map_jp_.insert(
++ make_pair(kKanaMapJp[i].keysym, kKanaMapJp[i].kana)).second);
++ }
++ for (int i = 0; i < arraysize(kKanaMapUs); ++i) {
++ CHECK(kana_map_us_.insert(
++ make_pair(kKanaMapUs[i].keysym, kKanaMapUs[i].kana)).second);
++ }
++}
++
++bool KeyTranslator::IsModifierKey(FcitxKeySym sym, unsigned int state) const {
++ return modifier_keys_.find(sym) != modifier_keys_.end();
++}
++
++bool KeyTranslator::IsSpecialKey(
++ FcitxKeySym sym, unsigned int state,
++ mozc::commands::KeyEvent::SpecialKey *out) const {
++ map<uint32, mozc::commands::KeyEvent::SpecialKey>::const_iterator iter =
++ special_key_map_.find(sym);
++ if (iter == special_key_map_.end()) {
++ return false;
++ }
++ if (out) {
++ *out = iter->second;
++ }
++ return true;
++}
++
++// static
++void KeyTranslator::NormalizeHiraganaKatakanaKeyWithShift(
++ FcitxKeySym origsym, unsigned int origstate, FcitxKeySym* sym, unsigned int* state) {
++ if (origsym == FcitxKey_Hiragana_Katakana) {
++ *sym = FcitxKey_Katakana;
++ *state = origstate & ~FcitxKeyState_Shift;
++ }
++ else {
++ *sym = origsym;
++ *state = origstate;
++ }
++}
++
++
++
++bool KeyTranslator::IsSpecialAscii(
++ FcitxKeySym sym, unsigned int state, uint32 *out) const {
++ map<uint32, uint32>::const_iterator iter = special_ascii_map_.find(sym);
++ if (iter == special_ascii_map_.end()) {
++ return false;
++ }
++ if (out) {
++ *out = iter->second;
++ }
++ return true;
++}
++
++void KeyTranslator::SetLayout(FcitxMozcLayout l)
++{
++ layout = l;
++}
++
++void KeyTranslator::SetInputState(FcitxInputState* i)
++{
++ input = i;
++}
++
++
++bool KeyTranslator::IsKanaAvailable(
++ FcitxKeySym sym, unsigned int state, string *out) const {
++ if ((state & FcitxKeyState_Ctrl) != 0 || (state & FcitxKeyState_Alt) != 0) {
++ return false;
++ }
++ const map<uint32, const char *> &kana_map =
++ IsJapaneseLayout(layout) ? kana_map_jp_ : kana_map_us_;
++
++ // We call get_ascii_code() to support clients that does not send the shift
++ // modifier. By calling the function, both "Shift + 3" and "#" would be
++ // normalized to '#'.
++ const char ascii_code = get_ascii_code(sym);
++
++ map<uint32, const char *>::const_iterator iter = kana_map.find(ascii_code);
++ if (iter == kana_map.end()) {
++ return false;
++ }
++ if (out) {
++ if (ascii_code == '\\' && IsJapaneseLayout(layout)) {
++ uint32_t keycode = 0;
++ if (input)
++ keycode = FcitxInputStateGetKeyCode(input);
++ if (keycode == FcitxKey_bar) {
++ *out = "\xe3\x83\xbc"; // "ー"
++ } else {
++ *out = "\xe3\x82\x8d"; // "ろ"
++ }
++ } else {
++ *out = iter->second;
++ }
++ }
++ return true;
++}
++
++/* static */
++bool KeyTranslator::IsAscii(FcitxKeySym sym, unsigned int state) {
++ // get_ascii_code(sym) returns non-zero value for SPACE, ENTER, LineFeed,
++ // TAB, BACKSPACE, ESCAPE, and Keypad codes. So we don't use it here.
++ return (sym > FcitxKey_space &&
++ // Note: Space key (0x20) is a special key in Mozc.
++ sym <= FcitxKey_asciitilde); // 0x7e.
++}
++
++/* static */
++bool KeyTranslator::IsJapaneseLayout(FcitxMozcLayout layout) {
++ // We guess that most people using the Kana input mode uses Japanese
++ // keyboards, so we prefer applying the Japanese layout.
++ return layout == FcitxMozcLayout_Japanese;
++}
++
++} // namespace fcitx
++
++} // namespace mozc
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.h b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.h
new file mode 100644
index 000000000000..7f9cc7a1cd69
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_key_translator.h
@@ -0,0 +1,117 @@
+--- unix/fcitx/fcitx_key_translator.h.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx_key_translator.h 2012-05-22 13:42:56.601828473 +0900
+@@ -0,0 +1,114 @@
++/***************************************************************************
++ * Copyright (C) 2012~2012 by CSSlayer *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
++ ***************************************************************************/
++
++#ifndef MOZC_UNIX_FCITX_FCITX_KEY_TRANSLATOR_H_
++#define MOZC_UNIX_FCITX_FCITX_KEY_TRANSLATOR_H_
++
++#include <map>
++#include <set>
++#include <string>
++
++#include <fcitx-config/hotkey.h>
++
++#include "base/base.h" // for DISALLOW_COPY_AND_ASSIGN.
++#include "session/commands.pb.h"
++#include "unix/fcitx/fcitx_config.h"
++#include <fcitx/ime.h>
++
++namespace mozc {
++
++namespace fcitx {
++
++// This class is responsible for converting scim::KeyEvent object (defined in
++// /usr/include/scim-1.0/scim_event.h) to IPC input for mozc_server.
++class KeyTranslator {
++public:
++ KeyTranslator();
++ ~KeyTranslator();
++
++ // Converts scim_key into Mozc key code and stores them on out_translated.
++ // scim_key must satisfy the following precondition: CanConvert(scim_key)
++ void Translate(FcitxKeySym sym,
++ unsigned int state,
++ mozc::config::Config::PreeditMethod method,
++ mozc::commands::KeyEvent *out_event) const;
++
++ // Converts 'left click on a candidate window' into Mozc message.
++ // unique_id: Unique identifier of the clicked candidate.
++ void TranslateClick(int32 unique_id,
++ mozc::commands::SessionCommand *out_command) const;
++
++ // Returns true iff scim_key can be converted to mozc::commands::Input.
++ // Note: some keys and key events, such as 'key released', 'modifier key
++ // pressed', or 'special key that Mozc doesn't know pressed' cannot be
++ // converted to mozc::commands::Input.
++ bool CanConvert(FcitxKeySym sym, unsigned int state) const;
++
++ void SetLayout(FcitxMozcLayout l);
++
++ void SetInputState(FcitxInputState* i);
++
++private:
++ // Returns true iff scim_key is modifier key such as SHIFT, ALT, or CAPSLOCK.
++ bool IsModifierKey(FcitxKeySym sym, unsigned int state) const;
++
++ // Returns true iff scim_key is special key such as ENTER, ESC, or PAGE_UP.
++ bool IsSpecialKey(FcitxKeySym sym, unsigned int state,
++ mozc::commands::KeyEvent::SpecialKey *out) const;
++
++ // Returns a normalized key event iff key is HiraganaKatakana with shift
++ // modifier. See http://code.google.com/p/mozc/issues/detail?id=136 for
++ // the background information.
++ // Otherwire returns the original key.
++ static void NormalizeHiraganaKatakanaKeyWithShift(
++ FcitxKeySym origsym, unsigned int origstate, FcitxKeySym* sym, unsigned int* state);
++
++ // Returns true iff scim_key is special key that can be converted to ASCII.
++ // For example, scim::FCITX_KEY_KP_0 (numeric keypad zero) in FCITX can be
++ // treated as ASCII code '0' in Mozc.
++ bool IsSpecialAscii(FcitxKeySym sym, unsigned int state, uint32 *out) const;
++
++ // Returns true iff scim_key is key with a kana assigned.
++ bool IsKanaAvailable(FcitxKeySym sym, unsigned int state, string *out) const;
++
++ // Returns true iff scim_key is ASCII such as '0', 'A', or '!'.
++ static bool IsAscii(FcitxKeySym sym, unsigned int state);
++
++ // Returns true iff kana_map_jp_ is to be used.
++ static bool IsJapaneseLayout(FcitxMozcLayout layout);
++
++ // Initializes private fields.
++ void InitializeKeyMaps();
++
++ map<uint32, mozc::commands::KeyEvent::SpecialKey> special_key_map_;
++ set<uint32> modifier_keys_;
++ map<uint32, uint32> special_ascii_map_;
++ map<uint32, const char *> kana_map_jp_;
++ map<uint32, const char *> kana_map_us_;
++ FcitxInputState* input;
++ FcitxMozcLayout layout;
++
++ DISALLOW_COPY_AND_ASSIGN(KeyTranslator);
++};
++
++} // namespace fcitx
++
++} // namespace mozc
++
++#endif // MOZC_UNIX_FCITX_FCITX_KEY_TRANSLATOR_H_
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.cc b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.cc
new file mode 100644
index 000000000000..47e1f1748f7f
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.cc
@@ -0,0 +1,525 @@
+--- unix/fcitx/fcitx_mozc.cc.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx_mozc.cc 2012-05-22 13:42:56.603828937 +0900
+@@ -0,0 +1,522 @@
++/***************************************************************************
++ * Copyright (C) 2012~2012 by CSSlayer *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
++ ***************************************************************************/
++
++#include "unix/fcitx/fcitx_mozc.h"
++
++#include <string>
++#include <fcitx/candidate.h>
++#include <fcitx-config/xdg.h>
++
++#include "base/const.h"
++#include "base/logging.h"
++#include "base/process.h"
++#include "base/util.h"
++#include "unix/fcitx/mozc_connection.h"
++#include "unix/fcitx/mozc_response_parser.h"
++#include "unix/fcitx/fcitx_key_translator.h"
++#include <fcitx/context.h>
++
++#define N_(x) (x)
++
++namespace
++{
++
++static const std::string empty_string;
++
++const struct CompositionMode
++{
++ const char *icon;
++ const char *label;
++ const char *description;
++ mozc::commands::CompositionMode mode;
++} kPropCompositionModes[] =
++{
++ {
++ "mozc-direct.png",
++ "A",
++ N_("Direct"),
++ mozc::commands::DIRECT,
++ }, {
++ "mozc-hiragana.png",
++ "\xe3\x81\x82", // Hiragana letter A in UTF-8.
++ N_("Hiragana"),
++ mozc::commands::HIRAGANA,
++ }, {
++ "mozc-katakana_full.png",
++ "\xe3\x82\xa2", // Katakana letter A.
++ N_("Full Katakana"),
++ mozc::commands::FULL_KATAKANA,
++ }, {
++ "mozc-alpha_half.png",
++ "A",
++ N_("Half ASCII"),
++ mozc::commands::HALF_ASCII,
++ }, {
++ "mozc-alpha_full.png",
++ "\xef\xbc\xa1", // Full width ASCII letter A.
++ N_("Full ASCII"),
++ mozc::commands::FULL_ASCII,
++ }, {
++ "mozc-katakana_half.png",
++ "\xef\xbd\xb1", // Half width Katakana letter A.
++ N_("Half Katakana"),
++ mozc::commands::HALF_KATAKANA,
++ },
++};
++const size_t kNumCompositionModes = arraysize ( kPropCompositionModes );
++
++// This array must correspond with the CompositionMode enum in the
++// mozc/session/command.proto file.
++COMPILE_ASSERT (
++ mozc::commands::NUM_OF_COMPOSITIONS == arraysize ( kPropCompositionModes ),
++ bad_number_of_modes );
++
++} // namespace
++
++INPUT_RETURN_VALUE FcitxMozcGetCandidateWord(void* arg, FcitxCandidateWord* candWord)
++{
++ mozc::fcitx::FcitxMozc* fcitx_mozc = (mozc::fcitx::FcitxMozc*) arg;
++ fcitx_mozc->select_candidate(candWord);
++
++ return IRV_DISPLAY_CANDWORDS;
++}
++
++
++namespace mozc
++{
++
++namespace fcitx
++{
++
++// For unittests.
++FcitxMozc::FcitxMozc ( FcitxInstance* inst,
++ MozcConnectionInterface *connection,
++ MozcResponseParser *parser ) :
++ instance(inst),
++ input(FcitxInstanceGetInputState(inst)),
++ connection_ ( connection ),
++ parser_ ( parser ),
++ composition_mode_ ( mozc::commands::HIRAGANA )
++{
++ VLOG ( 1 ) << "FcitxMozc created.";
++ const bool is_vertical
++ = false;
++ parser_->set_use_annotation ( is_vertical );
++ InitializeBar();
++ InitializeMenu();
++ SetCompositionMode( mozc::commands::HIRAGANA );
++}
++
++FcitxMozc::~FcitxMozc()
++{
++ VLOG ( 1 ) << "FcitxMozc destroyed.";
++}
++
++// This function is called from SCIM framework when users press or release a
++// key.
++bool FcitxMozc::process_key_event ( FcitxKeySym sym, unsigned int state )
++{
++
++ if ( !connection_->CanSend ( sym, state ) )
++ {
++ VLOG ( 1 ) << "Mozc doesn't handle the key. Not consumed.";
++ return false; // not consumed.
++ }
++
++ string error;
++ mozc::commands::Output raw_response;
++ if ( !connection_->TrySendKeyEvent (
++ sym, state, composition_mode_, &raw_response, &error ) )
++ {
++ // TODO(yusukes): Show |error|.
++ return false; // not consumed.
++ }
++
++ return ParseResponse ( raw_response );
++}
++
++// This function is called from SCIM framework when users click the candidate
++// window.
++void FcitxMozc::select_candidate ( FcitxCandidateWord* candWord )
++{
++ int32 *id = (int32*) candWord->priv;
++
++ if ( *id == kBadCandidateId )
++ {
++ LOG ( ERROR ) << "The clicked candidate doesn't have unique ID.";
++ return;
++ }
++ VLOG ( 1 ) << "select_candidate, id=" << *id;
++
++ string error;
++ mozc::commands::Output raw_response;
++ if ( !connection_->TrySendClick ( *id, &raw_response, &error ) )
++ {
++ LOG ( ERROR ) << "IPC failed. error=" << error;
++ SetAuxString ( error );
++ DrawAll();
++ }
++ else
++ {
++ ParseResponse ( raw_response );
++ }
++}
++
++// This function is called from SCIM framework.
++void FcitxMozc::resetim()
++{
++ VLOG ( 1 ) << "resetim";
++ string error;
++ mozc::commands::Output raw_response;
++ if ( connection_->TrySendCommand (
++ mozc::commands::SessionCommand::REVERT, &raw_response, &error ) )
++ {
++ parser_->ParseResponse ( raw_response, this );
++ }
++ ClearAll(); // just in case.
++ DrawAll();
++
++}
++
++void FcitxMozc::reset()
++{
++ FcitxIM* im = FcitxInstanceGetCurrentIM(instance);
++ if (!im || strcmp(im->uniqueName, "mozc") != 0) {
++ FcitxUISetStatusVisable(instance, "mozc-tool", false);
++ FcitxUISetStatusVisable(instance, "mozc-composition-mode", false);
++ }
++ else {
++ FcitxUISetStatusVisable(instance, "mozc-tool", true);
++ FcitxUISetStatusVisable(instance, "mozc-composition-mode", true);
++ }
++}
++
++
++// This function is called from SCIM framework when the ic gets focus.
++void FcitxMozc::init()
++{
++ VLOG ( 1 ) << "focus_in";
++ boolean flag = false;
++ FcitxInstanceSetContext(instance, CONTEXT_DISABLE_AUTOENG, &flag);
++ FcitxInstanceSetContext(instance, CONTEXT_DISABLE_QUICKPHRASE, &flag);
++ FcitxInstanceSetContext(instance, CONTEXT_IM_KEYBOARD_LAYOUT, "jp");
++ DrawAll();
++}
++
++// This function is called when the ic loses focus.
++void FcitxMozc::focus_out()
++{
++ VLOG ( 1 ) << "focus_out";
++ string error;
++ mozc::commands::Output raw_response;
++ if ( connection_->TrySendCommand (
++ mozc::commands::SessionCommand::REVERT, &raw_response, &error ) )
++ {
++ parser_->ParseResponse ( raw_response, this );
++ }
++ ClearAll(); // just in case.
++ DrawAll();
++ // TODO(yusukes): Call client::SyncData() like ibus-mozc.
++}
++
++
++bool FcitxMozc::ParseResponse ( const mozc::commands::Output &raw_response )
++{
++ ClearAll();
++ const bool consumed = parser_->ParseResponse ( raw_response, this );
++ if ( !consumed )
++ {
++ VLOG ( 1 ) << "The input was not consumed by Mozc.";
++ }
++ OpenUrl();
++ DrawAll();
++ return consumed;
++}
++
++void FcitxMozc::SetResultString ( const std::string &result_string )
++{
++ FcitxInstanceCommitString(instance, FcitxInstanceGetCurrentIC(instance), result_string.c_str());
++}
++
++void FcitxMozc::SetPreeditInfo ( const PreeditInfo *preedit_info )
++{
++ preedit_info_.reset ( preedit_info );
++}
++
++void FcitxMozc::SetAuxString ( const std::string &str )
++{
++ aux_ = str;
++}
++
++void FcitxMozc::SetCompositionMode ( mozc::commands::CompositionMode mode )
++{
++ composition_mode_ = mode;
++ DCHECK(composition_mode_ < kNumCompositionModes);
++ if (composition_mode_ < kNumCompositionModes) {
++ FcitxUISetStatusString(instance,
++ "mozc-composition-mode",
++ _(kPropCompositionModes[composition_mode_].label),
++ _(kPropCompositionModes[composition_mode_].description));
++ }
++}
++
++void FcitxMozc::SendCompositionMode(mozc::commands::CompositionMode mode)
++{
++ // Send the SWITCH_INPUT_MODE command.
++ string error;
++ mozc::commands::Output raw_response;
++ if (connection_->TrySendCompositionMode(
++ kPropCompositionModes[mode].mode, &raw_response, &error)) {
++ parser_->ParseResponse(raw_response, this);
++ }
++}
++
++
++void FcitxMozc::SetUrl ( const string &url )
++{
++ url_ = url;
++}
++
++void FcitxMozc::ClearAll()
++{
++ SetPreeditInfo ( NULL );
++ SetAuxString ( "" );
++ FcitxCandidateWordReset(FcitxInputStateGetCandidateList(input));
++ url_.clear();
++}
++
++void FcitxMozc::DrawPreeditInfo()
++{
++ FcitxProfile* profile = FcitxInstanceGetProfile(instance);
++ FcitxMessages* preedit = FcitxInputStateGetPreedit(input);
++ FcitxMessages* clientpreedit = FcitxInputStateGetClientPreedit(input);
++ FcitxMessagesSetMessageCount(preedit, 0);
++ FcitxMessagesSetMessageCount(clientpreedit, 0);
++ FcitxInputContext* ic = FcitxInstanceGetCurrentIC(instance);
++ if ( preedit_info_.get() )
++ {
++ VLOG ( 1 ) << "DrawPreeditInfo: cursor=" << preedit_info_->cursor_pos;
++
++ if (ic && ((ic->contextCaps & CAPACITY_PREEDIT) == 0 || !profile->bUsePreedit))
++ FcitxInputStateSetShowCursor(input, true);
++
++ for (int i = 0; i < preedit_info_->preedit.size(); i ++) {
++ if (ic && ((ic->contextCaps & CAPACITY_PREEDIT) == 0 || !profile->bUsePreedit))
++ FcitxMessagesAddMessageAtLast(preedit, preedit_info_->preedit[i].type, "%s", preedit_info_->preedit[i].str.c_str());
++ FcitxMessagesAddMessageAtLast(clientpreedit, preedit_info_->preedit[i].type, "%s", preedit_info_->preedit[i].str.c_str());
++ }
++ if (ic && ((ic->contextCaps & CAPACITY_PREEDIT) == 0 || !profile->bUsePreedit))
++ FcitxInputStateSetCursorPos(input, preedit_info_->cursor_pos);
++ FcitxInputStateSetClientCursorPos(input, preedit_info_->cursor_pos);
++ }
++ else {
++ FcitxInputStateSetShowCursor(input, true);
++ }
++}
++
++void FcitxMozc::DrawAux()
++{
++ FcitxMessages* auxUp = FcitxInputStateGetAuxUp(input);
++ FcitxMessages* auxDown = FcitxInputStateGetAuxDown(input);
++ FcitxMessagesSetMessageCount(auxUp, 0);
++ FcitxMessagesSetMessageCount(auxDown, 0);
++ if ( !aux_.empty() ) {
++ FcitxMessagesAddMessageAtLast(auxUp, MSG_TIPS, "%s ", aux_.c_str());
++ }
++}
++
++void FcitxMozc::DrawAll()
++{
++ DrawPreeditInfo();
++ DrawAux();
++}
++
++void FcitxMozc::OpenUrl()
++{
++ if ( url_.empty() )
++ {
++ return;
++ }
++ mozc::Process::OpenBrowser ( url_ );
++ url_.clear();
++}
++
++static const char* GetCompositionIconName(void* arg)
++{
++ FcitxMozc* mozc = (FcitxMozc*) arg;
++ return mozc->GetCurrentCompositionModeIcon().c_str();
++}
++
++
++static const char* GetMozcToolIcon(void* arg)
++{
++ FcitxMozc* mozc = (FcitxMozc*) arg;
++ return mozc->GetIconFile("mozc-tool.png").c_str();
++}
++
++void FcitxMozc::InitializeBar()
++{
++ VLOG ( 1 ) << "Registering properties";
++
++ FcitxUIRegisterComplexStatus(instance, this,
++ "mozc-composition-mode",
++ _("Composition Mode"),
++ _("Composition Mode"),
++ NULL,
++ GetCompositionIconName
++ );
++
++ if ( mozc::Util::FileExists ( mozc::Util::JoinPath (
++ mozc::Util::GetServerDirectory(), mozc::kMozcTool ) ) )
++ {
++ FcitxUIRegisterComplexStatus(instance, this,
++ "mozc-tool",
++ _("Tool"),
++ _("Tool"),
++ NULL,
++ GetMozcToolIcon
++ );
++ }
++ FcitxUISetStatusVisable(instance, "mozc-tool", false);
++ FcitxUISetStatusVisable(instance, "mozc-composition-mode", false);
++}
++
++FcitxMozc::FcitxMozc(const mozc::fcitx::FcitxMozc& )
++{
++
++}
++
++boolean CompositionMenuAction(struct _FcitxUIMenu *menu, int index)
++{
++ FcitxMozc* mozc = (FcitxMozc*) menu->priv;
++ if (index == mozc::commands::DIRECT) {
++ FcitxInstanceCloseIM(mozc->GetInstance(), FcitxInstanceGetCurrentIC(mozc->GetInstance()));
++ }
++ else {
++ mozc->SendCompositionMode((mozc::commands::CompositionMode) index);
++ }
++ return true;
++}
++
++void UpdateCompositionMenu(struct _FcitxUIMenu *menu)
++{
++ FcitxMozc* mozc = (FcitxMozc*) menu->priv;
++ menu->mark = mozc->GetCompositionMode();
++}
++
++boolean ToolMenuAction(struct _FcitxUIMenu *menu, int index)
++{
++ string args;
++ switch(index) {
++ case 0:
++ args = "--mode=config_dialog";
++ break;
++ case 1:
++ args = "--mode=dictionary_tool";
++ break;
++ case 2:
++ args = "--mode=hand_writing";
++ break;
++ case 3:
++ args = "--mode=character_palette";
++ break;
++ case 4:
++ args = "--mode=word_register_dialog";
++ break;
++ case 5:
++ args = "--mode=about_dialog";
++ break;
++ }
++ mozc::Process::SpawnMozcProcess("mozc_tool", args);
++ return true;
++}
++
++void UpdateToolMenu(struct _FcitxUIMenu *menu)
++{
++ return;
++}
++
++void FcitxMozc::InitializeMenu()
++{
++ FcitxMenuInit(&this->compositionMenu);
++ compositionMenu.name = strdup(_("Composition Mode"));
++ compositionMenu.candStatusBind = strdup("mozc-composition-mode");
++ compositionMenu.UpdateMenu = UpdateCompositionMenu;
++ compositionMenu.MenuAction = CompositionMenuAction;
++ compositionMenu.priv = this;
++ compositionMenu.isSubMenu = false;
++ int i;
++ for (i = 0; i < kNumCompositionModes; i ++)
++ FcitxMenuAddMenuItem(&compositionMenu, _(kPropCompositionModes[i].description), MENUTYPE_SIMPLE, NULL);
++
++ FcitxUIRegisterMenu(instance, &compositionMenu);
++
++ FcitxMenuInit(&this->toolMenu);
++ toolMenu.name = strdup(_("Mozc Tool"));
++ toolMenu.candStatusBind = strdup("mozc-tool");
++ toolMenu.UpdateMenu = UpdateToolMenu;
++ toolMenu.MenuAction = ToolMenuAction;
++ toolMenu.priv = this;
++ toolMenu.isSubMenu = false;
++ FcitxMenuAddMenuItem(&toolMenu, _("Configuration Tool"), MENUTYPE_SIMPLE, NULL);
++ FcitxMenuAddMenuItem(&toolMenu, _("Dictionary Tool"), MENUTYPE_SIMPLE, NULL);
++ FcitxMenuAddMenuItem(&toolMenu, _("Hand Writing"), MENUTYPE_SIMPLE, NULL);
++ FcitxMenuAddMenuItem(&toolMenu, _("Character Palette"), MENUTYPE_SIMPLE, NULL);
++ FcitxMenuAddMenuItem(&toolMenu, _("Add Word"), MENUTYPE_SIMPLE, NULL);
++ FcitxMenuAddMenuItem(&toolMenu, _("About Mozc"), MENUTYPE_SIMPLE, NULL);
++ FcitxUIRegisterMenu(instance, &toolMenu);
++}
++
++FcitxInputState* FcitxMozc::GetInputState()
++{
++ return input;
++}
++
++const std::string& FcitxMozc::GetIconFile(const std::string key)
++{
++ if (iconMap.count(key)) {
++ return iconMap[key];
++ }
++
++ char* retFile;
++ FILE* fp = FcitxXDGGetFileWithPrefix("mozc/icon", key.c_str(), "r", &retFile);
++ if (fp)
++ fclose(fp);
++ if (retFile) {
++ iconMap[key] = std::string(retFile);
++ free(retFile);
++ }
++ else {
++ iconMap[key] = "";
++ }
++ return iconMap[key];
++}
++
++
++const std::string& FcitxMozc::GetCurrentCompositionModeIcon() {
++ DCHECK(composition_mode_ < kNumCompositionModes);
++ if (composition_mode_ < kNumCompositionModes) {
++ return GetIconFile(kPropCompositionModes[composition_mode_].icon);
++ }
++ return empty_string;
++}
++
++} // namespace fcitx
++
++} // namespace mozc_unix_scim
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.h b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.h
new file mode 100644
index 000000000000..b49cdde75950
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_fcitx_mozc.h
@@ -0,0 +1,153 @@
+--- unix/fcitx/fcitx_mozc.h.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/fcitx_mozc.h 2012-05-22 13:42:56.603828937 +0900
+@@ -0,0 +1,150 @@
++/***************************************************************************
++ * Copyright (C) 2012~2012 by CSSlayer *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
++ ***************************************************************************/
++
++
++#ifndef MOZC_UNIX_FCITX_FCITX_MOZC_H_
++#define MOZC_UNIX_FCITX_FCITX_MOZC_H_
++
++#include <fcitx/instance.h>
++#include <fcitx/candidate.h>
++#include <fcitx-config/hotkey.h>
++#include <libintl.h>
++#include "base/base.h" // for DISALLOW_COPY_AND_ASSIGN.
++#include "base/run_level.h"
++#include "session/commands.pb.h"
++
++#define _(x) dgettext("fcitx-mozc", (x))
++
++INPUT_RETURN_VALUE FcitxMozcGetCandidateWord(void* arg, FcitxCandidateWord* candWord);;
++
++namespace mozc
++{
++
++namespace fcitx
++{
++const int32 kBadCandidateId = -12345;
++class IMEngineFactory;
++class MozcConnectionInterface;
++class MozcResponseParser;
++class KeyTranslator;
++
++struct PreeditItem {
++ std::string str;
++ FcitxMessageType type;
++};
++
++// Preedit string and its attributes.
++struct PreeditInfo
++{
++ uint32 cursor_pos;
++
++ std::vector<PreeditItem> preedit;
++};
++
++class FcitxMozc
++{
++public:
++ // This constructor is used by unittests.
++ FcitxMozc ( FcitxInstance* instance,
++ MozcConnectionInterface *connection,
++ MozcResponseParser *parser );
++ virtual ~FcitxMozc();
++
++ bool process_key_event ( FcitxKeySym sym, unsigned int state );
++ void select_candidate ( FcitxCandidateWord* candWord );
++ void resetim();
++ void reset();
++ void init();
++ void focus_out();
++
++ // Functions called by the MozcResponseParser class to update UI.
++
++ // Displays a 'result' (aka 'commit string') on FCITX UI.
++ void SetResultString ( const std::string &result_string );
++ // Displays a 'preedit' string on FCITX UI. This function takes ownership
++ // of preedit_info. If the parameter is NULL, hides the string currently
++ // displayed.
++ void SetPreeditInfo ( const PreeditInfo *preedit_info );
++ // Displays an auxiliary message (e.g., an error message, a title of
++ // candidate window). If the string is empty (""), hides the message
++ // currently being displayed.
++ void SetAuxString ( const std::string &str );
++ // Sets a current composition mode (e.g., Hankaku Katakana).
++ void SetCompositionMode ( mozc::commands::CompositionMode mode );
++
++ void SendCompositionMode ( mozc::commands::CompositionMode mode );
++
++ // Sets the url to be opened by the default browser.
++ void SetUrl ( const string &url );
++
++ const std::string& GetIconFile(const std::string key);
++
++ const std::string& GetCurrentCompositionModeIcon();
++
++ mozc::commands::CompositionMode GetCompositionMode() { return composition_mode_; }
++
++ FcitxInstance* GetInstance() { return instance; }
++
++ FcitxInputState* GetInputState();
++
++private:
++ friend class FcitxMozcTest;
++
++ // Adds Mozc-specific icons to FCITX toolbar.
++ void InitializeBar();
++
++ void InitializeMenu();
++
++ // Parses the response from mozc_server. Returns whether the server consumes
++ // the input or not (true means 'consumed').
++ bool ParseResponse ( const mozc::commands::Output &request );
++
++ void ClearAll();
++ void DrawAll();
++ void DrawPreeditInfo();
++ void DrawAux();
++
++ // Open url_ with a default browser.
++ void OpenUrl();
++
++ FcitxInstance* instance;
++ FcitxInputState* input;
++ const scoped_ptr<MozcConnectionInterface> connection_;
++ const scoped_ptr<MozcResponseParser> parser_;
++
++ // Strings and a window currently displayed on FCITX UI.
++ scoped_ptr<const PreeditInfo> preedit_info_;
++ std::string aux_; // error tooltip, or candidate window title.
++ string url_; // URL to be opened by a browser.
++ mozc::commands::CompositionMode composition_mode_;
++
++ std::map<std::string, std::string> iconMap;
++
++ FcitxUIMenu compositionMenu;
++ FcitxUIMenu toolMenu;
++
++ DISALLOW_COPY_AND_ASSIGN ( FcitxMozc );
++};
++
++} // namespace fcitx
++
++} // namespace mozc
++
++#endif // MOZC_UNIX_FCITX_FCITX_MOZC_H_
++
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_gen_fcitx_mozc_i18n.sh b/japanese/mozc-server/files/patch-unix_fcitx_gen_fcitx_mozc_i18n.sh
new file mode 100644
index 000000000000..f605a9b2002a
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_gen_fcitx_mozc_i18n.sh
@@ -0,0 +1,14 @@
+--- unix/fcitx/gen_fcitx_mozc_i18n.sh.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/gen_fcitx_mozc_i18n.sh 2012-05-22 13:46:54.090828960 +0900
+@@ -0,0 +1,11 @@
++#!/bin/sh
++objdir="$1"
++
++cd po || exit 1
++
++mkdir -p "$1"
++
++for pofile in *.po
++do
++ msgfmt "$pofile" -o "$1/${pofile%po}mo"
++done
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_mozc.conf b/japanese/mozc-server/files/patch-unix_fcitx_mozc.conf
new file mode 100644
index 000000000000..c06bb8b4f788
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_mozc.conf
@@ -0,0 +1,10 @@
+--- unix/fcitx/mozc.conf.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/mozc.conf 2012-05-22 13:42:56.617829320 +0900
+@@ -0,0 +1,7 @@
++[InputMethod]
++UniqueName=mozc
++Name=Mozc
++IconName=/usr/share/fcitx/mozc/icon/mozc.png
++Priority=1
++LangCode=ja
++Parent=fcitx-mozc
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.cc b/japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.cc
new file mode 100644
index 000000000000..29ce5991d22e
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.cc
@@ -0,0 +1,177 @@
+--- unix/fcitx/mozc_connection.cc.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/mozc_connection.cc 2012-05-22 13:42:56.618829027 +0900
+@@ -0,0 +1,174 @@
++// Copyright 2010-2012, Google Inc.
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions are
++// met:
++//
++// * Redistributions of source code must retain the above copyright
++// notice, this list of conditions and the following disclaimer.
++// * Redistributions in binary form must reproduce the above
++// copyright notice, this list of conditions and the following disclaimer
++// in the documentation and/or other materials provided with the
++// distribution.
++// * Neither the name of Google Inc. nor the names of its
++// contributors may be used to endorse or promote products derived from
++// this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++#include "unix/fcitx/mozc_connection.h"
++
++#include <string>
++
++#include "base/logging.h"
++#include "base/util.h"
++#include "client/client.h"
++#include "ipc/ipc.h"
++#include "session/commands.pb.h"
++#include "session/ime_switch_util.h"
++#include "unix/fcitx/fcitx_key_translator.h"
++
++namespace mozc {
++namespace fcitx {
++
++MozcConnectionInterface::~MozcConnectionInterface() {
++}
++
++MozcConnection::MozcConnection(
++ mozc::client::ServerLauncherInterface *server_launcher,
++ mozc::IPCClientFactoryInterface *client_factory)
++ : translator_(new KeyTranslator),
++ preedit_method_(mozc::config::Config::ROMAN),
++ client_factory_(client_factory) {
++ VLOG(1) << "MozcConnection is created";
++ mozc::client::ClientInterface *client =
++ mozc::client::ClientFactory::NewClient();
++ client->SetServerLauncher(server_launcher);
++ client->SetIPCClientFactory(client_factory_.get());
++ client_.reset(client);
++
++ mozc::config::Config config;
++ if (client_->EnsureConnection() &&
++ client_->GetConfig(&config) && config.has_preedit_method()) {
++ preedit_method_ = config.preedit_method();
++ }
++ VLOG(1)
++ << "Current preedit method is "
++ << (preedit_method_ == mozc::config::Config::ROMAN ? "Roman" : "Kana");
++}
++
++MozcConnection::~MozcConnection() {
++ client_->SyncData();
++ VLOG(1) << "MozcConnection is destroyed";
++}
++
++bool MozcConnection::TrySendKeyEvent(
++ FcitxKeySym sym, unsigned int state,
++ mozc::commands::CompositionMode composition_mode,
++ mozc::commands::Output *out,
++ string *out_error) const {
++ DCHECK(out);
++ DCHECK(out_error);
++
++ // Call EnsureConnection just in case MozcConnection::MozcConnection() fails
++ // to establish the server connection.
++ if (!client_->EnsureConnection()) {
++ *out_error = "EnsureConnection failed";
++ VLOG(1) << "EnsureConnection failed";
++ return false;
++ }
++
++ mozc::commands::KeyEvent event;
++ translator_->Translate(sym, state, preedit_method_, &event);
++
++ if ((composition_mode == mozc::commands::DIRECT) &&
++ !mozc::config::ImeSwitchUtil::IsDirectModeCommand(event)) {
++ VLOG(1) << "In DIRECT mode. Not consumed.";
++ return false; // not consumed.
++ }
++
++ VLOG(1) << "TrySendKeyEvent: " << endl << event.DebugString();
++ if (!client_->SendKey(event, out)) {
++ *out_error = "SendKey failed";
++ VLOG(1) << "ERROR";
++ return false;
++ }
++ VLOG(1) << "OK: " << endl << out->DebugString();
++ return true;
++}
++
++bool MozcConnection::TrySendClick(int32 unique_id,
++ mozc::commands::Output *out,
++ string *out_error) const {
++ DCHECK(out);
++ DCHECK(out_error);
++
++ mozc::commands::SessionCommand command;
++ translator_->TranslateClick(unique_id, &command);
++ return TrySendCommandInternal(command, out, out_error);
++}
++
++bool MozcConnection::TrySendCompositionMode(
++ mozc::commands::CompositionMode mode,
++ mozc::commands::Output *out,
++ string *out_error) const {
++ DCHECK(out);
++ DCHECK(out_error);
++
++ mozc::commands::SessionCommand command;
++ command.set_type(mozc::commands::SessionCommand::SWITCH_INPUT_MODE);
++ command.set_composition_mode(mode);
++ return TrySendCommandInternal(command, out, out_error);
++}
++
++bool MozcConnection::TrySendCommand(
++ mozc::commands::SessionCommand::CommandType type,
++ mozc::commands::Output *out,
++ string *out_error) const {
++ DCHECK(out);
++ DCHECK(out_error);
++
++ mozc::commands::SessionCommand command;
++ command.set_type(type);
++ return TrySendCommandInternal(command, out, out_error);
++}
++
++bool MozcConnection::TrySendCommandInternal(
++ const mozc::commands::SessionCommand& command,
++ mozc::commands::Output *out,
++ string *out_error) const {
++ VLOG(1) << "TrySendCommandInternal: " << endl << command.DebugString();
++ if (!client_->SendCommand(command, out)) {
++ *out_error = "SendCommand failed";
++ VLOG(1) << "ERROR";
++ return false;
++ }
++ VLOG(1) << "OK: " << endl << out->DebugString();
++ return true;
++}
++
++bool MozcConnection::CanSend(FcitxKeySym sym, unsigned int state) const {
++ return translator_->CanConvert(sym, state);
++}
++
++MozcConnection *MozcConnection::CreateMozcConnection() {
++ mozc::client::ServerLauncher *server_launcher
++ = new mozc::client::ServerLauncher;
++
++ return new MozcConnection(server_launcher, new mozc::IPCClientFactory);
++}
++
++} // namespace fcitx
++
++} // namespace mozc
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.h b/japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.h
new file mode 100644
index 000000000000..8d8cbf12e5db
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_mozc_connection.h
@@ -0,0 +1,139 @@
+--- unix/fcitx/mozc_connection.h.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/mozc_connection.h 2012-05-22 13:42:56.619826989 +0900
+@@ -0,0 +1,136 @@
++// Copyright 2010-2012, Google Inc.
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions are
++// met:
++//
++// * Redistributions of source code must retain the above copyright
++// notice, this list of conditions and the following disclaimer.
++// * Redistributions in binary form must reproduce the above
++// copyright notice, this list of conditions and the following disclaimer
++// in the documentation and/or other materials provided with the
++// distribution.
++// * Neither the name of Google Inc. nor the names of its
++// contributors may be used to endorse or promote products derived from
++// this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++#ifndef MOZC_UNIX_FCITX_MOZC_CONNECTION_H_
++#define MOZC_UNIX_FCITX_MOZC_CONNECTION_H_
++
++#include <string>
++#include <fcitx-config/hotkey.h>
++
++#include "base/base.h"
++#include "session/commands.pb.h"
++
++namespace mozc {
++
++class IPCClientInterface;
++class IPCClientFactoryInterface;
++
++namespace client {
++class ClientInterface;
++class ServerLauncherInterface;
++} // namespace client
++
++} // namespace mozc
++
++namespace mozc {
++
++namespace fcitx {
++
++class KeyTranslator;
++
++// This class is for mozc_response_parser_test.cc.
++class MozcConnectionInterface {
++ public:
++ virtual ~MozcConnectionInterface();
++
++ virtual bool TrySendKeyEvent(FcitxKeySym sym, unsigned int state,
++ mozc::commands::CompositionMode composition_mode,
++ mozc::commands::Output *out,
++ string *out_error) const = 0;
++ virtual bool TrySendClick(int32 unique_id,
++ mozc::commands::Output *out,
++ string *out_error) const = 0;
++ virtual bool TrySendCompositionMode(mozc::commands::CompositionMode mode,
++ mozc::commands::Output *out,
++ string *out_error) const = 0;
++ virtual bool TrySendCommand(mozc::commands::SessionCommand::CommandType type,
++ mozc::commands::Output *out,
++ string *out_error) const = 0;
++ virtual bool CanSend(FcitxKeySym sym, unsigned int state) const = 0;
++};
++
++class MozcConnection : public MozcConnectionInterface {
++ public:
++ static const int kNoSession;
++
++ static MozcConnection *CreateMozcConnection();
++ virtual ~MozcConnection();
++
++ // Sends key event to the server. If the IPC succeeds, returns true and the
++ // response is stored on 'out' (and 'out_error' is not modified). If the IPC
++ // fails, returns false and the error message is stored on 'out_error'. In
++ // this case, 'out' is not modified.
++ virtual bool TrySendKeyEvent(FcitxKeySym sym, unsigned int state,
++ mozc::commands::CompositionMode composition_mode,
++ mozc::commands::Output *out,
++ string *out_error) const;
++
++ // Sends 'mouse click on the candidate window' event to the server.
++ virtual bool TrySendClick(int32 unique_id,
++ mozc::commands::Output *out,
++ string *out_error) const;
++
++ // Sends composition mode to the server.
++ virtual bool TrySendCompositionMode(mozc::commands::CompositionMode mode,
++ mozc::commands::Output *out,
++ string *out_error) const;
++
++ // Sends a command to the server.
++ virtual bool TrySendCommand(mozc::commands::SessionCommand::CommandType type,
++ mozc::commands::Output *out,
++ string *out_error) const;
++
++ // Returns true iff TrySendKeyEvent() accepts the key.
++ virtual bool CanSend(FcitxKeySym sym, unsigned int state) const;
++
++ private:
++ friend class MozcConnectionTest;
++ MozcConnection(mozc::client::ServerLauncherInterface *server_launcher,
++ mozc::IPCClientFactoryInterface *client_factory);
++
++ bool TrySendCommandInternal(
++ const mozc::commands::SessionCommand& command,
++ mozc::commands::Output *out,
++ string *out_error) const;
++
++ const scoped_ptr<KeyTranslator> translator_;
++ mozc::config::Config::PreeditMethod preedit_method_;
++ // Keep definition order of client_factory_ and client_.
++ // We should delete client_ before deleting client_factory_.
++ scoped_ptr<mozc::IPCClientFactoryInterface> client_factory_;
++ scoped_ptr<mozc::client::ClientInterface> client_;
++
++ DISALLOW_COPY_AND_ASSIGN(MozcConnection);
++};
++
++} // namespace fcitx
++
++} // namespace mozc
++
++#endif // MOZC_UNIX_SCIM_MOZC_CONNECTION_H_
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.cc b/japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.cc
new file mode 100644
index 000000000000..790561bd33a4
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.cc
@@ -0,0 +1,284 @@
+--- unix/fcitx/mozc_response_parser.cc.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/mozc_response_parser.cc 2012-05-22 13:42:56.620828933 +0900
+@@ -0,0 +1,281 @@
++// Copyright 2010-2012, Google Inc.
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions are
++// met:
++//
++// * Redistributions of source code must retain the above copyright
++// notice, this list of conditions and the following disclaimer.
++// * Redistributions in binary form must reproduce the above
++// copyright notice, this list of conditions and the following disclaimer
++// in the documentation and/or other materials provided with the
++// distribution.
++// * Neither the name of Google Inc. nor the names of its
++// contributors may be used to endorse or promote products derived from
++// this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++#include "unix/fcitx/mozc_response_parser.h"
++
++#include <string>
++#include <vector>
++
++#include "base/logging.h"
++#include "session/commands.pb.h"
++#include "unix/fcitx/fcitx_mozc.h"
++#include <fcitx/candidate.h>
++
++namespace {
++
++// Returns true if the candidate window contains only suggestions.
++bool IsSuggestion(const mozc::commands::Candidates &candidates) {
++ return !candidates.has_focused_index();
++}
++
++// Returns a position that determines a preedit cursor position _AND_ top-left
++// position of a candidate window. Note that we can't set these two positions
++// independently. That's a SCIM's limitation.
++uint32 GetCursorPosition(const mozc::commands::Output &response) {
++ if (!response.has_preedit()) {
++ return 0;
++ }
++ if (response.preedit().has_highlighted_position()) {
++ return response.preedit().highlighted_position();
++ }
++ return response.preedit().cursor();
++}
++
++string CreateDescriptionString(const string &description) {
++ return " [" + description + "]";
++}
++
++} // namespace
++
++namespace mozc {
++
++namespace fcitx {
++
++MozcResponseParser::MozcResponseParser()
++ : use_annotation_(false) {
++}
++
++MozcResponseParser::~MozcResponseParser() {
++}
++
++bool MozcResponseParser::ParseResponse(const mozc::commands::Output &response,
++ FcitxMozc *fcitx_mozc) const {
++ DCHECK(fcitx_mozc);
++ if (!fcitx_mozc) {
++ return false;
++ }
++
++ // We should check the mode field first since the response for a
++ // SWITCH_INPUT_MODE request only contains mode and id fields.
++ if (response.has_mode()) {
++ fcitx_mozc->SetCompositionMode(response.mode());
++ }
++
++ if (!response.consumed()) {
++ // The key was not consumed by Mozc.
++ return false;
++ }
++
++ if (response.has_result()) {
++ const mozc::commands::Result &result = response.result();
++ ParseResult(result, fcitx_mozc);
++ }
++
++ // First, determine the cursor position.
++ if (response.has_preedit()) {
++ const mozc::commands::Preedit &preedit = response.preedit();
++ ParsePreedit(preedit, GetCursorPosition(response), fcitx_mozc);
++ }
++
++ // Then show the candidate window.
++ if (response.has_candidates()) {
++ const mozc::commands::Candidates &candidates = response.candidates();
++ ParseCandidates(candidates, fcitx_mozc);
++ }
++
++ if (response.has_url()) {
++ const string &url = response.url();
++ fcitx_mozc->SetUrl(url);
++ }
++
++ return true; // mozc consumed the key.
++}
++
++void MozcResponseParser::set_use_annotation(bool use_annotation) {
++ use_annotation_ = use_annotation;
++}
++
++void MozcResponseParser::ParseResult(const mozc::commands::Result &result,
++ FcitxMozc *fcitx_mozc) const {
++ switch (result.type()) {
++ case mozc::commands::Result::NONE: {
++ fcitx_mozc->SetAuxString("No result"); // not a fatal error.
++ break;
++ }
++ case mozc::commands::Result::STRING: {
++ fcitx_mozc->SetResultString(result.value());
++ break;
++ }
++ }
++}
++
++void MozcResponseParser::ParseCandidates(
++ const mozc::commands::Candidates &candidates, FcitxMozc *fcitx_mozc) const {
++ const commands::Footer &footer = candidates.footer();
++ if (candidates.has_footer()) {
++ string auxString;
++ if (footer.has_label()) {
++ // TODO(yusukes,mozc-team): label() is not localized. Currently, it's always
++ // written in Japanese (in UTF-8).
++ auxString += footer.label();
++ } else if (footer.has_sub_label()) {
++ // Windows client shows sub_label() only when label() is not specified. We
++ // follow the policy.
++ auxString += footer.sub_label();
++ }
++
++ if (footer.has_index_visible() && footer.index_visible()) {
++ // Max size of candidates is 200 so 128 is sufficient size for the buffer.
++ char index_buf[128] = {0};
++ const int result = snprintf(index_buf,
++ sizeof(index_buf) - 1,
++ "%s%d/%d",
++ (auxString.empty() ? "" : " "),
++ candidates.focused_index() + 1,
++ candidates.size());
++ DCHECK_GE(result, 0) << "snprintf in ComposeAuxiliaryText failed";
++ auxString += index_buf;
++ }
++ fcitx_mozc->SetAuxString(auxString);
++ }
++
++ FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(fcitx_mozc->GetInputState());
++ FcitxCandidateWordReset(candList);
++ FcitxCandidateWordSetPageSize(candList, 9);
++ char strChoose[] = "\0\0\0\0\0\0\0\0\0\0\0";
++
++ int focused_index = -1;
++ int local_index = -1;
++ if (candidates.has_focused_index()) {
++ focused_index = candidates.focused_index();
++ }
++ for (int i = 0; i < candidates.candidate_size(); ++i) {
++ const uint32 index = candidates.candidate(i).index();
++ if (focused_index != -1 && index == focused_index) {
++ local_index = i;
++ }
++ int32* id = (int32*) fcitx_utils_malloc0(sizeof(int32));
++ FcitxCandidateWord candWord;
++ candWord.callback = FcitxMozcGetCandidateWord;
++ candWord.extraType = MSG_INPUT;
++ candWord.strExtra = NULL;
++ candWord.priv = id;
++ candWord.strWord = NULL;
++ candWord.wordType = MSG_INPUT;
++ candWord.owner = fcitx_mozc;
++
++ string value;
++ if (use_annotation_ &&
++ candidates.candidate(i).has_annotation() &&
++ candidates.candidate(i).annotation().has_prefix()) {
++ value = candidates.candidate(i).annotation().prefix();
++ }
++ value += candidates.candidate(i).value();
++ if (use_annotation_ &&
++ candidates.candidate(i).has_annotation() &&
++ candidates.candidate(i).annotation().has_suffix()) {
++ value += candidates.candidate(i).annotation().suffix();
++ }
++ if (use_annotation_ &&
++ candidates.candidate(i).has_annotation() &&
++ candidates.candidate(i).annotation().has_description()) {
++ // Display descriptions ([HALF][KATAKANA], [GREEK], [Black square], etc).
++ value += CreateDescriptionString(
++ candidates.candidate(i).annotation().description());
++ }
++
++ candWord.strWord = strdup(value.c_str());
++
++ if (candidates.candidate(i).has_id()) {
++ const int32 cid = candidates.candidate(i).id();
++ DCHECK_NE(kBadCandidateId, cid) << "Unexpected id is passed.";
++ *id = cid;
++ } else {
++ // The parent node of the cascading window does not have an id since the
++ // node does not contain a candidate word.
++ *id = kBadCandidateId;
++ }
++ FcitxCandidateWordAppend(candList, &candWord);
++ }
++
++ if (footer.has_index_visible() && footer.index_visible())
++ FcitxCandidateWordSetChoose(candList, DIGIT_STR_CHOOSE);
++ else
++ FcitxCandidateWordSetChoose(candList, strChoose);
++ FcitxCandidateWordSetFocus(candList, local_index);
++}
++
++static int GetRawCursorPos(const char * str, int upos)
++{
++ unsigned int i;
++ int pos = 0;
++ for (i = 0; i < upos; i++) {
++ pos += fcitx_utf8_char_len(fcitx_utf8_get_nth_char((char*)str, i));
++ }
++ return pos;
++}
++
++
++void MozcResponseParser::ParsePreedit(const mozc::commands::Preedit &preedit,
++ uint32 position,
++ FcitxMozc *fcitx_mozc) const {
++ PreeditInfo *info = new PreeditInfo;
++ std::string s;
++
++ for (int i = 0; i < preedit.segment_size(); ++i) {
++ const mozc::commands::Preedit_Segment &segment = preedit.segment(i);
++ const std::string &str = segment.value();
++ FcitxMessageType type = MSG_INPUT;
++
++ switch (segment.annotation()) {
++ case mozc::commands::Preedit_Segment::NONE:
++ type = (FcitxMessageType) (MSG_INPUT | MSG_NOUNDERLINE);
++ break;
++ case mozc::commands::Preedit_Segment::UNDERLINE:
++ type = (FcitxMessageType) (MSG_TIPS);
++ break;
++ case mozc::commands::Preedit_Segment::HIGHLIGHT:
++ type = (FcitxMessageType) (MSG_CODE | MSG_NOUNDERLINE | MSG_HIGHLIGHT);
++ break;
++ }
++ s += str;
++
++ PreeditItem item;
++ item.type = type;
++ item.str = str;
++ info->preedit.push_back(item);
++ }
++ info->cursor_pos = GetRawCursorPos(s.c_str(), position);
++
++ fcitx_mozc->SetPreeditInfo(info);
++}
++
++} // namespace fcitx
++
++} // namespace mozc
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.h b/japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.h
new file mode 100644
index 000000000000..8a3f8f709a6d
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_mozc_response_parser.h
@@ -0,0 +1,96 @@
+--- unix/fcitx/mozc_response_parser.h.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/mozc_response_parser.h 2012-05-22 13:42:56.620828933 +0900
+@@ -0,0 +1,93 @@
++// Copyright 2010-2012, Google Inc.
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions are
++// met:
++//
++// * Redistributions of source code must retain the above copyright
++// notice, this list of conditions and the following disclaimer.
++// * Redistributions in binary form must reproduce the above
++// copyright notice, this list of conditions and the following disclaimer
++// in the documentation and/or other materials provided with the
++// distribution.
++// * Neither the name of Google Inc. nor the names of its
++// contributors may be used to endorse or promote products derived from
++// this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++#ifndef MOZC_UNIX_FCITX_MOZC_RESPONSE_PARSER_H_
++#define MOZC_UNIX_FCITX_MOZC_RESPONSE_PARSER_H_
++
++#include "base/base.h" // for DISALLOW_COPY_AND_ASSIGN.
++
++namespace mozc
++{
++namespace commands
++{
++
++class Candidates;
++class Input;
++class Output;
++class Preedit;
++class Result;
++
++} // namespace commands
++} // namespace mozc
++
++namespace mozc
++{
++
++namespace fcitx
++{
++
++class FcitxMozc;
++
++// This class parses IPC response from mozc_server (mozc::commands::Output) and
++// updates the FCITX UI.
++class MozcResponseParser
++{
++public:
++ MozcResponseParser();
++ ~MozcResponseParser();
++
++ // Parses a response from Mozc server and sets persed information on fcitx_mozc
++ // object. Returns true if response.consumed() is true. fcitx_mozc must be non
++ // NULL. This function does not take ownership of fcitx_mozc.
++ bool ParseResponse ( const mozc::commands::Output &response,
++ FcitxMozc *fcitx_mozc ) const;
++
++ // Setter for use_annotation_. If use_annotation_ is true, ParseCandidates()
++ // uses annotation infomation.
++ void set_use_annotation ( bool use_annotation );
++
++private:
++ void ParseResult ( const mozc::commands::Result &result,
++ FcitxMozc *fcitx_mozc ) const;
++ void ParseCandidates ( const mozc::commands::Candidates &candidates,
++ FcitxMozc *fcitx_mozc ) const;
++ void ParsePreedit ( const mozc::commands::Preedit &preedit,
++ uint32 position,
++ FcitxMozc *fcitx_mozc ) const;
++
++ bool use_annotation_;
++
++ DISALLOW_COPY_AND_ASSIGN ( MozcResponseParser );
++};
++
++} // namespace fcitx
++
++} // namespace mozc
++
++#endif // MOZC_UNIX_FCITX_MOZC_RESPONSE_PARSER_H_
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_po_Messages.sh b/japanese/mozc-server/files/patch-unix_fcitx_po_Messages.sh
new file mode 100644
index 000000000000..5017b26848b4
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_po_Messages.sh
@@ -0,0 +1,36 @@
+--- unix/fcitx/po/Messages.sh.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/po/Messages.sh 2012-05-22 13:42:56.625829289 +0900
+@@ -0,0 +1,33 @@
++#!/bin/sh
++
++BASEDIR="../" # root of translatable sources
++PROJECT="fcitx-mozc" # project name
++BUGADDR="fcitx-dev@googlegroups.com" # MSGID-Bugs
++WDIR="`pwd`" # working dir
++
++echo "Preparing rc files"
++
++echo "Done preparing rc files"
++echo "Extracting messages"
++
++# see above on sorting
++
++find "${BASEDIR}" -name '*.cc' -o -name '*.h' -o -name '*.c' | sort > "${WDIR}/infiles.list"
++
++xgettext --from-code=UTF-8 -k_ -kN_ --msgid-bugs-address="${BUGADDR}" --files-from=infiles.list \
++ -D "${BASEDIR}" -D "${WDIR}" -o "${PROJECT}.pot" || \
++ { echo "error while calling xgettext. aborting."; exit 1; }
++echo "Done extracting messages"
++
++echo "Merging translations"
++catalogs=`find . -name '*.po'`
++for cat in $catalogs; do
++ echo "$cat"
++ msgmerge -o "$cat.new" "$cat" "${WDIR}/${PROJECT}.pot"
++ mv "$cat.new" "$cat"
++done
++
++echo "Done merging translations"
++echo "Cleaning up"
++rm "${WDIR}/infiles.list"
++echo "Done"
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_po_fcitx-mozc.pot b/japanese/mozc-server/files/patch-unix_fcitx_po_fcitx-mozc.pot
new file mode 100644
index 000000000000..7ee8bb642e91
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_po_fcitx-mozc.pot
@@ -0,0 +1,81 @@
+--- unix/fcitx/po/fcitx-mozc.pot.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/po/fcitx-mozc.pot 2012-05-22 13:42:56.626829067 +0900
+@@ -0,0 +1,78 @@
++# SOME DESCRIPTIVE TITLE.
++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
++# This file is distributed under the same license as the PACKAGE package.
++# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
++#
++#, fuzzy
++msgid ""
++msgstr ""
++"Project-Id-Version: PACKAGE VERSION\n"
++"Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n"
++"POT-Creation-Date: 2012-04-07 11:37+0800\n"
++"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
++"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
++"Language-Team: LANGUAGE <LL@li.org>\n"
++"Language: \n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=CHARSET\n"
++"Content-Transfer-Encoding: 8bit\n"
++
++#: ../fcitx_mozc.cc:53
++msgid "Direct"
++msgstr ""
++
++#: ../fcitx_mozc.cc:58
++msgid "Hiragana"
++msgstr ""
++
++#: ../fcitx_mozc.cc:63
++msgid "Full Katakana"
++msgstr ""
++
++#: ../fcitx_mozc.cc:68
++msgid "Half ASCII"
++msgstr ""
++
++#: ../fcitx_mozc.cc:73
++msgid "Full ASCII"
++msgstr ""
++
++#: ../fcitx_mozc.cc:78
++msgid "Half Katakana"
++msgstr ""
++
++#: ../fcitx_mozc.cc:379 ../fcitx_mozc.cc:380 ../fcitx_mozc.cc:458
++msgid "Composition Mode"
++msgstr ""
++
++#: ../fcitx_mozc.cc:390 ../fcitx_mozc.cc:391
++msgid "Tool"
++msgstr ""
++
++#: ../fcitx_mozc.cc:471
++msgid "Mozc Tool"
++msgstr ""
++
++#: ../fcitx_mozc.cc:477
++msgid "Configuration Tool"
++msgstr ""
++
++#: ../fcitx_mozc.cc:478
++msgid "Dictionary Tool"
++msgstr ""
++
++#: ../fcitx_mozc.cc:479
++msgid "Hand Writing"
++msgstr ""
++
++#: ../fcitx_mozc.cc:480
++msgid "Character Palette"
++msgstr ""
++
++#: ../fcitx_mozc.cc:481
++msgid "Add Word"
++msgstr ""
++
++#: ../fcitx_mozc.cc:482
++msgid "About Mozc"
++msgstr ""
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_po_ja.po b/japanese/mozc-server/files/patch-unix_fcitx_po_ja.po
new file mode 100644
index 000000000000..095124e0333a
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_po_ja.po
@@ -0,0 +1,84 @@
+--- unix/fcitx/po/ja.po.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/po/ja.po 2012-05-22 13:42:56.626829067 +0900
+@@ -0,0 +1,81 @@
++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
++# This file is distributed under the same license as the PACKAGE package.
++#
++# Translators:
++# <wengxt@gmail.com>, 2012.
++msgid ""
++msgstr ""
++"Project-Id-Version: fcitx\n"
++"Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n"
++"POT-Creation-Date: 2012-04-07 11:37+0800\n"
++"PO-Revision-Date: 2012-04-07 11:45+0800\n"
++"Last-Translator: Weng Xuetian <wengxt@gmail.com>\n"
++"Language-Team: Chinese Traditional <fcitx-dev@googlegroups.com>\n"
++"language/ja_JP/)\n"
++"Language: ja_JP\n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++"Plural-Forms: nplurals=1; plural=0\n"
++"X-Generator: Lokalize 1.4\n"
++
++#: ../fcitx_mozc.cc:53
++msgid "Direct"
++msgstr "直接入力"
++
++#: ../fcitx_mozc.cc:58
++msgid "Hiragana"
++msgstr "ひらがな"
++
++#: ../fcitx_mozc.cc:63
++msgid "Full Katakana"
++msgstr "全角カタカナ"
++
++#: ../fcitx_mozc.cc:68
++msgid "Half ASCII"
++msgstr "半角英数"
++
++#: ../fcitx_mozc.cc:73
++msgid "Full ASCII"
++msgstr "全角英数"
++
++#: ../fcitx_mozc.cc:78
++msgid "Half Katakana"
++msgstr "半角カタカナ"
++
++#: ../fcitx_mozc.cc:379 ../fcitx_mozc.cc:380 ../fcitx_mozc.cc:458
++msgid "Composition Mode"
++msgstr "変換モード"
++
++#: ../fcitx_mozc.cc:390 ../fcitx_mozc.cc:391
++msgid "Tool"
++msgstr "ツールを"
++
++#: ../fcitx_mozc.cc:471
++msgid "Mozc Tool"
++msgstr "Mozc ツールを"
++
++#: ../fcitx_mozc.cc:477
++msgid "Configuration Tool"
++msgstr "設定ツールを"
++
++#: ../fcitx_mozc.cc:478
++msgid "Dictionary Tool"
++msgstr "辞書ツールを"
++
++#: ../fcitx_mozc.cc:479
++msgid "Hand Writing"
++msgstr "手書き文字認識"
++
++#: ../fcitx_mozc.cc:480
++msgid "Character Palette"
++msgstr "文字パレット"
++
++#: ../fcitx_mozc.cc:481
++msgid "Add Word"
++msgstr "単語登録"
++
++#: ../fcitx_mozc.cc:482
++msgid "About Mozc"
++msgstr "Mozc について"
++
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_po_zh_CN.po b/japanese/mozc-server/files/patch-unix_fcitx_po_zh_CN.po
new file mode 100644
index 000000000000..34bc8cfe3642
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_po_zh_CN.po
@@ -0,0 +1,82 @@
+--- unix/fcitx/po/zh_CN.po.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/po/zh_CN.po 2012-05-22 13:42:56.627828914 +0900
+@@ -0,0 +1,79 @@
++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
++# This file is distributed under the same license as the PACKAGE package.
++#
++# Weng Xuetian <wengxt@gmail.com>, 2012.
++msgid ""
++msgstr ""
++"Project-Id-Version: \n"
++"Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n"
++"POT-Creation-Date: 2012-04-07 11:37+0800\n"
++"PO-Revision-Date: 2012-04-07 11:39+0800\n"
++"Last-Translator: Weng Xuetian <wengxt@gmail.com>\n"
++"Language-Team: Chinese Simplified <fcitx-dev@googlegroups.com>\n"
++"Language: zh_CN\n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++"Plural-Forms: nplurals=2; plural=n != 1;\n"
++"X-Generator: Lokalize 1.4\n"
++
++#: ../fcitx_mozc.cc:53
++msgid "Direct"
++msgstr "直接键盘输入"
++
++#: ../fcitx_mozc.cc:58
++msgid "Hiragana"
++msgstr "平假名"
++
++#: ../fcitx_mozc.cc:63
++msgid "Full Katakana"
++msgstr "全角片假名"
++
++#: ../fcitx_mozc.cc:68
++msgid "Half ASCII"
++msgstr "半角 ASCII"
++
++#: ../fcitx_mozc.cc:73
++msgid "Full ASCII"
++msgstr "全角 ASCII"
++
++#: ../fcitx_mozc.cc:78
++msgid "Half Katakana"
++msgstr "半角片假名"
++
++#: ../fcitx_mozc.cc:379 ../fcitx_mozc.cc:380 ../fcitx_mozc.cc:458
++msgid "Composition Mode"
++msgstr "编辑模式"
++
++#: ../fcitx_mozc.cc:390 ../fcitx_mozc.cc:391
++msgid "Tool"
++msgstr "工具"
++
++#: ../fcitx_mozc.cc:471
++msgid "Mozc Tool"
++msgstr "Mozc 工具"
++
++#: ../fcitx_mozc.cc:477
++msgid "Configuration Tool"
++msgstr "配置工具"
++
++#: ../fcitx_mozc.cc:478
++msgid "Dictionary Tool"
++msgstr "词典工具"
++
++#: ../fcitx_mozc.cc:479
++msgid "Hand Writing"
++msgstr "手写输入"
++
++#: ../fcitx_mozc.cc:480
++msgid "Character Palette"
++msgstr "字符映射表"
++
++#: ../fcitx_mozc.cc:481
++msgid "Add Word"
++msgstr "添加单词"
++
++#: ../fcitx_mozc.cc:482
++msgid "About Mozc"
++msgstr "关于 Mozc"
++
diff --git a/japanese/mozc-server/files/patch-unix_fcitx_po_zh_TW.po b/japanese/mozc-server/files/patch-unix_fcitx_po_zh_TW.po
new file mode 100644
index 000000000000..df33a8cce915
--- /dev/null
+++ b/japanese/mozc-server/files/patch-unix_fcitx_po_zh_TW.po
@@ -0,0 +1,85 @@
+--- unix/fcitx/po/zh_TW.po.orig 1970-01-01 09:00:00.000000000 +0900
++++ unix/fcitx/po/zh_TW.po 2012-05-22 13:42:56.627828914 +0900
+@@ -0,0 +1,82 @@
++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
++# This file is distributed under the same license as the PACKAGE package.
++#
++# Translators:
++# Alisha <alisha.4m@gmail.com>, 2012.
++# Weng Xuetian <wengxt@gmail.com>, 2012.
++msgid ""
++msgstr ""
++"Project-Id-Version: fcitx\n"
++"Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n"
++"POT-Creation-Date: 2012-04-07 11:37+0800\n"
++"PO-Revision-Date: 2012-04-07 11:46+0800\n"
++"Last-Translator: Weng Xuetian <wengxt@gmail.com>\n"
++"Language-Team: Chinese Traditional <fcitx-dev@googlegroups.com>\n"
++"language/zh_TW/)\n"
++"Language: zh_TW\n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=UTF-8\n"
++"Content-Transfer-Encoding: 8bit\n"
++"Plural-Forms: nplurals=1; plural=0\n"
++"X-Generator: Lokalize 1.4\n"
++
++#: ../fcitx_mozc.cc:53
++msgid "Direct"
++msgstr "直接鍵盤輸入"
++
++#: ../fcitx_mozc.cc:58
++msgid "Hiragana"
++msgstr "平假名"
++
++#: ../fcitx_mozc.cc:63
++msgid "Full Katakana"
++msgstr "全形片假名"
++
++#: ../fcitx_mozc.cc:68
++msgid "Half ASCII"
++msgstr "半形 ASCII"
++
++#: ../fcitx_mozc.cc:73
++msgid "Full ASCII"
++msgstr "全形 ASCII"
++
++#: ../fcitx_mozc.cc:78
++msgid "Half Katakana"
++msgstr "半形片假名"
++
++#: ../fcitx_mozc.cc:379 ../fcitx_mozc.cc:380 ../fcitx_mozc.cc:458
++msgid "Composition Mode"
++msgstr "編輯模式"
++
++#: ../fcitx_mozc.cc:390 ../fcitx_mozc.cc:391
++msgid "Tool"
++msgstr "工具"
++
++#: ../fcitx_mozc.cc:471
++msgid "Mozc Tool"
++msgstr "Mozc 工具"
++
++#: ../fcitx_mozc.cc:477
++msgid "Configuration Tool"
++msgstr "設定工具"
++
++#: ../fcitx_mozc.cc:478
++msgid "Dictionary Tool"
++msgstr "字典工具"
++
++#: ../fcitx_mozc.cc:479
++msgid "Hand Writing"
++msgstr "手寫輸入"
++
++#: ../fcitx_mozc.cc:480
++msgid "Character Palette"
++msgstr "字符映射表"
++
++#: ../fcitx_mozc.cc:481
++msgid "Add Word"
++msgstr "添加單詞"
++
++#: ../fcitx_mozc.cc:482
++msgid "About Mozc"
++msgstr "關於 Mozc"
++