2
* Smart Common Input Method
4
* Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn>
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library 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 Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this program; if not, write to the
19
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20
* Boston, MA 02111-1307 USA
22
* $Id: scim_utility.cpp,v 1.48.2.5 2006/11/02 04:11:51 suzhe Exp $
25
#define Uses_SCIM_UTILITY
26
#define Uses_SCIM_CONFIG_PATH
36
#include <sys/types.h>
44
#include "scim_private.h"
50
utf8_mbtowc (ucs4_t *pwc, const unsigned char *src, int src_len)
55
unsigned char c = src [0];
60
} else if (c < 0xc2) {
62
} else if (c < 0xe0) {
65
if (!((src [1] ^ 0x80) < 0x40))
67
*pwc = ((ucs4_t) (c & 0x1f) << 6)
68
| (ucs4_t) (src [1] ^ 0x80);
70
} else if (c < 0xf0) {
73
if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40
74
&& (c >= 0xe1 || src [1] >= 0xa0)))
76
*pwc = ((ucs4_t) (c & 0x0f) << 12)
77
| ((ucs4_t) (src [1] ^ 0x80) << 6)
78
| (ucs4_t) (src [2] ^ 0x80);
80
} else if (c < 0xf8) {
83
if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40
84
&& (src [3] ^ 0x80) < 0x40
85
&& (c >= 0xf1 || src [1] >= 0x90)))
87
*pwc = ((ucs4_t) (c & 0x07) << 18)
88
| ((ucs4_t) (src [1] ^ 0x80) << 12)
89
| ((ucs4_t) (src [2] ^ 0x80) << 6)
90
| (ucs4_t) (src [3] ^ 0x80);
92
} else if (c < 0xfc) {
95
if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40
96
&& (src [3] ^ 0x80) < 0x40 && (src [4] ^ 0x80) < 0x40
97
&& (c >= 0xf9 || src [1] >= 0x88)))
99
*pwc = ((ucs4_t) (c & 0x03) << 24)
100
| ((ucs4_t) (src [1] ^ 0x80) << 18)
101
| ((ucs4_t) (src [2] ^ 0x80) << 12)
102
| ((ucs4_t) (src [3] ^ 0x80) << 6)
103
| (ucs4_t) (src [4] ^ 0x80);
105
} else if (c < 0xfe) {
107
return RET_TOOFEW(0);
108
if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40
109
&& (src [3] ^ 0x80) < 0x40 && (src [4] ^ 0x80) < 0x40
110
&& (src [5] ^ 0x80) < 0x40
111
&& (c >= 0xfd || src [1] >= 0x84)))
113
*pwc = ((ucs4_t) (c & 0x01) << 30)
114
| ((ucs4_t) (src [1] ^ 0x80) << 24)
115
| ((ucs4_t) (src [2] ^ 0x80) << 18)
116
| ((ucs4_t) (src [3] ^ 0x80) << 12)
117
| ((ucs4_t) (src [4] ^ 0x80) << 6)
118
| (ucs4_t) (src [5] ^ 0x80);
125
utf8_wctomb (unsigned char *dest, ucs4_t wc, int dest_size)
135
else if (wc < 0x10000)
137
else if (wc < 0x200000)
139
else if (wc < 0x4000000)
141
else if (wc <= 0x7fffffff)
145
if (dest_size < count)
147
switch (count) { /* note: code falls through cases! */
148
case 6: dest [5] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x4000000;
149
case 5: dest [4] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x200000;
150
case 4: dest [3] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x10000;
151
case 3: dest [2] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x800;
152
case 2: dest [1] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0xc0;
153
case 1: dest [0] = wc;
159
utf8_read_wchar (std::istream &is)
161
unsigned char utf8[6];
164
for (int i=0; i<6; ++i) {
165
is.read ((char*)(utf8+i), sizeof(unsigned char));
166
if ((count=utf8_mbtowc (&wc, utf8, i+1)) > 0)
168
if (count == RET_ILSEQ)
175
utf8_read_wstring (std::istream &is, ucs4_t delim, bool rm_delim)
179
while ((wc = utf8_read_wchar (is)) > 0) {
192
utf8_write_wchar (std::ostream &os, ucs4_t wc)
194
unsigned char utf8[6];
197
if ((count=utf8_wctomb (utf8, wc, 6)) > 0)
198
os.write ((char*)utf8, count * sizeof (unsigned char));
204
utf8_write_wstring (std::ostream &os, const WideString & wstr)
206
for (unsigned int i=0; i<wstr.size (); ++i)
207
utf8_write_wchar (os, wstr [i]);
213
utf8_mbstowcs (const String & str)
220
const unsigned char *s = (const unsigned char *) str.c_str ();
222
while (sn < str.length () && *s != 0 &&
223
(un=utf8_mbtowc (&wc, s, str.length () - sn)) > 0) {
232
utf8_mbstowcs (const char *str, int len)
241
if (len < 0) len = strlen (str);
243
while (sn < len && *str != 0 && (un=utf8_mbtowc (&wc, (const unsigned char *)str, len - sn)) > 0) {
254
utf8_wcstombs (const WideString & wstr)
260
for (unsigned int i = 0; i<wstr.size (); ++i) {
261
un = utf8_wctomb ((unsigned char*)utf8, wstr [i], 6);
263
str.append (utf8, un);
269
utf8_wcstombs (const ucs4_t *wstr, int len)
277
for (len = 0; wstr [len]; ++len) NULL;
279
for (int i = 0; i < len; ++i) {
280
un = utf8_wctomb ((unsigned char*)utf8, wstr [i], 6);
282
str.append (utf8, un);
289
scim_validate_locale (const String& locale)
293
String last = String (setlocale (LC_CTYPE, 0));
295
if (setlocale (LC_CTYPE, locale.c_str ())) {
298
std::vector<String> vec;
299
if (scim_split_string_list (vec, locale, '.') == 2) {
300
if (isupper (vec[1][0])) {
301
for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i)
302
*i = (char) tolower (*i);
304
for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i)
305
*i = (char) toupper (*i);
307
if (setlocale (LC_CTYPE, (vec[0] + "." + vec[1]).c_str ())) {
308
good = vec [0] + "." + vec[1];
313
setlocale (LC_CTYPE, last.c_str ());
319
scim_get_locale_encoding (const String& locale)
321
String last = String (setlocale (LC_CTYPE, 0));
324
if (setlocale (LC_CTYPE, locale.c_str ()))
325
encoding = String (nl_langinfo (CODESET));
327
std::vector<String> vec;
328
if (scim_split_string_list (vec, locale, '.') == 2) {
329
if (isupper (vec[1][0])) {
330
for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i)
331
*i = (char) tolower (*i);
333
for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i)
334
*i = (char) toupper (*i);
336
if (setlocale (LC_CTYPE, (vec[0] + "." + vec[1]).c_str ()))
337
encoding = String (nl_langinfo (CODESET));
342
setlocale (LC_CTYPE, last.c_str ());
348
scim_get_locale_maxlen (const String& locale)
352
String last = String (setlocale (LC_CTYPE, 0));
354
if (setlocale (LC_CTYPE, locale.c_str ()))
359
setlocale (LC_CTYPE, last.c_str ());
364
scim_split_string_list (std::vector<String>& vec, const String& str, char delim)
369
String::const_iterator bg, ed;
376
while (bg != str.end () && ed != str.end ()) {
377
for (; ed != str.end (); ++ed) {
381
temp.assign (bg, ed);
382
vec.push_back (temp);
385
if (ed != str.end ())
392
scim_combine_string_list (const std::vector<String>& vec, char delim)
395
for (std::vector<String>::const_iterator i = vec.begin (); i!=vec.end (); ++i) {
397
if (i+1 != vec.end ())
404
scim_if_wchar_ucs4_equal ()
406
if (sizeof (wchar_t) != sizeof (ucs4_t))
410
wchar_t wcbuf [2] = {0,0};
411
ucs4_t ucsbuf [2] = {0x4E00, 0x0001};
412
size_t wclen = 2 * sizeof (wchar_t);
413
size_t ucslen = 2 * sizeof (ucs4_t);
415
char *wcp = (char *) wcbuf;
416
ICONV_CONST char *ucsp = (ICONV_CONST char *) ucsbuf;
418
if (scim_is_little_endian ())
419
cd = iconv_open ("UCS-4LE", "wchar_t");
421
cd = iconv_open ("UCS-4BE", "wchar_t");
423
if (cd == (iconv_t) -1)
426
iconv (cd, &ucsp, &ucslen, &wcp, &wclen);
430
if (wcbuf [0] == (wchar_t) ucsbuf [0] &&
431
wcbuf [1] == (wchar_t) ucsbuf [1])
441
} __half_full_table [] = {
443
{0x0021, 0xFF01, 0x5E},
496
{0xFFA1, 0x3131, 30},
508
* convert a half width unicode char to full width char
511
scim_wchar_to_full_width (ucs4_t code)
514
while (__half_full_table [i].size) {
515
if (code >= __half_full_table [i].half &&
516
code < __half_full_table [i].half +
517
__half_full_table [i].size)
518
return __half_full_table [i].full +
519
(code - __half_full_table [i].half);
526
* convert a full width unicode char to half width char
529
scim_wchar_to_half_width (ucs4_t code)
532
while (__half_full_table [i].size) {
533
if (code >= __half_full_table [i].full &&
534
code < __half_full_table [i].full +
535
__half_full_table [i].size)
536
return __half_full_table [i].half +
537
(code - __half_full_table [i].full);
546
const char * home_dir = 0;
551
pw = getpwuid (getuid ());
555
home_dir = pw->pw_dir;
559
home_dir = getenv ("HOME");
562
return String (home_dir);
566
scim_get_user_name ()
569
const char *user_name;
572
pw = getpwuid (getuid ());
575
if (pw && pw->pw_name)
576
return String (pw->pw_name);
577
else if ((user_name = getenv ("USER")) != NULL)
578
return String (user_name);
582
snprintf (uid_str, 10, "%u", getuid ());
584
return String (uid_str);
588
scim_get_user_data_dir ()
590
String dir = scim_get_home_dir () + String ("/.scim");
596
scim_get_current_locale ()
598
char *locale = setlocale (LC_MESSAGES, 0);
600
if (locale) return String (locale);
604
String scim_get_current_language ()
606
return scim_get_locale_language (scim_get_current_locale ());
610
scim_is_little_endian ()
613
return (*((char *)&endian) != 0);
617
scim_load_file (const String &filename, char **bufptr)
619
if (!filename.length ())
624
if (stat (filename.c_str (), &statbuf) < 0 ||
625
!S_ISREG (statbuf.st_mode) ||
630
return statbuf.st_size;
632
FILE *fp = fopen (filename.c_str (), "r");
640
*bufptr = new char [statbuf.st_size];
651
size_t size = fread (*bufptr, 1, statbuf.st_size, fp);
664
scim_make_dir (const String &dir)
666
std::vector <String> paths;
669
scim_split_string_list (paths, dir, SCIM_PATH_DELIM);
671
for (size_t i = 0; i < paths.size (); ++i) {
672
path += SCIM_PATH_DELIM_STRING + paths [i];
674
//Make the dir if it's not exist.
675
if (access (path.c_str (), R_OK) != 0) {
676
mkdir (path.c_str (), S_IRUSR | S_IWUSR | S_IXUSR);
677
if (access (path.c_str (), R_OK) != 0)
686
const char *normalized;
688
const char *untranslated;
689
const char *locale_suffix;
692
static __Language __languages [] = {
693
{ "C", NULL, N_("English/Keyboard"), NULL, NULL},
694
{ "am_ET", NULL, N_("Amharic"), NULL, NULL },
695
{ "ar", "ar_EG", N_("Arabic"), NULL, NULL },
696
{ "ar_EG", NULL, N_("Arabic (Egypt)"), NULL, NULL },
697
{ "ar_LB", NULL, N_("Arabic (Lebanon)"), NULL, NULL },
698
{ "as_IN", NULL, N_("Assamese"), NULL, NULL},
699
{ "az_AZ", NULL, N_("Azerbaijani"), NULL, NULL },
700
{ "be_BY", NULL, N_("Belarusian"), "Беларуская мова", NULL },
701
{ "bg_BG", NULL, N_("Bulgarian"), "Български", NULL },
702
{ "bn", "bn_BD", N_("Bengali"), "বাংলা", NULL },
703
{ "bn_BD", NULL, N_("Bengali"), "বাংলা", NULL },
704
{ "bn_IN", NULL, N_("Bengali (India)"), "বাংলা", NULL },
705
{ "bo", NULL, N_("Tibetan"), NULL, NULL },
706
{ "bs_BA", NULL, N_("Bosnian"), NULL, NULL },
707
{ "ca_ES", NULL, N_("Catalan"), "Català", "@euro" },
708
{ "cs_CZ", NULL, N_("Czech"), "čeština", NULL },
709
{ "cy_GB", NULL, N_("Welsh"), "Cymraeg", NULL },
710
{ "da_DK", NULL, N_("Danish"), "dansk", "@euro" },
711
{ "de_DE", NULL, N_("German"), "Deutsch", "@euro" },
712
{ "dv_MV", NULL, N_("Divehi"), "ދިވެހިބަސް", NULL },
713
{ "el_GR", NULL, N_("Greek"), "ελληνικά", NULL },
714
{ "en" , "en_US", N_("English"), "English", NULL },
715
{ "en_AU", NULL, N_("English (Australian)"), "Australian English", NULL },
716
{ "en_CA", NULL, N_("English (Canadian)"), "Canadian English", NULL },
717
{ "en_GB", NULL, N_("English (British)"), "British English", ".iso885915" },
718
{ "en_IE", NULL, N_("English (Ireland)"), "Irish English", NULL },
719
{ "en_US", NULL, N_("English (American)"), "American English", ".iso885915" },
720
{ "eo", NULL, N_("Esperanto"), "Esperanto", NULL },
721
{ "es", "es_ES", N_("Spanish"), "Español", NULL },
722
{ "es_ES", NULL, N_("Spanish"), "Español", "@euro" },
723
{ "es_MX", NULL, N_("Spanish (Mexico)"), "Español (Mexico)", NULL },
724
{ "et_EE", NULL, N_("Estonian"), "Eesti", ".iso885915" },
725
{ "eu_ES", NULL, N_("Basque"), "Euskara", "@euro" },
726
{ "fa_IR", NULL, N_("Persian"), "فارسی", NULL },
727
{ "fi_FI", NULL, N_("Finnish"), "Suomi", "@euro" },
728
{ "fr_FR", NULL, N_("French"), "Français", "@euro" },
729
{ "ga_IE", NULL, N_("Irish"), "Gaeilge", "@euro" },
730
{ "gl_ES", NULL, N_("Galician"), "Galego", "@euro" },
731
{ "gu_IN", NULL, N_("Gujarati"), NULL, NULL },
732
{ "he_IL", NULL, N_("Hebrew"), "עברית", NULL },
733
{ "hi_IN", NULL, N_("Hindi"), "हिंदी", NULL },
734
{ "hr_HR", NULL, N_("Croatian"), "Hrvatski", NULL },
735
{ "hu_HU", NULL, N_("Hungarian"), "Magyar", NULL },
736
{ "hy_AM", NULL, N_("Armenian"), "Հայերէն", NULL },
737
{ "ia" , NULL, N_("Interlingua"), NULL },
738
{ "id_ID", NULL, N_("Indonesian"), "Bahasa Indonesia", NULL },
739
{ "is_IS", NULL, N_("Icelandic"), NULL, NULL },
740
{ "it_IT", NULL, N_("Italian"), "Italiano", "@euro" },
741
{ "iw_IL", NULL, N_("Hebrew"), "עברית", NULL },
742
{ "ja_JP", NULL, N_("Japanese"), "日本語", ".EUC-JP,.SJIS,.eucJP" },
743
{ "ka_GE", NULL, N_("Georgian"), "ქართული", NULL },
744
{ "kk_KZ", NULL, N_("Kazakh"), NULL, NULL },
745
{ "km", NULL, N_("Cambodian"), NULL, NULL },
746
{ "kn_IN", NULL, N_("Kannada"), "ಕನ್ನಡ", NULL },
747
{ "ko_KR", NULL, N_("Korean"), "한국어", ".EUC-KR,.eucKR" },
748
{ "lo_LA", NULL, N_("Laothian"), NULL, NULL },
749
{ "lt_LT", NULL, N_("Lithuanian"), "Lietuvių", NULL },
750
{ "lv_LV", NULL, N_("Latvian"), "Latviešu", NULL },
751
{ "mk_MK", NULL, N_("Macedonian"), NULL, NULL },
752
{ "ml_IN", NULL, N_("Malayalam"), "മലയാളം", NULL },
753
{ "mn_MN", NULL, N_("Mongolian"), "Монгол", NULL },
754
{ "mr_IN", NULL, N_("Marathi"), NULL, NULL },
755
{ "ms_MY", NULL, N_("Malay"), "Bahasa Melayu", NULL },
756
{ "my_MM", NULL, N_("Burmese"), "", NULL },
757
{ "ne_NP", NULL, N_("Nepali"), NULL, NULL },
758
{ "nl_NL", NULL, N_("Dutch"), "Nederlands", "@euro" },
759
{ "nn_NO", NULL, N_("Norwegian (nynorsk)"), "Norsk (nynorsk)", NULL },
760
{ "no_NO", NULL, N_("Norwegian (bokmal)"), "Norsk (bokmål)", NULL },
761
{ "or_IN", NULL, N_("Oriya"), NULL, NULL },
762
{ "pa_IN", NULL, N_("Punjabi"), NULL, NULL },
763
{ "pl_PL", NULL, N_("Polish"), "Polski", NULL },
764
{ "pt", "pt_PT", N_("Portuguese"), "Português", NULL },
765
{ "pt_BR", NULL, N_("Portuguese (Brazil)"), "Português do Brasil", NULL },
766
{ "pt_PT", NULL, N_("Portuguese"), "Português", "@euro" },
767
{ "ro_RO", NULL, N_("Romanian"), "Română", NULL },
768
{ "ru_RU", NULL, N_("Russian"), "русский", ".koi8r" },
769
{ "si_LK", NULL, N_("Sinhala"), "සිංහල", NULL },
770
{ "sk_SK", NULL, N_("Slovak"), "Slovenský", NULL },
771
{ "sl_SI", NULL, N_("Slovenian"), "Slovenščina", NULL },
772
{ "sq_AL", NULL, N_("Albanian"), "Shqip", NULL },
773
{ "sr", "sr_YU", N_("Serbian"), "српски", NULL },
774
{ "sr_CS", NULL, N_("Serbian"), "српски", NULL },
775
{ "sr_YU", NULL, N_("Serbian"), "српски", "@cyrillic" },
776
{ "sv", "sv_SE", N_("Swedish"), "Svenska", NULL },
777
{ "sv_FI", NULL, N_("Swedish (Finland)"), "Svenska (Finland)", "@euro" },
778
{ "sv_SE", NULL, N_("Swedish"), "Svenska", ".iso885915" },
779
{ "ta_IN", NULL, N_("Tamil"), NULL, NULL },
780
{ "te_IN", NULL, N_("Telugu"), NULL, NULL },
781
{ "th_TH", NULL, N_("Thai"), "ไทย", NULL },
782
{ "tr_TR", NULL, N_("Turkish"), "Türkçe", NULL },
783
{ "ug", NULL, N_("Uighur"), NULL, NULL },
784
{ "uk_UA", NULL, N_("Ukrainian"), "Українська", NULL },
785
{ "ur_PK", NULL, N_("Urdu"), NULL, NULL },
786
{ "uz_UZ", NULL, N_("Uzbek"), NULL, "@cyrillic" },
787
{ "vi_VN", NULL, N_("Vietnamese"), "Việt Nam", ".tcvn" },
788
{ "wa_BE", NULL, N_("Walloon"), "Walon", "@euro" },
789
{ "yi" , "yi_US", N_("Yiddish"), "ייִדיש", NULL },
790
{ "yi_US", NULL, N_("Yiddish"), "ייִדיש", NULL },
791
{ "zh", "zh_CN", N_("Chinese"), "中文", NULL },
792
{ "zh_CN", NULL, N_("Chinese (simplified)"), "中文 (简体)", ".GB18030,.GBK,.GB2312,.eucCN" },
793
{ "zh_HK", "zh_TW", N_("Chinese (traditional)"), "中文 (繁體)", NULL },
794
{ "zh_SG", "zh_CN", N_("Chinese (simplified)"), "中文 (简体)", ".GBK" },
795
{ "zh_TW", NULL, N_("Chinese (traditional)"), "中文 (繁體)", ".eucTW" },
796
{ "", "", "", NULL, NULL }
802
bool operator () (const __Language &lhs, const __Language &rhs) const {
803
return strcmp (lhs.code, rhs.code) < 0;
806
bool operator () (const __Language &lhs, const String &rhs) const {
807
return strcmp (lhs.code, rhs.c_str ()) < 0;
810
bool operator () (const String &lhs, const __Language &rhs) const {
811
return strcmp (lhs.c_str (), rhs.code) < 0;
816
__find_language (const String &lang)
818
static __Language *langs_begin = __languages;
819
static __Language *langs_end = __languages + sizeof (__languages) / sizeof (__Language) - 1;
822
bool contry_code = false;
824
// Normalize the language name.
825
for (String::iterator it = nlang.begin (); it != nlang.end (); ++it) {
826
if (*it == '-' || *it == '_') {
829
} else if (contry_code) {
836
__Language *result = std::lower_bound (langs_begin, langs_end, nlang, __LanguageLess ());
838
if (result != langs_end) {
839
if (strncmp (result->code, nlang.c_str (), strlen (result->code)) == 0 ||
840
(strncmp (result->code, nlang.c_str (), nlang.length ()) == 0 &&
841
strncmp (result->code, (result+1)->code, nlang.length ()) != 0))
849
scim_get_language_name (const String &lang)
851
return String (_(scim_get_language_name_english (lang).c_str ()));
855
scim_get_language_name_english (const String &lang)
857
__Language *result = __find_language (lang);
860
return String (result->name);
862
return String ("Other");
866
scim_get_language_name_untranslated (const String &lang)
868
__Language *result = __find_language (lang);
871
if (result->untranslated)
872
return String (result->untranslated);
874
return String (_(result->name));
877
return String (_("Other"));
881
scim_get_language_locales (const String &lang)
883
__Language *result = __find_language (lang);
885
std::vector<String> locales;
890
if (strlen (result->code) < 5 && result->normalized)
891
result = __find_language (result->normalized);
893
good = scim_validate_locale (String (result->code) + ".UTF-8");
895
if (good.length ()) locales.push_back (good);
897
if (result->locale_suffix) {
898
std::vector<String> suffixes;
900
scim_split_string_list (suffixes, result->locale_suffix, ',');
901
for (size_t i = 0; i < suffixes.size (); ++ i) {
902
good = scim_validate_locale (String (result->code) + suffixes [i]);
903
if (good.length ()) locales.push_back (good);
907
good = scim_validate_locale (result->code);
909
if (good.length ()) locales.push_back (good);
912
return scim_combine_string_list (locales, ',');
916
scim_get_locale_language (const String &locale)
918
if (locale.length () == 0) return String ();
920
String str = locale.substr (0, locale.find ('.'));
921
return scim_validate_language (str.substr (0, str.find ('@')));
925
scim_validate_language (const String &lang)
927
__Language *result = __find_language (lang);
930
return String (result->code);
932
// Add prefix ~ to let other become the last item when sorting.
933
return String ("~other");
937
scim_get_normalized_language (const String &lang)
939
__Language *result = __find_language (lang);
942
if (result->normalized) return String (result->normalized);
943
else return String (result->code);
946
// Add prefix ~ to let other become the last item when sorting.
947
return String ("~other");
950
#ifndef SCIM_LAUNCHER
951
#define SCIM_LAUNCHER (SCIM_LIBEXECDIR "/scim-launcher")
954
int scim_launch (bool daemon,
955
const String &config,
956
const String &imengines,
957
const String &frontend,
958
char * const argv [])
960
if (!config.length () || !imengines.length () || !frontend.length ())
965
char verbose_buf [10];
967
new_argv [new_argc ++] = strdup (SCIM_LAUNCHER);
970
new_argv [new_argc ++] = strdup ("-d");
972
new_argv [new_argc ++] = strdup ("-c");
973
new_argv [new_argc ++] = strdup (config.c_str ());
974
new_argv [new_argc ++] = strdup ("-e");
975
new_argv [new_argc ++] = strdup (imengines.c_str ());
976
new_argv [new_argc ++] = strdup ("-f");
977
new_argv [new_argc ++] = strdup (frontend.c_str ());
980
for (int i = 0; argv [i] && new_argc < 40 ; ++i, ++new_argc)
981
new_argv [new_argc] = strdup (argv [i]);
984
new_argv [new_argc] = 0;
991
if (child_pid < 0) return -1;
993
// In child process, start scim-launcher.
994
if (child_pid == 0) {
995
return execv (SCIM_LAUNCHER, new_argv);
998
// In parent process, wait the child exit.
1000
for (int i = 0; i < new_argc; ++i)
1001
if (new_argv [i]) free (new_argv [i]);
1006
ret_pid = waitpid (child_pid, &status, 0);
1008
if (ret_pid == child_pid && WIFEXITED(status))
1009
return WEXITSTATUS(status);
1014
#ifndef SCIM_PANEL_PROGRAM
1015
#define SCIM_PANEL_PROGRAM (SCIM_LIBEXECDIR "/scim-panel-gtk")
1018
int scim_launch_panel (bool daemon,
1019
const String &config,
1020
const String &display,
1021
char * const argv [])
1023
if (!config.length ())
1026
String panel_program = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM, String (SCIM_PANEL_PROGRAM));
1028
if (!panel_program.length ())
1029
panel_program = String (SCIM_PANEL_PROGRAM);
1031
if (panel_program [0] != SCIM_PATH_DELIM) {
1032
panel_program = String (SCIM_LIBEXECDIR) +
1033
String (SCIM_PATH_DELIM_STRING) +
1037
//if the file is not exist or is not executable, fallback to default
1038
if (access (panel_program.c_str (), X_OK) != 0)
1039
panel_program = String (SCIM_PANEL_PROGRAM);
1042
char *new_argv [80];
1044
new_argv [new_argc ++] = strdup (panel_program.c_str ());
1046
new_argv [new_argc ++] = strdup ("--display");
1047
new_argv [new_argc ++] = strdup (display.c_str ());
1049
new_argv [new_argc ++] = strdup ("-c");
1050
new_argv [new_argc ++] = strdup (config.c_str ());
1053
new_argv [new_argc ++] = strdup ("-d");
1056
for (int i = 0; argv [i] && new_argc < 40; ++i, ++new_argc)
1057
new_argv [new_argc] = strdup (argv [i]);
1060
new_argv [new_argc] = 0;
1064
child_pid = fork ();
1067
if (child_pid < 0) return -1;
1069
// In child process, start scim-launcher.
1070
if (child_pid == 0) {
1071
return execv (panel_program.c_str (), new_argv);
1074
// In parent process, wait the child exit.
1076
for (int i = 0; i < new_argc; ++i)
1077
if (new_argv [i]) free (new_argv [i]);
1082
ret_pid = waitpid (child_pid, &status, 0);
1084
if (ret_pid == child_pid && WIFEXITED(status))
1085
return WEXITSTATUS(status);
1091
scim_usleep (unsigned int usec)
1093
if (usec == 0) return;
1096
struct timespec req, rem;
1098
req.tv_sec = usec / 1000000;
1099
req.tv_nsec = (usec % 1000000) * 1000;
1101
while (nanosleep (&req, &rem) == -1 && errno == EINTR && (rem.tv_sec != 0 || rem.tv_nsec != 0))
1104
unsigned int sec = usec / 1000000;
1107
for (unsigned int i = 0; i < sec; ++i)
1112
unsigned int sec = usec / 1000000;
1114
sleep (sec ? sec : 1);
1121
if (daemon (0, 0) == -1)
1122
std::cerr << "Error to make SCIM into a daemon!\n";
1130
std::cerr << "Error to make SCIM into a daemon!\n";
1132
} else if (id > 0) {
1138
std::cerr << "Error to make SCIM into a daemon!\n";
1140
} else if (id > 0) {
1151
vi:ts=4:ai:nowrap:expandtab