1<!doctype Book PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
2<book>
3  <bookinfo>
4    <title>Uim Developer's Document</title>
5    <author>
6      <firstname>Kazuki</firstname>
7      <surname>Ohta</surname>
8    </author>
9  </bookinfo>
10
11  <chapter>
12    <title>Introduction</title>
13    <para>
14      Uim is a multilingual input method library which does NOT adopt a Client/Server framework, in keeping with Uim's goal of being very "Simple and Secure".
15    </para>
16    <para>
17      This document aims to explain the use of Uim's API to the developer who wishes to engineer a bridge between the Uim library and an application (or GUI toolkit).
18      This is also the official reference document for the Uim library.
19      This document assumes the reader to have a good understanding of the C programming language, but does not require an intimate understanding of Uim internals.
20    </para>
21    <para>
22      This document is written based on Uim version 0.4.6. (Though 0.4.6 is
23      not released yet.) If you wish to create an application using Uim
24      while reading to this document, please install the Uim library
25      version 0.4.6 (or higher) and C compiler on your system.
26    </para>
27    <para>
28      You can use, modify, distribute and sell this package under the terms of BSD license.
29      Please see the COPYING file included in the package for details.
30    </para>
31
32    <section>
33      <title>IM related technical vocabulary</title>
34
35      <para>
36        One needs to know some IM related jargon when using Uim library.
37        We present a few of the commonly used words here.
38      </para>
39
40      <variablelist>
41        <varlistentry>
42          <term>commit</term>
43          <listitem>
44            <para>The transferrence of a input string from an input method to the application.</para>
45          </listitem>
46        </varlistentry>
47
48        <varlistentry>
49          <term>preedit</term>
50          <Listitem>
51            <Para>A string which is currently being inputted, but not yet committed</para>
52          </listitem>
53        </varlistentry>
54
55        <varlistentry>
56          <term>candidate</term>
57          <listitem>
58            <para>candidate for the conversion process</para>
59          </listitem>
60        </varlistentry>
61
62        <varlistentry>
63          <term>segment</term>
64          <listitem>
65            <para>basic block of characters withing a string</para>
66          </listitem>
67        </varlistentry>
68
69          <varlistentry>
70            <term>cb</term>
71            <listitem>
72              <para>An abbreviation for "callback"</para>
73            </listitem>
74          </varlistentry>
75
76          <varlistentry>
77            <term>property</term>
78            <listitem>
79              <para>a generic term describing a particular state of an input method</para>
80            </listitem>
81          </varlistentry>
82        </variablelist>
83    </section>
84  </chapter>
85
86  <chapter>
87    <title>Initializing and Finalizing library</title>
88    <para>
89      Starting in this chapter, the contents explain how to use Uim library.
90    </para>
91
92    <para>
93      You can initialize Uim library by calling uim_init() function.
94      To use this function, you need to include the &lt;uim/uim.h&gt; header.
95
96      <programlisting>
97        if (uim_init() != 0) {
98            printf("uim_init() failed\n");
99            exit(1);
100        }
101      </programlisting>
102
103      As well as initializing, you can finalize library by calling uim_quit() function.
104
105      <programlisting>
106        uim_quit();
107      </programlisting>
108
109    </para>
110  </chapter>
111
112  <chapter>
113    <title>How to write your own input method</title>
114    <para>
115      This chapter would describe a rough image of writing your own input method.
116    </para>
117    <para>
118      Currently, uim is tied to Scheme interpreter. Uim could be used as an
119      shared library from the application side. But if you want to write your
120      own input method, you have to treat some scheme code (for now).
121    </para>
122  </chapter>
123
124  <chapter>
125    <title>Creating and Releasing Input Context</title>
126
127    <para>
128      In the Uim library, you must provide and instance of an Input Context structure when calling most of the functions.
129      The type of this Input Context object used in Uim is uim_context.
130    </para>
131    <para>
132      This chapter describes how to create and release a uim_context.
133    </para>
134    <para>
135      You can create Uim input context by calling uim_create_context() function.
136      A new input context needs to be created for each input method being used. For example, when switching from a "uim-anthy" input context to a "uim-prime" one, a new context needs to be created for the latter.
137      The 1st argument of this function is your private structure which is needed to handle IM management.
138    </para>
139    <para>
140      When you finish using the input context, you need to release input context by calling uim_release_context() function.
141    </para>
142    <para>
143      Below is an example of actual code (for uim-anthy).
144    </para>
145
146    <section>
147      <title>Sample Program</title>
148      <programlisting>
149        #include &lt;uim/uim.h&gt;
150        #include &lt;stdlib.h&gt;
151
152        typedef struct _IMUimContext {
153          uim_context uc;
154        } IMUimContext;
155
156        IMUimContext uic;
157
158        static void im_uim_commit_string(void *ptr, const char *str);
159
160        void init_im(void) {
161          if (uim_init() != 0) {
162            printf("uim_init() failed\n");
163            exit(1);
164          }
165
166          uic.uc = uim_create_context(&amp;uic, "UTF-8",
167              	                      NULL, "uim-anthy",
168                	              uim_iconv,
169                                      im_uim_commit_string);
170        }
171
172        static void im_uim_commit_string(void *ptr, const char *str) {
173          IMUimContext *uic = (IMUimContext*)ptr;
174	  printf("'%s' should be committed\n",str);
175          /* commit string */
176        }
177
178        void quit_im(void) {
179          uim_release_context(uic.uc);
180          uim_quit();
181        }
182      </programlisting>
183    </section>
184  </chapter>
185
186  <chapter>
187    <title>Retrieving the names of available input methods</title>
188
189    <para>
190      Uim has many available input methods and you can get a list of names of these methods.
191      uim_get_nr_im() function returns the number of available input methods, and uim_get_im_name() returns the name of an input method indexed by a number between zero and the return value of uim_get_nr_im().
192      You can also discover an input method's language by calling the uim_get_im_language() function.
193    </para>
194    <para>
195       Here is some example code.
196    </para>
197
198    <programlisting>
199      int i = 0;
200
201      uim_context tmpuc = uim_create_context(NULL, enconding, NULL, NULL, NULL);
202      for (i = 0; i < uim_get_nr_im(tmpuc); i++) {
203        im[i].name = uim_get_im_name(tmpuc, i);
204        im[i].lang = uim_get_im_language(tmpuc, i);
205      }
206      uim_release_context(tmpuc);
207    </programlisting>
208  </chapter>
209
210  <chapter>
211    <title>Setting callbacks</title>
212
213    <section>
214      <title>Preedit related callbacks</title>
215
216      <para>
217        To handle preedit buffers, you need to implement three callbacks: clear_cb(), pushback_cb(),and  update_cb().
218        Once implemented, they can be configured using uim_set_preedit_cb().
219        pushback_cb() is called sequentially between the calls of clear_cb() and update_cb().
220      </para>
221      <para>
222        The preedit string comes as a segment with attributes, so you need to store the preedit string in update_cb() and commit this in commit_cb() which is set by uim_create_context().
223      </para>
224      <para>
225        Each callback's outline behavior is like this.
226      </para>
227
228        <variablelist>
229          <varlistentry>
230            <term>clear_cb</term>
231            <listitem>
232              <para>freeing all stored preedit segment</para>
233            </listitem>
234          </varlistentry>
235
236          <varlistentry>
237            <term>pushback_cb</term>
238            <listitem>
239              <para>store the string and attributes</para>
240            </listitem>
241          </varlistentry>
242
243          <varlistentry>
244            <term>update_cb</term>
245            <listitem>
246              <para>show stored preedit string (real process </para>
247            </listitem>
248          </varlistentry>
249        </variablelist>
250    </section>
251
252    <section>
253      <title>Candidate related callbacks and Candidate related function</title>
254
255      <para>
256      </para>
257
258      <para>
259        Some language like Chinese and Japanese require a conversion from phoenetic representation to written respresentation. This process requires the user to select from a list of conversion candidates.
260        The typical approach is to display a list of candidates in a small window.
261      </para>
262      <para>
263        Uim's candidate related API is constructed very carefully as not to repeat a mistake in the design XIM.
264        In terms of the index of the selected candidate, both user and input system should be able to handle the index of current candidate.
265      </para>
266      <para>
267        To handle candidate window behavior, Uim provides special callbacks.
268        You need to implement four callbacks activate_cb(), select_cb(), shift_page_cb(), deactivate_cb().
269        Next, set these callbacks by calling uim_set_candidate_selector_cb().
270      </para>
271      <para>
272        Each callback's outline behavior is like this.
273      </para>
274
275        <variablelist>
276          <varlistentry>
277            <term>activate_cb(void *ptr, int nr, int displayLimit)</term>
278            <listitem>
279              <para>show the candidate window. $nr is the number of candidates, and displayLimit is the max number of displayed candidates.</para>
280            </listitem>
281          </varlistentry>
282
283          <varlistentry>
284            <term>select_cb(void *ptr, int index)</term>
285            <listitem>
286              <para>This callback communicates the index of the currently selected candidate</para>
287            </listitem>
288          </varlistentry>
289
290          <varlistentry>
291            <term>shift_page_cb(void *ptr, int direction)</term>
292            <listitem>
293              <para>
294                This callback is called when "generic-next-page-key" or "generic-prev-page-key" is pressed.
295                If next-page-key, $direction is 1. And if prev-page-key, $direction is 0.
296              </para>
297            </listitem>
298          </varlistentry>
299
300          <varlistentry>
301            <term>deactivate_cb(void *ptr)</term>
302            <listitem>
303              <para>hide the candidate window.</para>
304            </listitem>
305          </varlistentry>
306        </variablelist>
307
308      <para>
309        Note that the activate_cb() is not necessarily called before the select_cb(), as the activation/deactivation of a candidate window and selection of a candidate are orthogonal operations. It is possible for the input method to specify a candidate selection in a hidden window, and then call the activate_cb() at a later time.
310
311      </para>
312
313      <section>
314        <title>Candidate related functions</title>
315        <para>
316          You can access candidate data with the combination of uim_get_candidate(), uim_candidate_get_cand_str(), uim_candidate_get_heading_label(), uim_candidate_free().
317          First, you can get struct uim_candidate by calling uim_get_candidate() and then access candidate string and heading label by passing this struct as an argument into uim_candidate_get_cand_str(), uim_candidate_get_heading_label().
318          At last, you must free the struct by excuting uim_candidate_free().
319        </para>
320        <para>
321          The sample use is shown below.
322        </para>
323        <programlisting>
324          int i = 0;
325          uim_candidate cand = NULL;
326
327          for (i = 0; i < NR_CANDIDATES; i++) {
328            cand = uim_get_candidate(uc, i, i);
329
330            candidates[i].str = uim_candidate_get_cand_str(cand);
331            candidates[i].hlabel =
332            uim_candidate_get_heading_label(cand);
333
334            uim_candidate_free(cand);
335          }
336        </programlisting>
337        <para>
338          You should call uim_set_candidate_index() when specified index is selected by mouse clicking or key pressing etc.
339        </para>
340      </section>
341    </section>
342
343    <section>
344      <title>Property related callbacks</title>
345
346      <para>
347	Property describes input method's various properties such as input mode.
348	There is one callback function for property. You can set the callback
349	function via uim_set_prop_list_update_cb, uim_set_prop_label_update_cb.
350	To tell the truth, the design of property functions is fault. If we
351	have a chance to break libuim's API, the property API will be refined
352	at first.
353      </para>
354
355      <programlisting>
356        int i = 0;
357        uim_candidate cand = NULL;
358
359        for (i = 0; i < NR_CANDIDATES; i++) {
360	     cand = uim_get_candidate(uc, i, i);
361	     candidates[i].str = uim_candidate_get_cand_str(cand);
362	     candidates[i].hlabel = uim_candidate_get_heading_label(cand);
363             uim_candidate_free(cand);
364        }
365        </programlisting>
366    </section>
367  </chapter>
368
369  <chapter>
370    <title>Customization features</title>
371
372    <para>
373      Since 0.4.6, uim have a customization API named 'custom API'. All custom
374      API functions have a prefix uim_custom_ and defined in uim-custom.h.
375    </para>
376    <para>
377      Concept of custom API is similar to GLib's Key-value file parser,
378      but custom API has some convenience features. All settings are
379      automatically stored in ~/.uim.d/customs/group-name by the calling
380      of uim_save().
381    </para>
382    <para>
383
384    </para>
385
386    <section>
387      <title>Initialize and finalize</title>
388      <para>
389	To use full of custom API, you must call uim_custom_enable()
390	after uim_init(). Finalization process is done in uim_quit,
391	so you should call uim_quit() before exit.
392      </para>
393    </section>
394
395    <section>
396      <title>Getting all groups</title>
397      <para>
398	Custom API has a concept of 'group'. Each customization item
399	belongs to a group. For example, anthy-nr-candidate-max
400	belongs to 'anthy' group. This sample code show all custom
401	group label.
402      </para>
403
404      <programlisting>
405    char **primary_groups, **grp;
406
407    primary_groups = uim_custom_primary_groups();
408    for (grp = primary_groups; *grp; grp++) {
409      struct uim_custom_group *group;
410      group = uim_custom_group_get(*grp);
411      printf("Group:%s\n", group->label);
412    }
413    uim_custom_symbol_list_free(primary_groups);
414        </programlisting>
415
416    <para>
417      uim_custom_primary_groups returns NULL-terminated array of key
418      of custom group. uim_custom_group_get returns concrete custome
419      group struct from key string.
420    </para>
421    </section>
422
423  </chapter>
424
425  <chapter>
426    <title>How to debug</title>
427    <para>
428      If you want to debug uim, there're some useful features. At first,
429      you should configure your uim with
430      <emphasis>./configure --enable-debug</emphasis> to enable debug features.
431    </para>
432
433    <para>
434      There are some useful enviroment variables to debug.
435    </para>
436
437    <variablelist>
438
439      <varlistentry>
440        <term>LIBUIM_VERBOSE</term>
441        <listitem>
442          <para>
443	    This variable takes a number as a value. Range of number is 0-10. If LIBUIM_VERBOSE is
444	    greater than or equal 5, uim shows backtrace when error occurred.
445	  </para>
446	</listitem>
447      </varlistentry>
448
449      <varlistentry>
450	<term>UIM_IM_ENGINE</term>
451	<listitem>
452	  <para>
453	    This variable takes an input method name as a value. Unfortunately, there's no
454	    tool to know currently available input method names.
455	  </para>
456	</listitem>
457      </varlistentry>
458
459      <varlistentry>
460	<term>LIBUIM_VANILLA</term>
461	<listitem>
462	  <para>
463	    This variable takes an integer value. uim changes its
464	    behavior as follows if variable is defined.
465	  <programlisting>
466	LIBUIM_VANILLA=2 : vanilla + toppings
467       ;; disable ~/.uim, user customs and lazy loading, but enable loading
468       ;; modules
469
470	LIBUIM_VANILLA=1 : pure vanilla
471       ;; disable ~/.uim, user customs, lazy loading, loading modules
472
473	undefined : fully flavored
474       ;; enable ~/.uim, user customs, lazy loading if required, and loading
475       ;; modules
476	  </programlisting>
477	  </para>
478	</listitem>
479      </varlistentry>
480
481      <varlistentry>
482	<term>LIBUIM_SCM_FILES</term>
483	<listitem>
484	  <para>
485	    This variable takes a directory path as a value. If this variable
486	    is defined, uim add the value to the search path of .scm files.
487	  </para>
488	</listitem>
489      </varlistentry>
490
491      <varlistentry>
492	<term>LIBUIM_PLUGIN_LIB_DIR</term>
493	<listitem>
494	  <para>
495	    This variable takes a directory path as a value. If this variable
496	    is defined, uim add the value to the search path of plugin files.
497	  </para>
498	</listitem>
499      </varlistentry>
500    </variablelist>
501
502  </chapter>
503			</book>
504
505