1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2 /* vs: set ts=2 sw=2: */
3 /* IM-JA Japanese Input Method Module for GTK-2.0
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Authors: Botond Botyanszki <boti@rocketmail.com>
21 * Srin Tuar <srintuar26@earthlink.net>
22 */
23
24 #include <gdk/gdkevents.h>
25 #include <gdk/gdkkeysyms.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "common.h"
30 #include "conf.h"
31 #include "error.h"
32
euc2utf8(const gchar * str)33 gchar *euc2utf8(const gchar *str) {
34 GError *error = NULL;
35 gchar *result;
36
37 result = g_convert (str, -1, "UTF-8", "EUC-JP", NULL, NULL, &error);
38 if (!result) {
39 result = g_convert (str, -1, "UTF-8", "EUC-JISX0213", NULL, NULL, &error);
40 if( !result ) {
41 g_warning ("Error converting text from EUC-JP to UTF-8: %s\n", error->message);
42 g_error_free (error);
43 result = g_strdup("???");
44 }
45 }
46
47 return result;
48 }
49
utf82euc(const gchar * str)50 gchar *utf82euc(const gchar *str) {
51 GError *error = NULL;
52 gchar *result;
53
54 result = g_convert (str, -1, "EUC-JP", "UTF-8", NULL, NULL, &error);
55 if (!result) {
56 g_warning ("Error converting text from UTF-8 to EUC-JP: %s\n", error->message);
57 g_error_free (error);
58 }
59
60 return result;
61 }
62
utf8to16(const gchar * str)63 gchar *utf8to16(const gchar *str) {
64 GError *error = NULL;
65 gchar *result;
66
67 result = g_convert (str, -1, "UTF-16", "UTF-8", NULL, NULL, &error);
68 if (!result) {
69 g_warning ("Error converting text from UTF-8 to UTF-16: %s\n", error->message);
70 g_error_free (error);
71 }
72
73 return result;
74 }
75
euc2wc(gchar * eucstr)76 int euc2wc(gchar *eucstr) { /* probably reinvented the wheel here. */
77 int wcchar;
78
79 if (((unsigned char) (*eucstr)) > 128) {
80 wcchar = ((int) *eucstr << 8) + ((int) *(eucstr + 1) & 0xff);
81 }
82 else {
83 wcchar = *eucstr;
84 }
85 return wcchar;
86 }
87
wc2euc(wchar * wcstr,gint size)88 gchar *wc2euc(wchar *wcstr, gint size) { /* probably reinvented the wheel here. */
89 gchar *eucstr, *eucptr;
90 int i;
91 eucstr = g_new0(gchar, size * 2 + 1);
92 eucptr = eucstr;
93 i = 0;
94 for (i = 0; i < size; i++) {
95 if (*wcstr == 0) break;
96 if (*(wcstr + i) > 128) {
97 *eucptr = *(wcstr + i) >> 8;
98 *(eucptr + 1) = *(wcstr + i) & 0xff;
99 eucptr += 2;
100 }
101 else {
102 *eucptr = *(wcstr + i);
103 eucptr++;
104 }
105 }
106 return eucstr;
107 }
108
109
isJPChar(gunichar c)110 gboolean isJPChar(gunichar c) {
111 if (isKanaChar(c) == TRUE) return TRUE;
112 if (isKanjiChar(c) == TRUE) return TRUE;
113 if (isOtherChar(c) == TRUE) return TRUE;
114 return FALSE;
115 }
isKanaChar(gunichar c)116 gboolean isKanaChar(gunichar c) {
117 if (isKatakanaChar(c) == TRUE) return TRUE;
118 if (isHiraganaChar(c) == TRUE) return TRUE;
119 return FALSE;
120 }
isKatakanaChar(gunichar c)121 gboolean isKatakanaChar(gunichar c) {
122 if ((c >= 0x30A0) && (c <= 0x30FF)) return TRUE; /* Full and half Katakana */
123 if ((c >= 0xFF65) && (c <= 0xFF9F)) return TRUE; /* Narrow Katakana */
124 return FALSE;
125 }
isHiraganaChar(gunichar c)126 gboolean isHiraganaChar(gunichar c) {
127 if ((c >= 0x3040) && (c <= 0x309F)) return TRUE; /* Hiragana */
128 return FALSE;
129 }
isKanjiChar(gunichar c)130 gboolean isKanjiChar(gunichar c) {
131 if ((c >= 0x3300) && (c <= 0x33FF)) return TRUE; /* cjk compatibility */
132 if ((c >= 0x3400) && (c <= 0x4DBF)) return TRUE; /* cjk ext A */
133 if ((c >= 0x4E00) && (c <= 0x9FAF)) return TRUE; /* cjk unified */
134 if ((c >= 0x20000) && (c <= 0x2A6DF)) return TRUE; /* cjk ext B */
135 if ((c >= 0x2F800) && (c <= 0x2FA1F)) return TRUE; /* cjk supplement */
136 return FALSE;
137 }
isOtherChar(gunichar c)138 gboolean isOtherChar(gunichar c) {
139 if ((c >= 0x2E80) && (c <= 0x2EFF)) return TRUE; /* cjk radical */
140 if ((c >= 0x2F00) && (c <= 0x2FDF)) return TRUE; /* cjk kangxi radicals */
141 if ((c >= 0x2FF0) && (c <= 0x2FFF)) return TRUE; /* ideographic */
142 if ((c >= 0x3000) && (c <= 0x303F)) return TRUE; /* punctuation */
143 if ((c >= 0x3200) && (c <= 0x32FF)) return TRUE; /* enclosed letters */
144 if ((c >= 0xFE30) && (c <= 0xFE4F)) return TRUE; /* compatibility forms */
145 if ((c >= 0xFF00) && (c <= 0xFF64)) return TRUE; /* compatibility forms2 */
146 if ((c >= 0xFFA0) && (c <= 0xFFEF)) return TRUE; /* compatibility forms3 */
147 return FALSE;
148 }
149
150 /* Convert Hiragana -> Katakana.*/
hira2kata(gchar * hirastr)151 gchar *hira2kata(gchar *hirastr) {
152 gchar *hiraptr;
153 gchar *kata = g_new0(gchar, strlen(hirastr) + 6);
154 gchar *kataptr = kata;
155 int length;
156
157 hiraptr = hirastr;
158 while (*hiraptr != 0) {
159 if (isHiraganaChar(g_utf8_get_char(hiraptr)) == TRUE) {
160 g_unichar_to_utf8(g_utf8_get_char(hiraptr) + 96, kataptr);
161 }
162 else {
163 length = g_utf8_next_char(hiraptr) - hiraptr;
164 strncat(kataptr, hiraptr, length);
165 kataptr[length + 1] = 0;
166 }
167 kataptr = g_utf8_next_char(kataptr);
168 hiraptr = g_utf8_next_char(hiraptr);
169 if (hiraptr == NULL) break;
170 }
171 return kata;
172 }
173
174 /*
175 gint char_to_byte_pos(gchar *str, gint pos) {
176 gint byte_pos = 0;
177 gchar *ptr = str;
178 gint len = strlen(str);
179 gint cnt = 0;
180
181 if (len == 0) return 0;
182
183 while (byte_pos <= len) {
184 if (cnt == pos) break;
185 ptr = g_utf8_next_char(ptr);
186 byte_pos = ptr - str;
187 cnt++;
188 }
189 return byte_pos;
190 }
191 */
192
193 /* Convert fullsize katakana to half width*/
194 /*
195 gchar *full2half(gchar *instr) {
196 gchar *inptr = instr;
197 gchar *out = g_new0(gchar, strlen(instr));
198 gchar *outptr = out;
199 int length;
200
201 IM_JA_DEBUG("instr:%s\n", utf82euc(instr));
202
203 while (*inptr != 0) {
204 if (isKanaChar(g_utf8_get_char(inptr)) == TRUE) {
205 IM_JA_DEBUG("hex:%x\n", (int)g_utf8_get_char(inptr));
206 g_unichar_to_utf8(g_utf8_get_char(inptr) - 1, outptr);
207 }
208 else {
209 length = g_utf8_next_char(inptr) - inptr;
210 strncat(outptr, inptr, length);
211 outptr[length + 1] = 0;
212 }
213 outptr = g_utf8_next_char(outptr);
214 inptr = g_utf8_next_char(inptr);
215 if (inptr == NULL) break;
216 }
217 IM_JA_DEBUG("outstr:%s\n", utf82euc(out));
218 return out;
219 }
220 */
221
222 #define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK)
im_ja_is_printable_key(GdkEventKey * key)223 gboolean im_ja_is_printable_key(GdkEventKey *key) {
224 /*
225 guint keyval;
226 gint eff_group, level;
227 GdkModifierType consumed;
228
229 gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(), key->hardware_keycode,
230 key->state, key->group,
231 &keyval, &eff_group, &level, &consumed);
232 if (key->state & ~consumed & ALL_ACCELS_MASK) return FALSE;
233 */
234
235 if (key->state & (gtk_accelerator_get_default_mod_mask() & ~GDK_SHIFT_MASK)) return FALSE;
236
237 /* non-printable KP keys */
238 if (key->keyval >= GDK_KP_Enter && key->keyval <= GDK_KP_Delete) {
239 return FALSE;
240 }
241
242 IM_JA_DEBUG(" printable by gdk\n");
243 /* NORMAL CHAR KEYS */
244 if ((key->keyval >= GDK_exclam && key->keyval <= GDK_overline) ||
245 (key->keyval >= GDK_KP_Space && key->keyval <= GDK_KP_9)) {
246 return TRUE;
247 }
248
249 return FALSE;
250
251 }
252
ishotkey(GdkEventKey * key,int hotkey,IMJAConfig * cfg)253 gboolean ishotkey(GdkEventKey *key, int hotkey, IMJAConfig *cfg) {
254 guint state = key->state;
255
256 state &= ~GDK_LOCK_MASK;
257 state &= ~GDK_MOD2_MASK;
258 state &= ~GDK_MOD5_MASK;
259
260 if ((state == cfg->hotkey_states[hotkey]) &&
261 (key->keyval == cfg->hotkey_values[hotkey])) return TRUE;
262
263 return FALSE;
264
265 }
266
buffer_delchar(gchar * buf)267 gboolean buffer_delchar(gchar* buf) {
268 if( buf == NULL ) return FALSE;
269
270 g_utf8_prev_char(buf + strlen(buf))[0] = 0;
271 return TRUE;
272 }
273
274 /*
275 gchar *get_utf8_for_keyval(guint keyval) {
276 gchar *utf8strg = g_new0(gchar, 7);
277 int written = g_unichar_to_utf8(gdk_keyval_to_unicode(keyval), utf8strg);
278 utf8strg[written] = 0;
279 return utf8strg;
280 }
281 */
282
buffer_inschar(char * buf,int maxbuf,char * ins,int pos)283 int buffer_inschar(char* buf, int maxbuf, char *ins, int pos) {
284 char *repo, *end;
285 int clen = strlen(buf);
286 int nlen = strlen(ins);
287
288 if (clen+nlen >= maxbuf) {
289 nlen = maxbuf - clen - 1;
290 }
291
292 clen += nlen;
293
294 repo = buf + clen;
295 end = buf + pos + nlen;
296
297 while (repo >= end) {
298 *repo = *(repo-nlen);
299 --repo;
300 }
301
302 repo = buf + pos;
303 end = repo + nlen;
304
305 while (repo < end) *repo++ = *ins++;
306
307 return nlen;
308 }
309
buffer_bkspchar(char * buf,int pos)310 int buffer_bkspchar(char* buf, int pos) {
311 int delta=0;
312 char *prev, *at;
313
314 at = buf + pos;
315 prev = g_utf8_find_prev_char(buf, at);
316
317 if (prev) {
318 delta = at - prev;
319 do {
320 *prev++ = *at++;
321 }
322 while (*prev);
323 }
324
325 return delta;
326 }
327
buffer_deltchar(char * buf,int pos)328 int buffer_deltchar(char* buf, int pos) {
329 int delta=0;
330 char *next, *at;
331
332 at = buf + pos;
333 next = g_utf8_find_next_char(at, 0);
334
335 if (next) {
336 delta = next - at;
337 do {
338 *at++ = *next++;
339 }
340 while (*at);
341 }
342
343 return delta;
344 }
345