~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to uim/uim-func.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2006-11-23 15:10:53 UTC
  • mfrom: (3.1.8 edgy)
  • Revision ID: james.westby@ubuntu.com-20061123151053-q42sk1lvks41xpfx
Tags: 1:1.2.1-9
uim-gtk2.0.postinst: Don't call update-gtk-immodules on purge.
(closes: Bug#398530)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 
3
 
  Copyright (c) 2003,2004 uim Project http://uim.freedesktop.org/
 
3
  Copyright (c) 2003-2006 uim Project http://uim.freedesktop.org/
4
4
 
5
5
  All rights reserved.
6
6
 
17
17
     may be used to endorse or promote products derived from this software
18
18
     without specific prior written permission.
19
19
 
20
 
  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21
21
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
22
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 
  ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
23
  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24
24
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
25
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
26
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31
31
 
32
32
*/
33
33
 
 
34
#include <config.h>
 
35
 
34
36
#include <ctype.h>
35
37
#include <iconv.h>
36
38
#include <string.h>
37
39
#include <stdlib.h>
38
40
#include <stdarg.h>
39
 
#include "context.h"
40
 
#include "siod.h"
 
41
 
 
42
#ifdef HAVE_ALLOCA_H
 
43
# include <alloca.h>
 
44
#endif
 
45
#ifdef HAVE_STRINGS_H
 
46
#include <strings.h>
 
47
#endif
 
48
 
 
49
#include "uim-internal.h"
 
50
#include "uim-scm.h"
 
51
#include "uim-encoding.h"
 
52
#include "uim-util.h"
 
53
#include "uim-im-switcher.h"
41
54
 
42
55
#define MAX_LENGTH_OF_INT_AS_STR (((sizeof(int) == 4) ? sizeof("-2147483648") : sizeof("-9223372036854775808")) - sizeof((char)'\0'))
43
56
 
 
57
static const char **uim_get_encoding_alias(const char *encoding);
 
58
 
44
59
char *uim_return_str;
45
60
char *uim_return_str_list[10]; /* XXX */
46
61
/* duplicate definition */
54
69
};
55
70
struct uim_code_converter *uim_iconv = &uim_iconv_tbl;
56
71
 
57
 
#define TRUEP(x) EQ(x, true_sym)
58
 
#define FALSEP(x) EQ(x, false_sym)
59
 
 
60
 
#define NTRUEP(x) NEQ(x, true_sym)
61
 
#define NFALSEP(x) NEQ(x, false_sym)
62
 
 
63
 
static LISP true_sym;
64
 
static LISP false_sym;
65
72
 
66
73
/* push back a preedit segment to context */
67
74
static void
92
99
  }
93
100
}
94
101
 
95
 
static void
96
 
uim_flush_cb(uim_context uc)
97
 
{
98
 
  struct cb *cb = uc->cb_q.first_cb;
99
 
  while (cb) {
100
 
    struct cb *tmp = cb;
101
 
    cb = cb->next;
102
 
    switch (tmp->type) {
103
 
    case COMMIT_CB:
104
 
      {
105
 
        char *s;
106
 
        s = uc->conv_if->convert(uc->conv, tmp->str);
107
 
        if (uc->commit_cb) {
108
 
          uc->commit_cb(uc->ptr, s);
109
 
        }
110
 
        free(s);
111
 
      }
112
 
      break;
113
 
    case CAND_ACTIVATE_CB:
114
 
      {
115
 
        if (uc->candidate_selector_activate_cb) {
116
 
          uc->candidate_selector_activate_cb(uc->ptr, tmp->n1, tmp->n2);
117
 
        }
118
 
      }
119
 
      break;
120
 
    case CAND_SELECT_CB:
121
 
      {
122
 
        if (uc->candidate_selector_select_cb) {
123
 
          uc->candidate_selector_select_cb(uc->ptr, tmp->n1);
124
 
        }
125
 
      }
126
 
      break;
127
 
    case CAND_SHIFT_PAGE_CB:
128
 
      {
129
 
        if (uc->candidate_selector_shift_page_cb) {
130
 
          uc->candidate_selector_shift_page_cb(uc->ptr, tmp->n1);
131
 
        }
132
 
      }
133
 
      break;
134
 
    case CAND_DEACTIVATE_CB:
135
 
      {
136
 
        if (uc->candidate_selector_deactivate_cb) {
137
 
          uc->candidate_selector_deactivate_cb(uc->ptr);
138
 
        }
139
 
      }
140
 
      break;
141
 
    case PREEDIT_CLEAR_CB:
142
 
      {
143
 
        uim_release_preedit_segments(uc);
144
 
      }
145
 
      break;
146
 
    case PREEDIT_PUSHBACK_CB:
147
 
      {
148
 
        char *s;
149
 
        s = uc->conv_if->convert(uc->conv, tmp->str);
150
 
        pushback_preedit_segment(uc, tmp->n1, s);
151
 
      }
152
 
      break;
153
 
    case PREEDIT_UPDATE_CB:
154
 
      {
155
 
        uim_update_preedit_segments(uc);
156
 
      }
157
 
      break;
158
 
    case MODE_UPDATE_CB:
159
 
      {
160
 
        if (uc->mode_update_cb) {
161
 
          uc->mode_update_cb(uc->ptr, tmp->n1);
162
 
        }
163
 
      }
164
 
      break;
165
 
    case MODE_LIST_UPDATE_CB:
166
 
      {
167
 
        if (uc->mode_list_update_cb) {
168
 
          uc->mode_list_update_cb(uc->ptr);
169
 
        }
170
 
      }
171
 
      break;
172
 
    case PROP_LABEL_UPDATE_CB:
173
 
      {
174
 
        if (uc->prop_label_update_cb) {
175
 
          uc->prop_label_update_cb(uc->ptr, uc->proplabelstr);
176
 
        }
177
 
      }
178
 
      break;
179
 
    case PROP_LIST_UPDATE_CB:
180
 
      {
181
 
        if (uc->prop_list_update_cb) {
182
 
          uc->prop_list_update_cb(uc->ptr, uc->propstr);
183
 
        }
184
 
      }
185
 
      break;
186
 
    case REQUEST_SURROUNDING_CB:
187
 
      {
188
 
        if (uc->request_surrounding_text_cb) {
189
 
          uc->request_surrounding_text_cb(uc->ptr);
190
 
        }
191
 
      }
192
 
      break;
193
 
    case DELETE_SURROUNDING_CB:
194
 
      {
195
 
        if (uc->delete_surrounding_text_cb) {
196
 
          uc->delete_surrounding_text_cb(uc->ptr, tmp->n1, tmp->n2);
197
 
        }
198
 
      }
199
 
      break;
200
 
    default:;
201
 
    }
202
 
    if (tmp->str) {
203
 
      free(tmp->str);
204
 
    }
205
 
    free(tmp);
206
 
  }
207
 
  uc->cb_q.first_cb = NULL;
208
 
  uc->cb_q.tail_cb = NULL;
209
 
}
210
 
 
211
102
/* release preedit segment in a context */
212
103
void
213
104
uim_release_preedit_segments(uim_context uc)
214
105
{
215
106
  int i;
 
107
 
 
108
  if (!uc)
 
109
    return;
 
110
 
216
111
  if (!uc->psegs) {
217
112
    uc->nr_psegs = 0;
218
113
    return ;
225
120
  uc->nr_psegs = 0;
226
121
}
227
122
 
 
123
static int check_encoding_equivalence(const char *tocode, const char *fromcode)
 
124
{
 
125
  const char **alias_tocode;
 
126
  const char **alias_fromcode;
 
127
  int i, j;
 
128
  int alias_tocode_alloced = 0;
 
129
  int alias_fromcode_alloced = 0;
 
130
  int found = 0;
 
131
 
 
132
  alias_tocode = uim_get_encoding_alias(tocode);
 
133
  alias_fromcode = uim_get_encoding_alias(fromcode);
 
134
 
 
135
  if (!alias_tocode) {
 
136
    alias_tocode = malloc(sizeof(char *) * 2);
 
137
    alias_tocode[0] = tocode;
 
138
    alias_tocode[1] = NULL;
 
139
    alias_tocode_alloced = 1;
 
140
  }
 
141
  if (!alias_fromcode) {
 
142
    alias_fromcode = malloc(sizeof(char *) * 2);
 
143
    alias_fromcode[0] = fromcode;
 
144
    alias_fromcode[1] = NULL;
 
145
    alias_fromcode_alloced = 1;
 
146
  }
 
147
 
 
148
  for (i = 0; alias_tocode[i]; i++) {
 
149
    for (j = 0; alias_fromcode[j]; j++) {
 
150
      if (!strcmp(alias_tocode[i], alias_fromcode[j])) {
 
151
        found = 1;
 
152
        break;
 
153
      }
 
154
    }
 
155
    if (found)
 
156
      break;
 
157
  }
 
158
 
 
159
  if (alias_tocode_alloced)
 
160
    free(alias_tocode);
 
161
  if (alias_fromcode_alloced)
 
162
    free(alias_fromcode);
 
163
  return found;
 
164
}
 
165
 
228
166
int
229
167
uim_iconv_is_convertible(const char *tocode, const char *fromcode)
230
168
{
231
169
  iconv_t ic;
232
170
 
233
 
  if (!strcmp("UTF-8", fromcode) || !strcmp(tocode, fromcode)) {
 
171
  if (check_encoding_equivalence(tocode, fromcode))
234
172
    return 1;
235
 
  }
 
173
 
236
174
  /* TODO cache the result */
237
 
  ic = iconv_open(tocode, fromcode);
 
175
  ic = (iconv_t)uim_iconv_open(tocode, fromcode);
238
176
  if (ic == (iconv_t)-1) {
239
177
    return 0;
240
178
  }
242
180
  return 1;
243
181
}
244
182
 
 
183
static const char**
 
184
uim_get_encoding_alias(const char *encoding) {
 
185
  int i, j;
 
186
  const char **alias;
 
187
 
 
188
  for (i = 0; (alias = uim_encoding_list[i]); i++) {
 
189
    for (j = 0; alias[j]; j++) {
 
190
      if (!strcmp(alias[j], encoding))
 
191
        return alias;
 
192
    }
 
193
  }
 
194
  return NULL;
 
195
}
 
196
 
 
197
void *
 
198
uim_iconv_open(const char *tocode, const char *fromcode) {
 
199
  iconv_t cd = (iconv_t)-1;
 
200
  int i, j;
 
201
  const char **alias_tocode, **alias_fromcode;
 
202
  int alias_tocode_alloced = 0;
 
203
  int alias_fromcode_alloced = 0;
 
204
  int opened = 0;
 
205
 
 
206
  alias_tocode = uim_get_encoding_alias(tocode);
 
207
  alias_fromcode = uim_get_encoding_alias(fromcode);
 
208
 
 
209
  if (!alias_tocode) {
 
210
    alias_tocode = malloc(sizeof(char *) * 2);
 
211
    alias_tocode[0] = tocode;
 
212
    alias_tocode[1] = NULL;
 
213
    alias_tocode_alloced = 1;
 
214
  }
 
215
  if (!alias_fromcode) {
 
216
    alias_fromcode = malloc(sizeof(char *) * 2);
 
217
    alias_fromcode[0] = fromcode;
 
218
    alias_fromcode[1] = NULL;
 
219
    alias_fromcode_alloced = 1;
 
220
  }
 
221
 
 
222
  for (i = 0; alias_tocode[i]; i++) {
 
223
    for (j = 0; alias_fromcode[j]; j++) {
 
224
      cd = iconv_open(alias_tocode[i], alias_fromcode[j]);
 
225
      if (cd != (iconv_t)-1) {
 
226
        opened = 1;
 
227
        break;
 
228
      }
 
229
    }
 
230
    if (opened)
 
231
      break;
 
232
  }
 
233
 
 
234
  if (alias_tocode_alloced)
 
235
    free(alias_tocode);
 
236
  if (alias_fromcode_alloced)
 
237
    free(alias_fromcode);
 
238
  return (void *)cd;
 
239
}
 
240
 
245
241
void *
246
242
uim_iconv_create(const char *tocode, const char *fromcode)
247
243
{
248
244
  iconv_t ic;
249
245
 
250
 
  ic = iconv_open(tocode, fromcode);
 
246
  if (check_encoding_equivalence(tocode, fromcode))
 
247
    return NULL;
 
248
 
 
249
  ic = (iconv_t)uim_iconv_open(tocode, fromcode);
251
250
  if (ic == (iconv_t)-1) {
 
251
    /* since iconv_t is not explicit pointer, use 0 instead of NULL */
252
252
    ic = (iconv_t)0;
253
253
  }
254
254
  return (void *)ic;
265
265
  const char *inbuf;
266
266
 
267
267
  ic = (iconv_t)obj;
268
 
  if(!str)
 
268
  if (!str)
269
269
    return NULL;
 
270
 
 
271
  if (!ic)
 
272
    return strdup(str);
 
273
 
270
274
  len = strlen(str);
271
275
  buflen = (len * 6)+3;
272
276
  realbuf = alloca(buflen);
273
277
  outbuf = realbuf;
274
278
  inbuf = str;
275
 
  if (!ic) {
276
 
    return strdup(str);
277
 
  }
278
279
  bzero(realbuf, buflen);
279
280
  iconv(ic, (ICONV_CONST char **)&inbuf, &len, &outbuf, &buflen);
280
281
  return strdup(realbuf);
287
288
  err = iconv_close((iconv_t)obj);
288
289
}
289
290
 
290
 
void
291
 
uim_schedule_cb(uim_context uc, int type, char *str, int n1, int n2)
292
 
{
293
 
  struct cb *cb;
294
 
 
295
 
  if(!uc)
296
 
    return;
297
 
 
298
 
  cb = malloc(sizeof(struct cb));
299
 
  cb->type = type;
300
 
  cb->str = str;
301
 
  cb->n1 = n1;
302
 
  cb->n2 = n2;
303
 
  cb->next = NULL;
304
 
 
305
 
  if (!uc->cb_q.first_cb) {
306
 
    uc->cb_q.first_cb = cb;
307
 
  }
308
 
  if (uc->cb_q.tail_cb) {
309
 
    uc->cb_q.tail_cb->next = cb;
310
 
  }
311
 
  uc->cb_q.tail_cb = cb;
312
 
}
313
 
 
314
291
/** Calculate actual sexp string size from printf-style args.
315
292
 * This function calculates actual sexp string size from printf-style
316
293
 * args. Format string \a sexp_tmpl only accepts %d and %s.
320
297
{
321
298
  va_list ap;
322
299
  int len, size;
 
300
  int tmp;
323
301
  const char *sexp_tmpl_end, *escp = sexp_tmpl, *strarg;
324
302
  char fmtchr;
325
303
 
332
310
      fmtchr = *escp++;
333
311
      switch (fmtchr) {
334
312
      case 'd':
335
 
        va_arg(ap, int);
 
313
        tmp = va_arg(ap, int);
336
314
        len += MAX_LENGTH_OF_INT_AS_STR;
337
315
        break;
338
316
      case 's':
362
340
uim_eval_string(uim_context uc, char *buf)
363
341
{
364
342
  /* Evaluate */
365
 
  repl_c_string(buf, 0, 1);
366
 
 
367
 
  /* Flush callback requests queued during scheme evaluation 
368
 
   * (To avoid C -> scheme -> C call, actual call is delayed to here)
369
 
   */
370
 
  if (!uc->cb_q.flushing) {
371
 
    uc->cb_q.flushing ++;
372
 
    uim_flush_cb(uc);
373
 
    uc->cb_q.flushing --;
374
 
  }
 
343
  uim_scm_eval_c_string(buf);
375
344
}
376
345
 
377
346
/* this is not a uim API, so did not name as uim_retrieve_context() */
378
347
static uim_context
379
 
retrieve_uim_context(LISP id)
 
348
retrieve_uim_context(uim_lisp id)
380
349
{
381
350
  uim_context uc;
382
 
  if CONSP(id) {  /* passed as Scheme-side input context */
383
 
    id = car(id);
 
351
 
 
352
  if (uim_scm_consp(id)) {  /* passed as Scheme-side input context */
 
353
    id = uim_scm_car(id);
384
354
  }
385
 
  uc = uim_find_context(get_c_int(id));
 
355
  uc = uim_find_context(uim_scm_c_int(id));
386
356
  return uc;
387
357
}
388
358
 
389
 
static LISP
390
 
im_clear_preedit(LISP id)
 
359
static uim_lisp
 
360
im_clear_preedit(uim_lisp id)
391
361
{
392
362
  uim_context uc = retrieve_uim_context(id);
393
 
  uim_schedule_cb(uc, PREEDIT_CLEAR_CB, NULL, 0, 0);
394
 
  return false_sym;
 
363
  uim_release_preedit_segments(uc);
 
364
  return uim_scm_f();
395
365
}
396
366
 
397
 
static LISP
398
 
im_pushback_preedit(LISP id_, LISP attr_, LISP str_)
 
367
static uim_lisp
 
368
im_pushback_preedit(uim_lisp id_, uim_lisp attr_, uim_lisp str_)
399
369
{
400
370
  uim_context uc = retrieve_uim_context(id_);
401
 
  char *str = NULL;
402
 
  int attr = get_c_int(attr_);
 
371
  const char *str = NULL;
 
372
  int attr = uim_scm_c_int(attr_);
403
373
  if (str_) {
404
 
    str = uim_get_c_string(str_);
405
 
  }
406
 
  uim_schedule_cb(uc, PREEDIT_PUSHBACK_CB, str, attr, 0);
407
 
  return false_sym;
 
374
    str = uim_scm_refer_c_str(str_);
 
375
  }
 
376
  {
 
377
    char *s;
 
378
    s = uc->conv_if->convert(uc->conv, str);
 
379
    pushback_preedit_segment(uc, attr, s);
 
380
  }
 
381
  return uim_scm_f();
408
382
}
409
383
 
410
 
static LISP
411
 
im_update_preedit(LISP id)
 
384
static uim_lisp
 
385
im_update_preedit(uim_lisp id)
412
386
{
413
387
  uim_context uc = retrieve_uim_context(id);
414
 
  uim_schedule_cb(uc, PREEDIT_UPDATE_CB, NULL, 0, 0);
415
 
  return false_sym;
 
388
  uim_update_preedit_segments(uc);
 
389
  return uim_scm_f();
416
390
}
417
391
 
418
392
/* ID, STR */
419
 
static LISP
420
 
im_commit(LISP id, LISP str_)
 
393
static uim_lisp
 
394
im_commit(uim_lisp id, uim_lisp str_)
421
395
{
422
396
  uim_context uc = retrieve_uim_context(id);
423
 
  char *str = NULL;
424
 
  if STRINGP(str_) {
425
 
    str = uim_get_c_string(str_);
426
 
    uim_schedule_cb(uc, COMMIT_CB, str, 0, 0);
 
397
  const char *str = NULL;
 
398
  if (uim_scm_stringp(str_)) {
 
399
    str = uim_scm_refer_c_str(str_);
 
400
    {
 
401
      char *s;
 
402
      s = uc->conv_if->convert(uc->conv, str);
 
403
      if (uc->commit_cb) {
 
404
        uc->commit_cb(uc->ptr, s);
 
405
      }
 
406
      free(s);
 
407
    }
427
408
  }
428
 
  return false_sym;
 
409
  return uim_scm_f();
429
410
}
430
411
 
431
 
static LISP
432
 
im_commit_raw(LISP id)
 
412
static uim_lisp
 
413
im_commit_raw(uim_lisp id)
433
414
{
434
415
  uim_context uc = retrieve_uim_context(id);
435
416
  uc->commit_raw_flag = 1;
436
 
  return false_sym;
 
417
  return uim_scm_f();
437
418
}
438
419
 
439
 
static LISP
440
 
im_get_raw_key_str(LISP key_, LISP key_state_)
 
420
static uim_lisp
 
421
im_get_raw_key_str(uim_lisp key_, uim_lisp key_state_)
441
422
{
442
423
  int key;
443
 
  int key_state = get_c_int(key_state_);
 
424
  int key_state = uim_scm_c_int(key_state_);
444
425
  char buf[2];
445
426
  
446
 
  if (INTNUMP(key_)) {
447
 
    key = get_c_int(key_);
 
427
  if (uim_scm_integerp(key_)) {
 
428
    key = uim_scm_c_int(key_);
448
429
  } else {
449
 
    return false_sym;
 
430
    return uim_scm_f();
450
431
  }
451
432
  if ((key_state != 0 && key_state != UMod_Shift) ||
452
433
      key > 255) {
453
 
    return false_sym;
 
434
    return uim_scm_f();
454
435
  }
455
436
  
456
437
  buf[0] = key;
462
443
  if (key_state == UMod_Shift) {
463
444
    buf[0] = toupper(buf[0]);
464
445
  }
465
 
  return strcons(1, buf);
 
446
  return uim_scm_make_str(buf);
466
447
}
467
448
 
468
 
static LISP
469
 
im_set_encoding(LISP id, LISP enc)
 
449
static uim_lisp
 
450
im_set_encoding(uim_lisp id, uim_lisp enc)
470
451
{
471
 
  char *e = uim_get_c_string(enc);
 
452
  const char *e = uim_scm_refer_c_str(enc);
472
453
  uim_context uc = retrieve_uim_context(id);
473
454
 
474
 
  if(!uc)
475
 
    return false_sym;
 
455
  if (!uc)
 
456
    return uim_scm_f();
476
457
 
477
458
  if (uc->conv) {
478
459
    uc->conv_if->release(uc->conv);
479
460
  }
480
461
  if (!strcmp(uc->encoding, e)) {
481
 
    free(e);
482
462
    uc->conv = 0;
483
 
    return false_sym;
 
463
    return uim_scm_f();
484
464
  }
485
465
  uc->conv = uc->conv_if->create(uc->encoding, e);
486
 
  free(e);
487
 
  return false_sym;
 
466
  return uim_scm_f();
488
467
}
489
468
 
490
 
static LISP
491
 
im_clear_mode_list(LISP id)
 
469
static uim_lisp
 
470
im_clear_mode_list(uim_lisp id)
492
471
{
493
472
  int i;
494
473
  uim_context uc = retrieve_uim_context(id);
495
474
 
496
 
  if(!uc)
497
 
    return false_sym;
 
475
  if (!uc)
 
476
    return uim_scm_f();
498
477
 
499
478
  for (i = 0; i < uc->nr_modes; i++) {
500
479
    if (uc->modes[i]) {
501
480
      free(uc->modes[i]);
 
481
      uc->modes[i] = NULL;
502
482
    }
503
483
  }
504
484
  if (uc->modes) {
506
486
    uc->modes = NULL;
507
487
  }
508
488
  uc->nr_modes = 0;
509
 
  return false_sym;
 
489
  return uim_scm_f();
510
490
}
511
491
 
512
 
static LISP
513
 
im_pushback_mode_list(LISP id, LISP str)
 
492
static uim_lisp
 
493
im_pushback_mode_list(uim_lisp id, uim_lisp str)
514
494
{
515
 
  char *s;
 
495
  const char *s;
516
496
  uim_context uc = retrieve_uim_context(id);
517
497
 
518
 
  if(!uc)
519
 
    return false_sym;
 
498
  if (!uc)
 
499
    return uim_scm_f();
520
500
 
521
501
  uc->modes = realloc(uc->modes,
522
502
                      sizeof(char *)*(uc->nr_modes+1));
523
 
  s = uim_get_c_string(str);
 
503
  s = uim_scm_refer_c_str(str);
524
504
  uc->modes[uc->nr_modes] = uc->conv_if->convert(uc->conv, s);
525
 
  free(s);
526
505
  uc->nr_modes ++;
527
 
  return false_sym;
528
 
}
529
 
 
530
 
static LISP
531
 
im_update_mode_list(LISP id)
532
 
{
533
 
  uim_context uc = retrieve_uim_context(id);
534
 
 
535
 
  if(!uc)
536
 
    return false_sym;
537
 
 
538
 
  uim_schedule_cb(uc, MODE_LIST_UPDATE_CB, NULL, 0, 0);
539
 
  return false_sym;
540
 
}
541
 
 
542
 
static LISP
543
 
im_update_prop_list(LISP id, LISP prop_)
544
 
{
545
 
  uim_context uc = retrieve_uim_context(id);
546
 
  char *prop     = uim_get_c_string(prop_);
547
 
 
548
 
  if(uc)
549
 
    uim_schedule_cb(uc, PROP_LIST_UPDATE_CB, NULL, 0, 0);
 
506
  return uim_scm_f();
 
507
}
 
508
 
 
509
static uim_lisp
 
510
im_update_mode_list(uim_lisp id)
 
511
{
 
512
  uim_context uc = retrieve_uim_context(id);
 
513
 
 
514
  if (!uc)
 
515
    return uim_scm_f();
 
516
 
 
517
  if (uc->mode_list_update_cb) {
 
518
    uc->mode_list_update_cb(uc->ptr);
 
519
  }
 
520
  return uim_scm_f();
 
521
}
 
522
 
 
523
static uim_lisp
 
524
im_update_prop_list(uim_lisp id, uim_lisp prop_)
 
525
{
 
526
  uim_context uc = retrieve_uim_context(id);
 
527
  const char *prop = uim_scm_refer_c_str(prop_);
 
528
 
 
529
  if (!uc)
 
530
    return uim_scm_f();
550
531
  
551
 
  if(uc && uc->propstr)
 
532
  if (uc && uc->propstr)
552
533
    free(uc->propstr);
553
534
      
554
535
  uc->propstr = uc->conv_if->convert(uc->conv, prop);
555
 
  
556
 
  free(prop);
557
 
 
558
 
  return false_sym;
559
 
}
560
 
 
561
 
 
562
 
static LISP
563
 
im_update_prop_label(LISP id, LISP prop_)
564
 
{
565
 
  uim_context uc = retrieve_uim_context(id);
566
 
  char *prop     = uim_get_c_string(prop_);
567
 
    
568
 
  if(uc) {
569
 
    uim_schedule_cb(uc, PROP_LABEL_UPDATE_CB, NULL, 0, 0);
570
 
  } else {
571
 
    return false_sym;
572
 
  }
573
 
 
574
 
  if(uc && uc->proplabelstr)
575
 
    free(uc->proplabelstr);
576
 
  
577
 
  uc->proplabelstr = uc->conv_if->convert(uc->conv, prop);
578
 
  
579
 
  free(prop);
580
 
 
581
 
  return false_sym;
582
 
}
583
 
 
584
 
static LISP
585
 
im_update_mode(LISP id, LISP mode_)
586
 
{
587
 
  int mode = get_c_int(mode_);
588
 
  uim_context uc = retrieve_uim_context(id);
589
 
 
590
 
  if(!uc)
591
 
    return false_sym;
 
536
 
 
537
  if (uc->prop_list_update_cb)
 
538
    uc->prop_list_update_cb(uc->ptr, uc->propstr);
 
539
 
 
540
  return uim_scm_f();
 
541
}
 
542
 
 
543
static uim_lisp
 
544
im_update_mode(uim_lisp id, uim_lisp mode_)
 
545
{
 
546
  int mode = uim_scm_c_int(mode_);
 
547
  uim_context uc = retrieve_uim_context(id);
 
548
 
 
549
  if (!uc)
 
550
    return uim_scm_f();
592
551
 
593
552
  uc->mode = mode;
594
 
  uim_schedule_cb(uc, MODE_UPDATE_CB, NULL, mode, 0);
595
 
  return false_sym;
 
553
  if (uc->mode_update_cb) {
 
554
    uc->mode_update_cb(uc->ptr, mode);
 
555
  }
 
556
  return uim_scm_f();
596
557
}
597
558
 
598
559
static char *
599
 
get_im_lang(char *name)
 
560
get_im_lang(const char *name)
600
561
{
601
562
  int i;
602
563
  for (i = 0; i < uim_nr_im; i++) {
608
569
  return NULL;
609
570
}
610
571
 
611
 
static LISP
612
 
im_register_im(LISP name, LISP lang, LISP enc, LISP s_desc)
 
572
static uim_lisp
 
573
im_register_im(uim_lisp name, uim_lisp lang, uim_lisp enc, uim_lisp s_desc)
613
574
{
614
 
  char *im_name = get_c_string(name);
615
 
  char *lang_name = get_c_string(lang);
616
 
  char *encoding_name = get_c_string(enc);
617
 
  char *short_desc = get_c_string(s_desc);
 
575
  const char *im_name = uim_scm_refer_c_str(name);
618
576
  if (get_im_lang(im_name)) {
619
577
    /* avoid duplicate register */
620
 
    return false_sym;
 
578
    return uim_scm_f();
621
579
  }
622
580
  uim_im_array = realloc(uim_im_array,
623
581
                         sizeof(struct uim_im) *
624
582
                         (uim_nr_im + 1));
625
 
  uim_im_array[uim_nr_im].lang = strdup(lang_name);
626
 
  uim_im_array[uim_nr_im].name = strdup(im_name);
627
 
  uim_im_array[uim_nr_im].encoding = strdup(encoding_name);
628
 
  uim_im_array[uim_nr_im].short_desc = strdup(short_desc);
 
583
  uim_im_array[uim_nr_im].lang = uim_scm_c_str(lang);
 
584
  uim_im_array[uim_nr_im].name = uim_scm_c_str(name);
 
585
  uim_im_array[uim_nr_im].encoding = uim_scm_c_str(enc);
 
586
  uim_im_array[uim_nr_im].short_desc = uim_scm_c_str(s_desc);
629
587
  uim_nr_im ++;
630
 
  return true_sym;
631
 
}
632
 
 
633
 
static LISP
634
 
im_activate_candidate_selector(LISP id_, LISP nr_, LISP display_limit_)
635
 
{
636
 
  uim_context uc = retrieve_uim_context(id_);
637
 
  int display_limit = get_c_int(display_limit_);
638
 
  int nr = get_c_int(nr_);
639
 
  uim_schedule_cb(uc, CAND_ACTIVATE_CB, NULL, nr, display_limit);
640
 
  return false_sym;
641
 
}
642
 
 
643
 
static LISP
644
 
im_select_candidate(LISP id_, LISP idx_)
645
 
{
646
 
  uim_context uc = retrieve_uim_context(id_);
647
 
  int idx = get_c_int(idx_);
648
 
  uim_schedule_cb(uc, CAND_SELECT_CB, NULL, idx, 0);
649
 
  return false_sym;
 
588
  return uim_scm_t();
 
589
}
 
590
 
 
591
static uim_lisp
 
592
im_activate_candidate_selector(uim_lisp id_, uim_lisp nr_, uim_lisp display_limit_)
 
593
{
 
594
  uim_context uc = retrieve_uim_context(id_);
 
595
  int display_limit = uim_scm_c_int(display_limit_);
 
596
  int nr = uim_scm_c_int(nr_);
 
597
  if (uc->candidate_selector_activate_cb) {
 
598
    uc->candidate_selector_activate_cb(uc->ptr, nr, display_limit);
 
599
  }
 
600
  return uim_scm_f();
 
601
}
 
602
 
 
603
static uim_lisp
 
604
im_select_candidate(uim_lisp id_, uim_lisp idx_)
 
605
{
 
606
  uim_context uc = retrieve_uim_context(id_);
 
607
  int idx = uim_scm_c_int(idx_);
 
608
  if (uc->candidate_selector_select_cb) {
 
609
    uc->candidate_selector_select_cb(uc->ptr, idx);
 
610
  }
 
611
  return uim_scm_f();
650
612
}
651
613
 
652
614
 
653
615
/* My naming sense seems bad... */
654
 
static LISP
655
 
im_shift_page_candidate(LISP id_, LISP dir_)
 
616
static uim_lisp
 
617
im_shift_page_candidate(uim_lisp id_, uim_lisp dir_)
656
618
{
657
619
  uim_context uc = retrieve_uim_context(id_);
658
620
  int dir;
659
621
 
660
 
  if FALSEP(dir_)
 
622
  if UIM_SCM_FALSEP(dir_)
661
623
    dir = 0;
662
624
  else
663
625
    dir = 1;
664
626
    
665
 
  uim_schedule_cb(uc, CAND_SHIFT_PAGE_CB, NULL, dir, 0);
666
 
  return false_sym;
 
627
  if (uc->candidate_selector_shift_page_cb) {
 
628
    uc->candidate_selector_shift_page_cb(uc->ptr, dir);
 
629
  }
 
630
  return uim_scm_f();
667
631
}
668
632
 
669
 
static LISP
670
 
im_deactivate_candidate_selector(LISP id_)
 
633
static uim_lisp
 
634
im_deactivate_candidate_selector(uim_lisp id_)
671
635
{
672
636
  uim_context uc = retrieve_uim_context(id_);
673
 
  uim_schedule_cb(uc, CAND_DEACTIVATE_CB, NULL, 0, 0);
674
 
  return false_sym;
 
637
  if (uc->candidate_selector_deactivate_cb) {
 
638
    uc->candidate_selector_deactivate_cb(uc->ptr);
 
639
  }
 
640
  return uim_scm_f();
675
641
}
676
642
 
677
 
static LISP
678
 
im_return_str(LISP str_)
 
643
static uim_lisp
 
644
im_return_str(uim_lisp str_)
679
645
{
680
646
  if (uim_return_str) {
681
647
    free(uim_return_str);
682
648
    uim_return_str = NULL;
683
649
  }
684
 
  if STRINGP(str_) {
685
 
    uim_return_str = uim_get_c_string(str_);
 
650
  if (uim_scm_stringp(str_)) {
 
651
    uim_return_str = uim_scm_c_str(str_);
686
652
  }
687
 
  return false_sym;
 
653
  return uim_scm_f();
688
654
}
689
655
 
690
 
static LISP
691
 
im_return_str_list(LISP str_list_)
 
656
static uim_lisp
 
657
im_return_str_list(uim_lisp str_list_)
692
658
{
693
659
  /*XXX: This fixed length array is negligence */
694
660
  int i;
695
661
 
696
 
  if (uim_return_str_list) {
697
 
    for (i = 0; i < (int)UIM_RETURN_STR_LIST_SIZE; i++){
698
 
      if (uim_return_str_list[i]) {
699
 
        free(uim_return_str_list[i]);
700
 
        uim_return_str_list[i] = NULL;
701
 
      } else {
702
 
        break;
703
 
      }
 
662
  for (i = 0; i < (int)UIM_RETURN_STR_LIST_SIZE; i++) {
 
663
    if (uim_return_str_list[i]) {
 
664
      free(uim_return_str_list[i]);
 
665
      uim_return_str_list[i] = NULL;
 
666
    } else {
 
667
      break;
704
668
    }
705
669
  }
706
670
 
707
671
  i = 0;
708
672
 
709
 
  while (NNULLP(str_list_) && i < (int)UIM_RETURN_STR_LIST_SIZE) {
710
 
    LISP str_ = CAR(str_list_);
711
 
    if STRINGP(str_) {
712
 
      uim_return_str_list[i] = uim_get_c_string(str_);
 
673
  while (!uim_scm_nullp(str_list_) && i < (int)UIM_RETURN_STR_LIST_SIZE) {
 
674
    uim_lisp str_ = uim_scm_car(str_list_);
 
675
    if (uim_scm_stringp(str_)) {
 
676
      uim_return_str_list[i] = uim_scm_c_str(str_);
713
677
    }
714
678
 
715
679
    i++;
716
 
    str_list_ = CDR(str_list_);
 
680
    str_list_ = uim_scm_cdr(str_list_);
717
681
  }
718
682
  uim_return_str_list[i] = NULL;
719
 
  return false_sym;
 
683
  return uim_scm_f();
720
684
}
721
685
 
722
 
static LISP
723
 
im_request_surrounding(LISP id_)
 
686
static uim_lisp
 
687
im_request_surrounding(uim_lisp id_)
724
688
{
725
689
  uim_context uc = retrieve_uim_context(id_);
726
690
  if (!uc->request_surrounding_text_cb) {
727
 
    return NIL;
728
 
  }
729
 
  uim_schedule_cb(uc, REQUEST_SURROUNDING_CB, NULL, 0, 0);
730
 
  return true_sym;
 
691
    return uim_scm_f();
 
692
  }
 
693
  if (uc->request_surrounding_text_cb) {
 
694
    uc->request_surrounding_text_cb(uc->ptr);
 
695
  }
 
696
  return uim_scm_t();
731
697
}
732
698
 
733
 
static LISP
734
 
im_delete_surrounding(LISP id_, LISP offset_, LISP len_)
 
699
static uim_lisp
 
700
im_delete_surrounding(uim_lisp id_, uim_lisp offset_, uim_lisp len_)
735
701
{
736
702
  uim_context uc = retrieve_uim_context(id_);
737
 
  int offset = get_c_int(offset_);
738
 
  int len = get_c_int(len_);
 
703
  int offset = uim_scm_c_int(offset_);
 
704
  int len = uim_scm_c_int(len_);
739
705
  if (!uc->delete_surrounding_text_cb) {
740
 
    return NIL;
741
 
  }
742
 
  uim_schedule_cb(uc, DELETE_SURROUNDING_CB, NULL, offset, len);
743
 
  return true_sym;
 
706
    return uim_scm_f();
 
707
  }
 
708
  if (uc->delete_surrounding_text_cb) {
 
709
    uc->delete_surrounding_text_cb(uc->ptr, offset, len);
 
710
  }
 
711
  return uim_scm_t();
 
712
}
 
713
 
 
714
static uim_lisp
 
715
switch_im(uim_lisp id_, uim_lisp name_)
 
716
{
 
717
  uim_context uc;
 
718
  const char *name;
 
719
 
 
720
  uc = retrieve_uim_context(id_);
 
721
  name= uim_scm_refer_c_str(name_);
 
722
 
 
723
  uim_switch_im(uc, name);
 
724
  if (uc->configuration_changed_cb)
 
725
    uc->configuration_changed_cb(uc->ptr);
 
726
 
 
727
  return uim_scm_t();
 
728
}
 
729
 
 
730
static uim_lisp
 
731
switch_app_global_im(uim_lisp id_, uim_lisp name_)
 
732
{
 
733
  uim_context uc;
 
734
  const char *name;
 
735
 
 
736
  uc = retrieve_uim_context(id_);
 
737
  name = uim_scm_refer_c_str(name_);
 
738
 
 
739
  if (uc->switch_app_global_im_cb)
 
740
    uc->switch_app_global_im_cb(uc->ptr, name);
 
741
 
 
742
  return uim_scm_t();
 
743
}
 
744
 
 
745
static uim_lisp
 
746
switch_system_global_im(uim_lisp id_, uim_lisp name_)
 
747
{
 
748
  uim_context uc;
 
749
  const char *name;
 
750
 
 
751
  uc = retrieve_uim_context(id_);
 
752
  name = uim_scm_refer_c_str(name_);
 
753
 
 
754
  if (uc->switch_system_global_im_cb)
 
755
    uc->switch_system_global_im_cb(uc->ptr, name);
 
756
 
 
757
  return uim_scm_t();
744
758
}
745
759
 
746
760
void
747
761
uim_init_im_subrs(void)
748
762
{
749
 
  true_sym  = siod_true_value();
750
 
#if 0
751
 
  false_sym = siod_false_value();
752
 
#else
753
 
  /* false_sym has to be NIL until bug #617 and #642 are fixed
754
 
   * -- YamaKen
755
 
   */
756
 
  false_sym = NIL;
757
 
#endif
758
 
 
759
 
  /**/
760
 
  init_subr_1("im-return-str", im_return_str);
761
 
  init_subr_1("im-return-str-list", im_return_str_list);
762
 
  /**/
763
 
  init_subr_2("im-commit",       im_commit);
764
 
  init_subr_1("im-commit-raw",   im_commit_raw);
765
 
  init_subr_2("im-get-raw-key-str", im_get_raw_key_str);
766
 
  init_subr_2("im-set-encoding", im_set_encoding);
767
 
  /**/
768
 
  init_subr_4("im-register-im", im_register_im);
769
 
  /**/
770
 
  init_subr_1("im-clear-preedit",    im_clear_preedit);
771
 
  init_subr_3("im-pushback-preedit", im_pushback_preedit);
772
 
  init_subr_1("im-update-preedit",   im_update_preedit);
773
 
  /**/
774
 
  init_subr_1("im-clear-mode-list",    im_clear_mode_list);
775
 
  init_subr_2("im-pushback-mode-list", im_pushback_mode_list);
776
 
  init_subr_1("im-update-mode-list",   im_update_mode_list);
777
 
  /**/
778
 
  init_subr_2("im-update-prop-label", im_update_prop_label);
779
 
  init_subr_2("im-update-prop-list",  im_update_prop_list);
780
 
  /**/
781
 
  init_subr_2("im-update-mode", im_update_mode);
782
 
  /**/
783
 
  init_subr_3("im-activate-candidate-selector",  im_activate_candidate_selector);
784
 
  init_subr_2("im-select-candidate", im_select_candidate);
785
 
  init_subr_2("im-shift-page-candidate", im_shift_page_candidate);
786
 
  init_subr_1("im-deactivate-candidate-selector", im_deactivate_candidate_selector);
787
 
  /**/
788
 
  init_subr_1("im-request-surrounding", im_request_surrounding);
789
 
  init_subr_3("im-delete-surrounding", im_delete_surrounding);
 
763
  /**/
 
764
  uim_scm_init_subr_1("im-return-str", im_return_str);
 
765
  uim_scm_init_subr_1("im-return-str-list", im_return_str_list);
 
766
  /**/
 
767
  uim_scm_init_subr_2("im-commit",       im_commit);
 
768
  uim_scm_init_subr_1("im-commit-raw",   im_commit_raw);
 
769
  uim_scm_init_subr_2("im-get-raw-key-str", im_get_raw_key_str);
 
770
  uim_scm_init_subr_2("im-set-encoding", im_set_encoding);
 
771
  /**/
 
772
  uim_scm_init_subr_4("im-register-im", im_register_im);
 
773
  /**/
 
774
  uim_scm_init_subr_1("im-clear-preedit",    im_clear_preedit);
 
775
  uim_scm_init_subr_3("im-pushback-preedit", im_pushback_preedit);
 
776
  uim_scm_init_subr_1("im-update-preedit",   im_update_preedit);
 
777
  /**/
 
778
  uim_scm_init_subr_1("im-clear-mode-list",    im_clear_mode_list);
 
779
  uim_scm_init_subr_2("im-pushback-mode-list", im_pushback_mode_list);
 
780
  uim_scm_init_subr_1("im-update-mode-list",   im_update_mode_list);
 
781
  /**/
 
782
  uim_scm_init_subr_2("im-update-prop-list",  im_update_prop_list);
 
783
  /**/
 
784
  uim_scm_init_subr_2("im-update-mode", im_update_mode);
 
785
  /**/
 
786
  uim_scm_init_subr_3("im-activate-candidate-selector",  im_activate_candidate_selector);
 
787
  uim_scm_init_subr_2("im-select-candidate", im_select_candidate);
 
788
  uim_scm_init_subr_2("im-shift-page-candidate", im_shift_page_candidate);
 
789
  uim_scm_init_subr_1("im-deactivate-candidate-selector", im_deactivate_candidate_selector);
 
790
  /**/
 
791
  uim_scm_init_subr_1("im-request-surrounding", im_request_surrounding);
 
792
  uim_scm_init_subr_3("im-delete-surrounding", im_delete_surrounding);
 
793
  /**/
 
794
  uim_scm_init_subr_2("im-switch-im", switch_im);
 
795
  uim_scm_init_subr_2("im-switch-app-global-im", switch_app_global_im);
 
796
  uim_scm_init_subr_2("im-switch-system-global-im", switch_system_global_im);
790
797
}