Tizen 2.0 Release
[framework/uifw/ise-engine-anthy.git] / src / scim_anthy_utils.cpp
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  *  Copyright (C) 2005 Takuro Ashie
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This program 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
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include <string.h>
21 #include <sys/wait.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include "scim_anthy_utils.h"
26 #include "scim_anthy_default_tables.h"
27
28 namespace scim_anthy {
29
30 bool
31 util_match_key_event (const KeyEventList &list, const KeyEvent &key,
32                       uint16 ignore_mask)
33 {
34     KeyEventList::const_iterator kit;
35
36     for (kit = list.begin (); kit != list.end (); kit++) {
37         uint16 mod1, mod2;
38
39         mod1 = kit->mask;
40         mod2 = key.mask;
41         mod1 &= ~ignore_mask;
42         mod2 &= ~ignore_mask;
43
44         if (key.code == kit->code && mod1 == mod2)
45              return true;
46     }
47     return false;
48 }
49
50 void
51 util_split_string (String &str, std::vector<String> &str_list,
52                    char *delim, int num)
53 {
54     String::size_type start = 0, end;
55
56     for (int i = 0; (num > 0 && i < num) || start < str.length (); i++) {
57         end = str.find (delim, start);
58         if ((num > 0 && i == num - 1) || (end == String::npos))
59             end = str.length ();
60
61         if (start < str.length ()) {
62             str_list.push_back (str.substr (start, end - start));
63             start = end + strlen (delim);
64         } else {
65             str_list.push_back (String ());
66         }
67     }
68 }
69
70 void
71 util_convert_to_wide (WideString & wide, const String & str)
72 {
73     if (str.length () < 0)
74         return;
75
76     for (unsigned int i = 0; i < str.length (); i++) {
77         int c = str[i];
78         char cc[2]; cc[0] = c; cc[1] = '\0';
79         bool found = false;
80
81         for (unsigned int j = 0; scim_anthy_wide_table[j].code; j++) {
82             if ( scim_anthy_wide_table[j].code &&
83                 *scim_anthy_wide_table[j].code == c)
84             {
85                 wide += utf8_mbstowcs (scim_anthy_wide_table[j].wide);
86                 found = true;
87                 break;
88             }
89         }
90
91         if (!found)
92             wide += utf8_mbstowcs (cc);
93     }
94 }
95
96 void
97 util_convert_to_half (String & half, const WideString & str)
98 {
99     if (str.length () < 0)
100         return;
101
102     for (unsigned int i = 0; i < str.length (); i++) {
103         WideString wide = str.substr (i, 1);
104         bool found = false;
105
106         for (unsigned int j = 0; scim_anthy_wide_table[j].code; j++) {
107             if (scim_anthy_wide_table[j].wide &&
108                 wide == utf8_mbstowcs (scim_anthy_wide_table[j].wide))
109             {
110                 half += scim_anthy_wide_table[j].code;
111                 found = true;
112                 break;
113             }
114         }
115
116         if (!found)
117             half += utf8_wcstombs (wide);
118     }
119 }
120
121 void
122 util_convert_to_katakana (WideString & kata,
123                           const WideString & hira,
124                           bool half)
125 {
126     if (hira.length () < 0)
127         return;
128
129     for (unsigned int i = 0; i < hira.length (); i++) {
130         WideString tmpwide;
131         bool found = false;
132
133         HiraganaKatakanaRule *table = scim_anthy_hiragana_katakana_table;
134
135         for (unsigned int j = 0; table[j].hiragana; j++) {
136             tmpwide = utf8_mbstowcs (table[j].hiragana);
137             if (hira.substr(i, 1) == tmpwide) {
138                 if (half)
139                     kata += utf8_mbstowcs (table[j].half_katakana);
140                 else
141                     kata += utf8_mbstowcs (table[j].katakana);
142                 found = true;
143                 break;
144             }
145         }
146
147         if (!found)
148             kata += hira.substr(i, 1);
149     }
150 }
151
152 void
153 util_create_attributes (AttributeList &attrs,
154                         unsigned int start,
155                         unsigned int length,
156                         String type,
157                         unsigned int fg_color,
158                         unsigned int bg_color)
159 {
160     if (type == "None") {
161         return;
162     } else if (type == "Underline") {
163         attrs.push_back (Attribute (start, length,
164                                     SCIM_ATTR_DECORATE, 
165                                     SCIM_ATTR_DECORATE_UNDERLINE));
166     } else if (type == "Reverse") {
167         attrs.push_back (Attribute (start, length,
168                                     SCIM_ATTR_DECORATE, 
169                                     SCIM_ATTR_DECORATE_REVERSE));
170     } else if (type == "Highlight") {
171         attrs.push_back (Attribute (start, length,
172                                     SCIM_ATTR_DECORATE, 
173                                     SCIM_ATTR_DECORATE_HIGHLIGHT));
174     } else {
175         if (type == "Color" || type == "FGColor")
176             attrs.push_back (Attribute (start, length,
177                                         SCIM_ATTR_FOREGROUND,
178                                         fg_color));
179         if (type == "Color" || type == "BGColor")
180             attrs.push_back (Attribute (start, length,
181                                         SCIM_ATTR_BACKGROUND,
182                                         bg_color));
183     }
184 }
185
186 bool
187 util_key_is_keypad (const KeyEvent &key)
188 {
189     switch (key.code) {
190     case SCIM_KEY_KP_Equal:
191     case SCIM_KEY_KP_Multiply:
192     case SCIM_KEY_KP_Add:
193     case SCIM_KEY_KP_Separator:
194     case SCIM_KEY_KP_Subtract:
195     case SCIM_KEY_KP_Decimal:
196     case SCIM_KEY_KP_Divide:
197     case SCIM_KEY_KP_0:
198     case SCIM_KEY_KP_1:
199     case SCIM_KEY_KP_2:
200     case SCIM_KEY_KP_3:
201     case SCIM_KEY_KP_4:
202     case SCIM_KEY_KP_5:
203     case SCIM_KEY_KP_6:
204     case SCIM_KEY_KP_7:
205     case SCIM_KEY_KP_8:
206     case SCIM_KEY_KP_9:
207         return true;
208     default:
209         return false;
210     }
211 }
212
213 void
214 util_keypad_to_string (String &str, const KeyEvent &key)
215 {
216     char raw[2];
217
218     switch (key.code) {
219     case SCIM_KEY_KP_Equal:
220         raw[0] = '=';
221         break;
222
223     case SCIM_KEY_KP_Multiply:
224         raw[0] = '*';
225         break;
226
227     case SCIM_KEY_KP_Add:
228         raw[0] = '+';
229         break;
230
231     case SCIM_KEY_KP_Separator:
232         raw[0] = ',';
233         break;
234
235     case SCIM_KEY_KP_Subtract:
236         raw[0] = '-';
237         break;
238
239     case SCIM_KEY_KP_Decimal:
240         raw[0] = '.';
241         break;
242
243     case SCIM_KEY_KP_Divide:
244         raw[0] = '/';
245         break;
246
247     case SCIM_KEY_KP_0:
248     case SCIM_KEY_KP_1:
249     case SCIM_KEY_KP_2:
250     case SCIM_KEY_KP_3:
251     case SCIM_KEY_KP_4:
252     case SCIM_KEY_KP_5:
253     case SCIM_KEY_KP_6:
254     case SCIM_KEY_KP_7:
255     case SCIM_KEY_KP_8:
256     case SCIM_KEY_KP_9:
257         raw[0] = '0' + key.code - SCIM_KEY_KP_0;
258         break;
259
260     default:
261         if (isprint (key.get_ascii_code()))
262             raw[0] = key.get_ascii_code();
263         else
264             raw[0] = '\0';
265         break;
266     }
267
268     raw[1] = '\0';
269     str = raw;
270 }
271
272 void
273 util_launch_program (const char *command)
274 {
275     if (!command) return;
276
277     /* split string */
278     unsigned int len = strlen (command);
279     char tmp[len + 1];
280     strncpy (tmp, command, len);
281     tmp[len] = '\0';
282
283     char *str = tmp;
284     std::vector<char *> array;
285
286     for (unsigned int i = 0; i < len + 1; i++) {
287         if (!tmp[i] || isspace (tmp[i])) {
288             if (*str) {
289                 tmp[i] = '\0';
290                 array.push_back (str);
291             }
292             str = tmp + i + 1;
293         }
294     }
295
296     if (array.size () <= 0) return;
297     array.push_back (NULL);
298
299     char *args[array.size()];
300     for (unsigned int i = 0; i < array.size (); i++)
301         args[i] = array[i];
302
303
304     /* exec command */
305         pid_t child_pid;
306
307         child_pid = fork();
308         if (child_pid < 0) {
309                 perror("fork");
310         } else if (child_pid == 0) {             /* child process  */
311                 pid_t grandchild_pid;
312
313                 grandchild_pid = fork();
314                 if (grandchild_pid < 0) {
315                         perror("fork");
316                         _exit(1);
317                 } else if (grandchild_pid == 0) { /* grandchild process  */
318                         execvp(args[0], args);
319                         perror("execvp");
320                         _exit(1);
321                 } else {
322                         _exit(0);
323                 }
324         } else {                              /* parent process */
325                 int status;
326                 waitpid(child_pid, &status, 0);
327         }
328 }
329
330 }