1 #include "gcin.h"
2 #include "pho.h"
3 #include "gst.h"
4 #include "im-client/gcin-im-client-attr.h"
5 #include "win1.h"
6 #include "gcin-module.h"
7 #include "gcin-module-cb.h"
8 #include <anthy/anthy.h>
9 
10 #if 0
11 #if DEBUG
12 #define dbg(...) gmf.mf___gcin_dbg_(__VA_ARGS__)
13 #else
14 #define dbg(...) do {} while (0)
15 #endif
16 #endif
17 
18 static anthy_context_t ac;
19 static gint64 key_press_time;
20 static GtkWidget *event_box_anthy;
21 
22 static GCIN_module_main_functions gmf;
23 
24 void module_show_win();
25 void module_hide_win();
26 void module_change_font_size();
27 
28 enum {
29   STATE_hira=0,
30   STATE_kata=1,
31   STATE_half_kata=2
32 };
33 
34 static int state_hira_kata=STATE_hira;
35 
36 struct {
37   char *en;
38   char *hira;
39   char *kata;
40   char *half_kata;
41 } anthy_romaji_map[] = {
42 {"xtu",	"っ",  "ッ", "ッ"},
43 {"xtsu",	"っ",  "ッ", "ッ"},
44 {"ltu",	"っ",  "ッ", "ッ"},
45 {"ltsu",	"っ",  "ッ", "ッ"},
46 
47 {"-",	"ー", "ー", "ー"},
48 {"a",	"あ", "ア", "ア"},
49 {"i",	"い", "イ", "イ"},
50 {"u",	"う", "ウ", "ウ"},
51 {"e",	"え", "エ", "エ"},
52 {"o",	"お", "オ", "オ"},
53 
54 {"xa",	"ぁ", "ァ", "ァ"},
55 {"xi",	"ぃ", "ィ", "ィ"},
56 {"xu",	"ぅ", "ゥ", "ゥ"},
57 {"xe",	"ぇ", "ェ", "ェ"},
58 {"xo",	"ぉ", "ォ", "ォ"},
59 
60 {"la",	"ぁ", "ァ", "ァ"},
61 {"li",	"ぃ", "ィ", "ィ"},
62 {"lu",	"ぅ", "ゥ", "ゥ"},
63 {"le",	"ぇ", "ェ", "ェ"},
64 {"lo",	"ぉ", "ォ", "ォ"},
65 
66 {"wi",	"うぃ", "ウィ", "ウィ"},
67 {"we",	"うぇ", "ウェ", "ウェ"},
68 {"wha",	"うぁ", "ウァ", "ウァ"},
69 {"whi",	"うぃ", "ウィ", "ウィ"},
70 {"whe",	"うぇ", "ウェ", "ウェ"},
71 {"who",	"うぉ", "ウォ", "ウォ"},
72 
73 {"va",	"う゛ぁ", "ヴァ", "ヴァ"},
74 {"vi",	"う゛ぃ", "ヴィ", "ヴィ"},
75 {"vu",	"う゛", "ヴ", "ヴ"},
76 {"ve",	"う゛ぇ", "ヴェ", "ヴェ"},
77 {"vo",	"う゛ぉ", "ヴォ", "ヴォ"},
78 
79 {"ka",	"か", "カ", "カ"},
80 {"ki",	"き", "キ", "キ"},
81 {"ku",	"く", "ク", "ク"},
82 {"ke",	"け", "ケ", "ケ"},
83 {"ko",	"こ", "コ", "コ"},
84 
85 {"ga",	"が", "ガ", "ガ"},
86 {"gi",	"ぎ", "ギ", "ギ"},
87 {"gu",	"ぐ", "グ", "グ"},
88 {"ge",	"げ", "ゲ", "ゲ"},
89 {"go",	"ご", "ゴ", "ゴ"},
90 
91 {"kya",	"きゃ", "キャ", "キャ"},
92 {"kyi",	"きぃ", "キィ", "キィ"},
93 {"kyu",	"きゅ", "キュ", "キュ"},
94 {"kye",	"きぇ", "キェ", "キェ"},
95 {"kyo",	"きょ", "キョ", "キョ"},
96 {"gya",	"ぎゃ", "ギャ", "ギャ"},
97 {"gyi",	"ぎぃ", "ギィ", "ギィ"},
98 {"gyu",	"ぎゅ", "ギュ", "ギュ"},
99 {"gye",	"ぎぇ", "ギェ", "ギェ"},
100 {"gyo",	"ぎょ", "ギョ", "ギョ"},
101 
102 {"sa",	"さ", "サ", "サ"},
103 {"si",	"し", "シ", "シ"},
104 {"su",	"す", "ス", "ス"},
105 {"se",	"せ", "セ", "セ"},
106 {"so",	"そ", "ソ", "ソ"},
107 
108 {"za",	"ざ", "ザ", "ザ"},
109 {"zi",	"じ", "ジ", "ジ"},
110 {"zu",	"ず", "ズ", "ズ"},
111 {"ze",	"ぜ", "ゼ", "ゼ"},
112 {"zo",	"ぞ", "ゾ", "ゾ"},
113 
114 {"sya",	"しゃ", "シャ", "シャ"},
115 {"syi",	"しぃ", "シィ", "シィ"},
116 {"syu",	"しゅ", "シュ", "シュ"},
117 {"sye",	"しぇ", "シェ", "シェ"},
118 {"syo",	"しょ", "ショ", "ショ"},
119 {"sha",	"しゃ", "シャ", "シャ"},
120 {"shi",	"し", "シ", "シ"},
121 {"shu",	"しゅ", "シュ", "シュ"},
122 {"she",	"しぇ", "シェ", "シェ"},
123 {"sho",	"しょ", "ショ", "ショ"},
124 {"zya",	"じゃ", "ジャ", "ジャ"},
125 {"zyi",	"じぃ", "ジィ", "ジィ"},
126 {"zyu",	"じゅ", "ジュ", "ジュ"},
127 {"zye",	"じぇ", "ジェ", "ジェ"},
128 {"zyo",	"じょ", "ジョ", "ジョ"},
129 {"ja",	"じゃ", "ジャ", "ジャ"},
130 {"jya", "じゃ", "ジャ", "ジャ"},
131 {"ji",	"じ", "ジ", "ジ"},
132 {"jyi",	"じぃ", "ジィ", "ジィ"},
133 {"ju",	"じゅ", "ジュ", "ジュ"},
134 {"jyu",	"じゅ", "ジュ", "ジュ"},
135 {"je",	"じぇ", "ジェ", "ジェ"},
136 {"jye",	"じぇ", "ジェ", "ジェ"},
137 {"jo",	"じょ", "ジョ", "ジョ"},
138 {"jyo",	"じょ", "ジョ", "ジョ"},
139 {"ta",	"た", "タ", "タ"},
140 {"ti",	"ち", "チ", "チ"},
141 {"tu",	"つ", "ツ", "ツ"},
142 {"tsu",	"つ", "ツ", "ツ"},
143 {"te",	"て", "テ", "テ"},
144 {"to",	"と", "ト", "ト"},
145 
146 {"da",	"だ", "ダ", "ダ"},
147 {"di",	"ぢ", "ヂ", "ヂ"},
148 {"du",	"づ", "ヅ", "ヅ"},
149 {"de",	"で", "デ", "デ"},
150 {"do",	"ど", "ド", "ド"},
151 
152 
153 {"tya",	"ちゃ", "チャ", "チャ"},
154 {"tyi",	"ちぃ", "チィ", "チィ"},
155 {"tyu",	"ちゅ", "チュ", "チュ"},
156 {"tye",	"ちぇ", "チェ", "チェ"},
157 {"tyo",	"ちょ", "チョ", "チョ"},
158 
159 {"cha",	"ちゃ", "チャ", "チャ"},
160 {"chi",	"ち", "チ", "チ"},
161 {"chu",	"ちゅ", "チュ", "チュ"},
162 {"che",	"ちぇ", "チェ", "チェ"},
163 {"cho",	"ちょ", "チョ", "チョ"},
164 
165 {"dya",	"ぢゃ", "ヂャ", "ヂャ"},
166 {"dyi",	"ぢぃ", "ヂィ", "ヂィ"},
167 {"dyu",	"ぢゅ", "ヂュ", "ヂュ"},
168 {"dye",	"ぢぇ", "ヂェ", "ヂェ"},
169 {"dyo",	"ぢょ", "ヂョ", "ヂョ"},
170 
171 {"tha",	"てゃ", "テャ", "テャ"},
172 {"thi",	"てぃ", "ティ", "ティ"},
173 {"thu",	"てゅ", "テュ", "テュ"},
174 {"the",	"てぇ", "テェ", "テェ"},
175 {"tho",	"てょ", "テョ", "テョ"},
176 
177 {"dha",	"でゃ", "デャ", "デャ"},
178 {"dhi",	"でぃ", "ディ", "ディ"},
179 {"dhu",	"でゅ", "デュ", "デュ"},
180 {"dhe",	"でぇ", "デェ", "デェ"},
181 {"dho",	"でょ", "デョ", "デョ"},
182 
183 {"na",	"な", "ナ", "ナ"},
184 {"ni",	"に", "ニ", "ニ"},
185 {"nu",	"ぬ", "ヌ", "ヌ"},
186 {"ne",	"ね", "ネ", "ネ"},
187 {"no",	"の", "ノ", "ノ"},
188 {"nya",	"にゃ", "ニャ", "ニャ"},
189 {"nyi",	"にぃ", "ニィ", "ニィ"},
190 {"nyu",	"にゅ", "ニュ", "ニュ"},
191 {"nye",	"にぇ", "ニェ", "ニェ"},
192 {"nyo",	"にょ", "ニョ", "ニョ"},
193 
194 {"ha",	"は", "ハ", "ハ"},
195 {"hi",	"ひ", "ヒ", "ヒ"},
196 {"hu",	"ふ", "フ", "フ"},
197 {"he",	"へ", "ヘ", "ヘ"},
198 {"ho",	"ほ", "ホ", "ホ"},
199 
200 {"ba",	"ば", "バ", "バ"},
201 {"bi",	"び", "ビ", "ビ"},
202 {"bu",	"ぶ", "ブ", "ブ"},
203 {"be",	"べ", "ベ", "ベ"},
204 {"bo",	"ぼ", "ボ", "ボ"},
205 
206 {"pa",	"ぱ", "パ", "パ"},
207 {"pi",	"ぴ", "ピ", "ピ"},
208 {"pu",	"ぷ", "プ", "プ"},
209 {"pe",	"ぺ", "ペ", "ペ"},
210 {"po",	"ぽ", "ポ", "ポ"},
211 
212 {"hya",	"ひゃ", "ヒャ", "ヒャ"},
213 {"hyi",	"ひぃ", "ヒィ", "ヒィ"},
214 {"hyu",	"ひゅ", "ヒュ", "ヒュ"},
215 {"hye",	"ひぇ", "ヒェ", "ヒェ"},
216 {"hyo",	"ひょ", "ヒョ", "ヒョ"},
217 {"bya",	"びゃ", "ビャ", "ビャ"},
218 {"byi",	"びぃ", "ビィ", "ビィ"},
219 {"byu",	"びゅ", "ビュ", "ビュ"},
220 {"bye",	"びぇ", "ビェ", "ビェ"},
221 {"byo",	"びょ", "ビョ", "ビョ"},
222 {"pya",	"ぴゃ", "ピャ", "ピャ"},
223 {"pyi",	"ぴぃ", "ピィ", "ピィ"},
224 {"pyu",	"ぴゅ", "ピュ", "ピュ"},
225 {"pye",	"ぴぇ", "ピェ", "ピェ"},
226 {"pyo",	"ぴょ", "ピョ", "ピョ"},
227 
228 {"fa",	"ふぁ", "ファ", "ファ"},
229 {"fi",	"ふぃ", "フィ", "フィ"},
230 {"fu",	"ふ", "フ", "フ"},
231 {"fe",	"ふぇ", "フェ", "フェ"},
232 {"fo",	"ふぉ", "フォ", "フォ"},
233 
234 {"ma",	"ま", "マ", "マ"},
235 {"mi",	"み", "ミ", "ミ"},
236 {"mu",	"む", "ム", "ム"},
237 {"me",	"め", "メ", "メ"},
238 {"mo",	"も", "モ", "モ"},
239 
240 {"mya",	"みゃ", "ミャ", "ミャ"},
241 {"myi",	"みぃ", "ミィ", "ミィ"},
242 {"myu",	"みゅ", "ミュ", "ミュ"},
243 {"mye",	"みぇ", "ミェ", "ミェ"},
244 {"myo",	"みょ", "ミョ", "ミョ"},
245 {"lya",	"ゃ", "ャ", "ャ"},
246 {"xya",	"ゃ", "ャ", "ャ"},
247 {"ya",	"や", "ヤ", "ヤ"},
248 {"lyu",	"ゅ", "ュ", "ュ"},
249 {"xyu",	"ゅ", "ュ", "ュ"},
250 {"yu",	"ゆ", "ユ", "ユ"},
251 {"lyo",	"ょ", "ョ", "ョ"},
252 {"xyo",	"ょ", "ョ", "ョ"},
253 {"yo",	"よ", "ヨ", "ヨ"},
254 
255 {"ra",	"ら", "ラ", "ラ"},
256 {"ri",	"り", "リ", "リ"},
257 {"ru",	"る", "ル", "ル"},
258 {"re",	"れ", "レ", "レ"},
259 {"ro",	"ろ", "ロ", "ロ"},
260 
261 {"rya",	"りゃ", "リャ", "リャ"},
262 {"ryi",	"りぃ", "リィ", "リィ"},
263 {"ryu",	"りゅ", "リュ", "リュ"},
264 {"rye",	"りぇ", "リェ", "リェ"},
265 {"ryo",	"りょ", "リョ", "リョ"},
266 {"xwa",	"ゎ", "ヮ", "ワ"},
267 {"wa",	"わ", "ワ", "ワ"},
268 {"wo",	"を", "ヲ", "ヲ"},
269 {"n'",	"ん", "ン", "ン"},
270 {"nn",	"ん", "ン", "ン"},
271 {"n",	"ん", "ン", "ン"},
272 {"m",	"ん", "ン", "ン"}, // tombo
273 {"wyi",	"ゐ", "ヰ", "ィ"},
274 {"wye",	"ゑ", "ヱ", "ェ"},
275 {"cya",	"ちゃ", "チャ", "チャ"},
276 {"cye",	"ちぇ", "チェ", "チェ"},
277 {"cyi",	"ちぃ", "チィ", "チィ"},
278 {"cyo",	"ちょ", "チョ", "チョ"},
279 {"cyu",	"ちゅ", "チュ", "チュ"},
280 {"fya",	"ふゃ", "フャ", "フャ"},
281 {"fye",	"ふぇ", "フェ", "フェ"},
282 {"fyi",	"ふぃ", "フィ", "フィ"},
283 {"fyo",	"ふょ", "フョ", "フョ"},
284 {"fyu",	"ふゅ", "フュ", "フュ"},
285 {"lye",	"ぇ", "ェ", "ェ"},
286 {"lyi",	"ぃ", "ィ", "ィ"},
287 {"qa",	"くぁ", "クァ", "クァ"},
288 {"qe",	"くぇ", "クェ", "クェ"},
289 {"qi",	"くぃ", "クィ", "クィ"},
290 {"qo",	"くぉ", "クォ", "クォ"},
291 {"qu",	"く", "ク", "ク"},
292 {"tsa",	"つぁ", "ツァ", "ツァ"},
293 {"tse",	"つぇ", "ツェ", "ツェ"},
294 {"tsi",	"つぃ", "ツィ", "ツィ"},
295 {"tso",	"つぉ", "ツォ", "ツォ"},
296 {"vya",	"う゛ゃ", "ヴャ", "ヴャ"},
297 {"vyo",	"う゛ょ", "ヴョ", "ヴョ"},
298 {"vyu",	"う゛ゅ", "ヴュ", "ヴュ"},
299 {"whu",	"う", "ウ", "ウ"},
300 {"wu",	"う", "ウ", "ウ"},
301 {"xca",	"ヵ", "ヵ", "カ"},
302 {"xka",	"ヵ", "ヵ", "カ"},
303 {"xke",	"ヶ", "ヶ", "ケ"},
304 {"xye",	"ぇ", "ェ", "ェ"},
305 {"xyi",	"ぃ", "ィ", "ィ"},
306 {"ye",	"いぇ", "イェ", "イェ"},
307 {"z,",	"‥", "‥", ""},
308 {"z-",	"〜", "〜", ""},
309 {"z.",	"…", "…", ""},
310 {"z/",	"・", "・", "・"},
311 {"z[",	"『", "『", ""},
312 {"z]",	"』", "』", ""},
313 {"zh",	"←", "←", ""},
314 {"zj",	"↓", "↓", ""},
315 {"zk",	"↑", "↑", ""},
316 {"zl",	"→", "→", ""},
317 {"xwi",	"ゐ", "ヰ", "ィ"},
318 {"xwe",	"ゑ", "ヱ", "ェ"},
319 {"bwa",	"ぶぁ", "ブァ", "ブァ"},
320 {"bwi",	"ぶぃ", "ブィ", "ブィ"},
321 {"bwu",	"ぶぅ", "ブゥ", "ブゥ"},
322 {"bwe",	"ぶぇ", "ブェ", "ブェ"},
323 {"bwo",	"ぶぉ", "ブォ", "ブォ"},
324 {"d'i",	"でぃ", "ディ", "ディ"},
325 {"d'yu",	"でゅ", "デュ", "デュ"},
326 {"d'u",	"どぅ", "ドゥ", "ドゥ"},
327 {"dsu",	"づ", "ヅ", "ヅ"},
328 {"dwa",	"どぁ", "ドァ", "ドァ"},
329 {"dwi",	"どぃ", "ドィ", "ドィ"},
330 {"dwu",	"どぅ", "ドゥ", "ドゥ"},
331 {"dwe",	"どぇ", "ドェ", "ドェ"},
332 {"dwo",	"どぉ", "ドォ", "ドォ"},
333 {"fwa",	"ふぁ", "ファ", "ファ"},
334 {"fwi",	"ふぃ", "フィ", "フィ"},
335 {"fwu",	"ふぅ", "フゥ", "フゥ"},
336 {"fwe",	"ふぇ", "フェ", "フェ"},
337 {"fwo",	"ふぉ", "フォ", "フォ"},
338 {"gwa",	"ぐぁ", "グァ", "グァ"},
339 {"gwi",	"ぐぃ", "グィ", "グィ"},
340 {"gwu",	"ぐぅ", "グゥ", "グゥ"},
341 {"gwe",	"ぐぇ", "グェ", "グェ"},
342 {"gwo",	"ぐぉ", "グォ", "グォ"},
343 {"hwa",	"ふぁ", "ファ", "ファ"},
344 {"hwi",	"ふぃ", "フィ", "フィ"},
345 {"hwe",	"ふぇ", "フェ", "フェ"},
346 {"hwo",	"ふぉ", "フォ", "フォ"},
347 {"kwa",	"くぁ", "クァ", "クァ"},
348 {"kwi",	"くぃ", "クィ", "クィ"},
349 {"kwu",	"くぅ", "クゥ", "クゥ"},
350 {"kwe",	"くぇ", "クェ", "クェ"},
351 {"kwo",	"くぉ", "クォ", "クォ"},
352 {"mwa",	"むぁ", "ムァ", "ムァ"},
353 {"mwi",	"むぃ", "ムィ", "ムィ"},
354 {"mwu",	"むぅ", "ムゥ", "ムゥ"},
355 {"mwe",	"むぇ", "ムェ", "ムェ"},
356 {"mwo",	"むぉ", "ムォ", "ムォ"},
357 {"pwa",	"ぷぁ", "プァ", "プァ"},
358 {"pwi",	"ぷぃ", "プィ", "プィ"},
359 {"pwu",	"ぷぅ", "プゥ", "プゥ"},
360 {"pwe",	"ぷぇ", "プェ", "プェ"},
361 {"pwo",	"ぷぉ", "プォ", "プォ"},
362 {"qwa",	"くぁ", "クァ", "クァ"},
363 {"qwi",	"くぃ", "クィ", "クィ"},
364 {"qwu",	"くぅ", "クゥ", "クゥ"},
365 {"qwe",	"くぇ", "クェ", "クェ"},
366 {"qwo",	"くぉ", "クォ", "クォ"},
367 {"qya",	"くゃ", "クャ", "クャ"},
368 {"qyi",	"くぃ", "クィ", "クィ"},
369 {"qyu",	"くゅ", "クュ", "クュ"},
370 {"qye",	"くぇ", "クェ", "クェ"},
371 {"qyo",	"くょ", "クョ", "クョ"},
372 {"rwa",	"るぁ", "ルァ", "ルァ"},
373 {"rwi",	"るぃ", "ルィ", "ルィ"},
374 {"rwu",	"るぅ", "ルゥ", "ルゥ"},
375 {"rwe",	"るぇ", "ルェ", "ルェ"},
376 {"rwo",	"るぉ", "ルォ", "ルォ"},
377 {"swa",	"すぁ", "スァ", "スァ"},
378 {"swi",	"すぃ", "スィ", "スィ"},
379 {"swu",	"すぅ", "スゥ", "スゥ"},
380 {"swe",	"すぇ", "スェ", "スェ"},
381 {"swo",	"すぉ", "スォ", "スォ"},
382 {"t'i",	"てぃ", "ティ", "ティ"},
383 {"t'yu",	"てゅ", "テュ", "テュ"},
384 {"t'u",	"とぅ", "トゥ", "トゥ"},
385 {"twa",	"とぁ", "トァ", "トァ"},
386 {"twi",	"とぃ", "トィ", "トィ"},
387 {"twu",	"とぅ", "トゥ", "トゥ"},
388 {"twe",	"とぇ", "トェ", "トェ"},
389 {"two",	"とぉ", "トォ", "トォ"},
390 {"ywa",	"ゆぁ", "ユァ", "ユァ"},
391 {"ywi",	"ゆぃ", "ユィ", "ユィ"},
392 {"ywu",	"ゆぅ", "ユゥ", "ユゥ"},
393 {"ywe",	"ゆぇ", "ユェ", "ユェ"},
394 {"ywo",	"ゆぉ", "ユォ", "ユォ"},
395 {"zwa",	"ずぁ", "ズァ", "ズァ"},
396 {"zwi",	"ずぃ", "ズィ", "ズィ"},
397 {"zwu",	"ずぅ", "ズゥ", "ズゥ"},
398 {"zwe",	"ずぇ", "ズェ", "ズェ"},
399 {"zwo",	"ずぉ", "ズォ", "ズォ"},
400 {",",	"、", "、", "、"},
401 {".",	"。", "。", "。"},
402 {"[",	"「", "「", "「"},
403 {"]",	"」", "」", "」"},
404 {"/",	"/", "/", "/"},
405 {"\\",	"\", "\", "\\"},
406 {"=",	"=", "=", "="},
407 {"+",	"+", "+", "+"},
408 {"_",	"_", "_", "_"},
409 {"¥",	"¥", "¥", "¥"},
410 {"~",	"〜", "〜", "~"},
411 {"!",	"!", "!", "!"},
412 {"@",	"@", "@", "@"},
413 {"#",	"#", "#", "#"},
414 {"$",	"$", "$", "$"},
415 {"%",	"%", "%", "%"},
416 {"^",	"^", "^", "^"},
417 {"&",	"&", "&", "&"},
418 {"*",	"*", "*", "*"},
419 {"(",	"(", "(", "("},
420 {")",	")", ")", ")"},
421 {"<",	"<", "<", "<"},
422 {">",	">", ">", ">"},
423 {"{",	"{", "{", "{"},
424 {"}",	"}", "}", "}"},
425 {"|",	"|", "|", "|"},
426 {"'",	"’", "’", "'"},
427 {"\"",	"”", "”", "\""},
428 {"`",	"‘", "‘", "`"},
429 {"?",	"?", "?", "?"},
430 {":",	":", ":", ":"},
431 {";",	";", ";", ";"},
432 {"0",	"0", "0", "0"},
433 {"1",	"1", "1", "1"},
434 {"2",	"2", "2", "2"},
435 {"3",	"3", "3", "3"},
436 {"4",	"4", "4", "4"},
437 {"5",	"5", "5", "5"},
438 {"6",	"6", "6", "6"},
439 {"7",	"7", "7", "7"},
440 {"8",	"8", "8", "8"},
441 {"9",	"9", "9", "9"},
442 };
443 
idx_hira_kata(int idx,gboolean always_hira)444 static char *idx_hira_kata(int idx, gboolean always_hira)
445 {
446   char *s=NULL;
447 
448   if (!always_hira) {
449     if (state_hira_kata==STATE_kata)
450       s = anthy_romaji_map[idx].kata;
451     else
452     if (state_hira_kata==STATE_half_kata)
453       s = anthy_romaji_map[idx].half_kata;
454   }
455 
456   if (!s)
457     s = anthy_romaji_map[idx].hira;
458 
459   return s;
460 }
461 
462 
463 static short int anthy_romaji_mapN = sizeof(anthy_romaji_map)/sizeof(anthy_romaji_map[0]);
464 
is_legal_char(int k)465 static int is_legal_char(int k)
466 {
467   int i;
468 
469   if (k==' ')
470     return 1;
471   for(i=0; i < anthy_romaji_mapN; i++)
472     if (strchr(anthy_romaji_map[i].en, k))
473       return 1;
474   return 0;
475 }
476 
477 #define MAX_KEYS 32
478 
479 typedef u_short jp_t;
480 
481 static char keys[MAX_KEYS];
482 static short int keysN;
483 static jp_t *jp;
484 static short int jpN=0;
485 static short pageidx;
486 
487 typedef struct {
488   GtkWidget *label;
489   u_char selidx, selN;
490   u_char ofs, len;
491 } SEG;
492 static SEG *seg;
493 static short segN;
494 #define MAX_SEG_N 100
495 
496 typedef struct {
497   u_char ofs, len;
498   char *sel_str;
499 } SEL_SEG;
500 static SEL_SEG *sel_seg;
501 static int sel_segN;
502 
503 static short cursor;
504 enum {
505   STATE_ROMANJI=1,
506   STATE_CONVERT=2,
507   STATE_SELECT=4,
508 };
509 static char state = STATE_ROMANJI;
510 
511 static GtkWidget *win_anthy;
512 
is_empty()513 static gboolean is_empty()
514 {
515   return !jpN && !segN && !keysN;
516 }
517 
auto_hide()518 static void auto_hide()
519 {
520 //  puts("auto hide");
521   if (is_empty() && *gmf.mf_gcin_pop_up_win) {
522 //    puts("empty");
523     module_hide_win();
524   }
525 }
526 
insert_jp(jp_t rom_idx)527 static void insert_jp(jp_t rom_idx)
528 {
529   jp = trealloc(jp, jp_t, jpN);
530   if (cursor < jpN)
531     memmove(jp+cursor+1, jp+cursor, sizeof(jp[0]) * (jpN - cursor));
532 
533   jp[cursor]=rom_idx;
534   cursor++;
535   jpN++;
536 }
537 
538 #define SEND_PRE_INI 65535
539 
parse_key()540 static void parse_key()
541 {
542   int i;
543   int preN=0, eqN=0, sendpreN=0;
544   u_short eq, sendpre_i = SEND_PRE_INI;
545   static char ch2[]="kstzdhbrpfgvcjmwy";
546 
547   if (keysN==2 && keys[0]==keys[1] && strchr(ch2, keys[0])) {
548     insert_jp(0);
549     keys[1]=0;
550     keysN=1;
551     return;
552   }
553 
554   for(i=0; i < anthy_romaji_mapN; i++) {
555     char *en = anthy_romaji_map[i].en;
556     if (!strncmp(keys, en, keysN))
557       preN++;
558 
559     if (!strncmp(keys, en, strlen(en))) {
560       sendpre_i = i;
561       sendpreN++;
562     }
563 
564     if (!strcmp(keys, en)) {
565       eq = i;
566       eqN++;
567     }
568   }
569 
570   if (preN > 1)
571     return;
572 
573   if (eqN) {
574     if (eqN > 1) {
575       puts("bug");
576       exit(1);
577     }
578 
579     insert_jp(eq);
580 
581     keys[0]=0;
582     keysN=0;
583     return;
584   }
585 
586   if (sendpre_i != SEND_PRE_INI) {
587     char *en = anthy_romaji_map[sendpre_i].en;
588     int len =strlen(en);
589     int nlen = keysN - len;
590     memmove(keys, keys+len, sizeof(keys[0])*nlen);
591     keys[nlen] = 0;
592     keysN = nlen;
593 
594     insert_jp(sendpre_i);
595   }
596 }
597 
get_sel_seg_with_ofs(int ofs)598 static int get_sel_seg_with_ofs(int ofs)
599 {
600     int idx;
601     for(idx=0;idx<sel_segN;idx++)
602 	  if (sel_seg[idx].ofs == ofs)
603          break;
604     return idx;
605 }
606 
607 
clear_seg_label()608 static void clear_seg_label()
609 {
610 //  dbg("clear_seg_label\n");
611   int i;
612   for(i=0; i < MAX_SEG_N; i++) {
613     gtk_label_set_text(GTK_LABEL(seg[i].label), NULL);
614     seg[i].selidx = 0;
615   }
616 }
617 
cursor_markup(int idx,char * s)618 static void cursor_markup(int idx, char *s)
619 {
620   char cur[256];
621   GtkWidget *lab = seg[idx].label;
622   sprintf(cur, "<span background=\"%s\">%s</span>", *gmf.mf_tsin_cursor_color, s);
623   gtk_label_set_markup(GTK_LABEL(lab), cur);
624 }
625 
minimize_win_anthy()626 static void minimize_win_anthy()
627 {
628   if (!win_anthy)
629     return;
630   gtk_window_resize(GTK_WINDOW(win_anthy), 32, 12);
631 }
632 
disp_keys(int idx)633 static void disp_keys(int idx)
634 {
635   int i;
636   char tt[2];
637   tt[1]=0;
638   for(i=0; i < keysN; i++) {
639     tt[0]=keys[i];
640     gtk_label_set_text(GTK_LABEL(seg[idx+i].label), tt);
641   }
642 }
643 
644 
disp_input()645 static void disp_input()
646 {
647   int i;
648 
649   if (gmf.mf_gcin_edit_display_ap_only())
650     return;
651 
652   clear_seg_label();
653 
654   int idx;
655   for(idx=i=0; i < jpN; i++) {
656     if (i==cursor) {
657       disp_keys(idx);
658       idx+=keysN;
659       cursor_markup(idx++, idx_hira_kata(jp[i], FALSE));
660     }
661     else
662       gtk_label_set_text(GTK_LABEL(seg[idx++].label), idx_hira_kata(jp[i], FALSE));
663   }
664 
665   if (cursor==jpN) {
666     disp_keys(idx);
667     idx+=keysN;
668     cursor_markup(idx, " ");
669   }
670 
671   minimize_win_anthy();
672 }
673 
disp_convert()674 static void disp_convert()
675 {
676   int i;
677 
678   dbg("disp_convert cursor %d\n", cursor);
679   for(i=0; i < segN; i++) {
680     char tt[256];
681     strcpy(tt, gtk_label_get_text(GTK_LABEL(seg[i].label)));
682 
683     if (i==cursor && segN > 1)
684       cursor_markup(i, tt);
685     else
686       gtk_label_set_text(GTK_LABEL(seg[i].label), tt);
687   }
688 }
689 
delete_jpstr(int idx)690 static void delete_jpstr(int idx)
691 {
692   if (idx==jpN)
693     return;
694   memmove(jp+idx, jp+idx+1, sizeof(jp[0])*(jpN-1-idx));
695   jpN--;
696 }
697 
clear_all()698 static void clear_all()
699 {
700   clear_seg_label();
701   jpN=0;
702   keys[0]=0;
703   keysN = 0;
704   segN = 0;
705   cursor=0;
706   gmf.mf_tss->sel_pho = FALSE;
707   state_hira_kata = STATE_hira;
708   auto_hide();
709   sel_segN = 0;
710 }
711 
712 
send_seg()713 static void send_seg()
714 {
715   char out[512];
716   int i;
717   for(i=0, out[0]=0; i < segN; i++) {
718     strcat(out, gtk_label_get_text(GTK_LABEL(seg[i].label)));
719     anthy_commit_segment(ac, i, seg[i].selidx);
720     seg[i].selidx = 0;
721   }
722 
723 //  printf("sent convert '%s'\n", out);
724   gmf.mf_send_text(out);
725   clear_all();
726 }
727 
merge_jp(char out[],gboolean always_hira)728 static void merge_jp(char out[], gboolean always_hira)
729 {
730   int i;
731   for(i=0, out[0]=0; i < jpN; i++)
732     strcat(out, idx_hira_kata(jp[i], always_hira));
733 }
734 
735 
send_jp()736 static gboolean send_jp()
737 {
738   char out[512];
739   merge_jp(out, FALSE);
740 
741   if (!out[0])
742     return FALSE;
743 
744   clear_seg_label();
745   jpN=0;
746   keysN = 0;
747 
748 //  printf("sent romanji '%s'\n", out);
749   gmf.mf_send_text(out);
750   segN = 0;
751   return TRUE;
752 }
753 
disp_select()754 static void disp_select()
755 {
756   dbg("disp_select\n");
757   gmf.mf_clear_sele();
758   int endn = pageidx + gmf.mf_phkbm->selkeyN;
759   if (endn >  seg[cursor].selN)
760     endn = seg[cursor].selN;
761   int i;
762   for(i=pageidx; i<endn; i++) {
763     char buf[256];
764     anthy_get_segment(ac, cursor, i, buf, sizeof(buf));
765 //    printf("%d %s\n", i, buf);
766     gmf.mf_set_sele_text(i - pageidx, buf, -1);
767   }
768 
769   if (pageidx)
770     gmf.mf_disp_arrow_up();
771   if (i < seg[cursor].selN)
772     gmf.mf_disp_arrow_down();
773 
774   int x,y;
775   gmf.mf_get_widget_xy(win_anthy, seg[cursor].label, &x, &y);
776   dbg("%x cusor %d %d\n", win_anthy, cursor, x);
777   y = gmf.mf_gcin_edit_display_ap_only()?
778     *gmf.mf_win_y:*gmf.mf_win_y+*gmf.mf_win_yl;
779   gmf.mf_disp_selections(x, y);
780 }
781 
load_seg()782 static void load_seg()
783 {
784 	dbg("load_seg sel_segN:%d\n", sel_segN);
785       clear_seg_label();
786       struct anthy_conv_stat acs;
787       anthy_get_stat(ac, &acs);
788       segN = 0;
789       if (acs.nr_segment > 0) {
790         char buf[256];
791         int i;
792 
793 		int ofs = 0;
794         for(i=0; i < acs.nr_segment; i++) {
795           struct anthy_segment_stat ss;
796           anthy_get_segment_stat(ac, i, &ss);
797 		  int len = ss.seg_len;
798 		  int idx = get_sel_seg_with_ofs(ofs);
799 		  dbg("%d] sel idx:%d ofs:%d\n",i, idx, ofs);
800           int selN = seg[i].selN = ss.nr_candidate;
801 
802 		  char *old_str = NULL;
803 		  seg[i].selidx = 0;
804 		  if (idx < sel_segN && sel_seg[idx].len==len) {
805 			int j;
806 			for(j=0;j<selN;j++) {
807 			  anthy_get_segment(ac, i, j, buf, sizeof(buf));
808 			  if (!strcmp(buf, sel_seg[idx].sel_str) ) {
809 				dbg("old found %s", buf);
810 				seg[i].selidx = j;
811 				break;
812 		      }
813 			}
814 	      }
815 
816 	      anthy_get_segment(ac, i, seg[i].selidx, buf, sizeof(buf));
817           gtk_label_set_text(GTK_LABEL(seg[i].label), buf);
818 
819           dbg("seg len:%d\n", len);
820           seg[i].ofs = ofs;
821           seg[i].len = len;
822           segN++;
823           ofs += len;
824         }
825 
826         state=STATE_CONVERT;
827 //        cursor = 0;
828         if (cursor >= acs.nr_segment)
829           cursor = acs.nr_segment - 1;
830         disp_convert();
831       }
832       keysN=0;
833 }
834 
next_page()835 static void next_page()
836 {
837   pageidx += gmf.mf_phkbm->selkeyN;
838   if (pageidx >= seg[cursor].selN)
839     pageidx = 0;
840   disp_select();
841 }
842 
prev_page()843 static void prev_page()
844 {
845   pageidx -= gmf.mf_phkbm->selkeyN;
846   if (pageidx < 0)
847     pageidx = 0;
848   disp_select();
849 }
850 
851 void hide_selections_win();
852 
module_flush_input()853 int module_flush_input()
854 {
855   gmf.mf_hide_selections_win();
856 
857   int val;
858   if (state==STATE_CONVERT) {
859     val = TRUE;
860     send_seg();
861   } else {
862     val = send_jp();
863   }
864 
865 //  dbg("cursor %d\n", cursor);
866   clear_all();
867   return val;
868 }
869 
page_N()870 static int page_N()
871 {
872   int N = seg[cursor].selN - pageidx;
873   if (N > gmf.mf_phkbm->selkeyN)
874     N = gmf.mf_phkbm->selkeyN;
875   return N;
876 }
877 
878 
select_idx(int c)879 static gboolean select_idx(int c)
880 {
881   int idx = pageidx + c;
882 
883   if (idx < seg[cursor].selN) {
884     char buf[256];
885     anthy_get_segment(ac, cursor, idx, buf, sizeof(buf));
886     struct anthy_segment_stat ss;
887     anthy_get_segment_stat(ac, cursor, &ss);
888 	int len = ss.seg_len;
889 
890     gtk_label_set_text(GTK_LABEL(seg[cursor].label), buf);
891     seg[cursor].selidx = idx;
892 
893     int sidx = get_sel_seg_with_ofs(seg[cursor].ofs);
894 	if (sidx==sel_segN) {
895 	   sel_segN++;
896 	}
897 
898 	if (sel_seg[sidx].sel_str)
899 		free(sel_seg[sidx].sel_str);
900 
901 	dbg("select_idx idx:%d sidx:%d %s\n", idx, sidx, buf);
902 
903 	sel_seg[sidx].sel_str = strdup(buf);
904 	sel_seg[sidx].ofs = seg[cursor].ofs;
905 	sel_seg[sidx].len = len;
906 
907     state = STATE_CONVERT;
908     gmf.mf_hide_selections_win();
909     return (segN==1);
910   }
911 
912   return FALSE;
913 }
914 
915 
module_feedkey(int kv,int kvstate)916 gboolean module_feedkey(int kv, int kvstate)
917 {
918   int lkv = tolower(kv);
919   int shift_m=(kvstate&ShiftMask) > 0;
920 //  printf("%x %c  %d\n", kv, kv, shift_m);
921 
922   if (kvstate & ControlMask)
923     return FALSE;
924   if (kvstate & (Mod1Mask|Mod4Mask|Mod5Mask))
925     return FALSE;
926 
927   if (kv==XK_Shift_L||kv==XK_Shift_R) {
928     key_press_time = gmf.mf_current_time();
929   }
930 
931   if (!gmf.mf_tsin_pho_mode())
932     return 0;
933 
934   gboolean b_is_empty = is_empty();
935 
936   switch (kv) {
937     case XK_F7:
938       if (is_empty())
939         return FALSE;
940       state = STATE_ROMANJI;
941       if (state_hira_kata != STATE_kata)
942         state_hira_kata = STATE_kata;
943       else
944         state_hira_kata = STATE_hira;
945       disp_input();
946       return TRUE;
947     case XK_F8:
948       if (is_empty())
949         return FALSE;
950       state = STATE_ROMANJI;
951       if (state_hira_kata != STATE_half_kata)
952         state_hira_kata = STATE_half_kata;
953       else
954         state_hira_kata = STATE_hira;
955       disp_input();
956       return TRUE;
957     case XK_F11:
958       if (system("kasumi &") < 0)  {
959       }
960       return TRUE;
961     case XK_F12:
962       if (system("kasumi -a &") < 0) {
963       }
964       return TRUE;
965     case XK_Up:
966       if (b_is_empty)
967         return FALSE;
968       if (state==STATE_SELECT) {
969         int N = page_N();
970         gmf.mf_tss->pho_menu_idx--;
971         if (gmf.mf_tss->pho_menu_idx < 0)
972           gmf.mf_tss->pho_menu_idx = N - 1;
973         disp_select();
974       }
975       return TRUE;
976     case XK_Down:
977       if (b_is_empty)
978         return FALSE;
979       if (state==STATE_CONVERT) {
980         state = STATE_SELECT;
981         gmf.mf_tss->sel_pho = TRUE;
982   //      puts("STATE_SELECT");
983         disp_select();
984       } else
985       if (state==STATE_SELECT) {
986         int N = page_N();
987         gmf.mf_tss->pho_menu_idx=(gmf.mf_tss->pho_menu_idx+1)% N;
988         disp_select();
989       }
990       return TRUE;
991     case XK_Return:
992       if (b_is_empty)
993         return FALSE;
994       if (state==STATE_SELECT) {
995         if (select_idx(gmf.mf_tss->pho_menu_idx))
996           goto send;
997         return TRUE;
998       }
999 send:
1000       return module_flush_input();
1001     case XK_Escape:
1002         if (state==STATE_SELECT) {
1003           state = STATE_CONVERT;
1004           gmf.mf_tss->sel_pho = FALSE;
1005           gmf.mf_clear_sele();
1006         }
1007         else
1008         if (state==STATE_CONVERT)
1009           goto rom;
1010       return FALSE;
1011     case XK_BackSpace:
1012       if (b_is_empty) {
1013         state_hira_kata = STATE_hira;
1014         return FALSE;
1015       }
1016 
1017       gmf.mf_hide_selections_win();
1018 
1019       if (state&(STATE_CONVERT|STATE_SELECT)) {
1020 rom:
1021 //        puts("romanji");
1022         state = STATE_ROMANJI;
1023         cursor = jpN;
1024         segN = 0;
1025         disp_input();
1026         return TRUE;
1027       }
1028 
1029 //      puts("back");
1030       if (keysN) {
1031         keysN--;
1032         keys[keysN]=0;
1033       }
1034       else
1035       if (jpN && cursor) {
1036         delete_jpstr(cursor-1);
1037         cursor--;
1038       } else
1039         return FALSE;
1040       disp_input();
1041       auto_hide();
1042       return TRUE;
1043     case XK_Delete:
1044       if (b_is_empty)
1045         return FALSE;
1046       if (state&STATE_ROMANJI) {
1047         if (keysN)
1048           return TRUE;
1049         delete_jpstr(cursor);
1050         disp_input();
1051       }
1052       auto_hide();
1053       return TRUE;
1054     case XK_Left:
1055       if (b_is_empty)
1056         return FALSE;
1057       if (state&STATE_ROMANJI) {
1058         if (keysN)
1059           keysN = 0;
1060         else {
1061           if (cursor)
1062             cursor--;
1063         }
1064         disp_input();
1065       } else
1066       if (state&STATE_CONVERT) {
1067         if (shift_m) {
1068           anthy_resize_segment(ac, cursor, -1);
1069           load_seg();
1070         } else {
1071           if (cursor) {
1072             cursor--;
1073             pageidx = 0;
1074           }
1075         }
1076         disp_convert();
1077       }
1078       return TRUE;
1079     case XK_Right:
1080       if (b_is_empty)
1081         return FALSE;
1082       if (state&STATE_ROMANJI) {
1083         if (cursor < jpN) {
1084           cursor++;
1085           pageidx = 0;
1086         }
1087         disp_input();
1088       } else
1089       if (state&STATE_CONVERT) {
1090         if (shift_m) {
1091           anthy_resize_segment(ac, cursor, 1);
1092           load_seg();
1093         } else {
1094           if (cursor < segN-1)
1095             cursor++;
1096         }
1097         disp_convert();
1098       }
1099       return TRUE;
1100     case XK_Home:
1101       if (b_is_empty)
1102         return FALSE;
1103       cursor = 0;
1104       if (state&STATE_ROMANJI) {
1105         disp_input();
1106       } else
1107       if (state&STATE_CONVERT) {
1108         disp_convert();
1109       }
1110       return TRUE;
1111     case XK_End:
1112       if (b_is_empty)
1113         return FALSE;
1114       if (state&STATE_ROMANJI) {
1115         cursor = jpN;
1116         disp_input();
1117       } else
1118       if (state&STATE_CONVERT) {
1119         cursor = segN-1;
1120         disp_convert();
1121       }
1122       return TRUE;
1123     case XK_Prior:
1124       if (state!=STATE_SELECT)
1125         return FALSE;
1126       prev_page();
1127       return TRUE;
1128     case XK_Next:
1129       if (state!=STATE_SELECT)
1130         return FALSE;
1131       next_page();
1132       return TRUE;
1133     case ' ':
1134       if (b_is_empty)
1135         return FALSE;
1136       goto lab1;
1137     default:
1138       if (state==STATE_SELECT) {
1139         char *pp;
1140         if ((pp=strchr(*gmf.mf_pho_selkey, lkv))) {
1141           int c=pp-*gmf.mf_pho_selkey;
1142           if (select_idx(c))
1143             goto send;
1144         }
1145         return TRUE;
1146       }
1147   }
1148 
1149 //  printf("kv %d\n", kv);
1150   if (!is_legal_char(kv))
1151     return FALSE;
1152 
1153   kv = lkv;
1154 
1155   if (state==STATE_CONVERT && kv!=' ') {
1156     send_seg();
1157     state = STATE_ROMANJI;
1158   }
1159 
1160 lab1:
1161   if (state==STATE_ROMANJI) {
1162     if (keysN < MAX_KEYS)
1163       keys[keysN++]=kv;
1164 
1165     keys[keysN]=0;
1166     parse_key();
1167     disp_input();
1168   }
1169 
1170   module_show_win();
1171 
1172   if (kv==' ') {
1173     if (state==STATE_ROMANJI) {
1174       char tt[512];
1175       clear_seg_label();
1176       merge_jp(tt, TRUE);
1177 //      dbg("tt %s %d\n", tt, strlen(tt));
1178       anthy_set_string(ac, tt);
1179       load_seg();
1180     } else
1181     if (state==STATE_CONVERT) {
1182       state = STATE_SELECT;
1183       gmf.mf_tss->sel_pho = TRUE;
1184 //      puts("STATE_SELECT");
1185       disp_select();
1186     } else
1187     if (state==STATE_SELECT) {
1188       next_page();
1189     }
1190   }
1191 
1192   return TRUE;
1193 }
1194 
mouse_button_callback(GtkWidget * widget,GdkEventButton * event,gpointer data)1195 static void mouse_button_callback( GtkWidget *widget,GdkEventButton *event, gpointer data)
1196 {
1197 //  dbg("mouse_button_callback %d\n", event->button);
1198   switch (event->button) {
1199     case 1:
1200       gmf.mf_toggle_win_sym();
1201       break;
1202     case 2:
1203       gmf.mf_inmd_switch_popup_handler(widget, (GdkEvent *)event);
1204       break;
1205     case 3:
1206       gmf.mf_exec_gcin_setup();
1207       break;
1208   }
1209 }
1210 
1211 
1212 #include <dlfcn.h>
1213 
1214 void create_win1(), create_win1_gui(), load_tab_pho_file(), show_win_sym();
1215 void hide_win_sym();
module_init_win(GCIN_module_main_functions * funcs)1216 int module_init_win(GCIN_module_main_functions *funcs)
1217 {
1218   gmf = *funcs;
1219 
1220 //  dbg("module_init_win\n");
1221 
1222   gmf.mf_set_tsin_pho_mode();
1223   gmf.mf_set_win1_cb((cb_selec_by_idx_t)select_idx, prev_page, next_page);
1224 
1225   if (win_anthy)
1226     return TRUE;
1227 
1228   if (anthy_init() == -1) {
1229     gmf.mf_box_warn("anthy_init() failed. Anthy not installed or incompatible anthy.so ?");
1230     return FALSE;
1231   }
1232 
1233   ac = anthy_create_context();
1234   if (!ac) {
1235     gmf.mf_box_warn("anthy_create_context error");
1236     return FALSE;
1237   }
1238 
1239   anthy_context_set_encoding(ac, ANTHY_UTF8_ENCODING);
1240 
1241   win_anthy = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1242   gtk_window_set_has_resize_grip(GTK_WINDOW(win_anthy), FALSE);
1243   gtk_window_set_resizable(GTK_WINDOW(win_anthy), FALSE);
1244 
1245   gtk_window_set_default_size(GTK_WINDOW (win_anthy), 40, 50);
1246 
1247 
1248   gtk_widget_realize (win_anthy);
1249   gmf.mf_set_no_focus(win_anthy);
1250 
1251   event_box_anthy = gtk_event_box_new();
1252   gtk_event_box_set_visible_window (GTK_EVENT_BOX(event_box_anthy), FALSE);
1253 
1254   gtk_container_add(GTK_CONTAINER(win_anthy), event_box_anthy);
1255 
1256   GtkWidget *hbox_top = gtk_hbox_new (FALSE, 0);
1257   gtk_container_add(GTK_CONTAINER(event_box_anthy), hbox_top);
1258 
1259   g_signal_connect(G_OBJECT(event_box_anthy),"button-press-event",
1260                    G_CALLBACK(mouse_button_callback), NULL);
1261 
1262   if (!seg) {
1263     int n=sizeof(SEG)*MAX_SEG_N;
1264     seg=malloc(n);
1265     bzero(seg, n);
1266 
1267     n=sizeof(SEL_SEG)*MAX_SEG_N;
1268     sel_seg = malloc(n);
1269     bzero(sel_seg, n);
1270   }
1271 
1272   int i;
1273   for(i=0; i < MAX_SEG_N; i++) {
1274     seg[i].label = gtk_label_new(NULL);
1275     gtk_widget_show(seg[i].label);
1276     gtk_box_pack_start (GTK_BOX (hbox_top), seg[i].label, FALSE, FALSE, 0);
1277   }
1278 
1279   gtk_widget_show_all(win_anthy);
1280 
1281   gmf.mf_init_tsin_selection_win();
1282 
1283   module_change_font_size();
1284 
1285   if (!gmf.mf_phkbm->selkeyN)
1286     gmf.mf_load_tab_pho_file();
1287 
1288   module_hide_win();
1289 
1290   return TRUE;
1291 }
1292 
module_win_visible()1293 int module_win_visible()
1294 {
1295   return GTK_WIDGET_VISIBLE(win_anthy);
1296 }
1297 
module_show_win()1298 void module_show_win()
1299 {
1300   if (gmf.mf_gcin_edit_display_ap_only())
1301     return;
1302   if (!*gmf.mf_gcin_pop_up_win || !is_empty() || *gmf.mf_force_show ) {
1303     if (!module_win_visible())
1304       gtk_widget_show(win_anthy);
1305     gmf.mf_show_win_sym();
1306   }
1307 }
1308 
module_hide_win()1309 void module_hide_win()
1310 {
1311   if (state == STATE_SELECT) {
1312     state = STATE_CONVERT;
1313     gmf.mf_hide_selections_win();
1314   }
1315   gtk_widget_hide(win_anthy);
1316   gmf.mf_hide_win_sym();
1317 }
1318 
module_change_font_size()1319 void module_change_font_size()
1320 {
1321   dbg("change_anthy_font_size\n");
1322   GdkColor fg;
1323   gdk_color_parse(*gmf.mf_gcin_win_color_fg, &fg);
1324 #if GTK_CHECK_VERSION(2,91,6)
1325   GdkRGBA rgbfg;
1326   gdk_rgba_parse(&rgbfg, gdk_color_to_string(&fg));
1327 #endif
1328   gmf.mf_change_win_bg(win_anthy);
1329   gmf.mf_change_win_bg(event_box_anthy);
1330 
1331   int i;
1332   for(i=0; i < MAX_SEG_N; i++) {
1333     GtkWidget *label = seg[i].label;
1334     gmf.mf_set_label_font_size(label, *gmf.mf_gcin_font_size);
1335     if (*gmf.mf_gcin_win_color_use) {
1336 #if !GTK_CHECK_VERSION(2,91,6)
1337       gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &fg);
1338 #else
1339       gtk_widget_override_color(label, GTK_STATE_FLAG_NORMAL, &rgbfg);
1340 #endif
1341     }
1342   }
1343 }
1344 
module_move_win(int x,int y)1345 void module_move_win(int x, int y)
1346 {
1347 #if 0
1348   best_win_x = x;
1349   best_win_y = y;
1350 #endif
1351   gtk_window_get_size(GTK_WINDOW(win_anthy), gmf.mf_win_xl, gmf.mf_win_yl);
1352 
1353   if (x + *gmf.mf_win_xl > *gmf.mf_dpy_xl)
1354     x = *gmf.mf_dpy_xl - *gmf.mf_win_xl;
1355   if (x < 0)
1356     x = 0;
1357 
1358   if (y + *gmf.mf_win_yl > *gmf.mf_dpy_yl)
1359     y = *gmf.mf_dpy_yl - *gmf.mf_win_yl;
1360   if (y < 0)
1361     y = 0;
1362 
1363   gtk_window_move(GTK_WINDOW(win_anthy), x, y);
1364   *gmf.mf_win_x = x;
1365   *gmf.mf_win_y = y;
1366 
1367   gmf.mf_move_win_sym();
1368 }
1369 
module_feedkey_release(KeySym xkey,int kbstate)1370 int module_feedkey_release(KeySym xkey, int kbstate)
1371 {
1372   switch (xkey) {
1373      case XK_Shift_L:
1374      case XK_Shift_R:
1375         if (
1376 (  (*gmf.mf_tsin_chinese_english_toggle_key == TSIN_CHINESE_ENGLISH_TOGGLE_KEY_Shift) ||
1377    (*gmf.mf_tsin_chinese_english_toggle_key == TSIN_CHINESE_ENGLISH_TOGGLE_KEY_ShiftL
1378      && xkey == XK_Shift_L) ||
1379    (*gmf.mf_tsin_chinese_english_toggle_key == TSIN_CHINESE_ENGLISH_TOGGLE_KEY_ShiftR
1380      && xkey == XK_Shift_R))
1381           &&  gmf.mf_current_time() - key_press_time < 300000) {
1382 #if WIN32
1383           if (!*gmf.test_mode)
1384 #endif
1385           {
1386             module_flush_input();
1387             key_press_time = 0;
1388             gmf.mf_hide_selections_win();
1389             gmf.mf_tsin_set_eng_ch(!gmf.mf_tsin_pho_mode());
1390           }
1391           return 1;
1392         } else
1393           return 0;
1394      default:
1395         return 0;
1396   }
1397 }
1398 
1399 
module_get_preedit(char * str,GCIN_PREEDIT_ATTR attr[],int * pcursor,int * comp_flag)1400 int module_get_preedit(char *str, GCIN_PREEDIT_ATTR attr[], int *pcursor, int *comp_flag)
1401 {
1402   int i;
1403 
1404   dbg("anthy_get_preedit %d  state:%d\n", cursor, state);
1405   str[0]=0;
1406   *pcursor=0;
1407 
1408   attr[0].flag=GCIN_PREEDIT_ATTR_FLAG_UNDERLINE;
1409   attr[0].ofs0=0;
1410   int attrN=0;
1411   int ch_N=0;
1412 
1413   if (state&(STATE_CONVERT|STATE_SELECT)) {
1414     dbg("state==STATE_CONVERT\n");
1415 
1416     if (segN)
1417       attrN=1;
1418 
1419     for(i=0; i < segN; i++) {
1420       char *s = (char *)gtk_label_get_text(GTK_LABEL(seg[i].label));
1421       int N = gmf.mf_utf8_str_N(s);
1422       ch_N+=N;
1423       if (i < cursor)
1424         *pcursor+=N;
1425       if (gmf.mf_gcin_edit_display_ap_only() && i==cursor) {
1426         attr[1].ofs0=*pcursor;
1427         attr[1].ofs1=*pcursor+N;
1428         attr[1].flag=GCIN_PREEDIT_ATTR_FLAG_REVERSE;
1429         attrN++;
1430       }
1431       strcat(str, s);
1432     }
1433 
1434     attr[0].ofs1 = ch_N;
1435   } else {
1436     if (jpN)
1437       attrN=1;
1438 
1439     keys[keysN]=0;
1440 
1441     for(i=0;i < jpN; i++) {
1442       char *s=idx_hira_kata(jp[i], FALSE);
1443 
1444       int N = gmf.mf_utf8_str_N(s);
1445 //      dbg("%d]%s N:%d\n", i, s, N);
1446       if (gmf.mf_gcin_edit_display_ap_only() && i==cursor) {
1447         strcat(str, keys);
1448         ch_N+=keysN;
1449         *pcursor = ch_N;
1450         attr[1].ofs0=ch_N;
1451         attr[1].ofs1=ch_N+N;
1452         attr[1].flag=GCIN_PREEDIT_ATTR_FLAG_REVERSE;
1453         attrN++;
1454       }
1455       strcat(str, s);
1456       ch_N+=N;
1457     }
1458 
1459     if (cursor==jpN) {
1460       *pcursor = ch_N;
1461       strcat(str, keys);
1462       ch_N+=keysN;
1463     }
1464 
1465     attr[0].ofs1 = ch_N;
1466 //    dbg("cursor %d  ch_N:%d  '%s'\n", *pcursor, ch_N, str);
1467   }
1468 
1469   *comp_flag = keysN>0;
1470   if (win_anthy && GTK_WIDGET_VISIBLE(win_anthy))
1471     *comp_flag|=2;
1472   if (segN || jpN)
1473     *comp_flag|=4;
1474 
1475   return attrN;
1476 }
1477 
1478 
module_reset()1479 int module_reset()
1480 {
1481   if (!win_anthy)
1482     return 0;
1483   int v = !is_empty();
1484 
1485   clear_all();
1486   return v;
1487 }
1488 
module_win_geom()1489 void module_win_geom()
1490 {
1491   if (!win_anthy)
1492     return;
1493   gtk_window_get_position(GTK_WINDOW(win_anthy), gmf.mf_win_x, gmf.mf_win_y);
1494 
1495   gmf.mf_get_win_size(win_anthy, gmf.mf_win_xl, gmf.mf_win_yl);
1496 }
1497