1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * Copyright (C) Hiroyuki Ikezoe <poincare@ikezoe.net>
4 * Copyright (C) 2004 Takuro Ashie <ashie@homa.ne.jp>
5 * Copyright (C) 2012 CSSlayer
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 /*
23 * The original code is scim_uim_imengine.cpp in scim-uim-0.1.3.
24 * Copyright (C) 2004 James Su <suzhe@tsinghua.org.cn>
25 */
26
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <fcitx/instance.h>
32 #include <libintl.h>
33 #include <fcitx-config/xdg.h>
34 #include <fcitx/hook.h>
35 #include <fcitx-utils/log.h>
36 #include <errno.h>
37
38 #include "factory.h"
39 #include "imengine.h"
40
41 static void* FcitxAnthyCreate(FcitxInstance* instance);
42 static void FcitxAnthyDestory(void* arg);
43 static boolean FcitxAnthyInit(void* arg);
44 static INPUT_RETURN_VALUE FcitxAnthyDoInput(void* arg, FcitxKeySym sym, unsigned int state);
45 static INPUT_RETURN_VALUE FcitxAnthyDoReleaseInput(void* arg, FcitxKeySym sym, unsigned int state);
46 static void FcitxAnthyReloadConfig(void* arg);
47 static void FcitxAnthySave(void* arg);
48 static void FcitxAnthyReset(void* arg);
49 static void FcitxAnthyFocusIn(void* arg);
50 static void FcitxAnthyResetIM(void* arg);
51 static void FcitxAnthyOnClose(void* arg, FcitxIMCloseEventType event);
52 static const char * FcitxAnthyGetSubModeName(void* arg);
53
54 FCITX_DEFINE_PLUGIN(fcitx_anthy, ime2, FcitxIMClass2) = {
55 FcitxAnthyCreate,
56 FcitxAnthyDestory,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 NULL,
63 };
64
FcitxAnthyCreate(FcitxInstance * instance)65 void* FcitxAnthyCreate(FcitxInstance* instance)
66 {
67 if (anthy_init())
68 return NULL;
69
70 AnthyInstance* anthy = new AnthyInstance(instance);
71 if (!anthy->load_config()) {
72 anthy_quit();
73 delete anthy;
74 return NULL;
75 }
76
77 bindtextdomain("fcitx-anthy", LOCALEDIR);
78 bind_textdomain_codeset("fcitx-anthy", "UTF-8");
79
80 FcitxIMIFace iface;
81 memset(&iface, 0, sizeof(FcitxIMIFace));
82 iface.Init = FcitxAnthyInit;
83 iface.ResetIM = FcitxAnthyResetIM;
84 iface.DoInput = FcitxAnthyDoInput;
85 iface.DoReleaseInput = FcitxAnthyDoReleaseInput;
86 iface.ReloadConfig = FcitxAnthyReloadConfig;
87 iface.Save = FcitxAnthySave;
88 iface.OnClose = FcitxAnthyOnClose;
89 iface.GetSubModeName = FcitxAnthyGetSubModeName;
90
91 FcitxInstanceRegisterIMv2(
92 instance,
93 anthy,
94 "anthy",
95 _("Anthy"),
96 "anthy",
97 iface,
98 1,
99 "ja"
100 );
101
102 FcitxIMEventHook hk;
103 hk.arg = anthy;
104 hk.func = FcitxAnthyReset;
105 FcitxInstanceRegisterResetInputHook(instance, hk);
106 hk.func = FcitxAnthyFocusIn;
107 FcitxInstanceRegisterInputFocusHook(instance, hk);
108
109 return anthy;
110 }
111
FcitxAnthyDestory(void * arg)112 void FcitxAnthyDestory(void* arg)
113 {
114 AnthyInstance* anthy = (AnthyInstance*) arg;
115 delete anthy;
116
117 anthy_quit();
118 }
119
FcitxAnthyInit(void * arg)120 boolean FcitxAnthyInit(void* arg)
121 {
122 AnthyInstance* anthy = (AnthyInstance*) arg;
123 anthy->init();
124 anthy->update_ui();
125 return true;
126 }
127
FcitxAnthyResetIM(void * arg)128 void FcitxAnthyResetIM(void* arg)
129 {
130 AnthyInstance* anthy = (AnthyInstance*) arg;
131 anthy->reset_im();
132 anthy->update_ui();
133 }
134
FcitxAnthyReset(void * arg)135 void FcitxAnthyReset(void* arg)
136 {
137 AnthyInstance* anthy = (AnthyInstance*) arg;
138 anthy->reset();
139 anthy->update_ui();
140 }
141
FcitxAnthyShowIMInfo(void * arg)142 void FcitxAnthyShowIMInfo(void* arg)
143 {
144 AnthyInstance* anthy = (AnthyInstance*) arg;
145 static FcitxInputContext* ic;
146
147 // don't show the info again if ic is not changed, this is annoying
148 // when cursor jumps within same application.
149 FcitxInputContext* newic = FcitxInstanceGetCurrentIC(anthy->get_owner());
150 if (newic == ic) {
151 return;
152 }
153
154 ic = newic;
155 if (!ic) {
156 return;
157 }
158
159 FcitxIM* im = FcitxInstanceGetCurrentIM(anthy->get_owner());
160 if (im && strcmp(im->uniqueName, "anthy") == 0) {
161 FcitxInstanceShowCurrentIMInfo(anthy->get_owner());
162 }
163 }
164
FcitxAnthyFocusIn(void * arg)165 void FcitxAnthyFocusIn(void* arg)
166 {
167 AnthyInstance* anthy = (AnthyInstance*) arg;
168 FcitxInstance* instance = anthy->get_owner();
169
170 if (anthy->get_config()->m_show_input_mode_on_focus &&
171 !FcitxInstanceCheckTimeoutByFunc(instance, FcitxAnthyShowIMInfo)) {
172 FcitxInstanceAddTimeout(instance, 100, FcitxAnthyShowIMInfo, anthy);
173 }
174 }
175
FcitxAnthySave(void * arg)176 void FcitxAnthySave(void* arg)
177 {
178 }
179
FcitxAnthyDoInput(void * arg,FcitxKeySym sym,unsigned int state)180 INPUT_RETURN_VALUE FcitxAnthyDoInput(void* arg, FcitxKeySym sym, unsigned int state)
181 {
182 AnthyInstance* anthy = (AnthyInstance*) arg;
183 KeyEvent event;
184 FcitxInputState* input = FcitxInstanceGetInputState(anthy->get_owner());
185 event.sym = (FcitxKeySym) FcitxInputStateGetKeySym(input);
186 event.is_release = false;
187 event.keycode = FcitxInputStateGetKeyCode(input);
188 event.state = FcitxInputStateGetKeyState(input) & FcitxKeyState_SimpleMask;
189 bool result = anthy->process_key_event(event);
190 anthy->update_ui();
191 if (result)
192 return IRV_DO_NOTHING;
193 else
194 return IRV_TO_PROCESS;
195 }
196
FcitxAnthyDoReleaseInput(void * arg,FcitxKeySym sym,unsigned int state)197 INPUT_RETURN_VALUE FcitxAnthyDoReleaseInput(void* arg, FcitxKeySym sym, unsigned int state)
198 {
199 AnthyInstance* anthy = (AnthyInstance*) arg;
200 KeyEvent event;
201 FcitxInputState* input = FcitxInstanceGetInputState(anthy->get_owner());
202 event.sym = (FcitxKeySym) FcitxInputStateGetKeySym(input);
203 event.keycode = FcitxInputStateGetKeyCode(input);
204 event.is_release = true;
205 event.state = FcitxInputStateGetKeyState(input) & FcitxKeyState_SimpleMask;
206 bool result = anthy->process_key_event(event);
207 anthy->update_ui();
208 if (result)
209 return IRV_DO_NOTHING;
210 else
211 return IRV_TO_PROCESS;
212 }
213
FcitxAnthyReloadConfig(void * arg)214 void FcitxAnthyReloadConfig(void* arg)
215 {
216 AnthyInstance* anthy = (AnthyInstance*) arg;
217 anthy->load_config();
218 anthy->configure();
219 anthy->update_ui();
220 }
221
FcitxAnthyOnClose(void * arg,FcitxIMCloseEventType event)222 void FcitxAnthyOnClose(void* arg, FcitxIMCloseEventType event)
223 {
224 AnthyInstance* anthy = (AnthyInstance*) arg;
225 anthy->auto_commit(event);
226 }
227
FcitxAnthyGetSubModeName(void * arg)228 const char * FcitxAnthyGetSubModeName(void *arg)
229 {
230 AnthyInstance* anthy = (AnthyInstance*) arg;
231 return anthy->get_input_mode_name();
232 }
233
234
235 void
SaveAnthyConfig(AnthyInstance * anthy)236 SaveAnthyConfig(AnthyInstance* anthy)
237 {
238 anthy->save_config();
239 }
240
241 boolean
LoadAnthyConfig(AnthyInstance * anthy)242 LoadAnthyConfig(AnthyInstance* anthy)
243 {
244 anthy->load_config();
245 return true;
246 }
247
ConfigAnthy(AnthyInstance * anthy)248 void ConfigAnthy(AnthyInstance* anthy) {
249 anthy->configure();
250 anthy->update_ui();
251 }
252