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

« back to all changes in this revision

Viewing changes to emacs/context.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
/*
 
2
  Copyright (c) 2005-2006 uim Project http://uim.freedesktop.org/
 
3
 
 
4
  All rights reserved.
 
5
 
 
6
  Redistribution and use in source and binary forms, with or
 
7
  without modification, are permitted provided that the
 
8
  following conditions are met:
 
9
 
 
10
  1. Redistributions of source code must retain the above
 
11
     copyright notice, this list of conditions and the
 
12
     following disclaimer.
 
13
  2. Redistributions in binary form must reproduce the above
 
14
     copyright notice, this list of conditions and the
 
15
     following disclaimer in the documentation and/or other
 
16
     materials provided with the distribution.
 
17
  3. Neither the name of authors nor the names of its
 
18
     contributors may be used to endorse or promote products
 
19
     derived from this software without specific prior written
 
20
     permission.
 
21
 
 
22
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 
23
  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 
24
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
25
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
26
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
27
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
28
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
29
  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
30
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
31
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
32
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
33
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
34
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
35
*/
 
36
 
 
37
#include "context.h"
 
38
 
 
39
/* current focused context */
 
40
uim_agent_context *current;
 
41
 
 
42
/* global foscu */
 
43
int focused = 0;
 
44
 
 
45
uim_agent_context_list *agent_context_list_head = NULL;
 
46
uim_agent_context_list *agent_context_list_tail = NULL;
 
47
 
 
48
static void
 
49
update_context_im(uim_agent_context *ua)
 
50
{
 
51
  debug_printf(DEBUG_NOTE, "update_context_im\n");
 
52
 
 
53
  uim_switch_im(ua->context, ua->im);
 
54
 
 
55
  if (ua->im && strcmp(ua->im, uim_get_current_im_name(ua->context)) != 0) {
 
56
        debug_printf(DEBUG_ERROR,
 
57
                                 "update_context_im: failed to switch IM to %s\n", ua->im);
 
58
        free(ua->im);
 
59
        ua->im = strdup(uim_get_current_im_name(ua->context));
 
60
  }
 
61
}
 
62
 
 
63
static void
 
64
update_context_encoding(uim_agent_context *ua)
 
65
{
 
66
 
 
67
  debug_printf(DEBUG_NOTE, "update_context_encoding\n");
 
68
 
 
69
  /* discard current context */
 
70
  clear_candidate(ua->cand);
 
71
  clear_preedit(ua->pe);
 
72
  uim_release_context(ua->context);
 
73
  
 
74
  ua->context = create_context(ua->encoding, ua);
 
75
 
 
76
  update_context_im(ua);
 
77
  
 
78
}
 
79
 
 
80
 
 
81
/* search context */
 
82
uim_agent_context *
 
83
get_uim_agent_context(int id)
 
84
{
 
85
  uim_agent_context_list *ptr;
 
86
 
 
87
  debug_printf(DEBUG_NOTE, "get_uim_agent_context (%d)\n", id);
 
88
  
 
89
  for (ptr = agent_context_list_head; ptr != NULL; ptr = ptr->next) {
 
90
        if (ptr->agent_context->context_id == id)
 
91
          return ptr->agent_context;
 
92
  }
 
93
 
 
94
  return NULL;
 
95
}
 
96
 
 
97
 
 
98
 
 
99
uim_agent_context *
 
100
switch_context_im(uim_agent_context *ua, const char *im)
 
101
{
 
102
  const char *encoding;
 
103
 
 
104
  debug_printf(DEBUG_NOTE, "switch_context_im\n");
 
105
 
 
106
  encoding = get_im_encoding(im);
 
107
 
 
108
  /* update IM name */
 
109
  if (ua->im) free(ua->im);
 
110
 
 
111
  if (im)
 
112
        ua->im = strdup(im);
 
113
  else
 
114
        ua->im = NULL;
 
115
 
 
116
  if (strcmp(ua->encoding, encoding) == 0) {
 
117
        /* encodings are same */
 
118
 
 
119
        debug_printf(DEBUG_NOTE, "same encoding %s %s\n", ua->im, im);
 
120
 
 
121
        update_context_im(ua);
 
122
 
 
123
        uim_prop_list_update(ua->context);
 
124
 
 
125
  } else {
 
126
        /* encodings are different */
 
127
 
 
128
        debug_printf(DEBUG_NOTE, 
 
129
                                 "different encoding %s %s\n", ua->encoding, encoding);
 
130
 
 
131
        if (ua->encoding) free(ua->encoding);
 
132
        ua->encoding = strdup(encoding);
 
133
 
 
134
        update_context_encoding(ua);
 
135
 
 
136
  }
 
137
 
 
138
  uim_prop_list_update(ua->context);
 
139
 
 
140
  return ua;
 
141
 
 
142
}
 
143
 
 
144
 
 
145
void
 
146
switch_context_im_all(const char *im)
 
147
{
 
148
  char *quot_im_name;
 
149
  uim_agent_context_list *ptr;
 
150
 
 
151
  /* change default IM  */
 
152
  update_default_engine(im);
 
153
 
 
154
  /* check focus state when change IM of current application */
 
155
  quot_im_name = (char *)malloc(strlen(im) + 2);
 
156
  quot_im_name[0] = '\'';
 
157
  quot_im_name[1] = '\0';
 
158
  strcat(quot_im_name, im);
 
159
 
 
160
  if (agent_context_list_head)
 
161
        /* update default IM name in libuim? should be called only one time? */
 
162
        uim_prop_update_custom(agent_context_list_head->agent_context->context,
 
163
                                                   "custom-preserved-default-im-name",
 
164
                                                   quot_im_name);
 
165
 
 
166
  for (ptr = agent_context_list_head; ptr != NULL; ptr = ptr->next) {
 
167
        switch_context_im(ptr->agent_context, im);
 
168
  }
 
169
 
 
170
  free(quot_im_name);
 
171
}
 
172
 
 
173
 
 
174
 
 
175
uim_context
 
176
create_context(const char *encoding, uim_agent_context *ptr)
 
177
{
 
178
  uim_context context;
 
179
 
 
180
  context = uim_create_context(ptr,
 
181
                                                           encoding,
 
182
                                                           NULL,
 
183
                                                           NULL,  /*default_engine_name,*/
 
184
                                                           uim_iconv,
 
185
                                                           commit_cb);
 
186
 
 
187
  uim_set_preedit_cb(context,
 
188
                                         preedit_clear_cb,
 
189
                                         preedit_pushback_cb,
 
190
                                         preedit_update_cb);
 
191
 
 
192
  uim_set_candidate_selector_cb(context,
 
193
                                                                candidate_activate_cb,
 
194
                                                                candidate_select_cb,
 
195
                                                                candidate_shift_page_cb,
 
196
                                                                candidate_deactivate_cb);
 
197
 
 
198
  uim_set_prop_list_update_cb(context,
 
199
                                                          prop_list_update_cb);
 
200
 
 
201
 
 
202
  uim_set_configuration_changed_cb(context,
 
203
                                                                   configuration_changed_cb);
 
204
 
 
205
  uim_set_im_switch_request_cb(context,
 
206
                                                           switch_app_global_im_cb,
 
207
                                                           switch_system_global_im_cb);
 
208
 
 
209
  
 
210
  return context;
 
211
 
 
212
}
 
213
 
 
214
 
 
215
uim_agent_context *
 
216
create_uim_agent_context(const char *encoding)
 
217
{
 
218
 
 
219
  uim_agent_context *ret;
 
220
  const char *im;
 
221
 
 
222
  debug_printf(DEBUG_NOTE, "create_uim_agent_context\n");
 
223
 
 
224
  ret = (uim_agent_context *)malloc(sizeof(uim_agent_context));
 
225
 
 
226
  if (encoding) {
 
227
        ret->encoding = strdup(encoding);
 
228
  } else {
 
229
        if (debug_level > 0)
 
230
          ret->encoding = strdup("EUC-JP");
 
231
        else
 
232
          ret->encoding = strdup("UTF-8");
 
233
  }
 
234
 
 
235
  ret->context = create_context(ret->encoding, ret);
 
236
 
 
237
  if ((im = uim_get_default_im_name(setlocale(LC_ALL, NULL))))
 
238
        ret->im = strdup(im);
 
239
  else
 
240
        ret->im = NULL;
 
241
 
 
242
  ret->pe = create_preedit();
 
243
  ret->cand = create_candidate();
 
244
  ret->prop = create_prop();
 
245
 
 
246
  ret->comstr = (char *)NULL;
 
247
 
 
248
  return ret;
 
249
}
 
250
 
 
251
 
 
252
 
 
253
 
 
254
/* add context to context list */
 
255
uim_agent_context *
 
256
new_uim_agent_context(int id, const char *encoding)
 
257
{
 
258
  uim_agent_context_list *ptr;
 
259
  
 
260
  debug_printf(DEBUG_NOTE, "add_uim_agent_context(%d)\n", id);
 
261
 
 
262
  ptr = (uim_agent_context_list *)malloc(sizeof(uim_agent_context_list));
 
263
 
 
264
  ptr->agent_context = create_uim_agent_context(encoding);
 
265
  ptr->next = NULL;
 
266
  ptr->prev = NULL;
 
267
 
 
268
  ptr->agent_context->context_id = id;
 
269
 
 
270
  if (agent_context_list_tail != NULL) {
 
271
        agent_context_list_tail->next = ptr;
 
272
        ptr->prev = agent_context_list_tail;
 
273
  }
 
274
 
 
275
  agent_context_list_tail = ptr;
 
276
 
 
277
  if (agent_context_list_head == NULL)
 
278
        agent_context_list_head = ptr;
 
279
 
 
280
  return ptr->agent_context;
 
281
}
 
282
 
 
283
 
 
284
/* release context from context list */
 
285
int
 
286
release_uim_agent_context(int context_id)
 
287
{
 
288
  uim_agent_context_list *ptr;
 
289
  
 
290
  for (ptr = agent_context_list_head; ptr != NULL; ptr = ptr->next) {
 
291
        if (ptr->agent_context->context_id == context_id) {
 
292
 
 
293
          uim_agent_context *ua = ptr->agent_context;
 
294
 
 
295
          /* clear current */
 
296
          if (current == ua)
 
297
                clear_current_uim_agent_context();
 
298
          
 
299
          /* release */
 
300
          uim_release_context(ua->context);
 
301
 
 
302
          /* clear candidate */
 
303
          clear_candidate(ua->cand);
 
304
          free(ua->cand);
 
305
 
 
306
          /* clear preedit */
 
307
          clear_preedit(ua->pe);
 
308
          free(ua->pe);
 
309
 
 
310
          /* free others */
 
311
          free(ua->encoding);
 
312
          free(ua->im);
 
313
          free(ua->prop);
 
314
          free(ua->comstr);
 
315
 
 
316
          /* rebuild list */
 
317
          if (ptr->next != NULL)
 
318
                ptr->next->prev = ptr->prev;
 
319
          else
 
320
                agent_context_list_tail = ptr->prev;
 
321
 
 
322
          if (ptr->prev != NULL)
 
323
                ptr->prev->next = ptr->next;
 
324
          else
 
325
                agent_context_list_head = ptr->next;
 
326
 
 
327
          free(ptr);
 
328
 
 
329
          return context_id;
 
330
        }
 
331
  }
 
332
 
 
333
  return -1;
 
334
}
 
335
 
 
336
 
 
337
 
 
338
 
 
339
 
 
340
int
 
341
set_current_uim_agent_context(uim_agent_context *ua)
 
342
{
 
343
  debug_printf(DEBUG_NOTE, "set_current_context\n");
 
344
 
 
345
  if (ua == NULL || ua->context == NULL) {
 
346
        debug_printf(DEBUG_ERROR, "set_current_context: invalid context\n");
 
347
        return -1;
 
348
  }
 
349
 
 
350
  helper_send_message("focus_in\n");
 
351
 
 
352
  current = ua;
 
353
  focused = 1;
 
354
 
 
355
  uim_prop_list_update(ua->context);
 
356
 
 
357
  return ua->context_id;
 
358
}
 
359
 
 
360
 
 
361
int
 
362
clear_current_uim_agent_context(void)
 
363
{
 
364
 
 
365
  debug_printf(DEBUG_NOTE, "unfocused\n");
 
366
 
 
367
  if (current == NULL || current->context == NULL) return -1;
 
368
 
 
369
  /*focused = 0;*/
 
370
 
 
371
  helper_send_message("focus_out\n");
 
372
 
 
373
  debug_printf(DEBUG_NOTE, " focused %d\n", focused);
 
374
  
 
375
  return current->context_id;
 
376
}
 
377
 
 
378
 
 
379
 
 
380
/* handle configuration change */
 
381
void
 
382
update_context_configuration(uim_agent_context *ua)
 
383
{
 
384
 
 
385
  /* configuration of context has changed at uim side */
 
386
  debug_printf(DEBUG_NOTE, "update_context_configuration\n");
 
387
  
 
388
  /* update IM name */
 
389
  if (ua->im) free(ua->im);
 
390
  ua->im = strdup(uim_get_current_im_name(ua->context));
 
391
 
 
392
  debug_printf(DEBUG_NOTE, "ua->im %s\n", ua->im);
 
393
 
 
394
  if (ua->encoding) free(ua->encoding);
 
395
  ua->encoding = strdup(get_im_encoding(ua->im));
 
396
 
 
397
  debug_printf(DEBUG_NOTE, "ua->encoding %s\n", ua->encoding);
 
398
 
 
399
  /* switch IM again */
 
400
  update_context_encoding(ua);
 
401
}
 
402
 
 
403
 
 
404
int
 
405
show_commit_string_uim_agent_context(uim_agent_context *ua)
 
406
{
 
407
  int ret;
 
408
  if (ua == NULL) {
 
409
        return -1;
 
410
  } else {
 
411
        ret = show_commit_string(ua->comstr);
 
412
        if (ret > 0) {
 
413
          reset_commit_string(ua->comstr);
 
414
          ua->comstr = NULL;
 
415
        }
 
416
        return ret;
 
417
  }
 
418
}
 
419
 
 
420
int
 
421
show_preedit_uim_agent_context(uim_agent_context *ua)
 
422
{
 
423
  if (ua && ua->cand->valid)
 
424
        return show_preedit_force(ua->pe);
 
425
  else if (ua == NULL || !ua->pe->valid) 
 
426
        return -1;
 
427
  else
 
428
        return show_preedit(ua->pe);
 
429
}
 
430
 
 
431
 
 
432
int
 
433
show_candidate_uim_agent_context(uim_agent_context *ua)
 
434
{
 
435
  if (ua == NULL || !ua->cand->valid)
 
436
        return -1;
 
437
  else if (focused)
 
438
        return show_candidate(ua->cand);
 
439
  else
 
440
        return 0;
 
441
}
 
442
 
 
443
 
 
444
int
 
445
show_prop_uim_agent_context(uim_agent_context *ua)
 
446
{
 
447
  if (ua == NULL || !ua->prop->valid)
 
448
        return -1;
 
449
  else 
 
450
        return show_prop(ua->prop);
 
451
}
 
452
 
 
453
 
 
454
int
 
455
show_im_uim_agent_context(uim_agent_context *ua)
 
456
{
 
457
  if (ua == NULL)
 
458
        return -1;
 
459
  else
 
460
        return show_im(ua->im);
 
461
}
 
462