Back to index

im-sdk  12.3.91
composer.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2003 Sun Microsystems Inc.
00003  *
00004  * This is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  *
00019  * Authors: Karl Park <karl.park@sun.com>
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include <config.h>
00024 #endif
00025 
00026 #include <string.h>
00027 #include <stdio.h>
00028 #include <assert.h>
00029 #ifdef HAVE_STDINT_H
00030 #include <stdint.h>
00031 #endif
00032 #include <stdlib.h>
00033 #include <IMProtocolStruct.h>
00034 #include <iconv.h>
00035 
00036 #include "composer.h"
00037 #include "hangul.h"
00038 #include "kolelog.h"
00039 
00040 
00041 typedef struct _CoupledJamoInfo {
00042   UTFCHAR first;
00043   UTFCHAR second;
00044   UTFCHAR coupled;
00045 } CoupledJamoInfo;
00046 
00047 static HANGUL *composer_hangul_new (void);
00048 static void composer_hangul_buffer_free (HANGULBuffer *hangul_buffer);
00049 
00050 static HANGUL *
00051 composer_hangul_buffer_get_first_hangul (HANGULBuffer *hangul_buffer);
00052 
00053 static Bool
00054 composer_hangul_remove_last_hangul (HANGULBuffer *hangul_buffer, HANGUL *deleted_hangul_return);
00055 
00056 static Bool
00057 composer_hangul_convert_input_to_unicode (int keyChar, int state, KEYBOARD_LAYOUT_T layout_id, MapInfo *map_info);
00058 
00059 
00060 /* Jamo convenience */
00061 static void _jamo_copy (Jamo *dst, Jamo *src);
00062 /* static Bool _jamo_is_clean (Jamo *jamo); */
00063 static Bool _jamo_initialize (Jamo *jamo);
00064 /* static UTFCHAR _jamo_get_value (Jamo *jamo); */
00065 static UTFCHAR _jamo_get_first (Jamo *jamo);
00066 static UTFCHAR _jamo_get_second (Jamo *jamo);
00067 static int _jamo_set_values (Jamo *jamo, UTFCHAR first, UTFCHAR second);
00068 static UTFCHAR composer_hangul_coupled_jamo (UTFCHAR first, UTFCHAR second);
00069 
00070 /* character set range checking */
00071 static Bool is_not_euc_with_trailing_consonant (HANGUL *hangul, UTFCHAR tc);
00072 
00073 
00074 static HANGUL *
00075 composer_hangul_new (void)
00076 {
00077   HANGUL *a_hangul;
00078   a_hangul = (HANGUL *)calloc (1, sizeof (HANGUL) );
00079 
00080   if(!a_hangul)
00081     return NULL;
00082   else {
00083 #undef L
00084 #if 0    
00085     a_hangul->L = (UTFCHAR)0x0000;
00086     a_hangul->V = (UTFCHAR)0x0000;
00087     a_hangul->T = (UTFCHAR)0x0000;
00088 #endif
00089 
00090     memset (a_hangul, 0, sizeof (HANGUL));
00091     
00092     a_hangul->completed = False;
00093     return a_hangul;
00094   }
00095 }
00096 
00097 void
00098 composer_hangul_initialize (HANGUL *a_hangul)
00099 {
00100   assert (a_hangul != NULL);
00101 #if 0
00102   a_hangul->L = 0x0000;
00103   a_hangul->V = 0x0000;
00104   a_hangul->T = 0x0000;
00105 #endif
00106   memset (a_hangul, 0, sizeof (HANGUL));
00107   a_hangul->completed = False;
00108 }
00109 
00110 void
00111 composer_hangul_free (HANGUL *a_hangul)
00112 {
00113   if(a_hangul)
00114     free(a_hangul);
00115 }
00116 
00117 static void
00118 _jamo_copy (Jamo *dst, Jamo *src)
00119 {
00120   assert (dst != NULL);
00121   assert (src != NULL);
00122 
00123   memcpy (dst, src, sizeof (Jamo));
00124 }
00125 
00126 Bool
00127 _jamo_is_clean (Jamo *jamo)
00128 {
00129   assert (jamo != NULL);
00130 
00131   return jamo->first ? False : True;
00132 }
00133 
00134 static Bool
00135 _jamo_is_done (Jamo *jamo)
00136 {
00137   assert (jamo != NULL);
00138   return jamo->second ? True : False;
00139 }
00140 
00141 static Bool
00142 _jamo_initialize (Jamo *jamo)
00143 {
00144   assert (jamo != NULL);
00145 
00146   memset (jamo, 0, sizeof (Jamo));
00147 }
00148 
00149 UTFCHAR
00150 _jamo_get_value (Jamo *jamo)
00151 {
00152   assert (jamo != NULL);
00153   return jamo->coupled;
00154 }
00155 static UTFCHAR
00156 _jamo_get_first (Jamo *jamo)
00157 {
00158   assert (jamo != NULL);
00159   return jamo->first;
00160 }
00161      
00162 static UTFCHAR
00163 _jamo_get_second (Jamo *jamo)
00164 {
00165   assert (jamo != NULL);
00166   return jamo->second;
00167 }
00168 
00169 /*
00170   _jamo_set_values basically returns coupling result,
00171   which is same as composer_hangul_coupled_jamo ().
00172   Thus,
00173   0 return means 'invalid coupling',
00174   !0 means 'valid coupling'
00175 */
00176 
00177 static int
00178 _jamo_set_values (Jamo *jamo, UTFCHAR first, UTFCHAR second)
00179 {
00180   UTFCHAR coupled_result;
00181 
00182   assert (jamo != NULL);
00183 
00184   if (first == 0x0000){
00185     jamo->first = jamo->second = jamo->coupled = 0x0000;
00186     return 0;
00187     
00188   } else if (second == 0x0000){
00189     
00190     jamo->first = first;
00191     jamo->second = 0x000;
00192     jamo->coupled = first;
00193     
00194     return jamo->first;
00195     
00196   } else {
00197     
00198     coupled_result = composer_hangul_coupled_jamo (first, second);
00199     if (coupled_result){
00200       jamo->first = first;
00201       jamo->second = second;
00202       jamo->coupled = coupled_result;
00203 
00204       return jamo->coupled;
00205       
00206     } else
00207       return 0;
00208   }
00209 }
00210 
00211 void
00212 composer_hangul_copy (HANGUL *dst, HANGUL *src)
00213 {
00214   assert (dst != NULL);
00215   assert (src != NULL);
00216   
00217   if (!dst || !src) {
00218     KOLE_LOG (LOGDEST_STDOUT, "error in composer_hangul_copy\n");
00219     return;
00220   }
00221   _jamo_copy (&dst->L, &src->L);
00222   _jamo_copy (&dst->V, &src->V);
00223   _jamo_copy (&dst->T, &src->T);
00224   
00225   dst->completed = src->completed;
00226   return;
00227 }
00228 
00229 HANGULBuffer *
00230 composer_hangul_buffer_new (void)
00231 {
00232   HANGULBuffer *_hangul_buffer;
00233   _hangul_buffer = (HANGULBuffer *) calloc(1, sizeof(HANGULBuffer));
00234        
00235   if(!_hangul_buffer)
00236     return NULL;
00237   else
00238     return _hangul_buffer;
00239 }
00240 
00241 void
00242 composer_hangul_buffer_initialize (HANGULBuffer *hangul_buffer)
00243 {
00244   assert (hangul_buffer != NULL);
00245 
00246   composer_hangul_buffer_free (hangul_buffer);
00247 
00248   hangul_buffer->count = 0; 
00249   hangul_buffer->buffer = NULL;
00250 }
00251 
00252 static void
00253 composer_hangul_buffer_free (HANGULBuffer *hangul_buffer)
00254 {
00255   int i;
00256 
00257   assert (hangul_buffer != NULL);
00258   if(hangul_buffer){
00259     for ( i = 0 ; i < hangul_buffer->count; i++)
00260       free (hangul_buffer->buffer[i]);
00261   }
00262   free (hangul_buffer->buffer);
00263   return;
00264 }
00265 
00266 
00267 static HANGUL *
00268 composer_hangul_buffer_get_first_hangul (HANGULBuffer *hangul_buffer)
00269 {
00270   assert (hangul_buffer != NULL );
00271   if (hangul_buffer == NULL) {
00272     KOLE_LOG (LOGDEST_STDERR, "hangul_buufer_get_first_hangul error: hangul_buffer can't be NULL\n");
00273     return NULL;
00274   } 
00275   else if (hangul_buffer->count == 0 ){
00276     KOLE_LOG (LOGDEST_STDERR, "hangl_buffer_get_first_hangul : there's no hangl character now\n");
00277     return NULL;
00278   } 
00279   else {
00280     return hangul_buffer->buffer[0];
00281   }
00282 }
00283 
00284 
00285 HANGUL *
00286 composer_hangul_buffer_get_next_hangul (HANGULBuffer *hangul_buffer, HANGUL *current_hangul)
00287 {
00288   HANGUL *next_hangul;
00289 
00290   assert (hangul_buffer != NULL);
00291   if (hangul_buffer == NULL) {
00292     KOLE_LOG (LOGDEST_STDERR, "hangul_buffer_get_next_hangul error: hangul_buffer can't be NULL\n");
00293     return NULL;
00294   } 
00295   next_hangul = current_hangul + 1;
00296 }
00297 
00298 int
00299 composer_hangul_buffer_get_hangul_length (HANGULBuffer *hangul_buffer)
00300 {
00301   assert (hangul_buffer != NULL);
00302   if (hangul_buffer == NULL) {
00303     KOLE_LOG (LOGDEST_STDERR, "hangul_buffer_get_hangul_length: hangul_buffer is null\n");
00304     return -1;
00305   }
00306   if (hangul_buffer->count < 0) {
00307     KOLE_LOG (LOGDEST_STDERR, "hangul_buffer_get_hangul_length: count is < 0\n");
00308     hangul_buffer->count = 0;
00309     return 0;
00310   } else 
00311     return hangul_buffer->count;
00312 }
00313 
00314 void
00315 composer_hangul_buffer_print (HANGULBuffer *hangul_buffer)
00316 {
00317   int i;
00318   HANGUL *han;
00319   UTFCHAR hangul_character;
00320   KOLE_LOG (LOGDEST_STDOUT, "===this values are pseudo===\n");
00321   for(i = 0 ; i < hangul_buffer->count; i++){
00322     han = hangul_buffer->buffer[i];
00323 #if 0
00324     KOLE_LOG (LOGDEST_STDOUT, "(0x%04X+0x%04X+0x%04X=>0x%04X):", 
00325            han->L, han->V, han->T,
00326            hangul_character = composer_hangul_combine_cho_jung_jong (han));
00327 #endif
00328 
00329     KOLE_LOG (LOGDEST_STDOUT, "(0x%04X+0x%04X+0x%04X=>0x%04X):", 
00330             han->L.coupled, han->V.coupled, han->T.coupled,
00331             hangul_character = composer_hangul_combine_cho_jung_jong (han));
00332             
00333   }
00334   KOLE_LOG (LOGDEST_STDOUT, "===this values are pseudo===\n");
00335   KOLE_LOG (LOGDEST_STDOUT, "\n");
00336 }
00337 
00338 /* delete_hangul_return may be NULL if you don't care about
00339    getting the copy of deleted HANGUL
00340 */
00341 Bool
00342 composer_hangul_buffer_delete_hangul_character (HANGULBuffer *hangul_buffer, 
00343                                           Bool delete_whole_character,
00344                                           HANGUL *deleted_hangul_return)
00345 {
00346   int count;
00347   HANGULList *tmp_array;
00348   HANGUL *last_hangul;
00349   Bool remove_return;
00350 
00351   assert (hangul_buffer != NULL);
00352   count = hangul_buffer->count;
00353   assert (count >= 0);
00354   if (count < 0){
00355     KOLE_LOG (LOGDEST_STDERR, "count of HANGULBuffer can't be less than 0\n");
00356     return False;
00357   } else if (count == 0){
00358     /* Nothing to return */
00359     if (deleted_hangul_return){
00360       memcpy (deleted_hangul_return, 0, sizeof (HANGUL));
00361     }
00362     return True;
00363   }
00364   last_hangul = hangul_buffer->buffer [count - 1];
00365   assert (last_hangul != NULL);
00366 
00367   /* create a return copy here */
00368   if (deleted_hangul_return != NULL)
00369     composer_hangul_copy (deleted_hangul_return, last_hangul);
00370 
00371   /*
00372     last hangul is incomplete character, thus likely(should be)
00373     last character, thus I delete it ja so unit.
00374   */
00375   if (last_hangul->completed != True){
00376     /* I need to think about doubled jongseong too ... */
00377     /* There was jong seong pending */
00378     
00379     if (!_jamo_is_clean (&last_hangul->T)){
00380       _jamo_initialize (&last_hangul->T);
00381     } else if (!_jamo_is_clean (&last_hangul->V) &&
00382               _jamo_get_value (&last_hangul->V) != JONGSEONG_FILLER) {
00383       /*
00384        There was jung seong pending
00385       */
00386       if (_jamo_get_second (&last_hangul->V)){
00387        _jamo_set_values (&last_hangul->V,
00388                       _jamo_get_first (&last_hangul->V),
00389                       0x00);
00390       } else
00391        _jamo_initialize (&last_hangul->V);
00392       
00393     } else {
00394       /*
00395        There was only choseong in the buffer,
00396        thus remove the entire character
00397       */
00398       remove_return =
00399        composer_hangul_remove_last_hangul (hangul_buffer,
00400                                        deleted_hangul_return);
00401       if (remove_return == False)
00402        {
00403          KOLE_LOG (LOGDEST_STDERR,
00404                  "composer_hangul_buffer_delete_hangul_character error:\n\t"
00405                  "composer_hangul_remove_last_hangul failed\n");
00406          return False;
00407        }
00408     }
00409          
00410   } else {
00411     /*
00412       I am begining to delete already completed character,
00413       not the current character being composed.
00414     */
00415     if (delete_whole_character != True){
00416       /* I need to think about doubled jongseong too ...*/
00417       
00418       /* There was jong seong pending */
00419 
00420       if (!_jamo_is_clean (&last_hangul->T)){
00421        _jamo_initialize (&last_hangul->T);
00422        
00423       } else if (!_jamo_is_clean (&last_hangul->V) &&
00424                _jamo_get_value (&last_hangul->V) != JONGSEONG_FILLER){
00425        /* There was jung seong pending */
00426        _jamo_initialize (&last_hangul->V);
00427       } else {
00428        /*
00429          There was only choseong in the buffer,
00430          thus remove the entire character
00431        */
00432       
00433        remove_return =
00434          composer_hangul_remove_last_hangul (hangul_buffer,
00435                                          deleted_hangul_return);
00436        if (remove_return == False){
00437          KOLE_LOG (LOGDEST_STDERR,
00438                  "composer_hangul_buffer_delete_hangul_character error: \n\t"
00439                  "composer_hangul_remove_last_hangul failed\n");
00440          return False;
00441        }
00442       }
00443     }
00444 
00445     else { /* delete_whole_character == True */
00446        
00447       remove_return =
00448        composer_hangul_remove_last_hangul (hangul_buffer,
00449                                        deleted_hangul_return);
00450       if (remove_return == False){
00451        KOLE_LOG (LOGDEST_STDERR,
00452                "composer_hangul_buffer_delete_hangul_character error:\n\t"
00453                "composer_hangul_remove_last_hangul failed\n");
00454        return False;
00455       }
00456        
00457     } /* if (delete_whole_character != True) */
00458   }
00459   return True;
00460 }
00461 
00462 static Bool
00463 composer_hangul_remove_last_hangul (HANGULBuffer *hangul_buffer,
00464                                 HANGUL *deleted_hangul_return)
00465 {
00466   int hangul_count = hangul_buffer->count;
00467   HANGUL *last_hangul = hangul_buffer->buffer [hangul_count - 1];
00468   HANGULList *tmp_list;
00469 
00470   assert (hangul_buffer != NULL);
00471   if (hangul_buffer == NULL) {
00472     KOLE_LOG (LOGDEST_STDERR, "composer_hangul_remove_last_hangul error: hangul_buffer was null \n");
00473     return False;
00474   }
00475   assert (last_hangul != NULL);
00476   if (last_hangul == NULL) {
00477     KOLE_LOG (LOGDEST_STDERR, "composer_hangul_remove_last_hangul error: last_hangul was null\n");
00478     return False;
00479   }
00480   assert (hangul_count > 0);
00481   if (hangul_count == 0){
00482     KOLE_LOG (LOGDEST_STDERR, "composer_hangul_remove_last_hangul error: hangul_count was 0\n");
00483     return False;
00484   }
00485 
00486   if (deleted_hangul_return != NULL) {
00487     composer_hangul_copy (deleted_hangul_return, last_hangul);
00488   }
00489 
00490   composer_hangul_free (last_hangul);
00491 
00492   if (hangul_count == 1) {
00493     tmp_list = NULL;
00494     free (hangul_buffer->buffer);
00495     hangul_buffer->buffer = NULL;
00496     hangul_buffer->count = 0;
00497 
00498   } else {
00499 
00500     tmp_list = (HANGULList *) calloc (hangul_count - 1, sizeof (HANGUL *));
00501 
00502     assert (tmp_list != NULL);
00503     if (tmp_list == NULL) {
00504       KOLE_LOG (LOGDEST_STDERR, "composer_hangul_remove_last_hangul error: calloc failed\n");
00505       return False;
00506     }
00507 
00508     memcpy (tmp_list, hangul_buffer->buffer, (hangul_count - 1) * sizeof (HANGUL *));
00509     free (hangul_buffer->buffer);
00510     hangul_buffer->buffer = tmp_list;
00511     hangul_buffer->count = hangul_count - 1;
00512   }
00513   return True;
00514 }
00515 
00516 /* create a copy of HANGUL a_hangul and append it to the array */
00517 HANGUL *
00518 composer_hangul_buffer_add_hangul (HANGULBuffer *hangul_buffer, HANGUL *a_hangul)
00519 {
00520   HANGULList *tmp;
00521   HANGUL *hangul = composer_hangul_new ();
00522        
00523   assert (hangul != NULL);
00524 
00525   if (hangul == NULL){
00526     KOLE_LOG (LOGDEST_STDOUT, "Error creating new hangul");
00527     return NULL;
00528   } else {
00529     tmp = (HANGULList *) calloc(hangul_buffer->count+ 1,sizeof(HANGULList));
00530     assert(tmp != NULL);
00531     if(tmp == NULL){
00532       KOLE_LOG (LOGDEST_STDERR, "Fatal error in composer_hangul_buffer_add_hangul\n");
00533       exit(-1);
00534     }
00535     if (hangul_buffer->count == 0){
00536       hangul_buffer->count++;
00537       hangul_buffer->buffer = (HANGULList *)calloc(1, sizeof(HANGULList));
00538       hangul_buffer->buffer[0] = hangul;
00539       composer_hangul_copy(hangul_buffer->buffer[0], a_hangul);
00540       return hangul_buffer->buffer[0];
00541     }
00542     else {
00543       memset(tmp, 0, (hangul_buffer->count + 1) * sizeof(HANGULList));
00544       memcpy(tmp, hangul_buffer->buffer, (hangul_buffer->count) * sizeof(HANGULList));
00545       tmp[hangul_buffer->count] = hangul;
00546       composer_hangul_copy(tmp[hangul_buffer->count], a_hangul);
00547       /* FIX ME */
00548       free (hangul_buffer->buffer);
00549       /* END OF FIX ME */
00550       hangul_buffer->buffer = tmp;
00551       hangul_buffer->count += 1;   
00552       return tmp[hangul_buffer->count - 1];
00553     }
00554   }
00555 }
00556 
00557 HANGUL *
00558 composer_hangul_buffer_pop_hangul (HANGULBuffer *hangul_buffer)
00559 {
00560   HANGUL *phangul;
00561   HANGULBuffer *tmp;
00562   int i;
00563   assert (hangul_buffer != NULL);
00564 
00565   if (hangul_buffer == NULL){
00566     KOLE_LOG (LOGDEST_STDERR, "%s",
00567              "composer_hangul_buffer_pop_hangul error");
00568     return NULL;
00569   }
00570   if (hangul_buffer->count == 0){
00571     KOLE_LOG (LOGDEST_STDERR, "%s",
00572              "composer_hangul_buffer_pop_hangul error: no hangul in buffer");
00573     return NULL;
00574   }
00575 
00576   tmp = (HANGULBuffer *) calloc (hangul_buffer->count - 1,
00577                              sizeof (HANGUL *));
00578 
00579   phangul = hangul_buffer->buffer[0];
00580   
00581   memcpy (tmp, hangul_buffer->buffer + 1,
00582          sizeof (HANGUL *) * hangul_buffer->count - 1);
00583   free (hangul_buffer->buffer);
00584   hangul_buffer->buffer = tmp;
00585   hangul_buffer->count--;
00586 
00587   return phangul;
00588 }
00589 
00590 static JAMO_T
00591 composer_jamo_type_of_input(UTFCHAR input_char)
00592 {
00593   if (input_char < 0x1100 || input_char > 0x11F9)
00594     return JM_NONE;
00595   else 
00596     {
00597       if (input_char >= 0x1100 && input_char <= 0x1112)
00598        return JAEUM;
00599       else if (input_char >= 0x1161 && input_char <= 0x1175)
00600        return MOEUM;
00601       else
00602        return JM_NONE;
00603     }
00604 }
00605 
00606 static Bool
00607 is_not_euc_with_trailing_consonant (HANGUL *hangul, UTFCHAR tc)
00608 {
00609   HANGUL my_hangul;
00610   iconv_t cd;
00611   size_t conv_ret;
00612   
00613   char inbuf[2];
00614   char *inptr = inbuf;
00615   size_t inlen = 2;
00616 
00617   char outbuf[2];
00618   char *outptr = outbuf;
00619   size_t outlen = 2;
00620   
00621   UTFCHAR u16_hangul;
00622 
00623   composer_hangul_copy (&my_hangul, hangul);
00624   if (_jamo_is_done (&my_hangul.T))
00625     return False;
00626 
00627   if (_jamo_is_clean (&my_hangul.T))
00628     _jamo_set_values (&my_hangul.T, tc, 0);
00629   else
00630     _jamo_set_values (&my_hangul.T, my_hangul.T.first, tc);
00631 
00632   
00633   u16_hangul = composer_hangul_combine_cho_jung_jong (&my_hangul);
00634   
00635   cd = iconv_open ("EUC-KR", "UTF16");
00636   memset (inbuf, 0, sizeof (inbuf));
00637   memset (inbuf, 0, sizeof (outbuf));
00638   memcpy (inbuf, &u16_hangul, sizeof (unsigned short));
00639   
00640   conv_ret = iconv (cd, &inptr, &inlen, &outptr, &outlen);
00641   iconv_close (cd);
00642   
00643   if (conv_ret == (size_t)-1)
00644     return True;
00645   else
00646     return False;
00647   
00648 }
00649 
00650 static Bool
00651 is_not_euc_with_vowel (HANGUL *hangul, UTFCHAR vowel)
00652 {
00653   HANGUL my_hangul;
00654   iconv_t cd;
00655   size_t conv_ret;
00656   
00657   char inbuf[2];
00658   char *inptr = inbuf;
00659   size_t inlen = 2;
00660 
00661   char outbuf[2];
00662   char *outptr = outbuf;
00663   size_t outlen = 2;
00664   
00665   UTFCHAR u16_hangul;
00666 
00667   composer_hangul_copy (&my_hangul, hangul);
00668   if (_jamo_is_done (&my_hangul.V))
00669     return False;
00670 
00671   if (_jamo_is_clean (&my_hangul.V))
00672     _jamo_set_values (&my_hangul.V, vowel, 0);
00673   else
00674     _jamo_set_values (&my_hangul.V, my_hangul.V.first, vowel);
00675 
00676   
00677   u16_hangul = composer_hangul_combine_cho_jung_jong (&my_hangul);
00678   
00679   cd = iconv_open ("EUC-KR", "UTF16");
00680   memset (inbuf, 0, sizeof (inbuf));
00681   memset (inbuf, 0, sizeof (outbuf));
00682   memcpy (inbuf, &u16_hangul, sizeof (unsigned short));
00683   
00684   conv_ret = iconv (cd, &inptr, &inlen, &outptr, &outlen);
00685   iconv_close (cd);
00686   
00687   if (conv_ret == (size_t)-1)
00688     return True;
00689   else
00690     return False;
00691   
00692 }
00693 
00694 /* NULL return indicates either
00695    hangul_buffer was not valid
00696    or
00697    there was not HANGUL element in the buffer
00698 */
00699 
00700 HANGUL *
00701 composer_hangul_buffer_get_last_hangul (HANGULBuffer *hangul_buffer)
00702 {
00703   HANGUL *last_hangul;
00704   assert(hangul_buffer != NULL);
00705 
00706   if ( hangul_buffer->count == 0 )
00707     return NULL;
00708 
00709   last_hangul = hangul_buffer->buffer[hangul_buffer->count - 1];
00710   return last_hangul;
00711 }
00712 
00713 
00714 /****************************************************
00715        For detailed information on this algorithim,
00716        See Unicode Standard 3.0,
00717               3.11 Conjoining Jamo Behavior
00718 
00719        return =  0: failure
00720                      !=  0: success
00721 ****************************************************/
00722 
00723 UTFCHAR
00724 composer_hangul_combine_cho_jung_jong (HANGUL *a_hangul)
00725 {
00726   static UTFCHAR hangul_base    = 0xac00;
00727   static UTFCHAR choseong_base  = 0x1100;
00728   static UTFCHAR jungseong_base = 0x1161;
00729   static UTFCHAR jongseong_base = 0x11a7;
00730 
00731   static int number_of_jungseong = 21;
00732   static int number_of_jongseong = 28;
00733 
00734   UTFCHAR l_consonant,vowel,t_consonant;
00735   UTFCHAR ch;
00736 
00737   assert (a_hangul != NULL);
00738   if (a_hangul == NULL)
00739     return 0;
00740 
00741   l_consonant = _jamo_get_value (&a_hangul->L);
00742   vowel = _jamo_get_value (&a_hangul->V);
00743   t_consonant = _jamo_get_value (&a_hangul->T);
00744        
00745   if (t_consonant == 0)
00746     t_consonant = JONGSEONG_FILLER; /* 0x11A7 */
00747        
00748   if (l_consonant  < 0x1100 || l_consonant  > 0x1112)
00749     return 0;
00750   if (vowel < 0x1161 || vowel > 0x1175)
00751     return 0;
00752   if (t_consonant < 0x11a7 || t_consonant > 0x11c2)
00753     return 0;
00754        
00755   l_consonant  -= choseong_base;
00756   vowel -= jungseong_base;
00757   t_consonant -= jongseong_base;
00758        
00759   ch = ((l_consonant * number_of_jungseong) + vowel) * number_of_jongseong + 
00760     t_consonant + hangul_base;
00761   return ch;
00762 }
00763 
00764 /*
00765   If non-printable keycodes like IM_VK_HOME, etc is passed,
00766   the return is 0x0000, signalling the caller that extra
00767   action needs to be taken depending on the sementics of the
00768   non-printable keycode, for example, moving the cursor to the home.
00769  */
00770 UTFCHAR
00771 get_utf_input_by_keyboard (IMEKeyEventStruct *iiim_key_ev,
00772                          KEYBOARD_LAYOUT_T i_keyboard)
00773 {
00774   UTFCHAR utf_input  = 0x0000;
00775   Bool keymap_return;
00776   int keychar;
00777   int keycode;
00778   int state;
00779   MapInfo map_info;
00780 
00781   assert (iiim_key_ev != NULL);
00782 
00783   keycode = iiim_key_ev->key_code;
00784   keychar = iiim_key_ev->key_char;
00785   state = iiim_key_ev->key_modifier;
00786   KOLE_LOG(LOGDEST_STDOUT, "get_utf_input_by_keyboard():keyboard id is %d,  keycode is %d, keychar is %c, state is %d\n", i_keyboard,  keycode, keychar, state);
00787 
00788   /* Below case is cheked, before keyboard mapping lookup is done.
00789      This is becuase thos mapping table doesn't consider
00790      mapping entry for below values, and actually this is not
00791      keyboard mapping dependent input
00792   */
00793   switch (keycode){
00794   case IM_VK_ENTER:
00795   case IM_VK_TAB:
00796   case IM_VK_SPACE:
00797     return (UTFCHAR )keycode;
00798     break;
00799 
00800   case IM_VK_LEFT:
00801   case IM_VK_UP:
00802   case IM_VK_RIGHT:
00803   case IM_VK_DOWN:
00804   case IM_VK_PAGE_DOWN:
00805   case IM_VK_PAGE_UP:
00806   case IM_VK_HOME:
00807   case IM_VK_END:
00808     return 0x0000;
00809     break;
00810   case IM_VK_BACK_SLASH:
00811     if((state & IM_SHIFT_MASK) && (i_keyboard == LAYOUT_2PART || i_keyboard == LAYOUT_3PART390)) 
00812        break;
00813     if((state == 0) && (i_keyboard == LAYOUT_3PART_FINAL))
00814         break;
00815     if((state == 0) && (i_keyboard == LAYOUT_2PART || i_keyboard == LAYOUT_3PART390))
00816        return 0x20a9;
00817     if((state & IM_SHIFT_MASK) &&  (i_keyboard == LAYOUT_3PART_FINAL))
00818        return 0x20a9;
00819 
00820   default:
00821     break;
00822   }
00823 
00824   if (keycode < 0x41){
00825     keymap_return = composer_hangul_convert_input_to_unicode (keychar,
00826                                                        state,
00827                                                        i_keyboard,
00828                                                        &map_info);
00829   } else {
00830     keymap_return = composer_hangul_convert_input_to_unicode (keychar,
00831                                                        state,
00832                                                        i_keyboard,
00833                                                        &map_info);
00834   }
00835   if (keymap_return)
00836     utf_input = map_info.val;
00837   else {
00838     utf_input = 0x0000;
00839   }
00840   
00841   return utf_input;
00842 }
00843 
00844 
00845 /*
00846   parameters: 
00847 
00848   return:
00849   return -1 indicates input character was not valid, thus ignore
00850   return -2 indicates input character was not valid, but should commit
00851 
00852   $@2beolsik@$
00853 */
00854 
00855 
00856 
00857 int
00858 composer_hangul_automata_2pair (int keyCode, int keyChar, int state,
00859                             HANGULBuffer *hangul_buffer, Config *pconfig)
00860 {
00861   UTFCHAR utf_input;
00862   HANGUL *last_hangul;
00863   HANGUL a_hangul;
00864   HANGUL *new_hangul;
00865   
00866   JAMO_T input_type_is;
00867   
00868   KEYBOARD_LAYOUT_T i_keyboard = LAYOUT_2PART;
00869   
00870   UTFCHAR jongseong_from_choseong, choseong_from_jongseong;
00871   UTFCHAR decomposed_jongseong, decomposed_choseong;
00872 
00873   UTFCHAR coupled_jaeum, coupled_moeum;
00874   Bool last_hangul_was_newly_created = False;
00875   Bool keymap_return;
00876   MapInfo map_info;
00877 
00878   assert (hangul_buffer != NULL);
00879 
00880   keymap_return = composer_hangul_convert_input_to_unicode (keyChar,
00881                                                      state,
00882                                                      i_keyboard,
00883                                                      &map_info);
00884   if (keymap_return)
00885     utf_input = map_info.val;
00886   else
00887     return ComposerRetErr;
00888   
00889   input_type_is = composer_jamo_type_of_input (utf_input);
00890   if (input_type_is == JM_NONE){     /* not a hangul character */
00891     if ((utf_input >= 0x0020 && utf_input <= 0x007f)){
00892       /* printable commit characters */
00893       KOLE_LOG(LOGDEST_STDOUT, "composer_hangul_automata_2pair(),utf_input is %d\n", utf_input);
00894       return ComposerRetBreak;
00895     } else
00896       return ComposerRetErr;
00897   }
00898 
00899 
00900   last_hangul = composer_hangul_buffer_get_last_hangul (hangul_buffer);
00901 
00902   composer_hangul_initialize (&a_hangul);
00903 
00904   if (last_hangul == NULL){
00905     /* there was no HANGUL, so create the first one */
00906     last_hangul = composer_hangul_new ();
00907     last_hangul_was_newly_created = True;
00908 
00909     if (input_type_is == JAEUM){
00910       _jamo_set_values (&last_hangul->L, utf_input, 0x0);
00911     } else {
00912       _jamo_set_values (&last_hangul->L, 0x0, 0x0);
00913       _jamo_set_values (&last_hangul->V, utf_input, 0);
00914       _jamo_set_values (&last_hangul->T, 0x0, 0x0);
00915       
00916       last_hangul->completed = True;
00917     }
00918 
00919     composer_hangul_buffer_add_hangul (hangul_buffer, last_hangul); 
00920     composer_hangul_free (last_hangul);
00921        
00922     return ComposerRetKeep;
00923   }
00924 
00925   if (input_type_is == JAEUM) {
00926     if (last_hangul->completed == True){
00927       new_hangul = composer_hangul_new ();
00928       _jamo_set_values (&new_hangul->L, utf_input, 0x0);
00929       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
00930       /* free new_hangul */
00931       composer_hangul_free (new_hangul);
00932       return ComposerRetKeep;
00933       
00934     } else if (!_jamo_is_clean (&last_hangul->T)) {
00935       /* last_hangul had T */
00936       jongseong_from_choseong =
00937        hangul_combining_chosung_to_combining_jongsung (utf_input);
00938       if ((!_jamo_is_done (&last_hangul->T)) &&
00939          (IS_VALID_JONGSEONG (jongseong_from_choseong))){
00940 
00941        coupled_jaeum =
00942          composer_hangul_coupled_jamo (last_hangul->T.first,
00943                                    jongseong_from_choseong);
00944        if (!coupled_jaeum){
00945          /* invalid coupling */
00946          _jamo_set_values (&a_hangul.L , utf_input, 0x0);
00947          /* finished the previous character,
00948             and starting new character */
00949          last_hangul->completed = True;
00950          composer_hangul_buffer_add_hangul (hangul_buffer, &a_hangul);
00951        } else {
00952          /* valid coupling */
00953          if (pconfig->charset == IN_EUC &&
00954              is_not_euc_with_trailing_consonant (last_hangul, jongseong_from_choseong)){
00955 
00956            last_hangul->completed = True;
00957            
00958            new_hangul = composer_hangul_new ();
00959            _jamo_set_values (&new_hangul->L, utf_input, 0x0);
00960            composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
00961            composer_hangul_free (new_hangul);
00962            
00963          } else {
00964            _jamo_set_values (&last_hangul->T,
00965                            last_hangul->T.first, jongseong_from_choseong);
00966          }
00967        }
00968        
00969       } else {
00970        _jamo_set_values (&a_hangul.L , utf_input, 0x0);
00971        composer_hangul_buffer_add_hangul (hangul_buffer, &a_hangul);
00972       }
00973       return ComposerRetKeep;
00974 
00975     } else if (!_jamo_is_clean (&last_hangul->V)) {
00976       jongseong_from_choseong =
00977        hangul_combining_chosung_to_combining_jongsung (utf_input);
00978       if (IS_VALID_JONGSEONG(jongseong_from_choseong) ){
00979        if (pconfig->charset == IN_EUC &&
00980            is_not_euc_with_trailing_consonant (last_hangul, jongseong_from_choseong)){
00981          last_hangul->completed = True;
00982          new_hangul = composer_hangul_new ();
00983          _jamo_set_values (&new_hangul->L, utf_input, 0x0);
00984          composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
00985          composer_hangul_free (new_hangul);
00986        } else {
00987          _jamo_set_values (&last_hangul->T, jongseong_from_choseong, 0x0);
00988        }
00989       }
00990       else {
00991        last_hangul->completed = True;
00992        _jamo_set_values (&a_hangul.L, utf_input, 0x0);
00993        composer_hangul_buffer_add_hangul (hangul_buffer, &a_hangul);
00994       }
00995       return ComposerRetKeep;
00996     }
00997     else if (!_jamo_is_clean (&last_hangul->L)) {
00998       coupled_jaeum =
00999        composer_hangul_coupled_jamo (last_hangul->L.first, utf_input);
01000       if (!_jamo_is_done (&last_hangul->L) && coupled_jaeum){
01001        _jamo_set_values (&last_hangul->L,
01002                        last_hangul->L.first, utf_input);
01003       } else {
01004        _jamo_set_values (&last_hangul->V, 0x0, 0x0);
01005        _jamo_set_values (&last_hangul->T, 0x0, 0x0);
01006        last_hangul->completed = True;
01007        _jamo_set_values (&a_hangul.L, utf_input, 0);
01008        composer_hangul_buffer_add_hangul (hangul_buffer, &a_hangul);  
01009       }
01010       return ComposerRetKeep;
01011     }
01012                      
01013   } else if (input_type_is == MOEUM) {
01014     if (last_hangul->completed == True){
01015 
01016       new_hangul = composer_hangul_new ();
01017       _jamo_set_values (&new_hangul->L, 0x0, 0x0);
01018       _jamo_set_values (&new_hangul->V, utf_input, 0x0);
01019       _jamo_set_values (&new_hangul->T, 0x0, 0x0);
01020       new_hangul->completed = True;
01021       
01022       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01023       /* free new_hangul */
01024       composer_hangul_free (new_hangul);
01025       return ComposerRetKeep;
01026       
01027     } else if (!_jamo_is_clean (&last_hangul->T)){
01028       UTFCHAR tmp;
01029       if (!_jamo_is_done (&last_hangul->T)){
01030        /* last_hangul->T.first needs to be taken forward
01031           to current new character */
01032        tmp =
01033          hangul_combining_jongsung_to_combining_chosung
01034          (_jamo_get_first (&last_hangul->T));
01035        _jamo_set_values (&last_hangul->T, 0x0, 0x0);
01036       } else {
01037        tmp =
01038          hangul_combining_jongsung_to_combining_chosung (
01039                                                    _jamo_get_second (&last_hangul->T));
01040        _jamo_set_values (&last_hangul->T, last_hangul->T.first, 0x0);
01041       }
01042       last_hangul->completed = True;
01043       
01044       _jamo_set_values (&a_hangul.L, tmp, 0x0);
01045       _jamo_set_values (&a_hangul.V, utf_input, 0x0);
01046       composer_hangul_buffer_add_hangul (hangul_buffer, &a_hangul);
01047       return ComposerRetKeep;
01048     }
01049     else if(!_jamo_is_clean (&last_hangul->V)) {
01050       coupled_moeum =
01051        composer_hangul_coupled_jamo (
01052                                   _jamo_get_first (&last_hangul->V),
01053                                   utf_input);
01054       if (!_jamo_is_done (&last_hangul->V) && coupled_moeum){
01055        if (pconfig->charset == IN_EUC &&
01056            is_not_euc_with_vowel (last_hangul, utf_input)){
01057          
01058          last_hangul->completed = True;
01059          new_hangul = composer_hangul_new ();
01060          _jamo_set_values (&new_hangul->L, 0x0, 0x0);
01061          _jamo_set_values (&new_hangul->V, utf_input, 0x0);
01062          new_hangul->completed = True;
01063          composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01064          composer_hangul_free (new_hangul);
01065 
01066        } else {
01067          _jamo_set_values (&last_hangul->V,
01068                          last_hangul->V.first, utf_input);
01069        }
01070       } else {
01071        last_hangul->completed = True;
01072        
01073        _jamo_set_values (&a_hangul.L, 0x0, 0x0);
01074        _jamo_set_values (&a_hangul.V, utf_input, 0x0);
01075        a_hangul.completed = True;
01076        
01077        composer_hangul_buffer_add_hangul (hangul_buffer, &a_hangul);
01078       }
01079       return ComposerRetKeep;
01080     } else if(!_jamo_is_clean(&last_hangul->L)){
01081       _jamo_set_values (&last_hangul->V, utf_input, 0x0);
01082       return ComposerRetKeep;
01083     }
01084   }
01085 }
01086 
01087 int
01088 composer_hangul_automata_3pair_final (int keyCode, int keyChar, int state,
01089                                   HANGULBuffer *hangul_buffer, Config *pconfig, KEYBOARD_LAYOUT_T i_keyboard)
01090 {
01091   UTFCHAR utf_input;
01092   HANGUL *last_hangul;
01093   HANGUL a_hangul;
01094   HANGUL *new_hangul;
01095   
01096   JAMO_T input_type_is;
01097   
01098 //  KEYBOARD_LAYOUT_T i_keyboard = LAYOUT_3PART_FINAL;
01099   
01100   UTFCHAR jongseong_from_choseong, choseong_from_jongseong;
01101   UTFCHAR decomposed_jongseong, decomposed_choseong;
01102 
01103   UTFCHAR coupled_jaeum, coupled_moeum;
01104   Bool last_hangul_was_newly_created = False;
01105 
01106   Bool keymap_return;
01107   MapInfo map_info;
01108   CHOJUNGJONG_T cjj;
01109 
01110   assert (hangul_buffer != NULL);
01111 
01112   keymap_return = composer_hangul_convert_input_to_unicode (keyChar,
01113                                                      state,
01114                                                      i_keyboard,
01115                                                      &map_info);
01116   
01117   if (keymap_return){
01118     utf_input = map_info.val;
01119     cjj = map_info.type;
01120   } else
01121     return -1;
01122  
01123 
01124  
01125   if (cjj == CJJ_NONE){
01126     KOLE_LOG (LOGDEST_STDERR, "composer_hangul_automata_3pair_final error: "
01127             "cjj is CJJ_NONE\n");
01128     return ComposerRetBreak;
01129   }
01130 
01131   last_hangul = composer_hangul_buffer_get_last_hangul (hangul_buffer);
01132 
01133   composer_hangul_initialize (&a_hangul);
01134     
01135   /* Create New buffer to do automata */
01136     
01137   if (last_hangul == NULL){
01138     /* there was no HANGUL, so create the first one */
01139     last_hangul = composer_hangul_new ();
01140     last_hangul_was_newly_created = True;
01141 
01142     if (cjj == CJJ_CHOSUNG){
01143          
01144       _jamo_set_values (&last_hangul->L, utf_input, 0);
01145          
01146     } else if (cjj == CJJ_JUNGSUNG) {
01147          
01148       _jamo_set_values (&last_hangul->V, utf_input, 0);
01149       last_hangul->completed = True;
01150          
01151     } else if (cjj == CJJ_JONGSUNG){
01152          
01153       _jamo_set_values (&last_hangul->T, utf_input, 0);
01154       last_hangul->completed = True;
01155     }
01156 
01157     composer_hangul_buffer_add_hangul (hangul_buffer, last_hangul); 
01158     composer_hangul_free (last_hangul);
01159     last_hangul = NULL;
01160     return ComposerRetKeep;
01161 
01162   }
01163 
01164   if (cjj == CJJ_CHOSUNG){
01165     if (last_hangul->completed == True){
01166       new_hangul = composer_hangul_new ();
01167       _jamo_set_values (&new_hangul->L, utf_input, 0x0);
01168       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01169       /* free new_hangul */
01170       composer_hangul_free (new_hangul);
01171     } else if (!_jamo_is_clean (&last_hangul->T) ||
01172               !_jamo_is_clean (&last_hangul->V) ){
01173       last_hangul->completed = True;
01174       new_hangul = composer_hangul_new ();
01175       _jamo_set_values (&new_hangul->L, utf_input, 0x0);
01176       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01177       /* free new_hangul */
01178       composer_hangul_free (new_hangul);
01179     } else if (_jamo_is_done (&last_hangul->L)){
01180       /* chosung is already finished */
01181       last_hangul->completed = True;
01182       /* thus, create a next one */
01183       new_hangul = composer_hangul_new ();
01184       _jamo_set_values (&new_hangul->L, utf_input, 0x0);
01185       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01186       /* free new_hangul */
01187       composer_hangul_free (new_hangul);
01188       new_hangul = NULL;
01189     } else if (!_jamo_is_clean (&last_hangul->L)){
01190       
01191       UTFCHAR first, ch;
01192       first = _jamo_get_first (&last_hangul->L);
01193       ch = composer_hangul_coupled_jamo (first, utf_input);
01194       if (ch){
01195        _jamo_set_values (&last_hangul->L, first, utf_input);
01196       } else {
01197        /* invalid coupling, thus create a next one */
01198        last_hangul->completed = True;
01199        
01200        new_hangul = composer_hangul_new ();
01201        _jamo_set_values (&new_hangul->L, utf_input, 0);
01202        composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01203        /* free new_hangul */
01204        composer_hangul_free (new_hangul);
01205        new_hangul = NULL;
01206       
01207       }
01208     } else {
01209       /* This is not likely to be happened... */
01210       _jamo_set_values (&last_hangul->L, utf_input, 0);
01211       
01212     }
01213     return ComposerRetKeep;
01214   } else if (cjj == CJJ_JUNGSUNG) {
01215     if (last_hangul->completed == True){
01216       new_hangul = composer_hangul_new ();
01217       new_hangul->completed = True;
01218       _jamo_set_values (&new_hangul->V, utf_input, 0);
01219 
01220       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01221       /* free new_hangul */
01222       composer_hangul_free (new_hangul);
01223     } else if (!_jamo_is_clean (&last_hangul->T) ||
01224               _jamo_is_done (&last_hangul->V)){
01225       /* last_hangul is done, 'cause new hangul is being created */
01226       last_hangul->completed = True;
01227            
01228       new_hangul = composer_hangul_new ();
01229       new_hangul->completed = True;
01230       _jamo_set_values (&new_hangul->V, utf_input, 0);
01231       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01232       /* free new_hangul */
01233       composer_hangul_free (new_hangul);
01234     } else if (!_jamo_is_clean (&last_hangul->V)){
01235       coupled_jaeum =
01236        composer_hangul_coupled_jamo (last_hangul->V.first, utf_input);
01237            
01238       if(coupled_jaeum == 0){
01239        /* invalid coupling */
01240        /* last_hangul is done, 'cause new hangul is being created */
01241        last_hangul->completed = True;
01242               
01243        new_hangul = composer_hangul_new ();
01244        new_hangul->completed = True;
01245        _jamo_set_values (&new_hangul->V, utf_input, 0);
01246        composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01247        /* free new_hangul */
01248        composer_hangul_free (new_hangul);
01249 
01250       } else {
01251        /* valid coupling */
01252        _jamo_set_values (&last_hangul->V,
01253                        last_hangul->V.first, utf_input);
01254       }
01255     } else if (!_jamo_is_clean (&last_hangul->L)){
01256       /*
01257        Here, there's some chosung, but no jung sung,
01258        thus, put the current utf_input(jungsung)
01259       */
01260       _jamo_set_values (&last_hangul->V, utf_input, 0);
01261            
01262     } else {
01263       /*
01264        Here, there was no chosung, thus,
01265        I need to create a new hangul buffer again..
01266       */
01267       last_hangul->completed = True;
01268               
01269       new_hangul = composer_hangul_new ();
01270       new_hangul->completed = True;
01271       _jamo_set_values (&new_hangul->V, utf_input, 0);
01272       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01273       /* free new_hangul */
01274       composer_hangul_free (new_hangul);
01275     }
01276     return ComposerRetKeep;
01277   } else if (cjj == CJJ_JONGSUNG) {
01278     if (last_hangul->completed == True ||
01279        _jamo_is_done (&last_hangul->T)){
01280            
01281       new_hangul = composer_hangul_new ();
01282       new_hangul->completed = True;
01283       _jamo_set_values (&new_hangul->T, utf_input, 0);
01284 
01285       composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01286       /* free new_hangul */
01287       composer_hangul_free (new_hangul);
01288            
01289     } else if (!_jamo_is_clean (&last_hangul->T)){
01290            
01291       coupled_jaeum =
01292        composer_hangul_coupled_jamo (last_hangul->T.first, utf_input);
01293            
01294       if(coupled_jaeum == 0){
01295        /* invalid coupling */
01296        /* last_hangul is done, 'cause new hangul is being created */
01297        last_hangul->completed = True;
01298               
01299        new_hangul = composer_hangul_new ();
01300        new_hangul->completed = True;
01301        _jamo_set_values (&new_hangul->T, utf_input, 0);
01302        composer_hangul_buffer_add_hangul (hangul_buffer, new_hangul);
01303        /* free new_hangul */
01304        composer_hangul_free (new_hangul);
01305       } else {
01306        /* valid coupling */
01307        _jamo_set_values (&last_hangul->T,
01308                        last_hangul->T.first, utf_input);
01309        /* because both jongsungs are in place,
01310           this character is not done..
01311        */
01312        last_hangul->completed = True;
01313       }
01314     } else {
01315       
01316       if (_jamo_is_clean (&last_hangul->L) ||
01317          _jamo_is_clean (&last_hangul->V)){
01318        /* invalid composition */
01319        last_hangul->completed = True;
01320        new_hangul = composer_hangul_new ();
01321        new_hangul->completed = True;
01322        _jamo_set_values (&new_hangul->T, utf_input, 0);
01323       } else {
01324        _jamo_set_values (&last_hangul->T, utf_input, 0);
01325       }
01326       
01327     }
01328 
01329     return ComposerRetKeep;
01330   } else {
01331     /*
01332       invalid input, that is,
01333       neither chosung, jungsung nor jongsung
01334     */
01335     return -1;
01336 
01337   }
01338 }
01339 
01340 static Bool
01341 composer_hangul_convert_input_to_unicode (int keyChar, int state, KEYBOARD_LAYOUT_T layout_id, MapInfo *map_info)
01342 {
01343   static const KeymapData map[] = {
01344     { 0x0021, CJJ_NONE,0x11bd, CJJ_JONGSUNG,0x11a9, CJJ_JONGSUNG},
01345     { 0x0022, CJJ_NONE,0x0022, CJJ_NONE,0x00b7, CJJ_NONE},
01346     { 0x0023, CJJ_NONE,0x0023, CJJ_NONE,0x11bd, CJJ_NONE},
01347     { 0x0024, CJJ_NONE,0x0024, CJJ_NONE,0x11b5, CJJ_JONGSUNG},
01348     { 0x0025, CJJ_NONE,0x0025, CJJ_NONE,0x11b4, CJJ_JONGSUNG},
01349     { 0x0026, CJJ_NONE,0x0026, CJJ_NONE,0x201c, CJJ_NONE},
01350     { 0x0027, CJJ_NONE,0x1110, CJJ_CHOSUNG,0x1110, CJJ_CHOSUNG},
01351     { 0x0028, CJJ_NONE,0x0028, CJJ_NONE,0x0027, CJJ_NONE},
01352     { 0x0029, CJJ_NONE,0x0029, CJJ_NONE,0x007e, CJJ_NONE},
01353     { 0x002a, CJJ_NONE,0x002a, CJJ_NONE,0x201d, CJJ_NONE},
01354     { 0x002b, CJJ_NONE,0x002b, CJJ_NONE,0x002b, CJJ_NONE},
01355     { 0x002c, CJJ_NONE,0x002c, CJJ_NONE,0x002c, CJJ_NONE},
01356     { 0x002d, CJJ_NONE,0x002d, CJJ_NONE,0x0029, CJJ_NONE},
01357     { 0x002e, CJJ_NONE,0x002e, CJJ_NONE,0x002e, CJJ_NONE},
01358     { 0x002f, CJJ_NONE,0x1169, CJJ_JUNGSUNG,0x1169, CJJ_JUNGSUNG},
01359     { 0x0030, CJJ_NONE,0x110f, CJJ_CHOSUNG,0x110f, CJJ_CHOSUNG},
01360     { 0x0031, CJJ_NONE,0x11c2, CJJ_JONGSUNG,0x11c2, CJJ_JONGSUNG},
01361     { 0x0032, CJJ_NONE,0x11bb, CJJ_JONGSUNG,0x11bb, CJJ_JONGSUNG},
01362     { 0x0033, CJJ_NONE,0x11b8, CJJ_JONGSUNG,0x11b8, CJJ_JONGSUNG},
01363     { 0x0034, CJJ_NONE,0x116d, CJJ_JUNGSUNG,0x116d, CJJ_JUNGSUNG},
01364     { 0x0035, CJJ_NONE,0x1172, CJJ_JUNGSUNG,0x1172, CJJ_JUNGSUNG},
01365     { 0x0036, CJJ_NONE,0x1163, CJJ_JUNGSUNG,0x1163, CJJ_JUNGSUNG},
01366     { 0x0037, CJJ_NONE,0x1168, CJJ_JUNGSUNG,0x1168, CJJ_JUNGSUNG},
01367     { 0x0038, CJJ_NONE,0x1174, CJJ_JUNGSUNG,0x1174, CJJ_JUNGSUNG},
01368     { 0x0039, CJJ_NONE,0x116e, CJJ_JUNGSUNG,0x116e, CJJ_JUNGSUNG},
01369     { 0x003a, CJJ_NONE,0x003a, CJJ_NONE,0x0034, CJJ_NONE},
01370     { 0x003b, CJJ_NONE,0x1107, CJJ_CHOSUNG,0x1107, CJJ_CHOSUNG},
01371     { 0x003c, CJJ_NONE,0x0032, CJJ_NONE,0x002c, CJJ_NONE},
01372     { 0x003d, CJJ_NONE,0x003d, CJJ_NONE,0x003e, CJJ_NONE},
01373     { 0x003e, CJJ_NONE,0x0033, CJJ_NONE,0x002e, CJJ_NONE},
01374     { 0x003f, CJJ_NONE,0x003f, CJJ_NONE,0x0021, CJJ_NONE},
01375     { 0x0040, CJJ_NONE,0x0040, CJJ_NONE,0x11b0, CJJ_JONGSUNG},
01376     { 0x1106, CJJ_NONE,0x11ae, CJJ_JONGSUNG,0x11ae, CJJ_JONGSUNG},
01377     { 0x1172, CJJ_NONE,0x0021, CJJ_NONE,0x003f, CJJ_NONE},
01378     { 0x110e, CJJ_NONE,0x11b1, CJJ_JONGSUNG,0x11bf, CJJ_JONGSUNG},
01379     { 0x110b, CJJ_NONE,0x11b0, CJJ_JONGSUNG,0x11b2, CJJ_JONGSUNG},
01380     { 0x1104, CJJ_NONE,0x11bf, CJJ_JONGSUNG,0x11ac, CJJ_JONGSUNG},
01381     { 0x1105, CJJ_NONE,0x11a9, CJJ_JONGSUNG,0x11b1, CJJ_JONGSUNG},
01382     { 0x1112, CJJ_NONE,0x002f, CJJ_NONE,0x1164, CJJ_JUNGSUNG},
01383     { 0x1169, CJJ_NONE,0x0027, CJJ_NONE,0x0030, CJJ_NONE},
01384     { 0x1163, CJJ_NONE,0x0038, CJJ_NONE,0x0037, CJJ_NONE},
01385     { 0x1165, CJJ_NONE,0x0034, CJJ_NONE,0x0031, CJJ_NONE},
01386     { 0x1161, CJJ_NONE,0x0035, CJJ_NONE,0x0032, CJJ_NONE},
01387     { 0x1175, CJJ_NONE,0x0036, CJJ_NONE,0x0033, CJJ_NONE},
01388     { 0x1173, CJJ_NONE,0x0031, CJJ_NONE,0x0022, CJJ_NONE},
01389     { 0x116e, CJJ_NONE,0x0030, CJJ_NONE,0x002d, CJJ_NONE},
01390     { 0x1164, CJJ_NONE,0x0039, CJJ_NONE,0x0038, CJJ_NONE},
01391     { 0x1168, CJJ_NONE,0x003e, CJJ_NONE,0x0039, CJJ_NONE},
01392     { 0x1108, CJJ_NONE,0x11c1, CJJ_JONGSUNG,0x11c1, CJJ_JONGSUNG},
01393     { 0x1101, CJJ_NONE,0x1164, CJJ_JUNGSUNG,0x11b6, CJJ_JONGSUNG},
01394     { 0x1102, CJJ_NONE,0x11ad, CJJ_JONGSUNG,0x11ad, CJJ_JONGSUNG},
01395     { 0x110a, CJJ_NONE,0x003b, CJJ_NONE,0x11b3, CJJ_JONGSUNG},
01396     { 0x1167, CJJ_NONE,0x0037, CJJ_NONE,0x0036, CJJ_NONE},
01397     { 0x1111, CJJ_NONE,0x11b6, CJJ_JONGSUNG,0x11aa, CJJ_JONGSUNG},
01398     { 0x110d, CJJ_NONE,0x11af, CJJ_JONGSUNG,0x11af, CJJ_JONGSUNG},
01399     { 0x1110, CJJ_NONE,0x11b9, CJJ_JONGSUNG,0x11b9, CJJ_JONGSUNG},
01400     { 0x116d, CJJ_NONE,0x003c, CJJ_NONE,0x0035, CJJ_NONE},
01401     { 0x110f, CJJ_NONE,0x11be, CJJ_JONGSUNG,0x11be, CJJ_JONGSUNG},
01402     { 0x005b, CJJ_NONE,0x005b, CJJ_NONE,0x0028, CJJ_NONE},
01403     { 0x005c, CJJ_NONE,0x005c, CJJ_NONE,0x003a, CJJ_NONE},
01404     { 0x005d, CJJ_NONE,0x005d, CJJ_NONE,0x003c, CJJ_NONE},
01405     { 0x005e, CJJ_NONE,0x005e, CJJ_NONE,0x003d, CJJ_NONE},
01406     { 0x005f, CJJ_NONE,0x005f, CJJ_NONE,0x003b, CJJ_NONE},
01407     { 0x0060, CJJ_NONE,0x002e, CJJ_NONE,0x002a, CJJ_NONE},
01408     { 0x1106, CJJ_NONE,0x11bc, CJJ_JONGSUNG,0x11bc, CJJ_JONGSUNG},
01409     { 0x1172, CJJ_NONE,0x116e, CJJ_JUNGSUNG,0x116e, CJJ_JUNGSUNG},
01410     { 0x110e, CJJ_NONE,0x1166, CJJ_JUNGSUNG,0x1166, CJJ_JUNGSUNG},
01411     { 0x110b, CJJ_NONE,0x1175, CJJ_JUNGSUNG,0x1175, CJJ_JUNGSUNG},
01412     { 0x1103, CJJ_NONE,0x1167, CJJ_JUNGSUNG,0x1167, CJJ_JUNGSUNG},
01413     { 0x1105, CJJ_NONE,0x1161, CJJ_JUNGSUNG,0x1161, CJJ_JUNGSUNG},
01414     { 0x1112, CJJ_NONE,0x1173, CJJ_JUNGSUNG,0x1173, CJJ_JUNGSUNG},
01415     { 0x1169, CJJ_NONE,0x1102, CJJ_CHOSUNG,0x1102, CJJ_CHOSUNG},
01416     { 0x1163, CJJ_NONE,0x1106, CJJ_CHOSUNG,0x1106, CJJ_CHOSUNG},
01417     { 0x1165, CJJ_NONE,0x110b, CJJ_CHOSUNG,0x110b, CJJ_CHOSUNG},
01418     { 0x1161, CJJ_NONE,0x1100, CJJ_CHOSUNG,0x1100, CJJ_CHOSUNG},
01419     { 0x1175, CJJ_NONE,0x110c, CJJ_CHOSUNG,0x110c, CJJ_CHOSUNG},
01420     { 0x1173, CJJ_NONE,0x1112, CJJ_CHOSUNG,0x1112, CJJ_CHOSUNG},
01421     { 0x116e, CJJ_NONE,0x1109, CJJ_CHOSUNG,0x1109, CJJ_CHOSUNG},
01422     { 0x1162, CJJ_NONE,0x110e, CJJ_CHOSUNG,0x110e, CJJ_CHOSUNG},
01423     { 0x1166, CJJ_NONE,0x1111, CJJ_CHOSUNG,0x1111, CJJ_CHOSUNG},
01424     { 0x1107, CJJ_NONE,0x11ba, CJJ_JONGSUNG,0x11ba, CJJ_JONGSUNG},
01425     { 0x1100, CJJ_NONE,0x1162, CJJ_JUNGSUNG,0x1162, CJJ_JUNGSUNG},
01426     { 0x1102, CJJ_NONE,0x11ab, CJJ_JONGSUNG,0x11ab, CJJ_JONGSUNG},
01427     { 0x1109, CJJ_NONE,0x1165, CJJ_JUNGSUNG,0x1165, CJJ_JUNGSUNG},
01428     { 0x1167, CJJ_NONE,0x1103, CJJ_CHOSUNG,0x1103, CJJ_CHOSUNG},
01429     { 0x1111, CJJ_NONE,0x1169, CJJ_JUNGSUNG,0x1169, CJJ_JUNGSUNG},
01430     { 0x110c, CJJ_NONE,0x11af, CJJ_JONGSUNG,0x11af, CJJ_JONGSUNG}, /*'w' */
01431     { 0x1110, CJJ_NONE,0x11a8, CJJ_JONGSUNG,0x11a8, CJJ_JONGSUNG},
01432     { 0x116d, CJJ_NONE,0x1105, CJJ_CHOSUNG,0x1105, CJJ_CHOSUNG},
01433     { 0x110f, CJJ_NONE,0x11b7, CJJ_JONGSUNG,0x11b7, CJJ_JONGSUNG},
01434     { 0x007b, CJJ_NONE,0x007b, CJJ_NONE,0x0025, CJJ_NONE},
01435     { 0x007c, CJJ_NONE,0x007c, CJJ_NONE,0x005c, CJJ_NONE},
01436     { 0x007d, CJJ_NONE,0x007d, CJJ_NONE,0x002f, CJJ_NONE},
01437     { 0x007e, CJJ_NONE,0x007e, CJJ_NONE,0x203b, CJJ_NONE},
01438   };
01439 
01440   assert (map_info != NULL);
01441   
01442   if (keyChar >= '!' && keyChar <= '~') {
01443     if (state & IM_SHIFT_MASK) {
01444       if (keyChar >= 'a' && keyChar <= 'z')
01445        keyChar -= ('a' - 'A');
01446     } else {
01447       if (keyChar >= 'A' && keyChar <= 'Z')
01448        keyChar += ('a' - 'A');
01449     }
01450     map_info->val = map[keyChar - '!'].layout[layout_id].val;
01451     map_info->type = map[keyChar - '!'].layout[layout_id].type;
01452     KOLE_LOG (LOGDEST_STDOUT, "composer_hangul_convert_input_to_unicode(): layout_id is %d, val is %X\n", layout_id, map_info->val);
01453 #if 0
01454     return map[keyChar - '!'].layout[layout_id].val;
01455 #endif
01456     return True;
01457 
01458   }
01459   
01460   map_info->val = 0x0000;
01461   map_info->type = CJJ_NONE;
01462   
01463   return False;
01464 }
01465 
01466 static const CoupledJamoInfo coupled_jamo[] = {
01467   { 0x1100, 0x1100, 0x1101 },   /* LC : g + g  = gg   */
01468   { 0x1103, 0x1103, 0x1104 },   /* LC : d + d  = dd   */
01469   { 0x1107, 0x1107, 0x1108 },   /* LC : b + b  = bb   */
01470   { 0x1109, 0x1109, 0x110a },   /* LC : s + s  = ss   */
01471   { 0x110c, 0x110c, 0x110d },   /* LC : j + j  = jj   */
01472   { 0x1169, 0x1161, 0x116a },   /* IV : o + a  = wa   */
01473   { 0x1169, 0x1162, 0x116b },   /* IV : o + ae = wae  */
01474   { 0x1169, 0x1175, 0x116c },   /* IV : o + i  = we   */
01475   { 0x116e, 0x1165, 0x116f },   /* IV : u + eo = weo  */
01476   { 0x116e, 0x1166, 0x1170 },   /* IV : u + e  = we   */
01477   { 0x116e, 0x1175, 0x1171 },   /* IV : u + i  = wi   */
01478   { 0x1173, 0x1175, 0x1174 },   /* IV : eu+ i  = eui  */
01479   { 0x11a8, 0x11a8, 0x11a9 },   /* TC : g + g  = gg   */
01480   { 0x11a8, 0x11ba, 0x11aa },   /* TC : g + s  = gs   */
01481   { 0x11ab, 0x11bd, 0x11ac },   /* TC : n + s  = ns   */
01482   { 0x11ab, 0x11c2, 0x11ad },   /* TC : n + h  = nh   */
01483   { 0x11af, 0x11a8, 0x11b0 },   /* TC : l + g  = lg   */
01484   { 0x11af, 0x11b7, 0x11b1 },   /* TC : l + m  = lm   */
01485   { 0x11af, 0x11b8, 0x11b2 },   /* TC : l + b  = lb   */
01486   { 0x11af, 0x11ba, 0x11b3 },   /* TC : l + s  = ls   */
01487   { 0x11af, 0x11c0, 0x11b4 },   /* TC : l + t  = lt   */
01488   { 0x11af, 0x11c1, 0x11b5 },   /* TC : l + p  = lp   */
01489   { 0x11af, 0x11c2, 0x11b6 },   /* TC : l + h  = lh   */
01490   { 0x11b8, 0x11ba, 0x11b9 },   /* TC : b + s  = bs   */
01491   { 0x11ba, 0x11ba, 0x11bb },   /* TC : s + s  = ss   */
01492 };
01493 
01494 
01495 /* return:
01496    0: not valid
01497    !0: valid
01498 */
01499 static UTFCHAR
01500 composer_hangul_coupled_jamo (UTFCHAR first, UTFCHAR second)
01501 {
01502   int i, len;
01503   
01504   len = (sizeof(coupled_jamo) / sizeof(coupled_jamo[0]));
01505   /*
01506     Fix me. Not very smart way,
01507     but should be okay becuase the loop will happen
01508     on relatively small array
01509   */
01510   
01511   for (i = 0 ; i < len ; i++){
01512     if (coupled_jamo [i].first == first &&
01513        coupled_jamo [i].second == second)
01514       return coupled_jamo [i].coupled;
01515   }
01516   return 0;  
01517 }
01518 
01519 Bool
01520 composer_hangul_hanja_lookup_start (HANGULBuffer *hangul_buffer, 
01521                                 int *number_of_candidates,
01522                                 UTFCHAR ***hanja_list_return)
01523 {
01524   HANGUL *first_hangul;
01525   UTFCHAR hangul_key;
01526   int table_index;
01527   int i;
01528   Bool mthd_return;
01529   UTFCHAR *u16hangul = NULL;
01530   int n_hangul_chars;
01531 
01532   assert (hangul_buffer != NULL);
01533 #if 0
01534   first_hangul = composer_hangul_buffer_get_first_hangul (hangul_buffer);
01535   if (first_hangul == NULL)
01536     return False;
01537 
01538   hangul_key = composer_hangul_combine_cho_jung_jong (first_hangul);
01539   if (hangul_key == 0x0000)
01540     return False;
01541 #endif
01542   n_hangul_chars = 
01543     composer_hangul_buffer_get_hangul_length (hangul_buffer);
01544   if (n_hangul_chars < 1)
01545     return False;
01546   
01547   mthd_return =
01548     composer_hangul_buffer_get_content_in_u16 (hangul_buffer, &u16hangul);
01549   if (!mthd_return){
01550     KOLE_LOG (LOGDEST_STDOUT, "composer_hangul_hanja_lookup_start error :"
01551             "composer_hangul_buffer_get_content_in_u16 failed\n");
01552     *number_of_candidates = 0;
01553     *hanja_list_return = NULL;
01554     return False;
01555   }
01556   
01557   mthd_return = dictionary_search_hanja_candidates_in_utf16
01558     (u16hangul, number_of_candidates, hanja_list_return );
01559 
01560   if (!mthd_return){
01561     return False;
01562   } else
01563     return True;
01564 }
01565 
01566 
01567 /*
01568   I create this function here after copying code from 
01569   hangul_imebuffer_get_preedit (IMEBuffer a_buffer, UTFCHAR **out_utfstr)
01570 
01571   I feel, hangul_imebuffer_get_preedit should call this function.
01572   I'll do it soon..
01573 */
01574 Bool
01575 composer_hangul_buffer_get_content_in_u16(HANGULBuffer *hbuf,
01576                                      UTFCHAR **u16hangul_return)
01577 {
01578   int i, utfchar_len;
01579   UTFCHAR *han_char;
01580   HANGUL *current_hangul;
01581 
01582   assert (hbuf != NULL);
01583   if (hbuf == NULL){
01584     KOLE_LOG (LOGDEST_STDOUT, "composer_hangul_buffer_get_content_in_u16 error :"
01585             "hbuf is null\n");
01586     *u16hangul_return = NULL;
01587     return False;
01588   }
01589   
01590   utfchar_len =
01591     composer_hangul_buffer_get_hangul_length (hbuf);
01592   
01593   assert (utfchar_len >= 0);
01594 
01595   if (utfchar_len <= -1) {
01596     KOLE_LOG (LOGDEST_STDERR, "hangul_imebuffer_get_preedit error: number of hangul "
01597            "can't be negative\n");
01598     return False;
01599   }
01600   else if (utfchar_len == 0) {
01601     *u16hangul_return = NULL;
01602     return True;
01603   }
01604   else {
01605   
01606     if (hbuf == NULL){
01607       KOLE_LOG (LOGDEST_STDERR, 
01608              "hangul_imebuffer_get_preedit error: composer_buffer can't be null\n");
01609       return False;
01610     }
01611               
01612     *u16hangul_return = (UTFCHAR *) calloc( utfchar_len + 1 , sizeof (UTFCHAR) );
01613 
01614     for (i = 0 ; i < utfchar_len; i++) {
01615       UTFCHAR combined_character;
01616       UTFCHAR tmp;
01617       
01618       combined_character =
01619        composer_hangul_combine_cho_jung_jong( (hbuf->buffer[i]) );
01620       if (combined_character){
01621        (*u16hangul_return)[i] = combined_character;
01622       } else {
01623        current_hangul = hbuf->buffer[i];
01624        
01625        if (!_jamo_is_clean (&current_hangul->L)){
01626          tmp = _jamo_get_value (&current_hangul->L);
01627          (*u16hangul_return)[i] =
01628            hangul_combining_chosung_to_compatibility_jamo (tmp);
01629        } else if (!_jamo_is_clean (&current_hangul->V)){
01630          tmp = _jamo_get_value (&current_hangul->V);
01631          (*u16hangul_return)[i] =
01632            hangul_combining_jungsung_to_compatibility_moeum (tmp);
01633        } else if (!_jamo_is_clean (&current_hangul->T)){
01634          tmp = _jamo_get_value (&current_hangul->V);
01635          (*u16hangul_return)[i] =
01636            hangul_combining_jongsung_to_compatibility_jaeum (tmp);     
01637        }
01638       }
01639     }
01640     (*u16hangul_return)[i] = 0x0000;
01641   }
01642 
01643   return True;
01644 }
01645 
01646 
01647 void
01648 composer_config_switch_codeset (Config *pconfig, int *next)
01649 {
01650   assert (pconfig != NULL);
01651   if (!pconfig){
01652     KOLE_LOG (LOGDEST_STDERR,
01653             "composer_config_switch_codeset error: pconfig is null\n");
01654     return;
01655   }
01656   if (!next){
01657     if (pconfig->charset == IN_EUC)
01658       pconfig->charset = IN_UNICODE;
01659     else
01660       pconfig->charset = IN_EUC;
01661   } else if ((*next >= IN_EUC) && (*next <= IN_UNICODE)) {
01662     pconfig->charset = *next;
01663   } else
01664     return;
01665 }
01666 
01667 
01668 void
01669 composer_config_switch_keyboard (Config *pconfig)
01670 {
01671   assert (pconfig != NULL);
01672   if (!pconfig){
01673     KOLE_LOG (LOGDEST_STDERR,
01674             "composer_config_switch_codeset error: pconfig is null\n");
01675     return;
01676   }
01677   if (pconfig->keyboard == (LAYOUT_NUM - 1)){
01678     pconfig->keyboard = LAYOUT_2PART;
01679   } else {
01680     pconfig->keyboard++;
01681   }
01682 }
01683 
01684 
01685 void
01686 composer_config_switch_commit_method (Config *pconfig)
01687 {
01688   assert (pconfig != NULL);
01689   if (!pconfig){
01690     KOLE_LOG (LOGDEST_STDERR,
01691             "composer_config_switch_codeset error: pconfig is null\n");
01692     return;
01693   }
01694   if (pconfig->commit_mode == COMMIT_BY_HOTKEY){
01695     pconfig->commit_mode = COMMIT_BY_CHAR;
01696   } else {
01697     pconfig->commit_mode++;
01698   }
01699 }
01700 
01701 #ifdef TEST_RUN
01702 int
01703 main(int argc, char **argv)
01704 {
01705   int c;
01706   HANGULBuffer *hb;
01707   hb = composer_hangul_buffer_new ();
01708   while(c = getc(stdin))
01709     {
01710       if(c == '\n'){
01711        KOLE_LOG (LOGDEST_STDOUT, "continue...\n");
01712        continue;
01713       }
01714       composer_hangul_automata_2pair (c, 0, 0, hb);
01715       composer_hangul_buffer_print (hb);
01716     }
01717 
01718 }
01719 #endif