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 <uim/uim.h> 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 <uim/uim.h> 150 #include <stdlib.h> 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(&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