~ubuntu-branches/ubuntu/wily/scim/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/29_scim-1.4.7-bz462820.patch/src/scim_utility.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Rolf Leggewie
  • Date: 2010-08-11 18:28:44 UTC
  • mfrom: (3.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100811182844-rnn95k63cwehtm75
Tags: 1.4.9-5
* debian/copyright: add my copyright
* debian/control: update to standard 3.9.1, no further changes necessary

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Smart Common Input Method
 
3
 * 
 
4
 * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn>
 
5
 *
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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
 
21
 *
 
22
 * $Id: scim_utility.cpp,v 1.48.2.5 2006/11/02 04:11:51 suzhe Exp $
 
23
 */
 
24
 
 
25
#define Uses_SCIM_UTILITY
 
26
#define Uses_SCIM_CONFIG_PATH
 
27
#define Uses_C_LOCALE
 
28
#define Uses_C_ICONV
 
29
#define Uses_C_STDLIB
 
30
#define Uses_C_STRING
 
31
 
 
32
#include <langinfo.h>
 
33
#include <pwd.h>
 
34
#include <dirent.h>
 
35
#include <ctype.h>
 
36
#include <sys/types.h>
 
37
#include <sys/wait.h>
 
38
#include <sys/stat.h>
 
39
#include <unistd.h>
 
40
#include <stdio.h>
 
41
#include <time.h>
 
42
#include <errno.h>
 
43
 
 
44
#include "scim_private.h"
 
45
#include "scim.h"
 
46
 
 
47
namespace scim {
 
48
 
 
49
int
 
50
utf8_mbtowc (ucs4_t *pwc, const unsigned char *src, int src_len)
 
51
{
 
52
    if (!pwc)
 
53
        return 0;
 
54
 
 
55
    unsigned char c = src [0];
 
56
 
 
57
    if (c < 0x80) {
 
58
        *pwc = c;
 
59
        return 1;
 
60
    } else if (c < 0xc2) {
 
61
        return RET_ILSEQ;
 
62
    } else if (c < 0xe0) {
 
63
        if (src_len < 2)
 
64
            return RET_TOOFEW(0);
 
65
        if (!((src [1] ^ 0x80) < 0x40))
 
66
            return RET_ILSEQ;
 
67
        *pwc = ((ucs4_t) (c & 0x1f) << 6)
 
68
                 | (ucs4_t) (src [1] ^ 0x80);
 
69
        return 2;
 
70
    } else if (c < 0xf0) {
 
71
        if (src_len < 3)
 
72
            return RET_TOOFEW(0);
 
73
        if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40
 
74
                && (c >= 0xe1 || src [1] >= 0xa0)))
 
75
            return RET_ILSEQ;
 
76
        *pwc = ((ucs4_t) (c & 0x0f) << 12)
 
77
                 | ((ucs4_t) (src [1] ^ 0x80) << 6)
 
78
                 | (ucs4_t) (src [2] ^ 0x80);
 
79
        return 3;
 
80
    } else if (c < 0xf8) {
 
81
        if (src_len < 4)
 
82
            return RET_TOOFEW(0);
 
83
        if (!((src [1] ^ 0x80) < 0x40 && (src [2] ^ 0x80) < 0x40
 
84
                && (src [3] ^ 0x80) < 0x40
 
85
                && (c >= 0xf1 || src [1] >= 0x90)))
 
86
            return RET_ILSEQ;
 
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);
 
91
        return 4;
 
92
    } else if (c < 0xfc) {
 
93
        if (src_len < 5)
 
94
            return RET_TOOFEW(0);
 
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)))
 
98
            return RET_ILSEQ;
 
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);
 
104
        return 5;
 
105
    } else if (c < 0xfe) {
 
106
        if (src_len < 6)
 
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)))
 
112
            return RET_ILSEQ;
 
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);
 
119
        return 6;
 
120
    } else
 
121
        return RET_ILSEQ;
 
122
}
 
123
 
 
124
int
 
125
utf8_wctomb (unsigned char *dest, ucs4_t wc, int dest_size)
 
126
{
 
127
    if (!dest)
 
128
        return 0;
 
129
 
 
130
    int count;
 
131
    if (wc < 0x80)
 
132
        count = 1;
 
133
    else if (wc < 0x800)
 
134
        count = 2;
 
135
    else if (wc < 0x10000)
 
136
        count = 3;
 
137
    else if (wc < 0x200000)
 
138
        count = 4;
 
139
    else if (wc < 0x4000000)
 
140
        count = 5;
 
141
    else if (wc <= 0x7fffffff)
 
142
        count = 6;
 
143
    else
 
144
        return RET_ILSEQ;
 
145
    if (dest_size < count)
 
146
        return RET_TOOSMALL;
 
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;
 
154
    }
 
155
    return count;
 
156
}
 
157
 
 
158
ucs4_t
 
159
utf8_read_wchar (std::istream &is)
 
160
{
 
161
    unsigned char utf8[6];
 
162
    ucs4_t wc;
 
163
    int count;
 
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) 
 
167
            return wc;
 
168
        if (count == RET_ILSEQ)
 
169
            return 0;
 
170
    }
 
171
    return 0;
 
172
}
 
173
 
 
174
WideString
 
175
utf8_read_wstring (std::istream &is, ucs4_t delim, bool rm_delim)
 
176
{
 
177
    WideString str;
 
178
    ucs4_t wc;
 
179
    while ((wc = utf8_read_wchar (is)) > 0) {
 
180
        if (wc != delim)
 
181
            str.push_back (wc);
 
182
        else {
 
183
            if (!rm_delim)
 
184
                str.push_back (wc);
 
185
            break;
 
186
        }
 
187
    }
 
188
    return str;
 
189
}
 
190
 
 
191
std::ostream &
 
192
utf8_write_wchar (std::ostream &os, ucs4_t wc)
 
193
{
 
194
    unsigned char utf8[6];
 
195
    int count = 0;
 
196
 
 
197
    if ((count=utf8_wctomb (utf8, wc, 6)) > 0)
 
198
        os.write ((char*)utf8, count * sizeof (unsigned char));
 
199
 
 
200
    return os;
 
201
}
 
202
 
 
203
std::ostream &
 
204
utf8_write_wstring (std::ostream &os, const WideString & wstr)
 
205
{
 
206
    for (unsigned int i=0; i<wstr.size (); ++i)
 
207
        utf8_write_wchar (os, wstr [i]);
 
208
 
 
209
    return os;
 
210
}
 
211
 
 
212
WideString
 
213
utf8_mbstowcs (const String & str)
 
214
{
 
215
    WideString wstr;
 
216
    ucs4_t wc;
 
217
    unsigned int sn = 0;
 
218
    int un = 0;
 
219
 
 
220
    const unsigned char *s = (const unsigned char *) str.c_str ();
 
221
 
 
222
    while (sn < str.length () && *s != 0 &&
 
223
            (un=utf8_mbtowc (&wc, s, str.length () - sn)) > 0) {
 
224
        wstr.push_back (wc);
 
225
        s += un;
 
226
        sn += un;
 
227
    }
 
228
    return wstr;
 
229
}
 
230
 
 
231
WideString
 
232
utf8_mbstowcs (const char *str, int len)
 
233
{
 
234
    WideString wstr;
 
235
 
 
236
    if (str) {
 
237
        ucs4_t wc;
 
238
        unsigned int sn = 0;
 
239
        int un = 0;
 
240
 
 
241
        if (len < 0) len = strlen (str);
 
242
 
 
243
        while (sn < len && *str != 0 && (un=utf8_mbtowc (&wc, (const unsigned char *)str, len - sn)) > 0) {
 
244
            wstr.push_back (wc);
 
245
            str += un;
 
246
            sn += un;
 
247
    
 
248
        }
 
249
    }
 
250
    return wstr;
 
251
}
 
252
 
 
253
String
 
254
utf8_wcstombs (const WideString & wstr)
 
255
{
 
256
    String str;
 
257
    char utf8 [6];
 
258
    int un = 0;
 
259
 
 
260
    for (unsigned int i = 0; i<wstr.size (); ++i) {
 
261
        un = utf8_wctomb ((unsigned char*)utf8, wstr [i], 6);
 
262
        if (un > 0)
 
263
            str.append (utf8, un);
 
264
    }
 
265
    return str;
 
266
}
 
267
 
 
268
String
 
269
utf8_wcstombs (const ucs4_t *wstr, int len)
 
270
{
 
271
    String str;
 
272
    char utf8 [6];
 
273
    int un = 0;
 
274
 
 
275
    if (wstr) {
 
276
        if (len < 0)
 
277
            for (len = 0; wstr [len]; ++len) NULL;
 
278
 
 
279
        for (int i = 0; i < len; ++i) {
 
280
            un = utf8_wctomb ((unsigned char*)utf8, wstr [i], 6);
 
281
            if (un > 0)
 
282
                str.append (utf8, un);
 
283
        }
 
284
    }
 
285
    return str;
 
286
}
 
287
 
 
288
String
 
289
scim_validate_locale (const String& locale)
 
290
{
 
291
    String good;
 
292
 
 
293
    String last = String (setlocale (LC_CTYPE, 0));
 
294
 
 
295
    if (setlocale (LC_CTYPE, locale.c_str ())) {
 
296
        good = locale;
 
297
    } else {
 
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);
 
303
            } else {
 
304
                for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i) 
 
305
                    *i = (char) toupper (*i);
 
306
            }
 
307
            if (setlocale (LC_CTYPE, (vec[0] + "." + vec[1]).c_str ())) {
 
308
                good = vec [0] + "." + vec[1];
 
309
            }
 
310
        }
 
311
    }
 
312
 
 
313
    setlocale (LC_CTYPE, last.c_str ());
 
314
 
 
315
    return good;
 
316
}
 
317
 
 
318
String
 
319
scim_get_locale_encoding (const String& locale)
 
320
{
 
321
    String last = String (setlocale (LC_CTYPE, 0));
 
322
    String encoding;
 
323
 
 
324
    if (setlocale (LC_CTYPE, locale.c_str ()))
 
325
        encoding = String (nl_langinfo (CODESET));
 
326
    else {
 
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);
 
332
            } else {
 
333
                for (String::iterator i=vec[1].begin (); i!=vec[1].end (); ++i) 
 
334
                    *i = (char) toupper (*i);
 
335
            }
 
336
            if (setlocale (LC_CTYPE, (vec[0] + "." + vec[1]).c_str ()))
 
337
                encoding = String (nl_langinfo (CODESET));
 
338
        }
 
339
        
 
340
    }
 
341
 
 
342
    setlocale (LC_CTYPE, last.c_str ());
 
343
 
 
344
    return encoding;
 
345
}
 
346
 
 
347
int
 
348
scim_get_locale_maxlen (const String& locale)
 
349
{
 
350
    int maxlen;
 
351
 
 
352
    String last = String (setlocale (LC_CTYPE, 0));
 
353
 
 
354
    if (setlocale (LC_CTYPE, locale.c_str ()))
 
355
        maxlen = MB_CUR_MAX;
 
356
    else
 
357
        maxlen = 1;
 
358
 
 
359
    setlocale (LC_CTYPE, last.c_str ());
 
360
    return maxlen;
 
361
}
 
362
 
 
363
int
 
364
scim_split_string_list (std::vector<String>& vec, const String& str, char delim)
 
365
{
 
366
    int count = 0;
 
367
 
 
368
    String temp;
 
369
    String::const_iterator bg, ed;
 
370
 
 
371
    vec.clear ();
 
372
 
 
373
    bg = str.begin ();
 
374
    ed = str.begin ();
 
375
 
 
376
    while (bg != str.end () && ed != str.end ()) {
 
377
        for (; ed != str.end (); ++ed) {
 
378
            if (*ed == delim)
 
379
                break;
 
380
        }
 
381
        temp.assign (bg, ed);
 
382
        vec.push_back (temp);
 
383
        ++count;
 
384
 
 
385
        if (ed != str.end ())
 
386
            bg = ++ ed;
 
387
    }
 
388
    return count;
 
389
}
 
390
 
 
391
String
 
392
scim_combine_string_list (const std::vector<String>& vec, char delim)
 
393
{
 
394
    String result;
 
395
    for (std::vector<String>::const_iterator i = vec.begin (); i!=vec.end (); ++i) {
 
396
        result += *i;
 
397
        if (i+1 != vec.end ())
 
398
            result += delim;
 
399
    }
 
400
    return result;
 
401
}
 
402
 
 
403
bool
 
404
scim_if_wchar_ucs4_equal ()
 
405
{
 
406
    if (sizeof (wchar_t) != sizeof (ucs4_t))
 
407
        return false;
 
408
 
 
409
    iconv_t cd;
 
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);
 
414
 
 
415
    char *wcp = (char *) wcbuf;
 
416
    ICONV_CONST char *ucsp = (ICONV_CONST char *) ucsbuf;
 
417
 
 
418
    if (scim_is_little_endian ())
 
419
        cd = iconv_open ("UCS-4LE", "wchar_t");
 
420
    else
 
421
        cd = iconv_open ("UCS-4BE", "wchar_t");
 
422
    
 
423
    if (cd == (iconv_t) -1)
 
424
        return false;
 
425
 
 
426
    iconv (cd, &ucsp, &ucslen, &wcp, &wclen);
 
427
 
 
428
    iconv_close (cd);
 
429
 
 
430
    if (wcbuf [0] == (wchar_t) ucsbuf [0] &&
 
431
        wcbuf [1] == (wchar_t) ucsbuf [1])
 
432
        return true;
 
433
 
 
434
    return false;
 
435
}
 
436
 
 
437
static struct {
 
438
    ucs4_t half;
 
439
    ucs4_t full;
 
440
    ucs4_t size;
 
441
} __half_full_table [] = {
 
442
    {0x0020, 0x3000, 1},
 
443
    {0x0021, 0xFF01, 0x5E},
 
444
    {0x00A2, 0xFFE0, 2},
 
445
    {0x00A5, 0xFFE5, 1},
 
446
    {0x00A6, 0xFFE4, 1},
 
447
    {0x00AC, 0xFFE2, 1},
 
448
    {0x00AF, 0xFFE3, 1},
 
449
    {0x20A9, 0xFFE6, 1},
 
450
    {0xFF61, 0x3002, 1},
 
451
    {0xFF62, 0x300C, 2},
 
452
    {0xFF64, 0x3001, 1},
 
453
    {0xFF65, 0x30FB, 1},
 
454
    {0xFF66, 0x30F2, 1},
 
455
    {0xFF67, 0x30A1, 1},
 
456
    {0xFF68, 0x30A3, 1},
 
457
    {0xFF69, 0x30A5, 1},
 
458
    {0xFF6A, 0x30A7, 1},
 
459
    {0xFF6B, 0x30A9, 1},
 
460
    {0xFF6C, 0x30E3, 1},
 
461
    {0xFF6D, 0x30E5, 1},
 
462
    {0xFF6E, 0x30E7, 1},
 
463
    {0xFF6F, 0x30C3, 1},
 
464
    {0xFF70, 0x30FC, 1},
 
465
    {0xFF71, 0x30A2, 1},
 
466
    {0xFF72, 0x30A4, 1},
 
467
    {0xFF73, 0x30A6, 1},
 
468
    {0xFF74, 0x30A8, 1},
 
469
    {0xFF75, 0x30AA, 2},
 
470
    {0xFF77, 0x30AD, 1},
 
471
    {0xFF78, 0x30AF, 1},
 
472
    {0xFF79, 0x30B1, 1},
 
473
    {0xFF7A, 0x30B3, 1},
 
474
    {0xFF7B, 0x30B5, 1},
 
475
    {0xFF7C, 0x30B7, 1},
 
476
    {0xFF7D, 0x30B9, 1},
 
477
    {0xFF7E, 0x30BB, 1},
 
478
    {0xFF7F, 0x30BD, 1},
 
479
    {0xFF80, 0x30BF, 1},
 
480
    {0xFF81, 0x30C1, 1},
 
481
    {0xFF82, 0x30C4, 1},
 
482
    {0xFF83, 0x30C6, 1},
 
483
    {0xFF84, 0x30C8, 1},
 
484
    {0xFF85, 0x30CA, 6},
 
485
    {0xFF8B, 0x30D2, 1},
 
486
    {0xFF8C, 0x30D5, 1},
 
487
    {0xFF8D, 0x30D8, 1},
 
488
    {0xFF8E, 0x30DB, 1},
 
489
    {0xFF8F, 0x30DE, 5},
 
490
    {0xFF94, 0x30E4, 1},
 
491
    {0xFF95, 0x30E6, 1},
 
492
    {0xFF96, 0x30E8, 6},
 
493
    {0xFF9C, 0x30EF, 1},
 
494
    {0xFF9D, 0x30F3, 1},
 
495
    {0xFFA0, 0x3164, 1},
 
496
    {0xFFA1, 0x3131, 30},
 
497
    {0xFFC2, 0x314F, 6},
 
498
    {0xFFCA, 0x3155, 6},
 
499
    {0xFFD2, 0x315B, 9},
 
500
    {0xFFE9, 0x2190, 4},
 
501
    {0xFFED, 0x25A0, 1},
 
502
    {0xFFEE, 0x25CB, 1},
 
503
    {0,0,0}
 
504
};
 
505
 
 
506
 
 
507
/**
 
508
 * convert a half width unicode char to full width char
 
509
 */
 
510
ucs4_t
 
511
scim_wchar_to_full_width (ucs4_t code)
 
512
{
 
513
    int i=0;
 
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);
 
520
        ++ i;
 
521
    }
 
522
    return code;
 
523
}
 
524
 
 
525
/**
 
526
 * convert a full width unicode char to half width char
 
527
 */
 
528
ucs4_t
 
529
scim_wchar_to_half_width (ucs4_t code)
 
530
{
 
531
    int i=0;
 
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);
 
538
        ++ i;
 
539
    }
 
540
    return code;
 
541
}
 
542
 
 
543
String
 
544
scim_get_home_dir ()
 
545
{
 
546
    const char * home_dir = 0;
 
547
 
 
548
    struct passwd *pw;
 
549
 
 
550
    home_dir = getenv ("SCIM_HOME");
 
551
    if (home_dir && *home_dir) {
 
552
        return String (home_dir);
 
553
    }
 
554
 
 
555
    setpwent ();
 
556
    pw = getpwuid (getuid ());
 
557
    endpwent ();
 
558
 
 
559
    if (pw) {
 
560
        home_dir = pw->pw_dir;
 
561
    }
 
562
 
 
563
    if (!home_dir) {
 
564
        home_dir = getenv ("HOME");
 
565
    }
 
566
 
 
567
    return String (home_dir);
 
568
}
 
569
 
 
570
String
 
571
scim_get_user_name ()
 
572
{
 
573
    struct passwd *pw;
 
574
    const char *user_name;
 
575
 
 
576
    user_name = getenv ("SCIM_USER");
 
577
    if (user_name && *user_name) {
 
578
        return String (user_name);
 
579
    }
 
580
 
 
581
    setpwent ();
 
582
    pw = getpwuid (getuid ());
 
583
    endpwent ();
 
584
 
 
585
    if (pw && pw->pw_name)
 
586
        return String (pw->pw_name);
 
587
    else if ((user_name = getenv ("USER")) != NULL)
 
588
        return String (user_name);
 
589
 
 
590
    char uid_str [10];
 
591
 
 
592
    snprintf (uid_str, 10, "%u", getuid ());
 
593
 
 
594
    return String (uid_str);
 
595
}
 
596
 
 
597
String
 
598
scim_get_user_data_dir ()
 
599
{
 
600
    String dir = scim_get_home_dir () + String ("/.scim");
 
601
    scim_make_dir (dir);
 
602
    return dir;
 
603
}
 
604
 
 
605
String
 
606
scim_get_current_locale ()
 
607
{
 
608
    char *locale = setlocale (LC_MESSAGES, 0);
 
609
 
 
610
    if (locale) return String (locale);
 
611
    return String ();
 
612
}
 
613
 
 
614
String scim_get_current_language ()
 
615
{
 
616
    return scim_get_locale_language (scim_get_current_locale ());
 
617
}
 
618
 
 
619
bool
 
620
scim_is_little_endian ()
 
621
{
 
622
    short endian = 1;
 
623
    return (*((char *)&endian) != 0);
 
624
}
 
625
 
 
626
size_t
 
627
scim_load_file (const String &filename, char **bufptr)
 
628
{
 
629
    if (!filename.length ())
 
630
        return 0;
 
631
 
 
632
    struct stat statbuf;
 
633
 
 
634
    if (stat (filename.c_str (), &statbuf) < 0 ||
 
635
        !S_ISREG (statbuf.st_mode) ||
 
636
        !statbuf.st_size)
 
637
        return 0;
 
638
 
 
639
    if (!bufptr)
 
640
        return statbuf.st_size;
 
641
 
 
642
    FILE *fp = fopen (filename.c_str (), "r");
 
643
 
 
644
    if (fp == NULL) {
 
645
        *bufptr = 0;
 
646
        return 0;
 
647
    }
 
648
 
 
649
    try {
 
650
        *bufptr = new char [statbuf.st_size];
 
651
    } catch (...) {
 
652
        fclose (fp);
 
653
        throw;
 
654
    }
 
655
 
 
656
    if (! (*bufptr)) {
 
657
        fclose (fp);
 
658
        return 0;
 
659
    }
 
660
 
 
661
    size_t size = fread (*bufptr, 1, statbuf.st_size, fp);
 
662
 
 
663
    fclose (fp);
 
664
 
 
665
    if (!size) {
 
666
        delete [] *bufptr;
 
667
        *bufptr = 0;
 
668
    }
 
669
 
 
670
    return size;
 
671
}
 
672
 
 
673
bool
 
674
scim_make_dir (const String &dir)
 
675
{
 
676
    std::vector <String> paths;
 
677
    String path;
 
678
 
 
679
    scim_split_string_list (paths, dir, SCIM_PATH_DELIM);
 
680
 
 
681
    for (size_t i = 0; i < paths.size (); ++i) {
 
682
        path += SCIM_PATH_DELIM_STRING + paths [i];
 
683
 
 
684
        //Make the dir if it's not exist.
 
685
        if (access (path.c_str (), R_OK) != 0) {
 
686
            mkdir (path.c_str (), S_IRUSR | S_IWUSR | S_IXUSR);
 
687
            if (access (path.c_str (), R_OK) != 0)
 
688
                return false;
 
689
        }
 
690
    }
 
691
    return true;
 
692
}
 
693
 
 
694
struct __Language {
 
695
    const char *code;
 
696
    const char *normalized;
 
697
    const char *name;
 
698
    const char *untranslated;
 
699
    const char *locale_suffix;
 
700
};
 
701
 
 
702
static __Language __languages [] = {
 
703
    { "C",        NULL, N_("English/Keyboard"), NULL, NULL},
 
704
    { "am_ET",    NULL, N_("Amharic"), NULL, NULL },
 
705
    { "ar",    "ar_EG", N_("Arabic"), NULL, NULL },
 
706
    { "ar_EG",    NULL, N_("Arabic (Egypt)"), NULL, NULL },
 
707
    { "ar_LB",    NULL, N_("Arabic (Lebanon)"), NULL, NULL },
 
708
    { "as_IN",    NULL, N_("Assamese"), NULL, NULL}, 
 
709
    { "az_AZ",    NULL, N_("Azerbaijani"), NULL, NULL },
 
710
    { "be_BY",    NULL, N_("Belarusian"), "Беларуская мова", NULL },
 
711
    { "bg_BG",    NULL, N_("Bulgarian"), "Български", NULL },
 
712
    { "bn",    "bn_BD", N_("Bengali"), "বাংলা", NULL },
 
713
    { "bn_BD",    NULL, N_("Bengali"), "বাংলা", NULL },
 
714
    { "bn_IN",    NULL, N_("Bengali (India)"), "বাংলা", NULL },
 
715
    { "bo",       NULL, N_("Tibetan"), NULL, NULL },
 
716
    { "bs_BA",    NULL, N_("Bosnian"), NULL, NULL },
 
717
    { "ca_ES",    NULL, N_("Catalan"), "Català", "@euro" },
 
718
    { "cs_CZ",    NULL, N_("Czech"), "čeština", NULL },
 
719
    { "cy_GB",    NULL, N_("Welsh"), "Cymraeg", NULL },
 
720
    { "da_DK",    NULL, N_("Danish"), "dansk", "@euro" },
 
721
    { "de_DE",    NULL, N_("German"), "Deutsch", "@euro" },
 
722
    { "dv_MV",    NULL, N_("Divehi"), "ދިވެހިބަސް", NULL },
 
723
    { "el_GR",    NULL, N_("Greek"), "ελληνικά", NULL },
 
724
    { "en"   , "en_US", N_("English"), "English", NULL },
 
725
    { "en_AU",    NULL, N_("English (Australian)"), "Australian English", NULL },
 
726
    { "en_CA",    NULL, N_("English (Canadian)"), "Canadian English", NULL },
 
727
    { "en_GB",    NULL, N_("English (British)"), "British English", ".iso885915" },
 
728
    { "en_IE",    NULL, N_("English (Ireland)"), "Irish English", NULL },
 
729
    { "en_US",    NULL, N_("English (American)"), "American English", ".iso885915" },
 
730
    { "eo",       NULL, N_("Esperanto"), "Esperanto", NULL },
 
731
    { "es",    "es_ES", N_("Spanish"), "Español", NULL },
 
732
    { "es_ES",    NULL, N_("Spanish"), "Español", "@euro" },
 
733
    { "es_MX",    NULL, N_("Spanish (Mexico)"), "Español (Mexico)", NULL },
 
734
    { "et_EE",    NULL, N_("Estonian"), "Eesti", ".iso885915" },
 
735
    { "eu_ES",    NULL, N_("Basque"), "Euskara", "@euro" },
 
736
    { "fa_IR",    NULL, N_("Persian"), "فارسی", NULL },
 
737
    { "fi_FI",    NULL, N_("Finnish"), "Suomi", "@euro" },
 
738
    { "fr_FR",    NULL, N_("French"), "Français", "@euro" },
 
739
    { "ga_IE",    NULL, N_("Irish"), "Gaeilge", "@euro" },
 
740
    { "gl_ES",    NULL, N_("Galician"), "Galego", "@euro" },
 
741
    { "gu_IN",    NULL, N_("Gujarati"), NULL, NULL },
 
742
    { "he_IL",    NULL, N_("Hebrew"), "עברית", NULL },
 
743
    { "hi_IN",    NULL, N_("Hindi"), "हिंदी", NULL },
 
744
    { "hr_HR",    NULL, N_("Croatian"), "Hrvatski", NULL },
 
745
    { "hu_HU",    NULL, N_("Hungarian"), "Magyar", NULL },
 
746
    { "hy_AM",    NULL, N_("Armenian"), "Հայերէն", NULL },
 
747
    { "ia"   ,    NULL, N_("Interlingua"), NULL },
 
748
    { "id_ID",    NULL, N_("Indonesian"), "Bahasa Indonesia", NULL },
 
749
    { "is_IS",    NULL, N_("Icelandic"), NULL, NULL },
 
750
    { "it_IT",    NULL, N_("Italian"), "Italiano", "@euro" },
 
751
    { "iw_IL",    NULL, N_("Hebrew"), "עברית", NULL },
 
752
    { "ja_JP",    NULL, N_("Japanese"), "日本語", ".EUC-JP,.SJIS,.eucJP" },
 
753
    { "ka_GE",    NULL, N_("Georgian"), "ქართული", NULL },
 
754
    { "kk_KZ",    NULL, N_("Kazakh"), NULL, NULL },
 
755
    { "km",       NULL, N_("Cambodian"), NULL, NULL },
 
756
    { "kn_IN",    NULL, N_("Kannada"), "ಕನ್ನಡ", NULL },
 
757
    { "ko_KR",    NULL, N_("Korean"), "한국어", ".EUC-KR,.eucKR" },
 
758
    { "lo_LA",    NULL, N_("Laothian"), NULL, NULL },
 
759
    { "lt_LT",    NULL, N_("Lithuanian"), "Lietuvių", NULL },
 
760
    { "lv_LV",    NULL, N_("Latvian"), "Latviešu", NULL },
 
761
    { "mk_MK",    NULL, N_("Macedonian"), NULL, NULL },
 
762
    { "ml_IN",    NULL, N_("Malayalam"), "മലയാളം", NULL },
 
763
    { "mn_MN",    NULL, N_("Mongolian"), "Монгол", NULL },
 
764
    { "mr_IN",    NULL, N_("Marathi"), NULL, NULL },
 
765
    { "ms_MY",    NULL, N_("Malay"), "Bahasa Melayu", NULL },
 
766
    { "my_MM",    NULL, N_("Burmese"), "", NULL },
 
767
    { "ne_NP",    NULL, N_("Nepali"), NULL, NULL },
 
768
    { "nl_NL",    NULL, N_("Dutch"), "Nederlands", "@euro" },
 
769
    { "nn_NO",    NULL, N_("Norwegian (nynorsk)"), "Norsk (nynorsk)", NULL },
 
770
    { "no_NO",    NULL, N_("Norwegian (bokmal)"), "Norsk (bokmål)", NULL },
 
771
    { "or_IN",    NULL, N_("Oriya"), NULL, NULL },
 
772
    { "pa_IN",    NULL, N_("Punjabi"), NULL, NULL },
 
773
    { "pl_PL",    NULL, N_("Polish"), "Polski", NULL },
 
774
    { "pt",    "pt_PT", N_("Portuguese"), "Português", NULL },
 
775
    { "pt_BR",    NULL, N_("Portuguese (Brazil)"), "Português do Brasil", NULL },
 
776
    { "pt_PT",    NULL, N_("Portuguese"), "Português", "@euro" },
 
777
    { "ro_RO",    NULL, N_("Romanian"), "Română", NULL },
 
778
    { "ru_RU",    NULL, N_("Russian"), "русский", ".koi8r" },
 
779
    { "si_LK",    NULL, N_("Sinhala"), "සිංහල", NULL },
 
780
    { "sk_SK",    NULL, N_("Slovak"), "Slovenský", NULL },
 
781
    { "sl_SI",    NULL, N_("Slovenian"), "Slovenščina", NULL },
 
782
    { "sq_AL",    NULL, N_("Albanian"), "Shqip", NULL },
 
783
    { "sr",    "sr_YU", N_("Serbian"), "српски", NULL },
 
784
    { "sr_CS",    NULL, N_("Serbian"), "српски", NULL },
 
785
    { "sr_YU",    NULL, N_("Serbian"), "српски", "@cyrillic" },
 
786
    { "sv",    "sv_SE", N_("Swedish"), "Svenska", NULL },
 
787
    { "sv_FI",    NULL, N_("Swedish (Finland)"), "Svenska (Finland)", "@euro" },
 
788
    { "sv_SE",    NULL, N_("Swedish"), "Svenska", ".iso885915" },
 
789
    { "ta_IN",    NULL, N_("Tamil"), NULL, NULL },
 
790
    { "te_IN",    NULL, N_("Telugu"), NULL, NULL },
 
791
    { "th_TH",    NULL, N_("Thai"), "ไทย", NULL },
 
792
    { "tr_TR",    NULL, N_("Turkish"), "Türkçe", NULL },
 
793
    { "ug",       NULL, N_("Uighur"), NULL, NULL },
 
794
    { "uk_UA",    NULL, N_("Ukrainian"), "Українська", NULL },
 
795
    { "ur_PK",    NULL, N_("Urdu"), NULL, NULL },
 
796
    { "uz_UZ",    NULL, N_("Uzbek"), NULL, "@cyrillic" },
 
797
    { "vi_VN",    NULL, N_("Vietnamese"), "Việt Nam", ".tcvn" },
 
798
    { "wa_BE",    NULL, N_("Walloon"), "Walon", "@euro" },
 
799
    { "yi"   , "yi_US", N_("Yiddish"), "ייִדיש", NULL },
 
800
    { "yi_US",    NULL, N_("Yiddish"), "ייִדיש", NULL },
 
801
    { "zh",    "zh_CN", N_("Chinese"), "中文", NULL },
 
802
    { "zh_CN",    NULL, N_("Chinese (simplified)"), "中文 (简体)", ".GB18030,.GBK,.GB2312,.eucCN" },
 
803
    { "zh_HK", "zh_TW", N_("Chinese (traditional)"), "中文 (繁體)", NULL },
 
804
    { "zh_SG", "zh_CN", N_("Chinese (simplified)"), "中文 (简体)", ".GBK" },
 
805
    { "zh_TW",    NULL, N_("Chinese (traditional)"), "中文 (繁體)", ".eucTW" },
 
806
    { "", "", "", NULL, NULL }
 
807
};
 
808
 
 
809
class __LanguageLess
 
810
{
 
811
public:
 
812
    bool operator () (const __Language &lhs, const __Language &rhs) const {
 
813
        return strcmp (lhs.code, rhs.code) < 0;
 
814
    }
 
815
 
 
816
    bool operator () (const __Language &lhs, const String &rhs) const {
 
817
        return strcmp (lhs.code, rhs.c_str ()) < 0;
 
818
    }
 
819
 
 
820
    bool operator () (const String &lhs, const __Language &rhs) const {
 
821
        return strcmp (lhs.c_str (), rhs.code) < 0;
 
822
    }
 
823
};
 
824
 
 
825
static __Language *
 
826
__find_language (const String &lang)
 
827
{
 
828
    static __Language *langs_begin = __languages;
 
829
    static __Language *langs_end   = __languages + sizeof (__languages) / sizeof (__Language) - 1;
 
830
 
 
831
    String nlang = lang;
 
832
    bool contry_code = false;
 
833
 
 
834
    // Normalize the language name.
 
835
    for (String::iterator it = nlang.begin (); it != nlang.end (); ++it) {
 
836
        if (*it == '-' || *it == '_') {
 
837
            *it = '_';
 
838
            contry_code = true;
 
839
        } else if (contry_code) {
 
840
            *it = toupper (*it);
 
841
        } else {
 
842
            *it = tolower (*it);
 
843
        }
 
844
    }
 
845
 
 
846
    __Language *result = std::lower_bound (langs_begin, langs_end, nlang, __LanguageLess ());
 
847
 
 
848
    if (result != langs_end) {
 
849
        if (strncmp (result->code, nlang.c_str (), strlen (result->code)) == 0 ||
 
850
            (strncmp (result->code, nlang.c_str (), nlang.length ()) == 0 &&
 
851
             strncmp (result->code, (result+1)->code, nlang.length ()) != 0))
 
852
            return result;
 
853
    }
 
854
 
 
855
    return NULL;
 
856
}
 
857
 
 
858
String
 
859
scim_get_language_name (const String &lang)
 
860
{
 
861
    return String (_(scim_get_language_name_english (lang).c_str ()));
 
862
}
 
863
 
 
864
String
 
865
scim_get_language_name_english (const String &lang)
 
866
{
 
867
    __Language *result = __find_language (lang);
 
868
 
 
869
    if (result) 
 
870
        return String (result->name);
 
871
 
 
872
    return String ("Other");
 
873
}
 
874
 
 
875
String
 
876
scim_get_language_name_untranslated (const String &lang)
 
877
{
 
878
    __Language *result = __find_language (lang);
 
879
 
 
880
    if (result) {
 
881
        if (result->untranslated)
 
882
            return String (result->untranslated);
 
883
        else
 
884
            return String (_(result->name));
 
885
    }
 
886
 
 
887
    return String (_("Other"));
 
888
}
 
889
 
 
890
String
 
891
scim_get_language_locales (const String &lang)
 
892
{
 
893
    __Language *result = __find_language (lang);
 
894
 
 
895
    std::vector<String> locales;
 
896
 
 
897
    if (result) {
 
898
        String good;
 
899
 
 
900
        if (strlen (result->code) < 5 && result->normalized)
 
901
            result = __find_language (result->normalized);
 
902
 
 
903
        good = scim_validate_locale (String (result->code) + ".UTF-8");
 
904
 
 
905
        if (good.length ()) locales.push_back (good);
 
906
 
 
907
        if (result->locale_suffix) {
 
908
            std::vector<String> suffixes;
 
909
 
 
910
            scim_split_string_list (suffixes, result->locale_suffix, ',');
 
911
            for (size_t i = 0; i < suffixes.size (); ++ i) {
 
912
                good = scim_validate_locale (String (result->code) + suffixes [i]);
 
913
                if (good.length ()) locales.push_back (good);
 
914
            }
 
915
        }
 
916
 
 
917
        good = scim_validate_locale (result->code);
 
918
 
 
919
        if (good.length ()) locales.push_back (good);
 
920
    }
 
921
 
 
922
    return scim_combine_string_list (locales, ',');
 
923
}
 
924
 
 
925
String
 
926
scim_get_locale_language (const String &locale)
 
927
{
 
928
    if (locale.length () == 0) return String ();
 
929
 
 
930
    String str = locale.substr (0, locale.find ('.'));
 
931
    return scim_validate_language (str.substr (0, str.find ('@')));
 
932
}
 
933
 
 
934
String
 
935
scim_validate_language (const String &lang)
 
936
{
 
937
    __Language *result = __find_language (lang);
 
938
 
 
939
    if (result)
 
940
        return String (result->code);
 
941
 
 
942
    // Add prefix ~ to let other become the last item when sorting.
 
943
    return String ("~other");
 
944
}
 
945
 
 
946
String
 
947
scim_get_normalized_language (const String &lang)
 
948
{
 
949
    __Language *result = __find_language (lang);
 
950
 
 
951
    if (result) {
 
952
        if (result->normalized) return String (result->normalized);
 
953
        else return String (result->code);
 
954
    }
 
955
 
 
956
    // Add prefix ~ to let other become the last item when sorting.
 
957
    return String ("~other");
 
958
}
 
959
 
 
960
#ifndef SCIM_LAUNCHER
 
961
 #define SCIM_LAUNCHER  (SCIM_LIBEXECDIR "/scim-launcher")
 
962
#endif
 
963
 
 
964
int  scim_launch (bool          daemon,
 
965
                  const String &config,
 
966
                  const String &imengines,
 
967
                  const String &frontend,
 
968
                  char  * const argv [])
 
969
{
 
970
    if (!config.length () || !imengines.length () || !frontend.length ())
 
971
        return -1;
 
972
 
 
973
    int   new_argc = 0;
 
974
    char *new_argv [40];
 
975
    char verbose_buf [10];
 
976
 
 
977
    new_argv [new_argc ++] = strdup (SCIM_LAUNCHER);
 
978
 
 
979
    if (daemon)
 
980
        new_argv [new_argc ++] = strdup ("-d");
 
981
 
 
982
    new_argv [new_argc ++] = strdup ("-c");
 
983
    new_argv [new_argc ++] = strdup (config.c_str ());
 
984
    new_argv [new_argc ++] = strdup ("-e");
 
985
    new_argv [new_argc ++] = strdup (imengines.c_str ());
 
986
    new_argv [new_argc ++] = strdup ("-f");
 
987
    new_argv [new_argc ++] = strdup (frontend.c_str ());
 
988
 
 
989
    if (argv) {
 
990
        for (int i = 0; argv [i] && new_argc < 40 ; ++i, ++new_argc)
 
991
            new_argv [new_argc] = strdup (argv [i]);
 
992
    }
 
993
 
 
994
    new_argv [new_argc] = 0;
 
995
 
 
996
    pid_t child_pid;
 
997
 
 
998
    child_pid = fork ();
 
999
 
 
1000
    // Error fork.
 
1001
    if (child_pid < 0) return -1;
 
1002
 
 
1003
    // In child process, start scim-launcher.
 
1004
    if (child_pid == 0) {
 
1005
        return execv (SCIM_LAUNCHER, new_argv);
 
1006
    }
 
1007
 
 
1008
    // In parent process, wait the child exit.
 
1009
 
 
1010
    for (int i = 0; i < new_argc; ++i)
 
1011
        if (new_argv [i]) free (new_argv [i]);
 
1012
 
 
1013
    int status;
 
1014
    pid_t ret_pid;
 
1015
 
 
1016
    ret_pid = waitpid (child_pid, &status, 0);
 
1017
 
 
1018
    if (ret_pid == child_pid && WIFEXITED(status))
 
1019
        return WEXITSTATUS(status);
 
1020
 
 
1021
    return -1;
 
1022
}
 
1023
 
 
1024
#ifndef SCIM_PANEL_PROGRAM
 
1025
  #define SCIM_PANEL_PROGRAM  (SCIM_LIBEXECDIR "/scim-panel-gtk")
 
1026
#endif
 
1027
 
 
1028
int scim_launch_panel (bool          daemon,
 
1029
                       const String &config,
 
1030
                       const String &display,
 
1031
                       char * const  argv [])
 
1032
{
 
1033
    if (!config.length ())
 
1034
        return -1;
 
1035
 
 
1036
    String panel_program = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM, String (SCIM_PANEL_PROGRAM));
 
1037
 
 
1038
    if (!panel_program.length ())
 
1039
        panel_program = String (SCIM_PANEL_PROGRAM);
 
1040
 
 
1041
    if (panel_program [0] != SCIM_PATH_DELIM) {
 
1042
        panel_program = String (SCIM_LIBEXECDIR) +
 
1043
                        String (SCIM_PATH_DELIM_STRING) +
 
1044
                        panel_program;
 
1045
    }
 
1046
 
 
1047
    //if the file is not exist or is not executable, fallback to default
 
1048
    if (access (panel_program.c_str (), X_OK) != 0)
 
1049
            panel_program = String (SCIM_PANEL_PROGRAM);
 
1050
 
 
1051
    int   new_argc = 0;
 
1052
    char *new_argv [80];
 
1053
 
 
1054
    new_argv [new_argc ++] = strdup (panel_program.c_str ());
 
1055
 
 
1056
    new_argv [new_argc ++] = strdup ("--display");
 
1057
    new_argv [new_argc ++] = strdup (display.c_str ());
 
1058
 
 
1059
    new_argv [new_argc ++] = strdup ("-c");
 
1060
    new_argv [new_argc ++] = strdup (config.c_str ());
 
1061
 
 
1062
    if (daemon)
 
1063
        new_argv [new_argc ++] = strdup ("-d");
 
1064
 
 
1065
    if (argv) {
 
1066
        for (int i = 0; argv [i] && new_argc < 40; ++i, ++new_argc)
 
1067
            new_argv [new_argc] = strdup (argv [i]);
 
1068
    }
 
1069
 
 
1070
    new_argv [new_argc] = 0;
 
1071
 
 
1072
    pid_t child_pid;
 
1073
 
 
1074
    child_pid = fork ();
 
1075
 
 
1076
    // Error fork.
 
1077
    if (child_pid < 0) return -1;
 
1078
 
 
1079
    // In child process, start scim-launcher.
 
1080
    if (child_pid == 0) {
 
1081
        return execv (panel_program.c_str (), new_argv);
 
1082
    }
 
1083
 
 
1084
    // In parent process, wait the child exit.
 
1085
 
 
1086
    for (int i = 0; i < new_argc; ++i)
 
1087
        if (new_argv [i]) free (new_argv [i]);
 
1088
 
 
1089
    int status;
 
1090
    pid_t ret_pid;
 
1091
 
 
1092
    ret_pid = waitpid (child_pid, &status, 0);
 
1093
 
 
1094
    if (ret_pid == child_pid && WIFEXITED(status))
 
1095
        return WEXITSTATUS(status);
 
1096
 
 
1097
    return -1;
 
1098
}
 
1099
 
 
1100
void
 
1101
scim_usleep (unsigned int usec)
 
1102
{
 
1103
    if (usec == 0) return;
 
1104
 
 
1105
#if HAVE_NANOSLEEP
 
1106
    struct timespec req, rem;
 
1107
 
 
1108
    req.tv_sec = usec / 1000000;
 
1109
    req.tv_nsec = (usec % 1000000) * 1000;
 
1110
 
 
1111
    while (nanosleep (&req, &rem) == -1 && errno == EINTR && (rem.tv_sec != 0 || rem.tv_nsec != 0))
 
1112
        req = rem;
 
1113
#elif HAVE_USLEEP
 
1114
    unsigned int sec = usec / 1000000;
 
1115
    usec %= 1000000;
 
1116
 
 
1117
    for (unsigned int i = 0; i < sec; ++i)
 
1118
        sleep (1);
 
1119
 
 
1120
    usleep (usec);
 
1121
#else
 
1122
    unsigned int sec = usec / 1000000;
 
1123
 
 
1124
    sleep (sec ? sec : 1);
 
1125
#endif
 
1126
}
 
1127
 
 
1128
void scim_daemon ()
 
1129
{
 
1130
#if HAVE_DAEMON
 
1131
    if (daemon (0, 0) == -1)
 
1132
        std::cerr << "Error to make SCIM into a daemon!\n";
 
1133
 
 
1134
    return;
 
1135
#else        
 
1136
    pid_t id;
 
1137
 
 
1138
    id = fork ();
 
1139
    if (id == -1) {
 
1140
        std::cerr << "Error to make SCIM into a daemon!\n";
 
1141
        return;
 
1142
    } else if (id > 0) {
 
1143
        _exit (0);
 
1144
    }
 
1145
 
 
1146
    id = fork ();
 
1147
    if (id == -1) {
 
1148
        std::cerr << "Error to make SCIM into a daemon!\n";
 
1149
        return;
 
1150
    } else if (id > 0) {
 
1151
        _exit (0);
 
1152
    }
 
1153
 
 
1154
    return;
 
1155
#endif
 
1156
}
 
1157
 
 
1158
} // namespace scim
 
1159
 
 
1160
/*
 
1161
vi:ts=4:ai:nowrap:expandtab
 
1162
*/