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
util_match_key_event(const KeyEventList & list,const KeyEvent & key,uint16 ignore_mask)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
util_split_string(String & str,std::vector<String> & str_list,char * delim,int num)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
util_convert_to_wide(WideString & wide,const String & str)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
util_convert_to_half(String & half,const WideString & str)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
util_convert_to_katakana(WideString & kata,const WideString & hira,bool half)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
util_create_attributes(AttributeList & attrs,unsigned int start,unsigned int length,String type,unsigned int fg_color,unsigned int bg_color)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
util_key_is_keypad(const KeyEvent & key)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
util_keypad_to_string(String & str,const KeyEvent & key)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
util_launch_program(const char * command)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 }
331