src/ise-stt-mode.cpp
src/ise-stt-option.cpp
src/sdk/ise_lang_table.cpp
+ src/sdk/cji.cpp
src/sdk/sdk.cpp
src/sdk/sdk_option.cpp
src/candidate/candidate-factory.cpp
<?xml version="1.0" encoding="UTF-8"?>
-<layout width="360" height="240" magnifier="true" key_width="34" key_height="50" key_spacing="0" row_spacing="0" hit_left="0" hit_right="0" hit_top="0" hit_bottom="0" label_type="QTY_DEFAULT" vibe_style="DEFAULT" sound_style="DEFAULT">
+<layout width="360" height="240" magnifier="true" key_width="80" key_height="60" vibe_style="DEFAULT" sound_style="DEFAULT" label_type="3X4_DEFAULT">
<image_path>
<button_normal>B09_panel.png</button_normal>
</image_path>
<background_image>
- <rec button="normal">button/B09_Qwerty_btn_01.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_01.png</rec>
+ <rec button="pressed">key_btn_press.png</rec>
</background_image>
- <row x="10" y="0">
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="1" multitouch_type="settle_previous">
+ <row x="20">
+ <key key_type="user" long_key_value="1" long_key_type="string" longkey_magnifier="true">
<label>
- <rec shift="off" multi="0">ㅂ</rec>
- <rec shift="on" multi="0">ㅃ</rec>
- <rec shift="loc" multi="0">ㅃ</rec>
+ <rec multi="0" auto_upper="true">ㅣ</rec>
<rec multi="1">1</rec>
</label>
<key_value>
- <rec auto_upper="true">q</rec>
+ <rec auto_upper="true">SIPKEY_1</rec>
</key_value>
</key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="2" multitouch_type="settle_previous">
+ <key key_type="user" long_key_value="2" long_key_type="string" longkey_magnifier="true">
<label>
- <rec shift="off" multi="0">ㅈ</rec>
- <rec shift="on" multi="0">ㅉ</rec>
- <rec shift="loc" multi="0">ㅉ</rec>
+ <rec multi="0" auto_upper="true">.</rec>
<rec multi="1">2</rec>
</label>
<key_value>
- <rec auto_upper="true">w</rec>
+ <rec auto_upper="true">SIPKEY_2</rec>
</key_value>
</key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="3" multitouch_type="settle_previous">
+ <key key_type="user" long_key_value="3" long_key_type="string" longkey_magnifier="true">
<label>
- <rec shift="off" multi="0">ㄷ</rec>
- <rec shift="on" multi="0">ㄸ</rec>
- <rec shift="loc" multi="0">ㄸ</rec>
+ <rec multi="0" auto_upper="true">ㅡ</rec>
<rec multi="1">3</rec>
</label>
<key_value>
- <rec auto_upper="true">e</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="4" multitouch_type="settle_previous">
- <label>
- <rec shift="off" multi="0">ㄱ</rec>
- <rec shift="on" multi="0">ㄲ</rec>
- <rec shift="loc" multi="0">ㄲ</rec>
- <rec multi="1">4</rec>
- </label>
- <key_value>
- <rec auto_upper="true">r</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="5" multitouch_type="settle_previous">
- <label>
- <rec shift="off" multi="0">ㅅ</rec>
- <rec shift="on" multi="0">ㅆ</rec>
- <rec shift="loc" multi="0">ㅆ</rec>
- <rec multi="1">5</rec>
- </label>
- <key_value>
- <rec auto_upper="true">t</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="6" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅛ</rec>
- <rec multi="1">6</rec>
- </label>
- <key_value>
- <rec auto_upper="true">y</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="7" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅕ</rec>
- <rec multi="1">7</rec>
- </label>
- <key_value>
- <rec auto_upper="true">u</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="8" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅑ</rec>
- <rec multi="1">8</rec>
- </label>
- <key_value>
- <rec auto_upper="true">i</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="9" multitouch_type="settle_previous">
- <label>
- <rec shift="off" multi="0">ㅐ</rec>
- <rec shift="on" multi="0">ㅒ</rec>
- <rec shift="loc" multi="0">ㅒ</rec>
- <rec multi="1">9</rec>
- </label>
- <key_value>
- <rec auto_upper="true">o</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="0" multitouch_type="settle_previous" hit_right="8">
- <label>
- <rec shift="off" multi="0">ㅔ</rec>
- <rec shift="on" multi="0">ㅖ</rec>
- <rec shift="loc" multi="0">ㅖ</rec>
- <rec multi="1">0</rec>
- </label>
- <key_value>
- <rec auto_upper="true">p</rec>
- </key_value>
- </key>
- </row>
- <row x="25">
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="-" multitouch_type="settle_previous" hit_left="36">
- <label>
- <rec multi="0">ㅁ</rec>
- <rec multi="1">-</rec>
- </label>
- <key_value>
- <rec auto_upper="true">a</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="@" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㄴ</rec>
- <rec multi="1">@</rec>
- </label>
- <key_value>
- <rec auto_upper="true">s</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="*" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅇ</rec>
- <rec multi="1">*</rec>
- </label>
- <key_value>
- <rec auto_upper="true">d</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="^" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㄹ</rec>
- <rec multi="1">^</rec>
- </label>
- <key_value>
- <rec auto_upper="true">f</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value=":" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅎ</rec>
- <rec multi="1">:</rec>
- </label>
- <key_value>
- <rec auto_upper="true">g</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value=";" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅗ</rec>
- <rec multi="1">;</rec>
- </label>
- <key_value>
- <rec auto_upper="true">h</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="(" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅓ</rec>
- <rec multi="1">(</rec>
- </label>
- <key_value>
- <rec auto_upper="true">j</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value=")" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅏ</rec>
- <rec multi="1">)</rec>
- </label>
- <key_value>
- <rec auto_upper="true">k</rec>
+ <rec auto_upper="true">SIPKEY_3</rec>
</key_value>
</key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="~" multitouch_type="settle_previous" hit_right="35">
- <label>
- <rec multi="0">ㅣ</rec>
- <rec multi="1">~</rec>
- </label>
- <key_value>
- <rec auto_upper="true">l</rec>
- </key_value>
- </key>
- </row>
- <row x="20">
- <key long_key_value="LongShift" long_key_event="65505" button_type="selfish" key_type="control" width="40" hit_left="9">
+ <key key_type="control" use_repeat_key="true" image_label_type="IMAGE_3X4_TOP">
<image_label>
- <rec shift="off" button="normal">B09_icon_shift_off_54x54.png</rec>
- <rec shift="on" button="normal">B09_icon_shift_on_54x54.png</rec>
- <rec shift="loc" button="normal">B09_icon_shift_loc_54x54.png</rec>
- <rec button="pressed">B09_icon_shift_press_54x54.png</rec>
- <rec button="disabled">B09_icon_shift_dim_54x54.png</rec>
+ <rec button="normal">w_sip_3x4_btn_ic_delete.png</rec>
+ <rec button="pressed">w_sip_3x4_btn_ic_delete.png</rec>
</image_label>
- <background_image>
- <rec shift="off" button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec shift="on" button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec shift="loc" button="normal">button/B09_Qwerty_btn_doubletab.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
- <key_value>
- <rec>Shift</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="/" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅋ</rec>
- <rec multi="1">/</rec>
- </label>
- <key_value>
- <rec auto_upper="true">z</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="'" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅌ</rec>
- <rec multi="1">'</rec>
- </label>
- <key_value>
- <rec auto_upper="true">x</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value=""" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅊ</rec>
- <rec multi="1">"</rec>
- </label>
- <key_value>
- <rec auto_upper="true">c</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="." multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅍ</rec>
- <rec multi="1">.</rec>
- </label>
- <key_value>
- <rec auto_upper="true">v</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="," multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅠ</rec>
- <rec multi="1">,</rec>
- </label>
- <key_value>
- <rec auto_upper="true">b</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="?" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅜ</rec>
- <rec multi="1">?</rec>
- </label>
- <key_value>
- <rec auto_upper="true">n</rec>
- </key_value>
- </key>
- <key use_magnifier="true" longkey_magnifier="true" long_key_value="!" multitouch_type="settle_previous">
- <label>
- <rec multi="0">ㅡ</rec>
- <rec multi="1">!</rec>
- </label>
- <key_value>
- <rec auto_upper="true">m</rec>
- </key_value>
- </key>
- <key button_type="selfish" key_type="control" use_magnifier="true" longkey_magnifier="true" use_repeat_key="true" width="40" hit_right="8">
- <image_label>
- <rec button="normal">B09_icon_back_nor_54x54.png</rec>
- <rec button="pressed">B09_icon_back_press_54x54.png</rec>
- <rec button="disabled">B09_icon_back_dim_54x54.png</rec>
- </image_label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
<rec>BackSpace</rec>
</key_value>
</key>
</row>
- <row x="60" sub_layout="DEFAULT">
- <key button_type="selfish" key_type="modechange" label_type="QTY_?123" width="40" hit_left="9">
+ <row x="20">
+ <key key_type="user" long_key_value="4" long_key_type="string" longkey_magnifier="true">
<label>
- <rec>?123</rec>
+ <rec multi="0" auto_upper="true">ㄱㅋ</rec>
+ <rec multi="1">4</rec>
</label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
- <rec>SYM_QTY_1</rec>
+ <rec auto_upper="true">SIPKEY_4</rec>
</key_value>
</key>
- <key button_type="selfish" key_type="modechange" use_magnifier="false" custom_id="CM_KEY" label_type="SETTING_CUE" popup_type="longpress_popup_once" popup_offset_x="-12" popup_offset_y="-136">
+ <key key_type="user" long_key_value="5" long_key_type="string" longkey_magnifier="true">
<label>
- <rec>...</rec>
+ <rec multi="0" auto_upper="true">ㄴㄹ</rec>
+ <rec multi="1">5</rec>
</label>
- <image_label>
- <rec button="normal">setting icon/B09_icon_setting_nor_54x54.png</rec>
- <rec button="pressed">setting icon/B09_icon_setting_press_54x54.png</rec>
- <rec button="disabled">setting icon/B09_icon_setting_dim_54x54.png</rec>
- </image_label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
- <rec>OPTION</rec>
+ <rec auto_upper="true">SIPKEY_5</rec>
</key_value>
- <popup_input_mode_record>
- <popup_input_mode>CM_POPUP</popup_input_mode>
- </popup_input_mode_record>
</key>
- <key button_type="direction" key_type="control" label_type="QTY_SPACE" image_label_type="IMAGE_SPACE" width="100">
+ <key key_type="user" long_key_value="6" long_key_type="string" longkey_magnifier="true">
<label>
- <rec>_LANGUAGE_</rec>
+ <rec multi="0" auto_upper="true">ㄷㅌ</rec>
+ <rec multi="1">6</rec>
</label>
- <image_label>
- <rec button="normal">B09_icon_space_nor_73x22.png</rec>
- <rec button="pressed">B09_icon_space_press_73x22.png</rec>
- <rec button="disabled">B09_icon_space_dim_73x22.png</rec>
- </image_label>
<key_value>
- <rec>Space</rec>
+ <rec auto_upper="true">SIPKEY_6</rec>
</key_value>
</key>
- <key popup_type="longpress_popup_once" label_type="QTY_DOT" image_label_type="IMAGE_CUE" popup_offset_x="-391" popup_offset_y="-254">
- <label>
- <rec>.</rec>
- </label>
+ <key key_type="control" custom_id="Enter" image_label_type="IMAGE_3X4_TOP">
<image_label>
- <rec button="normal">B09_icon_question_45x30.png</rec>
- <rec button="pressed">B09_icon_question_45x30.png</rec>
- <rec button="disabled">B09_icon_question_45x30.png</rec>
+ <rec button="normal">w_sip_3x4_btn_ic_enter.png</rec>
+ <rec button="pressed">w_sip_3x4_btn_ic_enter.png</rec>
+ <rec button="disabled">w_sip_3x4_btn_ic_enter_d.png</rec>
</image_label>
- <popup_input_mode_record>
- <popup_input_mode>PUNCTUATION_POPUP</popup_input_mode>
- </popup_input_mode_record>
- </key>
- <key button_type="selfish" key_type="control" custom_id="Enter" label_type="QTY_?123" width="40" hit_right="8">
- <image_label>
- <rec button="normal">B09_icon_enter_nor_54x54.png</rec>
- <rec button="pressed">B09_icon_enter_press_54x54.png</rec>
- <rec button="disabled">B09_icon_enter_dim_54x54.png</rec>
- </image_label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
<rec>Enter</rec>
</key_value>
</key>
</row>
- <row x="9" sub_layout="URL">
- <key button_type="selfish" key_type="modechange" label_type="QTY_?123" width="100">
+ <row x="20">
+ <key key_type="user" long_key_value="7" long_key_type="string" longkey_magnifier="true">
<label>
- <rec>?123</rec>
+ <rec multi="0" auto_upper="true">ㅂㅍ</rec>
+ <rec multi="1">7</rec>
</label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
- <rec>SYM_QTY_1</rec>
+ <rec auto_upper="true">SIPKEY_7</rec>
</key_value>
</key>
- <key button_type="selfish" key_type="modechange" use_magnifier="false" custom_id="CM_KEY" label_type="SETTING_CUE" popup_type="longpress_popup_once" popup_offset_x="-12" popup_offset_y="-136">
+ <key key_type="user" long_key_value="8" long_key_type="string" longkey_magnifier="true">
<label>
- <rec>...</rec>
+ <rec multi="0" auto_upper="true">ㅅㅎ</rec>
+ <rec multi="1">8</rec>
</label>
- <image_label>
- <rec button="normal">setting icon/B09_icon_setting_nor_54x54.png</rec>
- <rec button="pressed">setting icon/B09_icon_setting_press_54x54.png</rec>
- <rec button="disabled">setting icon/B09_icon_setting_dim_54x54.png</rec>
- </image_label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
- <rec>OPTION</rec>
+ <rec auto_upper="true">SIPKEY_8</rec>
</key_value>
- <popup_input_mode_record>
- <popup_input_mode>CM_POPUP</popup_input_mode>
- </popup_input_mode_record>
- </key>
- <key key_type="string" label_type="QTY_LINE1">
- <label>
- <rec>/</rec>
- </label>
</key>
- <key button_type="direction" key_type="control" label_type="QTY_SPACE" image_label_type="IMAGE_SPACE" width="172">
+ <key key_type="user" long_key_value="9" long_key_type="string" longkey_magnifier="true">
<label>
- <rec>_LANGUAGE_</rec>
+ <rec multi="0" auto_upper="true">ㅈㅊ</rec>
+ <rec multi="1">9</rec>
</label>
- <image_label>
- <rec button="normal">B09_icon_space_nor_73x22.png</rec>
- <rec button="pressed">B09_icon_space_press_73x22.png</rec>
- <rec button="disabled">B09_icon_space_dim_73x22.png</rec>
- </image_label>
<key_value>
- <rec>Space</rec>
+ <rec auto_upper="true">SIPKEY_9</rec>
</key_value>
</key>
- <key key_type="string" label_type="QTY_LINE1">
- <label>
- <rec>.</rec>
- </label>
- </key>
- <key key_type="string" popup_type="longpress_popup_once" label_type="QTY_WWWCOM" popup_offset_x="-318" popup_offset_y="-230" width="100">
- <label>
- <rec>www.</rec>
- </label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
- <popup_input_mode_record>
- <popup_input_mode>URL_POPUP</popup_input_mode>
- </popup_input_mode_record>
- </key>
- <key button_type="selfish" key_type="control" custom_id="Enter" label_type="QTY_?123" width="100" hit_right="8">
+ <key key_type="control" image_label_type="IMAGE_3X4_TOP">
<image_label>
- <rec button="normal">B09_icon_enter_nor_54x54.png</rec>
- <rec button="pressed">B09_icon_enter_press_54x54.png</rec>
- <rec button="disabled">B09_icon_enter_dim_54x54.png</rec>
+ <rec shift="off" button="normal">w_sip_3x4_btn_ic_shift.png</rec>
+ <rec shift="on" button="normal">w_sip_3x4_btn_ic_shift.png</rec>
+ <rec shift="loc" button="normal">w_sip_3x4_btn_ic_shift_p.png</rec>
+ <rec button="pressed">w_sip_3x4_btn_ic_shift.png</rec>
+ <rec button="disabled">w_sip_3x4_btn_ic_shift_d.png</rec>
</image_label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
- <rec>Enter</rec>
+ <rec>Shift</rec>
</key_value>
</key>
</row>
- <row x="9" sub_layout="EMAIL">
- <key button_type="selfish" key_type="modechange" label_type="QTY_?123" width="100">
+ <row x="47">
+ <key key_type="user" long_key_value="0" long_key_type="string" longkey_magnifier="true" label_type="3X4_DEFAULT_0" width="133">
<label>
- <rec>?123</rec>
- </label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
- <key_value>
- <rec>SYM_QTY_1</rec>
- </key_value>
- </key>
- <key button_type="selfish" key_type="modechange" use_magnifier="false" custom_id="CM_KEY" label_type="SETTING_CUE" popup_type="longpress_popup_once" popup_offset_x="-12" popup_offset_y="-136">
- <label>
- <rec>...</rec>
+ <rec multi="0" auto_upper="true">ㅇㅁ</rec>
+ <rec multi="1">0</rec>
</label>
- <image_label>
- <rec button="normal">setting icon/B09_icon_setting_nor_54x54.png</rec>
- <rec button="pressed">setting icon/B09_icon_setting_press_54x54.png</rec>
- <rec button="disabled">setting icon/B09_icon_setting_dim_54x54.png</rec>
- </image_label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
<key_value>
- <rec>OPTION</rec>
+ <rec auto_upper="true">SIPKEY_0</rec>
</key_value>
- <popup_input_mode_record>
- <popup_input_mode>CM_POPUP</popup_input_mode>
- </popup_input_mode_record>
- </key>
- <key key_type="string" label_type="QTY_LINE1">
- <label>
- <rec>@</rec>
- </label>
</key>
- <key button_type="direction" key_type="control" label_type="QTY_SPACE" image_label_type="IMAGE_SPACE" width="172">
+ <key button_type="direction" key_type="control" label_type="3X4_DEFAULT_SPACE" image_label_type="IMAGE_3X4_SPACE" width="133">
<label>
<rec>_LANGUAGE_</rec>
</label>
<image_label>
- <rec button="normal">B09_icon_space_nor_73x22.png</rec>
- <rec button="pressed">B09_icon_space_press_73x22.png</rec>
- <rec button="disabled">B09_icon_space_dim_73x22.png</rec>
+ <rec button="normal">w_sip_3x4_btn_ic_space.png</rec>
+ <rec button="pressed">w_sip_3x4_btn_ic_space.png</rec>
</image_label>
<key_value>
<rec>Space</rec>
</key_value>
</key>
- <key key_type="string" label_type="QTY_LINE1">
- <label>
- <rec>.</rec>
- </label>
- </key>
- <key key_type="string" popup_type="longpress_popup_once" label_type="QTY_WWWCOM" popup_offset_x="-318" popup_offset_y="-230" width="100">
- <label>
- <rec>.com</rec>
- </label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
- <popup_input_mode_record>
- <popup_input_mode>URL_POPUP</popup_input_mode>
- </popup_input_mode_record>
- </key>
- <key button_type="selfish" key_type="control" custom_id="Enter" label_type="QTY_?123" width="100">
- <image_label>
- <rec button="normal">B09_icon_enter_nor_54x54.png</rec>
- <rec button="pressed">B09_icon_enter_press_54x54.png</rec>
- <rec button="disabled">B09_icon_enter_dim_54x54.png</rec>
- </image_label>
- <background_image>
- <rec button="normal">button/B09_Qwerty_btn_02.png</rec>
- <rec button="pressed">button/B09_Qwerty_btn_press.png</rec>
- <rec button="disabled">button/B09_Qwerty_btn_02.png</rec>
- </background_image>
- <key_value>
- <rec>Enter</rec>
- </key_value>
- </key>
</row>
</layout>
virtual sclboolean on_language_selected(const sclchar *language, const sclchar *input_mode) { return FALSE; }
/* Additional callback function, which is called when this language is unselected */
virtual sclboolean on_language_unselected(const sclchar *language, const sclchar *input_mode) { return FALSE; }
+
+ virtual sclboolean reset_language(const sclchar *language) { return FALSE; }
};
struct INPUT_MODE_INFO {
sclboolean select_next_language();
sclboolean select_previous_language();
+ sclboolean reset_language(const sclchar *name);
+
sclboolean set_language_enabled(const sclchar *name, sclboolean enabled);
sclboolean set_language_enabled_temporarily(const sclchar *name, sclboolean enabled_temporarily);
/* if languages num is 0, enable default language, othewise enable languages assigned */
g_keyboard_state.layout = new_layout;
if (g_keyboard_state.visible_state) {
+ _language_manager.reset_language(g_config_values.selected_language.c_str());
ise_show(g_keyboard_state.ic);
}
{
LOGD("");
_reset_multitap_state();
+ _language_manager.reset_language(g_config_values.selected_language.c_str());
}
void
LOGD("");
_reset_multitap_state();
g_keyboard_state.disable_force_latin = FALSE;
+ _language_manager.reset_language(g_config_values.selected_language.c_str());
}
void
void
ise_hide()
{
+ _language_manager.reset_language(g_config_values.selected_language.c_str());
+
_click_count = 0;
delete_commit_timer();
return ret;
}
+sclboolean
+ISELanguageManager::reset_language(const sclchar *name)
+{
+ sclboolean ret = FALSE;
+
+ if (name == NULL) return FALSE;
+ int pos = _find_language_info(name, _language_vector);
+
+ // the assigned language could not be found in the language info vector
+ if (pos < 0 || pos >= (int)_language_vector.size()) {
+ return FALSE;
+ }
+
+ // if the language is not the one currently selected
+ if (pos != _current_language) {
+ return FALSE;
+ }
+
+ LANGUAGE_INFO &language_info = _language_vector.at(pos);
+ // if not enabled and not temporary, return false
+ if (!language_info.enabled && !language_info.enabled_temporarily) {
+ return FALSE;
+ }
+
+ // run the callback function
+ ILanguageCallback *callback = language_info.callback;
+ if (callback) {
+ ret = callback->reset_language(get_current_language());
+ }
+
+ return ret;
+}
+
sclboolean ISELanguageManager::set_language_enabled(const sclchar *name, sclboolean enabled)
{
sclboolean ret = FALSE;
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cji.h"
+
+static int current_state = EMPTY_STATE;
+static int current_state_backup = EMPTY_STATE;
+
+static MAKECODE g_makecode;
+static MAKECODE g_makecode_backup;
+
+static AUTOMATA_HISTORY_INFO g_AH_Stack[MAX_AUTOMATA_HISTORY_LENGTH]; // Automata History Stack
+static AUTOMATA_HISTORY_INFO g_AH_Stack_backup[MAX_AUTOMATA_HISTORY_LENGTH]; // Automata History Stack
+
+static int g_AH_Stack_ptr=0;
+static int g_AH_Stack_ptr_backup=0;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+int process3X4RotationKey(int p_SIPKey)
+{
+ static int p_LastSIPKey = SIPKEY_ERROR;
+
+ int loop;
+ int p_ResultSIPKey = SIPKEY_ERROR;
+
+ if (p_SIPKey >= SIPKEY_3X4_KEY_START && p_SIPKey <= SIPKEY_3X4_KEY_END) {
+ int i3X4Index = p_SIPKey - SIPKEY_3X4_KEY_START;
+ for (loop = 0;loop < SIPKEY_3X4_KEY_ROTATION_CANIDATE_NUM &&
+ p_ResultSIPKey == SIPKEY_ERROR;loop++) {
+ if (SIPKEY3X4RotationTable[i3X4Index][loop] == p_LastSIPKey) {
+ loop++;
+ if (loop >= SIPKEY_3X4_KEY_ROTATION_CANIDATE_NUM) {
+ loop = 0;
+ }
+ if (SIPKEY3X4RotationTable[i3X4Index][loop] == SIPKEY_ERROR) {
+ loop = 0;
+ }
+
+ p_ResultSIPKey = SIPKEY3X4RotationTable[i3X4Index][loop];
+ }
+ }
+
+ if (p_ResultSIPKey == SIPKEY_ERROR) {
+ p_ResultSIPKey = SIPKEY3X4RotationTable[i3X4Index][0];
+ }
+ } else {
+ p_ResultSIPKey = p_SIPKey;
+ }
+
+ p_LastSIPKey = p_ResultSIPKey;
+
+ return p_ResultSIPKey;
+}
+
+MAKECODE CJI_GetMakeCode()
+{
+ return g_makecode;
+}
+
+/**
+* 한글 조합을 처리하는 오토 마타이다.
+* - 입력
+* p_isJAEUM : TRUE 자음, FALSE 모음
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* current_state : CURRENT_STATE를 입력으로 받아 ACTION 수행후 NEXT_STATE를 Setting 한다.
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+* return value : TRUE : 오토마타가 적절하게 수행됨 (legal case), FALSE : 오토마타가 적절하게 수행되지 못함 - 예외상황처리 (illegal case)
+*/
+int CJI_Automata(int p_isJAEUM, short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(current_state >= EMPTY_STATE && current_state <= NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE); //정의된 스테이트 값들을 가져야 한다.
+ ASSERT((p_isJAEUM == TRUE && (p_SIPKey >= 0 || p_SIPKey < SIPKEY_TABLE_SIZE) || //자음일 경우 자음 테이블 인덱스 안에 있어야 한다.
+ (p_isJAEUM == FALSE && (p_SIPKey >= 0 || p_SIPKey < 3)); //모음일 경우 천(0) 지(1) 인(2) 만을 사용한다.
+#endif // CJI_DEBUG
+
+ static int p_LastSIPKey = SIPKEY_ERROR;
+ bool b3X4KeyRotated = FALSE;
+ if (p_isJAEUM) {
+ int p_RotatedSIPKey = process3X4RotationKey(p_SIPKey);
+ if (p_RotatedSIPKey != p_SIPKey) {
+ if (p_SIPKey == p_LastSIPKey) {
+ b3X4KeyRotated = TRUE;
+ if (current_state != EMPTY_STATE) {
+ popFromAutomataHistoryStack();
+ }
+ }
+ p_LastSIPKey = p_SIPKey;
+ p_SIPKey = p_RotatedSIPKey;
+ } else {
+ p_LastSIPKey = p_SIPKey;
+ }
+ } else {
+ process3X4RotationKey(SIPKEY_ERROR);
+ p_LastSIPKey = SIPKEY_ERROR;
+ }
+
+ if(p_SIPKey == (short)SIPKEY_ERROR) {
+ return ACTION_ERROR_KEY(p_SIPKey, p_madecode);
+ }
+ if(p_SIPKey == (short)SIPKEY_BACKSPACE) {
+ return ACTION_BACKSPACE_KEY(p_SIPKey, p_madecode);
+ }
+
+ /* Automata History Stack */
+ if (current_state != EMPTY_STATE)
+ pushEnvToAutomataHistoryStack(current_state, g_makecode); //현재 오토마타 환경을 Stack에 저장하고 Next State로 이동한다.
+
+ switch (current_state) {
+
+ case EMPTY_STATE : //current_State 가 EMPTY_STATE 일 경우
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE를 Setting
+ ACTION_EMPTY_2_CHO(p_SIPKey, p_madecode); //EMPTY_STATE에서 CHO_STATE로 가는 ACTION 수행
+ return TRUE;
+ } else { //입력문자가 모음이면
+ current_state = NOCHO_JUNG_ERROR_STATE;
+ ACTION_ERROR_EMPTY_2_NOCHO_JUNG(p_SIPKey, p_madecode); //ERROR 처리
+ return TRUE;
+ }
+ break;
+
+ case CHO_STATE : //current_State 가 CHO_STATE 일 경우
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ int djong_idx = getJONGIndexofDJONG_withCHOandSIPKEY(g_makecode.cho_idx, p_SIPKey); //조합된 종성의 인덱스를 가져온다.
+ if (djong_idx == COMBINATION_FAIL) { //종성조합불가자음이면
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_ERROR_CHO_2_CHO(p_SIPKey, p_madecode); //ERROR 처리
+ return TRUE;
+ } else { //종성조합가능자음
+ current_state = NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE; //NEXT_STATE로 NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE Setting
+ ACTION_ERROR_CHO_2_NOCHO_NOJUNG_DOUBLEJONG(djong_idx, p_madecode); //ERROR 처리
+ return TRUE;
+ }
+
+ } else { //입력문자가 모음이면
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_2_CHO_JUNG(p_SIPKey, p_madecode); //CHO_STATE에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ }
+ break;
+
+ case CHO_JUNG_STATE : //current_State 가 CHO_JUNG_STATE 일 경우
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ if (g_makecode.jung_idx < 2) { //조합중인 모음이 '.', '..'이면
+ current_state = CHO_STATE;
+ ACTION_ERROR_CHO_JUNG_2_CHO(p_SIPKey, p_madecode); //ERROR 처리
+ return TRUE;
+ } else if (CANTJONGTable[p_SIPKey] == FALSE) { //종성불가자음 자음이면
+ if (b3X4KeyRotated) {
+ current_state = CHO_JUNG_CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_CHO_JUNG_2_CHO_JUNG_CHO(p_SIPKey, p_madecode); //CHO_JUNG_STATE에서 CHO_STATE로 가는 ACTION 수행
+ } else {
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_CHO_JUNG_2_CHO(p_SIPKey, p_madecode); //CHO_JUNG_STATE에서 CHO_STATE로 가는 ACTION 수행
+ }
+ return TRUE;
+ } else { //종성불가 자음이 아니면
+ current_state = CHO_JUNG_SINGLEJONG_STATE; //NEXT_STATE로 CHO_JUNG_SINGLEJONG Setting
+ ACTION_CHO_JUNG_2_CHO_JUNG_SINGLEJONG(p_SIPKey, p_madecode); //CHO_JUNG_STATE에서 CHO_JUNG_SINGLEJONG로 가는 ACTION 수행
+ return TRUE;
+ }
+
+ } else { //입력문자가 모음이면
+ int idx = MOEUMAutomata[g_makecode.jung_idx][p_SIPKey]; //모음 오토마타를 이용해 조합된 모음의 중성 Index를 얻는다.
+ if (idx == COMBINATION_FAIL) { //중성조합불가모음
+ /* 모음 조합이 안되는 경우 입력을 받지 않도록 변경.*/
+ /* 단 'ㅓ','ㅗ'후에 '.'이 들어온 경우에는 예외처리를 해준다. */
+ if (g_makecode.jung_idx == U_MOEUM_AUTOMATA_INDEX && p_SIPKey == SIPKEY_IDX0) { /* ㅓ */
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_JUNG_2_CHO_JUNG(p_SIPKey, YEO_MOEUM_AUTOMATA_INDEX, p_madecode); //CHO_JUNG_STATE에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ } else if (g_makecode.jung_idx == O_MOEUM_AUTOMATA_INDEX && p_SIPKey == SIPKEY_IDX0) { /* ㅗ */
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_JUNG_2_CHO_JUNG(p_SIPKey, YO_MOEUM_AUTOMATA_INDEX, p_madecode); //CHO_JUNG_STATE에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ } else {
+ //popFromAutomataHistoryStack();
+ current_state = NOCHO_JUNG_ERROR_STATE;
+ ACTION_ERROR_CHO_JUNG_2_NOCHO_JUNG(p_SIPKey, p_madecode); //ERROR 처리
+ return FALSE;
+ }
+
+ } else { //중성조합가능모음
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_JUNG_2_CHO_JUNG(p_SIPKey, idx, p_madecode); //CHO_JUNG_STATE에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ }
+ }
+ break;
+
+ case CHO_JUNG_CHO_STATE : //current_State 가 CHO_JUNG_CHO_STATE 일 경우
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_CHO_JUNG_CHO_2_CHO(p_SIPKey, p_madecode);
+ } else { //입력문자가 모음이면
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_JUNG_CHO_2_CHO_JUNG(p_SIPKey, p_madecode); //CHO_STATE에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ }
+ break;
+ case CHO_JUNG_SINGLEJONG_CHO_STATE : //current_State 가 CHO_JUNG_CHO_STATE 일 경우
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO(p_SIPKey, p_madecode);
+ } else { //입력문자가 모음이면
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO_JUNG(p_SIPKey, p_madecode); //CHO_STATE에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ }
+ break;
+
+
+ case CHO_JUNG_SINGLEJONG_STATE : //current_State 가 CHO_JUNG_SINGLEJONG_STATE 일 경우
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ int djong_idx = getJONGIndexofDJONG_withJONGandSIPKEY(g_makecode.jong_idx, p_SIPKey); //조합된 종성의 인덱스를 가져온다.
+ if (djong_idx == COMBINATION_FAIL) { //종성조합불가자음이면
+ if (getRotationKeyCanBeDOUBLEJONG(g_makecode.jong_idx, p_LastSIPKey)) {
+ current_state = CHO_JUNG_SINGLEJONG_CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_SINGLEJONG_CHO(p_SIPKey, p_madecode); //CHO_JUNG_SINGLEJONG_STATE 에서 CHO_STATE로 가는 ACTION 수행
+ return TRUE;
+ }
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_CHO_JUNG_SINGLEJONG_2_CHO(p_SIPKey, p_madecode); //CHO_JUNG_SINGLEJONG_STATE 에서 CHO_STATE로 가는 ACTION 수행
+ return TRUE;
+ } else { //종성조합가능자음
+ current_state = CHO_JUNG_DOUBLEJONG_STATE; //NEXT_STATE로 CHO_JUNG_DOUBLEJONG Setting
+ ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_DOUBLEJONG(djong_idx, p_madecode); //CHO_JUNG_SINGLEJONG_STATE 에서 CHO_JUNG_DOUBLEJONG로 가는 ACTION 수행
+ return TRUE;
+ }
+ } else { //입력문자가 모음이면
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG(p_SIPKey, p_madecode); //CHO_JUNG_SINGLEJONG에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ }
+ break;
+
+ case CHO_JUNG_DOUBLEJONG_STATE : //current_State 가 CHO_JUNG_SINGLEJONG_STATE 일 경우
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_CHO_JUNG_DOUBLEJONG_2_CHO(p_SIPKey, p_madecode); //CHO_JUNG_DOUBLEJONG_STATE 에서 CHO_STATE로 가는 ACTION 수행
+ return TRUE;
+ } else { //입력문자가 모음이면
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_CHO_JUNG_DOUBLEJONG_2_CHO_JUNG(p_SIPKey, p_madecode); //CHO_JUNG_DOUBLEJONG에서 CHO_JUNG_STATE로 가는 ACTION 수행
+ return TRUE;
+ }
+ break;
+
+
+ case NOCHO_JUNG_ERROR_STATE :
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_ERROR_NOCHO_JUNG_2_CHO(p_SIPKey, p_madecode); //ERROR 처리
+ return TRUE;
+ } else { //입력문자가 모음이면
+ int idx = MOEUMAutomata[g_makecode.jung_idx][p_SIPKey]; //모음 오토마타를 이용해 조합된 모음의 중성 Index를 얻는다.
+ if (idx == COMBINATION_FAIL) { //중성조합불가모음
+ current_state = NOCHO_JUNG_ERROR_STATE;
+ ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_NO(p_SIPKey, p_madecode); //ERROR 처리
+ return TRUE;
+ } else { //중성조합가능모음
+ current_state = NOCHO_JUNG_ERROR_STATE;
+ ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_OK(p_SIPKey, idx, p_madecode); //ERROR 처리
+ return TRUE;
+ }
+ }
+ break;
+
+
+ case NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE :
+ if (p_isJAEUM == TRUE) { //입력문자가 자음이면
+ current_state = CHO_STATE; //NEXT_STATE로 CHO_STATE Setting
+ ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO(p_SIPKey, p_madecode); //ERROR 처리
+ return TRUE;
+ } else { //입력문자가 모음이면
+ current_state = CHO_JUNG_STATE; //NEXT_STATE로 CHO_JUNG_STATE Setting
+ ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO_JUNG(p_SIPKey, p_madecode); //ERROR 처리
+ return TRUE;
+ }
+ break;
+
+ default :
+ break;
+ }
+
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+#endif // CJI_DEBUG
+
+ return FALSE;
+}
+
+#include <memory.h>
+void Backup_Automata()
+{
+ current_state_backup = current_state;
+ g_makecode_backup = g_makecode;
+ memcpy(g_AH_Stack_backup, g_AH_Stack, sizeof(g_AH_Stack_backup));
+ g_AH_Stack_ptr_backup = g_AH_Stack_ptr;
+}
+void Restore_Automata()
+{
+ current_state = current_state_backup;
+ g_makecode = g_makecode_backup;
+ memcpy(g_AH_Stack, g_AH_Stack_backup, sizeof(g_AH_Stack));
+ g_AH_Stack_ptr = g_AH_Stack_ptr_backup;
+}
+
+/**
+* ACTION_EMPTY_2_CHO : EMPTY_STATE에서 CHO_STATE로 갈때 처리
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_EMPTY_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+
+/**
+* ACTION_CHO_2_CHO_JUNG : CHO_STATE에서 CHO_JUNG_STATE로 갈때 처리
+* - 입력
+* p_SIPKey : 모음 - 천 0, 지 1, 인 2
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < 3); //천지인만 허용
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ if (p_SIPKey == CHUN_MOEUM_AUTOMATA_INDEX) { // "." 인 경우 처리
+ g_makecode.size = 2; //조합중인 코드 사이즈 2
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = JUNGUnicodeTable[p_SIPKey]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ }
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+
+/**
+* ACTION_CHO_JUNG_2_CHO_JUNG : CHO_JUNG_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 모음이 계속 조합될 때
+* - 입력
+* p_jung_idx : 중성테이블에서의 인덱스
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_2_CHO_JUNG(short p_SIPKey, short p_jung_idx, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_jung_idx >= 0 && p_jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+ short prev_jung_idx;
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ prev_jung_idx = g_makecode.jung_idx; //이전키의 중성 인덱스를 저장
+ g_makecode.jung_idx = p_jung_idx; //중성인덱스
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ if (p_jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || p_jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ g_makecode.size = 2; //조합중인 코드 사이즈 2
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = JUNGUnicodeTable[p_jung_idx]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ }
+
+ /* Automata History Stack */
+ /* ".." -> ".", "ㅑ"->"ㅏ', "ㅠ"->"ㅜ" 로 토글되는 경우에는 이전 상태를 Stack에서 제거 한다.
+ * "..", "ㅑ", "ㅠ" 를 " ", "ㅣ", "ㅡ" 상태로 만들어 주며 Next SIP 입력으로 현재 Env 저장시 "."이 Stack에 push되어 ".", "ㅏ", "ㅜ"로 복원
+ */
+ if ( ( prev_jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX || prev_jung_idx == I_MOEUM_AUTOMATA_INDEX || prev_jung_idx == B_MOEUM_AUTOMATA_INDEX ) &&
+ (p_SIPKey == SIPKEY_IDX0) ) {
+ popFromAutomataHistoryStack();
+ popFromAutomataHistoryStack();
+ }
+
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_CHO_JUNG_2_CHO : CHO_JUNG_STATE에서 CHO_STATE로 갈때 처리 - 종성불가자음 이 올 때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 1; //조합 완료 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합 완료 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_CHO_JUNG_2_CHO_JUNG_SINGLEJONG : CHO_JUNG_STATE에서 CHO_JUNG_SINGLEJONG_STATE로 갈때 처리 - 종성으로 단일자음 사용
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_2_CHO_JUNG_SINGLEJONG(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.jong_idx = SIPKEY2JONGTable[p_SIPKey]; //입력문자를 종성으로 사용
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, g_makecode.jong_idx); //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+bool ACTION_ERROR_KEY(short p_SIPKey, MADECODE *p_madecode)
+{
+ bool ret = FALSE;
+ if(current_state != EMPTY_STATE) {
+ ret = TRUE;
+ }
+ p_madecode->size = g_makecode.size;
+ p_madecode->ucode[0] = g_makecode.ucode[0];
+ p_madecode->ucode[1] = g_makecode.ucode[1];
+
+ initAutomataEnv();
+
+ return ret;
+}
+
+bool ACTION_BACKSPACE_KEY(short p_SIPKey, MADECODE *p_madecode)
+{
+ switch(current_state) {
+ case EMPTY_STATE:
+ {
+ return FALSE;
+ }
+ break;
+ case CHO_STATE:
+ case CHO_JUNG_SINGLEJONG_STATE:
+ case CHO_JUNG_DOUBLEJONG_STATE:
+ case NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE:
+ case CHO_JUNG_CHO_STATE:
+ case CHO_JUNG_SINGLEJONG_CHO_STATE:
+ {
+ int oldState = current_state;
+ do
+ {
+ popFromAutomataHistoryStack();
+ } while (current_state == oldState && current_state != EMPTY_STATE);
+ }
+ break;
+ case CHO_JUNG_STATE:
+ case NOCHO_JUNG_ERROR_STATE:
+ {
+ if(BS_MOEUMInfo_Automata[g_makecode.jung_idx] != EMPTY_CODE) {
+ g_makecode.jung_idx = BS_MOEUMInfo_Automata[g_makecode.jung_idx];
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ if(current_state == CHO_JUNG_STATE) {
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ } else { /* NOCHO_JUNG_ERROR_STATE */
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx] + COMPENSATE_VALUE_FOR_JUNGUCODE; //조합중인 글자의 유니코드
+ }
+ } else {
+ int oldState = current_state;
+ do
+ {
+ popFromAutomataHistoryStack();
+ } while (current_state == oldState && current_state != EMPTY_STATE);
+ }
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+/**
+* ACTION_CHO_JUNG_2_CHO_JUNG_CHO : CHO_JUNG_STATE에서 CHO_JUNG_CHO_STATE로 갈때 처리 - 초성 입력이지만 조합 완료시키지 않음
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_2_CHO_JUNG_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.next_cho_idx = p_SIPKey; //입력문자를 종성으로 사용
+ g_makecode.size = 2; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.next_cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_CHO_JUNG_CHO_2_CHO : CHO_JUNG_CHO_STATE에서 CHO_STATE로 갈때 처리 - 조합 완료후 새로운 조합 시작
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_CHO_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 2; //조합 완료 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합 완료 글자의 유니코드
+ p_madecode->ucode[1] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.next_cho_idx]]; //조합중인 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+}
+
+/**
+* ACTION_CHO_JUNG_CHO_2_CHO_JUNG : CHO_JUNG_CHO_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 조합 완료후 새로운 조합 시작
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_CHO_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 1; //조합 완료 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합 완료 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = g_makecode.next_cho_idx; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용 //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ if (g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ g_makecode.size = 2; //조합중인 코드 사이즈 2
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = JUNGUnicodeTable[p_SIPKey]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ }
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+}
+
+
+/**
+* ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_SINGLEJONG_CHO : CHO_JUNG_SINGLEJONG_STATE에서 CHO_JUNG_SINGLEJONG_CHO_STATE로 갈때 처리 - 초성 입력이지만 조합 완료시키지 않음
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_SINGLEJONG_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.next_cho_idx = p_SIPKey; //입력문자를 종성으로 사용
+ g_makecode.size = 2; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, g_makecode.jong_idx); //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.next_cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+
+/**
+* ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO : CHO_JUNG_SINGLEJONG_CHO_STATE에서 CHO_STATE로 갈때 처리 - 조합 완료후 새로운 조합 시작
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 2; //조합 완료 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, g_makecode.jong_idx); //조합 완료 글자의 유니코드
+ p_madecode->ucode[1] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.next_cho_idx]]; //조합중인 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+}
+
+/**
+* ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO_JUNG : CHO_JUNG_SINGLEJONG_CHO_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 조합 완료후 새로운 조합 시작
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 1; //조합 완료 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, g_makecode.jong_idx); //조합 완료 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = g_makecode.next_cho_idx; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용 //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ if (g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ g_makecode.size = 2; //조합중인 코드 사이즈 2
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = JUNGUnicodeTable[p_SIPKey]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ }
+
+ /* 완료글자의 종성문자를 조합중인 문자의 초성으로 Automata History Stack에 Push 한다. */
+ int TMPstate = CHO_STATE;
+ MAKECODE TMPcode;
+ TMPcode.cho_idx = g_makecode.cho_idx;
+ TMPcode.size = 1;
+ TMPcode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]];
+ pushEnvToAutomataHistoryStack(TMPstate, TMPcode); //초성의 오토마타 환경을 저장
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+}
+
+/**
+* ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG : CHO_JUNG_SINGLEJONG_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 종성이 나온 상태에서 모음이 나올 때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < 3); //천지인
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 1; //조합 완료 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합 완료 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = JONG2CHOTable[g_makecode.jong_idx]; //조합중인 글자의 종성을 초성으로 사용
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ if (p_SIPKey == CHUN_MOEUM_AUTOMATA_INDEX) { // "." 인 경우 처리
+ g_makecode.size = 2; //조합중인 코드 사이즈 2
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = JUNGUnicodeTable[p_SIPKey]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ }
+
+
+ /* Automata History Stack */
+ /* 완료글자의 종성문자를 조합중인 문자의 초성으로 Automata History Stack에 Push 한다. */
+ int TMPstate = CHO_STATE;
+ MAKECODE TMPcode;
+ TMPcode.cho_idx = g_makecode.cho_idx;
+ TMPcode.size = 1;
+ TMPcode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]];
+ pushEnvToAutomataHistoryStack(TMPstate, TMPcode); //초성의 오토마타 환경을 저장
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_CHO_JUNG_SINGLEJONG_2_CHO : CHO_JUNG_SINGLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 종성조합불가자음이 나올때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_SINGLEJONG_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 1;
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, g_makecode.jong_idx); //조합완료된 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_DOUBLEJONG : CHO_JUNG_SINGLEJONG_STATE에서 CHO_JUNG_DOUBLEJONG_STATE로 갈때 처리 - 종성조합가능자음이 나올때
+* - 입력
+* p_djong_idx : 조합된 이중자음의 index
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+void ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_DOUBLEJONG(short p_djong_idx, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_johapjaeum_idx >= SINGLE_JONG_SIZE && p_johapjaeum_idx < JONG_TABLE_SIZE);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.jong_idx = p_djong_idx; //조합된 이중자음을 종성으로 사용
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, g_makecode.jong_idx); //조합중인 글자의 유니코드
+
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= SINGLE_JONG_SIZE && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+ return;
+}
+
+/**
+* ACTION_CHO_JUNG_DOUBLEJONG_2_CHO_JUNG : CHO_JUNG_DOUBLEJONG_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 조합종성이 나온상태에서 모음이 나올때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_DOUBLEJONG_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < 3);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= SINGLE_JONG_SIZE && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ int tmp_jong_idx = DJONGIndexTable[g_makecode.jong_idx][0]; //이중자음의 제1자음 종성 인덱스를 가져온다.
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, tmp_jong_idx); //조합완료된 글자의 유니코드
+ p_madecode->size = 1;
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = DJONGIndexTable[g_makecode.jong_idx][1]; //조합중인 글자 종성 이중자음의 제2자음을 초성으로 사용
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ if (p_SIPKey == CHUN_MOEUM_AUTOMATA_INDEX) { // "." 인 경우 처리
+ g_makecode.size = 2; //조합중인 코드 사이즈 2
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = JUNGUnicodeTable[p_SIPKey]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ }
+
+
+ /* Automata History Stack */
+
+ /* 완료글자의 종성문자를 조합중인 문자의 초성으로 Automata History Stack에 Push 한다. */
+ int TMPstate = CHO_STATE;
+ MAKECODE TMPcode;
+ TMPcode.cho_idx = g_makecode.cho_idx;
+ TMPcode.size = 1;
+ TMPcode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]];
+ pushEnvToAutomataHistoryStack(TMPstate, TMPcode); //초성의 오토마타 환경을 저장
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_CHO_JUNG_DOUBLEJONG_2_CHO : CHO_JUNG_DOUBLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 조합종성이 나온상태에서 자음이 나올때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_CHO_JUNG_DOUBLEJONG_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < 3);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(g_makecode.jong_idx >= SINGLE_JONG_SIZE && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG_JONG(g_makecode.cho_idx, g_makecode.jung_idx, g_makecode.jong_idx); //조합완료된 글자의 유니코드
+ p_madecode->size = 1;
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+
+ return;
+}
+
+
+/**
+* 초성과 중성으로 이루어진 글자의 Unicode를 얻어온다.
+* !!!! 중성이 '.' 이 올수 있다. madecode 도 크기를 갖도록 수정해야 한다.
+*/
+short getUnicodeWithCHO_JUNG(short p_cho_idx, short p_jung_idx)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_cho_idx >= 0 && p_cho_idx < CHO_TABLE_SIZE);
+ ASSERT(p_jung_idx >= 0 && p_jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return (((p_cho_idx * 21) + p_jung_idx - 2) * 28) + 0xAC00;
+
+}
+
+/**
+* 초성 + 중성 + 종성으로 이루어진 글자의 Unicode를 얻어온다.
+*/
+short getUnicodeWithCHO_JUNG_JONG(short p_cho_idx, short p_jung_idx, short p_jong_idx)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_cho_idx >= 0 && p_cho_idx < CHO_TABLE_SIZE);
+ ASSERT(p_jung_idx >= 0 && p_jung_idx < JUNG_TABLE_SIZE);
+ ASSERT(p_jong_idx >= 0 && p_jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return (((p_cho_idx * 21) + p_jung_idx - 2) * 28) + (p_jong_idx + 1) + 0xAC00;
+
+}
+
+
+/**
+* 종성과 입력된 키가 결합한 이중 자음의 인덱스를 가져온다.
+* 종성과 입력된 SIPKey가 결합되어 이중자음을 생성할 때 사용 : Sparse Matrix 이나 프로그램으로 해결
+* - 입력
+* p_first_jong_idx : 제1자음 - 종성 idx 사용
+* p_second_SIPKEY_idx : 제2자음 - SIPKEY idx 사용
+* - return value : 이중자음의 인덱스 (종성 idx), COMBINATION_FAIL 결합불가
+*/
+
+int getJONGIndexofDJONG_withJONGandSIPKEY(int p_first_jong_idx, int p_second_SIPKEY_idx)
+{
+ switch (p_first_jong_idx) {
+ case 0 : //ㄱ
+ if (p_second_SIPKEY_idx == 9) { //ㅅ
+ return 2; //ㄳ
+ }
+ break;
+ case 3 : //ㄴ
+ switch (p_second_SIPKEY_idx) {
+ case 12 : //ㅈ
+ return 4; //ㄵ
+ case 18 : //ㅎ
+ return 5; //ㄶ
+ default :
+ break;
+ }
+ break;
+ case 7 : //ㄹ
+ switch (p_second_SIPKEY_idx) {
+ case 0 : //ㄱ
+ return 8; //ㄺ
+ case 6 : //ㅁ
+ return 9; //ㄻ
+ case 7 : //ㅂ
+ return 10; //ㄼ
+ case 9 : //ㅅ
+ return 11; //ㄽ
+ case 16 : //ㅌ
+ return 12; //ㄾ
+ case 17 : //ㅍ
+ return 13; //ㄿ
+ case 18 : //ㅎ
+ return 14; //ㅀ
+ default :
+ break;
+ }
+ break;
+ case 16 : //ㅂ
+ if (p_second_SIPKEY_idx == 9) { //ㅅ
+ return 17;
+ }
+ break;
+ default :
+ break;
+ }
+
+ return COMBINATION_FAIL;
+}
+
+
+
+/**
+* 초성과 입력된 키가 결합한 이중 자음의 종성 인덱스를 가져온다.
+* - 초성에 이중자음이 나올 경우에 처리하기 위해 사용 : Sparse Matrix 이나 프로그램으로 해결
+* - 입력
+* p_first_cho_idx : 제1자음 - 초성 idx 사용
+* p_second_SIPKEY_idx : 제2자음 - SIPKEY idx 사용
+* - return value : 이중자음의 인덱스 (종성 idx), COMBINATION_FAIL 결합불가
+*/
+
+int getJONGIndexofDJONG_withCHOandSIPKEY(int p_first_cho_idx, int p_second_SIPKEY_idx)
+{
+ //switch (p_first_cho_idx) {
+ //case 0 : //ㄱ
+ // if (p_second_SIPKEY_idx == 9) { //ㅅ
+ // return 2; //ㄳ
+ // }
+ // break;
+ //case 2 : //ㄴ
+ // switch (p_second_SIPKEY_idx) {
+ // case 12 : //ㅈ
+ // return 4; //ㄵ
+ // case 18 : //ㅎ
+ // return 5; //ㄶ
+ // default :
+ // break;
+ // }
+ // break;
+ //case 5 : //ㄹ
+ // switch (p_second_SIPKEY_idx) {
+ // case 0 : //ㄱ
+ // return 8; //ㄺ
+ // case 6 : //ㅁ
+ // return 9; //ㄻ
+ // case 7 : //ㅂ
+ // return 10; //ㄼ
+ // case 9 : //ㅅ
+ // return 11; //ㄽ
+ // case 16 : //ㅌ
+ // return 12; //ㄾ
+ // case 17 : //ㅍ
+ // return 13; //ㄿ
+ // case 18 : //ㅎ
+ // return 14; //ㅀ
+ // default :
+ // break;
+ // }
+ //case 7 : //ㅂ
+ // if (p_second_SIPKEY_idx == 9) { //ㅅ
+ // return 17; //ㅄ
+ // }
+ // break;
+ //default :
+ // break;
+ //}
+
+ return COMBINATION_FAIL;
+}
+
+
+int getRotationKeyCanBeDOUBLEJONG(int p_first_jong_idx, int p_second_SIPKEY_idx)
+{
+ if (p_second_SIPKEY_idx >= SIPKEY_3X4_KEY_START && p_second_SIPKEY_idx <= SIPKEY_3X4_KEY_END) {
+ if (p_first_jong_idx >= 0 && p_first_jong_idx < JONG_TABLE_SIZE) {
+ return RotationKey_CanBe_DOUBLEJONG[p_first_jong_idx][p_second_SIPKEY_idx - SIPKEY_3X4_KEY_START];
+ }
+ }
+
+ return FALSE;
+}
+
+//--------------------------------- ERROR 처리 부분 --------------------------------------------------------
+
+/**
+*ACTION_ERROR_EMPTY_2_NOCHO_JUNG : EMPTY_STATE에서 NOCHO_JUNG_ERROR_STATE로 갈때 처리 - 초성없이 모음이 나올 떄
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_EMPTY_2_NOCHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < 3);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용
+ g_makecode.cho_idx = EMPTY_CODE; //초성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ if (g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 2
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 1
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx] + COMPENSATE_VALUE_FOR_JUNGUCODE; //조합중인 글자의 유니코드
+ }
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_ERROR_CHO_2_CHO : CHO_STATE에서 CHO_STATE로 갈때 처리 - 초성 자음 뒤에 그것과 결합할 수 없는 초성 자음이 나옴
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_CHO_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합완료된 글자의 유니코드
+ p_madecode->size = 1;
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+ return;
+}
+
+/**
+* ACTION_ERROR_CHO_2_NOCHO_NOJUNG_DOUBLEJONG : CHO_STATE 에서 NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE로 갈때 처리 - 초성과 중성 없이 조합종성이 만들어 지는 상태
+* - 입력
+* p_djong_index : 조합된 이중자음의 index
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_CHO_2_NOCHO_NOJUNG_DOUBLEJONG(int p_djong_idx, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ g_makecode.jong_idx = p_djong_idx; //이중자음을 종성으로 사용
+ g_makecode.cho_idx = EMPTY_CODE; //초성은 비어있음
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[JONG2HCJAMOTable[p_djong_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_ERROR_CHO_JUNG_2_CHO : CHO_JUNG_STATE에서 CHO_STATE로 갈때 처리 - 초중에서 자음이 나왔으나 앞에 모음이 천('.') 또는 천천('..') 일때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_CHO_JUNG_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 2; //조합 완료된 글자의 코드 사이즈 2
+ p_madecode->ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합 완료된 글자의 유니코드
+ p_madecode->ucode[1] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합 완료된 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+ return;
+}
+
+/**
+* ACTION_ERROR_CHO_JUNG_2_NOCHO_JUNG : CHO_JUNG_STATE에서 NOCHO_JUNG_STATE로 갈때 처리 - 초중상태에서 모음 조합중 결합하지 못하는 모음이 나올 떄
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_CHO_JUNG_2_NOCHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ // Pre Condition
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < 3);
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ // 조합완료 문자만들기
+ if(g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ p_madecode->size = 2; //조합 완료된 글자의 코드 사이즈 2
+ p_madecode->ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합 완료된 글자의 유니코드
+ p_madecode->ucode[1] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합 완료된 글자의 유니코드
+ } else {
+ p_madecode->size = 1; //조합 완료된 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합 완료된 글자의 유니코드
+ }
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ // 조합중인 문자만들기
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용
+ g_makecode.cho_idx = EMPTY_CODE; //초성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ if(g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 2
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 1
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx] + COMPENSATE_VALUE_FOR_JUNGUCODE; //조합중인 글자의 유니코드
+ }
+
+#ifdef CJI_DEBUG
+ // Post Condition
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+ return;
+}
+
+
+/**
+* ACTION_ERROR_NOCHO_JUNG_2_CHO : NOCHO_JUNG_STATE에서 CHO_STATE로 갈때 처리 - 초성없이 모음 조합중 자음이 나올때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_NOCHO_JUNG_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ if (g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ p_madecode->size = 1; //조합 완료된 글자의 코드 사이즈 2
+ p_madecode->ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합 완료된 글자의 유니코드
+ } else {
+ p_madecode->size = 1; //조합 완료된 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx] + COMPENSATE_VALUE_FOR_JUNGUCODE; //조합 완료된 글자의 유니코드
+ }
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+ return;
+}
+
+/**
+* ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_NO : NOCHO_JUNG_STATE에서 NOCHO_JUNG_STATE로 갈때 처리 - 초성없이 모음 조합중 결합할 수 없는 모음이 나왔을 때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_NO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ if (g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ p_madecode->size = 1; //조합 완료된 글자의 코드 사이즈 2
+ p_madecode->ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합 완료된 글자의 유니코드
+ } else {
+ p_madecode->size = 1; //조합 완료된 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx] + COMPENSATE_VALUE_FOR_JUNGUCODE; //조합 완료된 글자의 유니코드
+ }
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용
+ g_makecode.cho_idx = EMPTY_CODE; //초성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ if (g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 2
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 1
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx] + COMPENSATE_VALUE_FOR_JUNGUCODE; //조합중인 글자의 유니코드
+ }
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+ return;
+}
+
+/**
+* ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_OK : NOCHO_JUNG_STATE에서 NOCHO_JUNG_STATE로 갈때 처리 - 초성없이 모음 조합중 결합 가능한 모음이 나올 때
+* - 입력
+* p_jung_idx : 중성 인덱스
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_OK(short p_SIPKey, int p_jung_idx, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+ short prev_jung_idx;
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = IN_COMPOSITION; //조합중이어서 조합완료된 코드가 없음을 표시
+
+ /* 조합중인 문자만들기 */
+ prev_jung_idx = g_makecode.jung_idx; //이전상태의 중성을 backup
+ g_makecode.jung_idx = p_jung_idx; //입력문자를 중성으로 사용
+ g_makecode.cho_idx = EMPTY_CODE; //초성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ if (g_makecode.jung_idx == CHUN_MOEUM_AUTOMATA_INDEX || g_makecode.jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX) { // "." 이거나 ".." 인 경우 처리
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 2
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 글자의 코드 사이즈 1
+ g_makecode.ucode[0] = JUNGUnicodeTable[g_makecode.jung_idx] + COMPENSATE_VALUE_FOR_JUNGUCODE; //조합중인 글자의 유니코드
+ }
+
+ /* Automata History Stack */
+ /* ".." -> ".", "ㅑ"->"ㅏ', "ㅠ"->"ㅜ" 로 토글되는 경우에는 이전 상태를 Stack에서 제거 한다.
+ * "..", "ㅑ", "ㅠ" 를 " ", "ㅣ", "ㅡ" 상태로 만들어 주며 Next SIP 입력으로 현재 Env 저장시 "."이 Stack에 push되어 ".", "ㅏ", "ㅜ"로 복원
+ */
+ if ( ( prev_jung_idx == CHUN_CHUN_MOEUM_AUTOMATA_INDEX || prev_jung_idx == I_MOEUM_AUTOMATA_INDEX || prev_jung_idx == B_MOEUM_AUTOMATA_INDEX ) &&
+ (p_SIPKey == SIPKEY_IDX0) ) {
+ popFromAutomataHistoryStack();
+ popFromAutomataHistoryStack();
+ }
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO : NOCHO_NOJUNG_DOUBLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 초성과 중성없이 조합종성이 나온상태에서 자음이 나올때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_makecode.jong_idx >= 0 && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ p_madecode->size = 1; //조합 완료된 글자의 코드 사이즈 1
+ p_madecode->ucode[0] = HCJAMOUnicodeTable[JONG2HCJAMOTable[g_makecode.jong_idx]]; //조합 완료된 글자의 유니코드
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = p_SIPKey; //입력문자를 초성으로 사용
+ g_makecode.jung_idx = EMPTY_CODE; //중성은 비어있음
+ g_makecode.jong_idx = EMPTY_CODE; //종성은 비어있음
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+*ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO_JUNG : NOCHO_NOJUNG_DOUBLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 초성과 중성없이 조합종성이 나온상태에서 모음이 나올때
+* - 입력
+* p_SIPKey : SIP 에서 들어온 입력 값 (SIPKEY)
+* - 출력
+* g_makecode : 조합중인 글자의 크기와 유니코드 값
+* p_madecode : 조합완료된 글자의 크기와 유니코드 값
+*/
+
+void ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode)
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_SIPKey >= 0 && p_SIPKey < 3);
+ ASSERT(g_makecode.jong_idx >= SINGLE_JONG_SIZE && g_makecode.jong_idx < JONG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+ /* 조합완료 문자만들기 */
+ int tmp_jong_idx = DJONGIndexTable[g_makecode.jong_idx][0]; //이중자음의 제1자음 종성 인덱스를 가져온다.
+ p_madecode->ucode[0] = HCJAMOUnicodeTable[JONG2HCJAMOTable[tmp_jong_idx]]; //조합완료된 글자의 유니코드
+ p_madecode->size = 1;
+ initAutomataHistoryStack(); //조합완료에 의한 History Stack clear
+
+ /* 조합중인 문자만들기 */
+ g_makecode.cho_idx = DJONGIndexTable[g_makecode.jong_idx][1]; //조합중인 글자 종성 이중자음의 제2자음을 초성으로 사용
+ g_makecode.jung_idx = MOEUMAutomata[MOEUM_EMPTY][p_SIPKey]; //입력문자를 중성으로 사용
+ g_makecode.jong_idx = EMPTY_CODE;
+ if (p_SIPKey == CHUN_MOEUM_AUTOMATA_INDEX) { // "." 인 경우 처리
+ g_makecode.size = 2; //조합중인 코드 사이즈 2
+ g_makecode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]]; //조합중인 글자의 유니코드
+ g_makecode.ucode[1] = JUNGUnicodeTable[p_SIPKey]; //조합중인 글자의 유니코드
+ } else {
+ g_makecode.size = 1; //조합중인 코드 사이즈 1
+ g_makecode.ucode[0] = getUnicodeWithCHO_JUNG(g_makecode.cho_idx, g_makecode.jung_idx); //조합중인 글자의 유니코드
+ }
+
+ /* Automata History Stack */
+
+ /* 완료글자의 종성문자를 조합중인 문자의 초성으로 Automata History Stack에 Push 한다. */
+ int TMPstate = CHO_STATE;
+ MAKECODE TMPcode;
+ TMPcode.cho_idx = g_makecode.cho_idx;
+ TMPcode.size = 1;
+ TMPcode.ucode[0] = HCJAMOUnicodeTable[CHO2HCJAMOTable[g_makecode.cho_idx]];
+ pushEnvToAutomataHistoryStack(TMPstate, TMPcode); //초성의 오토마타 환경을 저장
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_makecode.cho_idx >= 0 && g_makecode.cho_idx < CHO_TABLE_SIZE);
+ ASSERT(g_makecode.jung_idx >= 0 && g_makecode.jung_idx < JUNG_TABLE_SIZE);
+#endif // CJI_DEBUG
+
+
+ return;
+}
+
+
+//----------------------------- Back Space를 처리하기 위한 Automata History Stack 관련 함수 ------------------------------
+
+/**
+* initializeAutomataHistoryStack : Automata History Stack 을 초기화 한다.
+* Stack의 Bottom 부분에 dummy 를 넣어 준다.
+*/
+void initAutomataHistoryStack()
+{
+ g_AH_Stack[0].state = EMPTY_STATE;
+ g_AH_Stack[0].makecode.size = 0;
+ g_AH_Stack[0].makecode.cho_idx = EMPTY_CODE;
+ g_AH_Stack[0].makecode.jung_idx = EMPTY_CODE;
+ g_AH_Stack[0].makecode.jong_idx = EMPTY_CODE;
+
+ g_AH_Stack_ptr = 0;
+
+ return;
+}
+
+/**
+* pushCurrentEnvToAutomataHistoryStack : 오토마타와 관련된 환경을 Automata History Stack 에 push 한다.
+* sunny 컴멘트는 optimize code로 나중에 확인하고 넣어 주자.
+*/
+void pushEnvToAutomataHistoryStack(int p_state, MAKECODE p_tmp_makecode)
+{
+
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(p_state > EMPTY_STATE);
+#endif // CJI_DEBUG
+
+ g_AH_Stack_ptr++;
+
+ g_AH_Stack[g_AH_Stack_ptr].state = p_state;
+ g_AH_Stack[g_AH_Stack_ptr].makecode.size = p_tmp_makecode.size;
+ g_AH_Stack[g_AH_Stack_ptr].makecode.ucode[0] = p_tmp_makecode.ucode[0];
+ g_AH_Stack[g_AH_Stack_ptr].makecode.ucode[1] = p_tmp_makecode.ucode[1];
+ g_AH_Stack[g_AH_Stack_ptr].makecode.cho_idx = p_tmp_makecode.cho_idx;
+ g_AH_Stack[g_AH_Stack_ptr].makecode.jung_idx = p_tmp_makecode.jung_idx;
+ g_AH_Stack[g_AH_Stack_ptr].makecode.jong_idx = p_tmp_makecode.jong_idx;
+
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_AH_Stack_ptr < MAX_AUTOMATA_HISTORY_LENGTH);
+#endif // CJI_DEBUG
+
+ return;
+}
+
+/**
+* popFromAutomataHistoryStack
+* - 오토마타의 이전 환경을 Automata History Stack에서 가져와서 오토마타의 상태와 조합중 코드(current_state, g_makecode)를 이전 환경로 복원한다.
+* - Stack pop을 통해 오토마타를 이전 환경으로 되돌린다.
+*/
+void popFromAutomataHistoryStack()
+{
+#ifdef CJI_DEBUG
+ /* Pre Condition */
+ ASSERT(g_AH_Stack_ptr > 0);
+#endif // CJI_DEBUG
+
+ //if (g_AH_Stack_ptr < 0) { //EMPTY STATE
+ if (g_AH_Stack_ptr <= 0) { //EMPTY STATE
+ current_state = EMPTY_STATE;
+ g_makecode.size = 0;
+ } else {
+ /* 오토마타의 상태와 조합중 코드를 이전환경으로 되돌림 */
+ current_state = g_AH_Stack[g_AH_Stack_ptr].state;
+ g_makecode.size = g_AH_Stack[g_AH_Stack_ptr].makecode.size;
+ g_makecode.ucode[0] = g_AH_Stack[g_AH_Stack_ptr].makecode.ucode[0];
+ g_makecode.ucode[1] = g_AH_Stack[g_AH_Stack_ptr].makecode.ucode[1];
+ g_makecode.cho_idx = g_AH_Stack[g_AH_Stack_ptr].makecode.cho_idx;
+ g_makecode.jung_idx = g_AH_Stack[g_AH_Stack_ptr].makecode.jung_idx;
+ g_makecode.jong_idx = g_AH_Stack[g_AH_Stack_ptr].makecode.jong_idx;
+
+ /* Stack pop */
+ g_AH_Stack_ptr--;
+ }
+
+#ifdef CJI_DEBUG
+ /* Post Condition */
+ ASSERT(g_AH_Stack[g_AH_Stack_ptr].state > 0);
+#endif // CJI_DEBUG
+
+ return;
+
+}
+
+/**
+* initAutomataEnv : Automata의 환경을 초기화 한다.
+* - Automata 관련 전역변수 초기화
+* - Automata History Stack 초기화
+*/
+void initAutomataEnv()
+{
+ current_state = EMPTY_STATE; //current state 초기화
+ g_makecode.size = 0;
+ g_makecode.cho_idx = EMPTY_CODE;
+ g_makecode.jung_idx = EMPTY_CODE;
+ g_makecode.jong_idx = EMPTY_CODE;
+ g_makecode.ucode[0] = 0;
+ g_makecode.ucode[1] = 0;
+ initAutomataHistoryStack();
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _CJI_
+#define _CJI_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define NUMBER_OF_STATE 9 /* STATE의 수 Iegal state 7 + illegal state 2*/
+
+ /**
+ * STATE 정의
+ * 1 : EMPTYial State - 한글 조합문자와 백스페이스 이외의 문자가 들어 온 상태
+ * 2 : 초성 - 초성을 조합하고 있는 상태
+ * 3 : 초성 + 중성 - 중성을 조합하고 있는 상태
+ * 4 : 초성 + 중성 + 단일종성 - 종성을 조합하고 있는 상태
+ * 5 : 초성 + 중성 + 조합종성 - 종성이 완료되었으나 제 2자음이 초성으로 쓰일지 종성으로 쓰일지 모르는 상태
+ * 6 : 초성 + 중성 이후 입력된 자음이 Rotation Key 로 인해 마지막 자음이 초성으로 쓰일지 종성으로 쓰일지 모르는 상태
+ * 7 : 초성 + 중성 + 단일종성 이후 입력된 자음이 Rotation Key 로 인해 마지막 자음이 초성으로 쓰일지 종성으로 쓰일지 모르는 상태
+ * 8 : 초성 없이 중성이 온 상태
+ * 9 : 초성 + 중성 없이 이중자음형태의 종성이 온 상태
+ */
+#define EMPTY_STATE 1
+#define CHO_STATE 2
+#define CHO_JUNG_STATE 3
+#define CHO_JUNG_SINGLEJONG_STATE 4
+#define CHO_JUNG_DOUBLEJONG_STATE 5
+#define CHO_JUNG_CHO_STATE 6
+#define CHO_JUNG_SINGLEJONG_CHO_STATE 7
+#define NOCHO_JUNG_ERROR_STATE 8
+#define NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE 9
+
+
+ /**
+ * 사용용어정의
+ * 1. 단자음 : 하나로 이루어진 자음 11개 - ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅊㅋㅌㅍㅎ
+ * 2. 복자음 : 같은 자음 두개 로 이루어진다 5개 - ㄲㄸㅃㅆㅉ
+ * 3. 단일처리자음 : 단자음 + 복자음 으로 백스페이스로 지워지는 단위이다.
+ * 4. 이중자음 : 다른 자음 두개로 이루진다. 앞에 자음을 제 1자음, 뒤에 자음을 제 2자음이라 한다. 11개 - ㄳㄵㄶㄺㄻㄼㄽㄾㄿㅀㅄ
+ * 5. 단모음 : 키보드 상의 모음으로 하나의 처리단위로 백스페이스로 지워지는 단위이다. 14개 -ㅏ ㅑ ㅓ ㅕ ㅗ ㅛ ㅜ ㅠ ㅡ l ㅔ ㅐ ㅖ ㅒ
+ * 6. 이중모음 : 단모음으로 조합이 가능한 이중 모음, 앞의 모음을 제 1모음, 뒤의 모음을 제 2모음이라 한다. 7개 - ㅘ ㅙ ㅚ ㅝ ㅞ ㅟ ㅢ
+ */
+
+ /**
+ * SIPKEY LIST
+ * 사용하는 SIP(Software Input Panel) key의 인덱스 값 정의
+ * 자음과 모음은 isJaeum flag를 이용하여 구분한다.
+ */
+
+#define SIPKEY_IDX0 0 /* ㄱ */ /* . (천) */
+#define SIPKEY_IDX1 1 /* ㄲ */ /* ㅡ (지) */
+#define SIPKEY_IDX2 2 /* ㄴ */ /* ㅣ (인) */
+#define SIPKEY_IDX3 3 /* ㄷ */ /* ㅏ */
+#define SIPKEY_IDX4 4 /* ㄸ */ /* ㅑ */
+#define SIPKEY_IDX5 5 /* ㄹ */ /* ㅓ */
+#define SIPKEY_IDX6 6 /* ㅁ */ /* ㅕ */
+#define SIPKEY_IDX7 7 /* ㅂ */ /* ㅗ */
+#define SIPKEY_IDX8 8 /* ㅃ */ /* ㅛ */
+#define SIPKEY_IDX9 9 /* ㅅ */ /* ㅜ */
+#define SIPKEY_IDX10 10 /* ㅆ */ /* ㅠ */
+#define SIPKEY_IDX11 11 /* ㅇ */ /* ㅡ */
+#define SIPKEY_IDX12 12 /* ㅈ */ /* ㅣ */
+#define SIPKEY_IDX13 13 /* ㅉ */ /* ㅐ */
+#define SIPKEY_IDX14 14 /* ㅊ */ /* ㅔ */
+#define SIPKEY_IDX15 15 /* ㅋ */ /* ㅒ */
+#define SIPKEY_IDX16 16 /* ㅌ */ /* ㅖ */
+#define SIPKEY_IDX17 17 /* ㅍ */
+#define SIPKEY_IDX18 18 /* ㅎ */
+
+/* 3x4 keys */
+#define SIPKEY_IDX19 19 /* 3x4 4 Key */
+#define SIPKEY_IDX20 20 /* 3x4 5 Key */
+#define SIPKEY_IDX21 21 /* 3x4 6 Key */
+#define SIPKEY_IDX22 22 /* 3x4 7 Key */
+#define SIPKEY_IDX23 23 /* 3x4 8 Key */
+#define SIPKEY_IDX24 24 /* 3x4 9 Key */
+#define SIPKEY_IDX25 25 /* 3x4 0 Key */
+
+
+/* 3x4 key rotational table */
+#define SIPKEY_BACKSPACE -2
+#define SIPKEY_ERROR -1
+#define SIPKEY_3X4_KEY_ROTATION_CANIDATE_NUM 3
+#define SIPKEY_3X4_KEY_START SIPKEY_IDX19
+#define SIPKEY_3X4_KEY_END SIPKEY_IDX25
+#define SIPKEY_3X4_KEY_NUM (SIPKEY_3X4_KEY_END - SIPKEY_3X4_KEY_START + 1)
+
+ const static int SIPKEY3X4RotationTable[SIPKEY_3X4_KEY_NUM][SIPKEY_3X4_KEY_ROTATION_CANIDATE_NUM] = {
+ {SIPKEY_IDX0, SIPKEY_IDX15, SIPKEY_IDX1}, /* 3x4 4 Key */
+ {SIPKEY_IDX2, SIPKEY_IDX5, SIPKEY_ERROR}, /* 3x4 5 Key */
+ {SIPKEY_IDX3, SIPKEY_IDX16, SIPKEY_IDX4}, /* 3x4 6 Key */
+ {SIPKEY_IDX7, SIPKEY_IDX17, SIPKEY_IDX8}, /* 3x4 7 Key */
+ {SIPKEY_IDX9, SIPKEY_IDX18, SIPKEY_IDX10}, /* 3x4 8 Key */
+ {SIPKEY_IDX12, SIPKEY_IDX14, SIPKEY_IDX13}, /* 3x4 9 Key */
+ {SIPKEY_IDX11, SIPKEY_IDX6, SIPKEY_ERROR}, /* 3x4 0 Key */
+ };
+
+ /**
+ * SIPKEY Unicode 값 정의
+ */
+
+#define SIPKEY_TABLE_SIZE 19 /* 단자음 (14) + 복자음 (5) */
+
+ const static short SIPKEYUnicodeTable[SIPKEY_TABLE_SIZE] = {
+ 0x1100, /* 0 ㄱ */
+ 0x1101, /* 1 ㄲ */
+ 0x1102, /* 2 ㄴ */
+ 0x1103, /* 3 ㄷ */
+ 0x1104, /* 4 ㄸ */
+ 0x1105, /* 5 ㄹ */
+ 0x1106, /* 6 ㅁ */
+ 0x1107, /* 7 ㅂ */
+ 0x1108, /* 8 ㅃ */
+ 0x1109, /* 9 ㅅ */
+ 0x110A, /* 10 ㅆ */
+ 0x110B, /* 11 ㅇ */
+ 0x110C, /* 12 ㅈ */
+ 0x110D, /* 13 ㅉ */
+ 0x110E, /* 14 ㅊ */
+ 0x110F, /* 15 ㅋ */
+ 0x1110, /* 16 ㅌ */
+ 0x1111, /* 17 ㅍ */
+ 0x1112, /* 18 ㅎ */
+ };
+
+ /**
+ * 초성의 Unicode 값 정의
+ * SIPKEY 와 alias 한다.
+ */
+#define CHO_TABLE_SIZE SIPKEY_TABLE_SIZE
+
+
+ /**
+ * 중성의 Unicode 값 정의
+ */
+
+#define JUNG_TABLE_SIZE 23 /* 천(1) + 천천(1) + 단모음 (14) + 이중모음(7) = 23 */
+
+ const static short JUNGUnicodeTable[JUNG_TABLE_SIZE] = {
+ 0x00B7, /* 0 .(천) */ //0x119E 0x00B7 '.'
+ 0x2025, /* 1 ..(천천) */ //0x11A2 0x2025 '..'
+ 0x1161, /* 2 ㅏ */
+ 0x1162, /* 3 ㅐ */
+ 0x1163, /* 4 ㅑ */
+ 0x1164, /* 5 ㅒ */
+ 0x1165, /* 6 ㅓ */
+ 0x1166, /* 7 ㅔ */
+ 0x1167, /* 8 ㅕ */
+ 0x1168, /* 9 ㅖ */
+ 0x1169, /* 10 ㅗ */
+ 0x116a, /* 11 ㅘ */
+ 0x116b, /* 12 ㅙ */
+ 0x116c, /* 13 ㅚ */
+ 0x116d, /* 14 ㅛ */
+ 0x116e, /* 15 ㅜ */
+ 0x116f, /* 16 ㅝ */
+ 0x1170, /* 17 ㅞ */
+ 0x1171, /* 18 ㅟ */
+ 0x1172, /* 19 ㅠ */
+ 0x1173, /* 20 ㅡ */
+ 0x1174, /* 21 ㅢ */
+ 0x1175, /* 22 ㅣ */
+
+ };
+
+
+ /**
+ * 모음 오토마타
+ * - 현재 모음과 입력된 모음(천지인)이 결합하여 생성되는 모음의 index를 표시
+ * - COMBINATION_FAIL 은 결합 불가능을 표시
+ */
+
+#define MOEUMAUTOMATA_TABLE_SIZE JUNG_TABLE_SIZE+1 /* 중성 + Empty State */
+#define COMBINATION_FAIL -1 /* 모음 결합 실패 */
+
+#define CHUN_MOEUM_AUTOMATA_INDEX 0
+#define CHUN_CHUN_MOEUM_AUTOMATA_INDEX 1
+#define I_MOEUM_AUTOMATA_INDEX 4 //'ㅑ'의 인덱스 - '.'에 의한 토글을 처리하기 위해
+#define B_MOEUM_AUTOMATA_INDEX 19 //'ㅠ'의 인덱스 - '.'에 의한 토글을 처리하기 위해
+
+#define U_MOEUM_AUTOMATA_INDEX 6 //'ㅓ'의 인덱스 - 'ㅕ' 처리하기 위해
+#define O_MOEUM_AUTOMATA_INDEX 10 //'ㅗ'의 인덱스 - 'ㅛ' 처리하기 위해
+#define YEO_MOEUM_AUTOMATA_INDEX 8 //'ㅕ'의 인덱스
+#define YO_MOEUM_AUTOMATA_INDEX 14 //'ㅛ'의 인덱스
+
+#define MOEUM_EMPTY 23
+
+ const static int MOEUMAutomata[MOEUMAUTOMATA_TABLE_SIZE][17] = {
+/* .(천) 지(ㅡ) 인(ㅣ) ㅏ ㅑ ㅓ ㅕ ㅗ ㅛ ㅜ ㅠ ㅡ ㅣ ㅐ ㅔ ㅒ ㅖ */
+/* 0 .(천) */ {1, 10, 6, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 1 ..(천천) */ {0, 14, 8, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 2 ㅏ */ {4, COMBINATION_FAIL, 3, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 3 ㅐ */ {5, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 4 ㅑ */ {2, COMBINATION_FAIL, 5, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 5 ㅒ */ {3, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 6 ㅓ */ {8, COMBINATION_FAIL, 7, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 7 ㅔ */ {9 , COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 8 ㅕ */ {6, COMBINATION_FAIL, 9, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 9 ㅖ */ {7, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 10 ㅗ */ {COMBINATION_FAIL, COMBINATION_FAIL, 13, 11, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, 13, 12, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 11 ㅘ */ {COMBINATION_FAIL, COMBINATION_FAIL, 12, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 12 ㅙ */ {COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 13 ㅚ */ {11, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 14 ㅛ */ {10, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 15 ㅜ */ {19, COMBINATION_FAIL, 18, COMBINATION_FAIL, COMBINATION_FAIL, 16, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, 18, COMBINATION_FAIL, 17, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 16 ㅝ */ {COMBINATION_FAIL, COMBINATION_FAIL, 17, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 17 ㅞ */ {COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 18 ㅟ */ {16, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 19 ㅠ */ {15, COMBINATION_FAIL, 16, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 20 ㅡ */ {15, COMBINATION_FAIL, 21, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, 21, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 21 ㅢ */ {COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 22 ㅣ */ {2, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL, COMBINATION_FAIL},
+/* 23 EMPTY */ {0, 20, 22, 2, 4, 6, 8, 10, 14, 15, 19, 20, 22, 3, 7, 5, 9,},
+ };
+
+
+ /**
+ * 종성의 Unicode 값 정의
+ */
+
+#define JONG_TABLE_SIZE 27 /* 단자음 (14) + 복자음 (ㄲ, ㅆ) + 이중자음(11) = 27*/
+
+ const static short JONGUnicodeTable[JONG_TABLE_SIZE] = {
+ 0x11A8, /* 0 ㄱ */
+ 0x11A9, /* 1 ㄲ */
+ 0x11AA, /* 2 ㄳ */
+ 0x11AB, /* 3 ㄴ */
+ 0x11AC, /* 4 ㄵ */
+ 0x11AD, /* 5 ㄶ */
+ 0x11AE, /* 6 ㄷ */
+ 0x11AF, /* 7 ㄹ */
+ 0x11B0, /* 8 ㄺ */
+ 0x11B1, /* 9 ㄻ */
+ 0x11B2, /* 10 ㄼ */
+ 0x11B3, /* 11 ㄽ */
+ 0x11B4, /* 12 ㄾ */
+ 0x11B5, /* 13 ㄿ */
+ 0x11B6, /* 14 ㅀ */
+ 0x11B7, /* 15 ㅁ */
+ 0x11B8, /* 16 ㅂ */
+ 0x11B9, /* 17 ㅄ */
+ 0x11BA, /* 18 ㅅ */
+ 0x11BB, /* 19 ㅆ */
+ 0x11BC, /* 20 ㅇ */
+ 0x11BD, /* 21 ㅈ */
+ 0x11BE, /* 22 ㅊ */
+ 0x11BF, /* 23 ㅋ */
+ 0x11C0, /* 24 ㅌ */
+ 0x11C1, /* 25 ㅍ */
+ 0x11C2, /* 26 ㅎ */
+ };
+
+ /**
+ * 이중자음이 어떤 단자음의 결합으로 이루어졌는지를 나타내는 테이블 : 이중자음이 분리되어 종성과 초성으로 사용될 때 쓰임
+ * 이중자음의 종성인덱스를 이용하여 테이블을 서치하여 제1자음의 종성인덱스와 제 2 자음의 초성인덱스를 가져온다.
+ */
+
+#define INVALID -1 /* 단일처리자음인 경우 : 제 1자음과 제 2자음으로 나누어 사용할 수 없음*/
+
+ const static int DJONGIndexTable[JONG_TABLE_SIZE][2] = {
+ /* 제 1자음 제 2자음 */
+ {INVALID, INVALID}, /* 0 ㄱ */
+ {INVALID, INVALID}, /* 1 ㄲ */
+ {0, 9}, /* 2 ㄳ */
+ {INVALID, INVALID}, /* 3 ㄴ */
+ {3, 12}, /* 4 ㄵ */
+ {3, 18}, /* 5 ㄶ */
+ {INVALID, INVALID}, /* 6 ㄷ */
+ {INVALID, INVALID}, /* 7 ㄹ */
+ {7, 0}, /* 8 ㄺ */
+ {7, 6}, /* 9 ㄻ */
+ {7, 7}, /* 10 ㄼ */
+ {7, 9}, /* 11 ㄽ */
+ {7, 16}, /* 12 ㄾ */
+ {7, 17}, /* 13 ㄿ */
+ {7, 18}, /* 14 ㅀ */
+ {INVALID, INVALID}, /* 15 ㅁ */
+ {INVALID, INVALID}, /* 16 ㅂ */
+ {16, 9}, /* 17 ㅄ */
+ {INVALID, INVALID}, /* 18 ㅅ */
+ {INVALID, INVALID}, /* 19 ㅆ */
+ {INVALID, INVALID}, /* 20 ㅇ */
+ {INVALID, INVALID}, /* 21 ㅈ */
+ {INVALID, INVALID}, /* 22 ㅊ */
+ {INVALID, INVALID}, /* 23 ㅋ */
+ {INVALID, INVALID}, /* 24 ㅌ */
+ {INVALID, INVALID}, /* 25 ㅍ */
+ {INVALID, INVALID}, /* 26 ㅎ */
+
+ };
+
+
+ /**
+ * HCJAMO(Hangul Compatibility Jamo) Unicode Table
+ * - 초성이나 중성, 종성등이 조합되지 않고 단독으로 쓰일 때는 Unicode Hangul Compatibility Jamo 를 사용해야 한다.
+ * - 중성의 경우는 중성 Unicode에 보정값을 더하여 Hangul Compatibility Jamo unicode를 변환이 가능하다.
+ * - 따라서 자음부분만을 정의하여 사용하였다.
+ */
+
+#define HCJAMO_TABLE_SIZE 30 /* 단자음 (14) + 복자음 (5) + 이중자음 (11) = 30 */
+
+ const static short HCJAMOUnicodeTable[HCJAMO_TABLE_SIZE] = {
+ 0x3131, /* 0 ㄱ */
+ 0x3132, /* 1 ㄲ */
+ 0x3133, /* 2 ㄳ */
+ 0x3134, /* 3 ㄴ */
+ 0x3135, /* 4 ㄵ */
+ 0x3136, /* 5 ㄶ */
+ 0x3137, /* 6 ㄷ */
+ 0x3138, /* 7 ㄸ */
+ 0x3139, /* 8 ㄹ */
+ 0x313A, /* 9 ㄺ */
+ 0x313B, /* 10 ㄻ */
+ 0x313C, /* 11 ㄼ */
+ 0x313D, /* 12 ㄽ */
+ 0x313E, /* 13 ㄾ */
+ 0x313F, /* 14 ㄿ */
+ 0x3140, /* 15 ㅀ */
+ 0x3141, /* 16 ㅁ */
+ 0x3142, /* 17 ㅂ */
+ 0x3143, /* 18 ㅃ */
+ 0x3144, /* 19 ㅄ */
+ 0x3145, /* 20 ㅅ */
+ 0x3146, /* 21 ㅆ */
+ 0x3147, /* 22 ㅇ */
+ 0x3148, /* 23 ㅈ */
+ 0x3149, /* 24 ㅉ */
+ 0x314A, /* 25 ㅊ */
+ 0x314B, /* 26 ㅋ */
+ 0x314C, /* 27 ㅌ */
+ 0x314D, /* 28 ㅍ */
+ 0x314E, /* 29 ㅎ */
+
+ };
+
+ /**
+ * 중성 Unicode를 Hangul Compatibility Jamo unicode로 변환하기 위한 보정값
+ * '.'과 '..'을 제외하고 JUNGUnicodeTable[idx] + 0x1FEE 로 컨버젼 가능
+ */
+#define COMPENSATE_VALUE_FOR_JUNGUCODE 0x1FEE
+
+
+ /**
+ * 종성불가 자음 정의 테이블
+ * - 현재 입력으로 들어온 SIPKEY가 종성으로 사용될 수 있는 지를 표시
+ * - 종성불가이면 조합중인 글자를 완료 시키고 항상 초성으로 사용될 수 있도록 한다.
+ */
+ const static int CANTJONGTable[] = {
+ TRUE, /* 0 ㄱ */
+ TRUE, /* 1 ㄲ */
+ TRUE, /* 2 ㄴ */
+ TRUE, /* 3 ㄷ */
+ FALSE, /* 4 ㄸ */
+ TRUE, /* 5 ㄹ */
+ TRUE, /* 6 ㅁ */
+ TRUE, /* 7 ㅂ */
+ FALSE, /* 8 ㅃ */
+ TRUE, /* 9 ㅅ */
+ TRUE, /* 10 ㅆ */
+ TRUE, /* 11 ㅇ */
+ TRUE, /* 12 ㅈ */
+ FALSE, /* 13 ㅉ */
+ TRUE, /* 14 ㅊ */
+ TRUE, /* 15 ㅋ */
+ TRUE, /* 16 ㅌ */
+ TRUE, /* 17 ㅍ */
+ TRUE, /* 18 ㅎ */
+ };
+
+ /**
+ * 종성을 초성의 index로 바꾸는 테이블
+ * - 조합중인 글자의 종성을 새로운 글자의 초성으로 사용할 때 쓰임
+ * - '굴'에서 'ㅣ'가 들어 와서 '구''리'가 되는 경우
+ */
+ const static int JONG2CHOTable[JONG_TABLE_SIZE] = {
+ 0, /* 0 ㄱ */
+ 1, /* 1 ㄲ */
+ INVALID, /* 2 ㄳ */
+ 2, /* 3 ㄴ */
+ INVALID, /* 4 ㄵ */
+ INVALID, /* 5 ㄶ */
+ 3, /* 6 ㄷ */
+ 5, /* 7 ㄹ */
+ INVALID, /* 8 ㄺ */
+ INVALID, /* 9 ㄻ */
+ INVALID, /* 10 ㄼ */
+ INVALID, /* 11 ㄽ */
+ INVALID, /* 12 ㄾ */
+ INVALID, /* 13 ㄿ */
+ INVALID, /* 14 ㅀ */
+ 6, /* 15 ㅁ */
+ 7, /* 16 ㅂ */
+ INVALID, /* 17 ㅄ */
+ 9, /* 18 ㅅ */
+ 10, /* 19 ㅆ */
+ 11, /* 20 ㅇ */
+ 12, /* 21 ㅈ */
+ 14, /* 22 ㅊ */
+ 15, /* 23 ㅋ */
+ 16, /* 24 ㅌ */
+ 17, /* 25 ㅍ */
+ 18, /* 26 ㅎ */
+ };
+
+
+ /**
+ * SIPKEY를 종성의 index로 바꾸는 테이블
+ * - 입력된 SIPKEY가 조합중인 글자의 종성으로 사용될 때 쓰임
+ * - '구'에서 'ㄹ'이 입력되어 '굴'이 생성된 경우 'ㄹ'의 SIPKEY 인덱스를 '굴'에서 사용될 수 있도록 종성 인덱스로 바꾸어 준다
+ */
+ const static short SIPKEY2JONGTable[SIPKEY_TABLE_SIZE] = {
+ 0, /* 0 ㄱ */
+ 1, /* 1 ㄲ */
+ 3, /* 2 ㄴ */
+ 6, /* 3 ㄷ */
+ INVALID,/* 4 ㄸ */
+ 7, /* 5 ㄹ */
+ 15, /* 6 ㅁ */
+ 16, /* 7 ㅂ */
+ INVALID,/* 8 ㅃ */
+ 18, /* 9 ㅅ */
+ 19, /* 10 ㅆ */
+ 20, /* 11 ㅇ */
+ 21, /* 12 ㅈ */
+ INVALID,/* 13 ㅉ */
+ 22, /* 14 ㅊ */
+ 23, /* 15 ㅋ */
+ 24, /* 16 ㅌ */
+ 25, /* 17 ㅍ */
+ 26, /* 18 ㅎ */
+ };
+
+ /**
+ * 초성을 HCJAMO Unicode의 index로 바꾸는 테이블
+ * - CHO_STATE에서 조합중인 글자를 표시하기 위해 사용
+ */
+ const static short CHO2HCJAMOTable[CHO_TABLE_SIZE] = {
+ 0, /* 0 ㄱ */
+ 1, /* 1 ㄲ */
+ 3, /* 2 ㄴ */
+ 6, /* 3 ㄷ */
+ 7, /* 4 ㄸ */
+ 8, /* 5 ㄹ */
+ 16, /* 6 ㅁ */
+ 17, /* 7 ㅂ */
+ 18, /* 8 ㅃ */
+ 20, /* 9 ㅅ */
+ 21, /* 10 ㅆ */
+ 22, /* 11 ㅇ */
+ 23, /* 12 ㅈ */
+ 24, /* 13 ㅉ */
+ 25, /* 14 ㅊ */
+ 26, /* 15 ㅋ */
+ 27, /* 16 ㅌ */
+ 28, /* 17 ㅍ */
+ 29, /* 18 ㅎ */
+ };
+
+
+ /**
+ * 종성을 HCJAMO Unicode의 index로 바꾸는 테이블
+ * - 초성과 초성이 결합하여 종성이중자음이 될때 이를 표시하기 위해 사용
+ * - 'ㄱ'에서 'ㅅ'이 들어 와서 'ㄳ'이 되는 경우
+ */
+ const static int JONG2HCJAMOTable[JONG_TABLE_SIZE] = {
+ 0, /* 0 ㄱ */
+ 1, /* 1 ㄲ */
+ 2, /* 2 ㄳ */
+ 3, /* 3 ㄴ */
+ 4, /* 4 ㄵ */
+ 5, /* 5 ㄶ */
+ 6, /* 6 ㄷ */
+ 8, /* 7 ㄹ */
+ 9, /* 8 ㄺ */
+ 10, /* 9 ㄻ */
+ 11, /* 10 ㄼ */
+ 12, /* 11 ㄽ */
+ 13, /* 12 ㄾ */
+ 14, /* 13 ㄿ */
+ 15, /* 14 ㅀ */
+ 16, /* 15 ㅁ */
+ 17, /* 16 ㅂ */
+ 19, /* 17 ㅄ */
+ 20, /* 18 ㅅ */
+ 21, /* 19 ㅆ */
+ 22, /* 20 ㅇ */
+ 23, /* 21 ㅈ */
+ 25, /* 22 ㅊ */
+ 26, /* 23 ㅋ */
+ 27, /* 24 ㅌ */
+ 28, /* 25 ㅍ */
+ 29, /* 26 ㅎ */
+ };
+
+
+ typedef struct makecodeinfo {
+ int size; // 조합중인 코드의 크기 (자음 + 천(.) 이나 자음 + 천천(..) 은 2, 나머지는 1)
+ short ucode[2]; // 조합중인 글자의 유니코드 값
+ short cho_idx;
+ short jung_idx;
+ short jong_idx;
+ short next_cho_idx;
+ } MAKECODE;
+
+
+ typedef struct madecodeinfo {
+ int size; // 조합 완료된 코드의 크기 (자음 + 천(.) 이나 자음 + 천천(..) 은 2, 나머지는 1, 조합완료된 코드가 없는 경우 0)
+ short ucode[2]; // 조합중인 글자의 유니코드 값
+ } MADECODE;
+
+
+#define IN_COMPOSITION 0 /* 조합중이어서 조합완료된 코드가 없음을 표시 */
+
+
+//---- Back space 처리를 위한 정의 부분 start -----------
+ typedef struct automatahistoryinfo {
+ int state; //오토마타의 상태
+ MAKECODE makecode; //조합중인 글자
+ } AUTOMATA_HISTORY_INFO;
+
+#define MAX_AUTOMATA_HISTORY_LENGTH 10 // 자음(2) + 모음(5) + 자음(2) + 더미(1) = 10
+
+#define EMPTY_CODE -1
+
+ /**
+ * Back Space 가 눌렸을 때 모음부분을 처리하기 위한 Automata History Stack POP 정보
+ * - 자음은 입력단위로 지워지나 모음은 입력단위가 아닌 단모음 단위로 지워진다.
+ */
+ const static int BS_MOEUMInfo[JUNG_TABLE_SIZE] = {
+ 1, /* 0 .(천) */
+ 2, /* 1 ..(천천) */
+ 2, /* 2 ㅏ */
+ 3, /* 3 ㅐ */
+ 3, /* 4 ㅑ */
+ 4, /* 5 ㅒ */
+ 2, /* 6 ㅓ */
+ 3, /* 7 ㅔ */
+ 3, /* 8 ㅕ */
+ 4, /* 9 ㅖ */
+ 2, /* 10 ㅗ */
+ 2, /* 11 ㅘ */
+ 3, /* 12 ㅙ */
+ 1, /* 13 ㅚ */
+ 3, /* 14 ㅛ */
+ 2, /* 15 ㅜ */
+ 2, /* 16 ㅝ */
+ 3, /* 17 ㅞ */
+ 1, /* 18 ㅟ */
+ 3, /* 19 ㅠ */
+ 1, /* 20 ㅡ */
+ 2, /* 21 ㅢ */
+ 1, /* 22 ㅣ */
+ };
+
+ /**
+ * Back Space 가 눌렸을 때 모음부분을 처리하기 위한 모음 변환 Table
+ * - 자음은 입력단위로 지워지나 모음은 입력단위가 아닌 단모음 단위로 지워진다.
+ */
+ const static int BS_MOEUMInfo_Automata[JUNG_TABLE_SIZE] = {
+ EMPTY_CODE, /* 0 .(천) */
+ EMPTY_CODE, /* 1 ..(천천) */
+ EMPTY_CODE, /* 2 ㅏ */
+ EMPTY_CODE, /* 3 ㅐ */
+ EMPTY_CODE, /* 4 ㅑ */
+ EMPTY_CODE, /* 5 ㅒ */
+ EMPTY_CODE, /* 6 ㅓ */
+ EMPTY_CODE, /* 7 ㅔ */
+ EMPTY_CODE, /* 8 ㅕ */
+ EMPTY_CODE, /* 9 ㅖ */
+ EMPTY_CODE, /* 10 ㅗ */
+ 10, /* 11 ㅘ */ /* -> ㅗ */
+ 10, /* 12 ㅙ */ /* -> ㅗ */
+ 10, /* 13 ㅚ */ /* -> ㅗ */
+ EMPTY_CODE, /* 14 ㅛ */
+ EMPTY_CODE, /* 15 ㅜ */
+ 15, /* 16 ㅝ */ /* -> ㅜ */
+ 15, /* 17 ㅞ */ /* -> ㅜ */
+ 15, /* 18 ㅟ */ /* -> ㅜ */
+ EMPTY_CODE, /* 19 ㅠ */
+ EMPTY_CODE, /* 20 ㅡ */
+ 20, /* 21 ㅢ */ /* -> ㅡ */
+ EMPTY_CODE, /* 22 ㅣ */
+ };
+
+
+ /**
+ * 3X4 Rotation을 통해 종성이중자음이 될 수 있는 Key를 나타내는 테이블
+ * - 입력된 자음 Key가 이전 조합글자와 Composition state를 유지해야 하는지를 판단
+ * - '할'에서 'ㄷ'이 입력되어 '할ㄷ'이 생성된 경우 'ㄷ'이 'ㅌ'로 Rotation되어 '핥' 이 될 수 있으므로
+ * - Composition State를 유지해야 하는데, 이러한 판단을 하기 위한 Table
+ */
+ const static bool RotationKey_CanBe_DOUBLEJONG[JONG_TABLE_SIZE][SIPKEY_3X4_KEY_NUM] = {
+ // 3X4_4Key, 3X4_5Key, 3X4_6Key, 3X4_7Key, 3X4_8Key, 3X4_9Key, 3X4_0Key,
+ {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE}, /* 0 ㄱ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 1 ㄲ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 2 ㄳ */
+ {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE}, /* 3 ㄴ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 4 ㄵ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 5 ㄶ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 6 ㄷ */
+ {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE}, /* 7 ㄹ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 8 ㄺ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 9 ㄻ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 10 ㄼ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 11 ㄽ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 12 ㄾ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 13 ㄿ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 14 ㅀ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 15 ㅁ */
+ {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE}, /* 16 ㅂ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 17 ㅄ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 18 ㅅ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 19 ㅆ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 20 ㅇ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 21 ㅈ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 22 ㅊ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 23 ㅋ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 24 ㅌ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 25 ㅍ */
+ {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, /* 26 ㅎ */
+ };
+
+
+//------ Back space 처리를 위한 정의 부분 end -----------
+
+
+ /* 한글 조합을 처리하는 오토 마타의 메인 부분이다. */
+ int CJI_Automata(int p_isJAEUM, short p_SIPKey, MADECODE *p_madecode);
+
+ /* Get current make code, which means the character currently being composed */
+ MAKECODE CJI_GetMakeCode();
+
+ /* This saves/loads current state of automata */
+ void Backup_Automata();
+ void Restore_Automata();
+
+ /* ---------------- state 간의 전이시 수행하는 action 부분이다. ----------------------- */
+
+ /* ACTION_EMPTY_2_CHO : EMPTY_STATE에서 CHO_STATE로 갈때 처리 */
+ void ACTION_EMPTY_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_2_CHO_JUNG : CHO_STATE에서 CHO_JUNG_STATE로 갈때 처리 */
+ void ACTION_CHO_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_2_CHO_JUNG : CHO_JUNG_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 모음이 계속 조합될 때 */
+ void ACTION_CHO_JUNG_2_CHO_JUNG(short p_SIPKey, short p_jung_idx, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_2_CHO : CHO_JUNG_STATE에서 CHO_STATE로 갈때 처리 - 종성불가자음 이 올 때 */
+ void ACTION_CHO_JUNG_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ bool ACTION_ERROR_KEY(short p_SIPKey, MADECODE *p_madecode);
+ bool ACTION_BACKSPACE_KEY(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_2_CHO_JUNG_CHO : CHO_JUNG_STATE에서 CHO_JUNG_CHO_STATE로 갈때 처리 - 3X4 Rotation 종성불가자음 이 올 때 */
+ void ACTION_CHO_JUNG_2_CHO_JUNG_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_CHO_2_CHO : CHO_JUNG_CHO_STATE에서 CHO_STATE로 갈때 처리 - 다른 자음Key 입력시 */
+ void ACTION_CHO_JUNG_CHO_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+ /* ACTION_CHO_JUNG_CHO_2_CHO_JUNG : CHO_JUNG_CHO_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 모음 입력시 */
+ void ACTION_CHO_JUNG_CHO_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_SINGLEJONG_CHO : CHO_JUNG_SINGLEJONG_STATE에서 CHO_JUNG_SINGLEJONG_CHO_STATE로 갈때 처리 - 3X4 Rotation 종성조합불가자음 이 올 때 */
+ void ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_SINGLEJONG_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO : CHO_JUNG_SINGLEJONG_CHO_STATE에서 CHO_STATE로 갈때 처리 - 다른 자음Key 입력시 */
+ void ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+ /* ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO_JUNG : CHO_JUNG_SINGLEJONG_CHO_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 모음 입력시 */
+ void ACTION_CHO_JUNG_SINGLEJONG_CHO_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+ // }
+
+ /* ACTION_CHO_JUNG_2_CHO_JUNG_SINGLEJONG : CHO_JUNG_STATE에서 CHO_JUNG_SINGLEJONG_STATE로 갈때 처리 - 종성으로 단일자음 사용 */
+ void ACTION_CHO_JUNG_2_CHO_JUNG_SINGLEJONG(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG : CHO_JUNG_SINGLEJONG_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 종성이 나온 상태에서 모음이 나올 때 */
+ void ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_SINGLEJONG_2_CHO : CHO_JUNG_SINGLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 종성조합불가자음이 나올때 */
+ void ACTION_CHO_JUNG_SINGLEJONG_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_DOUBLEJONG : CHO_JUNG_SINGLEJONG_STATE에서 CHO_JUNG_DOUBLEJONG_STATE로 갈때 처리 - 종성조합가능자음이 나올때 */
+ void ACTION_CHO_JUNG_SINGLEJONG_2_CHO_JUNG_DOUBLEJONG(short p_johapjaeum_idx, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_DOUBLEJONG_2_CHO_JUNG : CHO_JUNG_DOUBLEJONG_STATE에서 CHO_JUNG_STATE로 갈때 처리 - 조합종성이 나온상태에서 모음이 나올때 */
+ void ACTION_CHO_JUNG_DOUBLEJONG_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_CHO_JUNG_DOUBLEJONG_2_CHO : CHO_JUNG_DOUBLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 조합종성이 나온상태에서 자음이 나올때 */
+ void ACTION_CHO_JUNG_DOUBLEJONG_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* --------------- state 전이시 발생하는 ERROR를 처리하기 위한 action 부분이다. ------------------ */
+
+ /* ACTION_ERROR_EMPTY_2_NOCHO_JUNG : EMPTY_STATE에서 NOCHO_JUNG_ERROR_STATE로 갈때 처리 - 초성없이 모음이 나올 떄 */
+ void ACTION_ERROR_EMPTY_2_NOCHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_CHO_2_CHO : CHO_STATE에서 CHO_STATE로 갈때 처리 - 초성 자음 뒤에 그것과 결합할 수 없는 초성 자음이 나옴 */
+ void ACTION_ERROR_CHO_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_CHO_2_NOCHO_NOJUNG_DOUBLEJONG : CHO_STATE 에서 NOCHO_NOJUNG_DOUBLEJONG_ERROR_STATE로 갈때 처리 - 초성과 중성 없이 조합종성이 만들어 지는 상태 */
+ void ACTION_ERROR_CHO_2_NOCHO_NOJUNG_DOUBLEJONG(int johapjaeum_idx, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_CHO_JUNG_2_CHO : CHO_JUNG_STATE에서 CHO_STATE로 갈때 처리 - 초중에서 자음이 나왔으나 앞에 모음이 천('.') 또는 천천('..') 일때 */
+ void ACTION_ERROR_CHO_JUNG_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_CHO_JUNG_2_NOCHO_JUNG : CHO_JUNG_STATE에서 NOCHO_JUNG_STATE로 갈때 처리 - 초중상태에서 모음 조합중 결합하지 못하는 모음이 나올 떄 */
+ void ACTION_ERROR_CHO_JUNG_2_NOCHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_NOCHO_JUNG_2_CHO : NOCHO_JUNG_STATE에서 CHO_STATE로 갈때 처리 - 초성없이 모음 조합중 자음이 나올때 */
+ void ACTION_ERROR_NOCHO_JUNG_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_NO : NOCHO_JUNG_STATE에서 NOCHO_JUNG_STATE로 갈때 처리 - 초성없이 모음 조합중 결합할 수 없는 모음이 나왔을 때 */
+ void ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_NO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_OK : NOCHO_JUNG_STATE에서 NOCHO_JUNG_STATE로 갈때 처리 - 초성없이 모음 조합중 결합 가능한 모음이 나올 때 */
+ void ACTION_ERROR_NOCHO_JUNG_2_NOCHO_JUNG_COMBINATION_OK(short p_SIPKey, int p_jung_idx, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO : NOCHO_NOJUNG_DOUBLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 초성과 중성없이 조합종성이 나온상태에서 자음이 나올때 */
+ void ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO(short p_SIPKey, MADECODE *p_madecode);
+
+ /* ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO_JUNG : NOCHO_NOJUNG_DOUBLEJONG_STATE에서 CHO_STATE로 갈때 처리 - 초성과 중성없이 조합종성이 나온상태에서 모음이 나올때 */
+ void ACTION_ERROR_NOCHO_NOJUNG_DOUBLEJONG_2_CHO_JUNG(short p_SIPKey, MADECODE *p_madecode);
+
+//-------------------- 내부 인덱스로 Unicode 값을 얻어 온다. --------------
+ /* 초성과 중성으로 이루어진 글자의 Unicode를 얻어온다. */
+ short getUnicodeWithCHO_JUNG(short p_cho_idx, short p_jung_idx);
+
+ /* 초성 + 중성 + 종성으로 이루어진 글자의 Unicode를 얻어온다. */
+ short getUnicodeWithCHO_JUNG_JONG(short p_cho_idx, short p_jung_idx, short p_jong_idx);
+
+ /* 종성과 입력된 키가 결합한 이중 자음의 인덱스를 가져온다. */
+ int getJONGIndexofDJONG_withJONGandSIPKEY(int p_first_jong_idx, int p_second_SIPKEY_idx);
+
+ /* 초성과 입력된 키가 결합한 이중 자음의 인덱스를 가져온다. */
+ int getJONGIndexofDJONG_withCHOandSIPKEY(int p_first_cho_idx, int p_second_SIPKEY_idx);
+
+ /* 종성과 입력된 3X4키의 Rotation Key들이 이중 자음으로 결합할 수 있는지를 확인한다. */
+ int getRotationKeyCanBeDOUBLEJONG(int p_first_jong_idx, int p_second_SIPKEY_idx);
+
+//------------------ Back Space를 처리하기 위한 Automata History Stack 관련 함수 ---------------
+ /* initializeAutomataHistoryStack : Automata History Stack 을 초기화 한다. */
+ void initAutomataHistoryStack();
+
+ /* pushCurrentEnvToAutomataHistoryStack : 오토마타와 관련된 환경을 Automata History Stack 에 push 한다.*/
+ void pushEnvToAutomataHistoryStack(int p_state, MAKECODE p_tmp_makecode);
+
+ /* popFromAutomataHistoryStack : Automata 관련 전역변수 BS이전으로 복원, Stack pop */
+ void popFromAutomataHistoryStack();
+
+ /* initAutomataEnv : Automata의 환경을 초기화 한다. */
+ void initAutomataEnv();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //remove duplicate
#include "ise_lang_table.h"
+#include <iconv.h>
+#include "cji.h"
+
using namespace scl;
#define MVK_Shift_L 0xffe1
sclboolean on_language_selected(const sclchar *language, const sclchar *input_mode);
sclboolean on_language_unselected(const sclchar *language, const sclchar *input_mode);
+ sclboolean reset_language(const sclchar *language);
+
sclboolean flush_imengine(const sclchar *language);
private:
SCLEventReturnType process_key_type_char(const SclUIEventDesc&);
+ SCLEventReturnType process_key_type_user(const SclUIEventDesc&);
};
static CSDKISE ise_instance;
extern CONFIG_VALUES g_config_values;
extern KEYBOARD_STATE g_keyboard_state;
+#define KOREAN_ENCODING_BUFFER_SIZE 256
+#define AUTOMATA_BASE_ENCODING "UCS-2"
+#define SYSTEM_OUTPUT_ENCODING "UTF8"
+
+int iconv_string(const char *from, const char *to, const char *src, char *dst, size_t inleftsize, size_t outleftsize)
+{
+ size_t dstlen;
+ size_t res;
+ iconv_t cd = (iconv_t)-1;
+
+ char *inptr;
+ char *outptr;
+
+ /* open iconv */
+ cd = iconv_open(to, from);
+ if (cd == (iconv_t)(-1)) {
+ return (int)cd;
+ }
+
+ dstlen = outleftsize;
+ inptr = (char*)src;
+ outptr = dst;
+
+ while (1) {
+ res = iconv(cd, &inptr, &inleftsize, &outptr, &outleftsize);
+ if (res == (size_t)(-1)) {
+ if (errno == EILSEQ) { /* not defined char in the table ? */
+ fprintf(stderr, "iconv_str: can't convert[%s]\n", src);
+ /* for 2-byte code incompleteness */
+ inptr++;
+ inleftsize--;
+ }
+ else if (errno == EINVAL) { /* incomplete char, need readin more codes */
+ fprintf(stderr, "iconv_str: incomplete char or shift sequence\n");
+ if (inleftsize <= 2) {
+ *outptr = '?';
+ outleftsize--;
+ break;
+ }
+ }
+ *outptr = '?';
+ outptr++;
+ outleftsize--;
+ inptr++;
+ inleftsize--;
+ }
+ else break;
+ }
+ dst[dstlen - outleftsize] = '\0';
+ /* close iconv */
+ iconv_close(cd);
+ return(dstlen - outleftsize);
+}
+
+int process_korean_automata(int is_consonant, unsigned short key_index)
+{
+ MADECODE madecode = {0};
+ MAKECODE makecode = { 0 };
+ char buffer[KOREAN_ENCODING_BUFFER_SIZE] = { 0 };
+
+ makecode = CJI_GetMakeCode();
+
+ int ret = CJI_Automata(is_consonant, key_index, &madecode);
+ iconv_string(AUTOMATA_BASE_ENCODING, SYSTEM_OUTPUT_ENCODING,
+ (const char*)(madecode.ucode), buffer, madecode.size * 2, KOREAN_ENCODING_BUFFER_SIZE);
+ if (buffer[0]) {
+ ise_send_string(buffer);
+ }
+ iconv_string(AUTOMATA_BASE_ENCODING, SYSTEM_OUTPUT_ENCODING,
+ (const char*)(CJI_GetMakeCode().ucode), buffer, CJI_GetMakeCode().size * 2, KOREAN_ENCODING_BUFFER_SIZE);
+ if (buffer[0] || makecode.size > 0) {
+ ise_update_preedit_string(buffer);
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
SCLEventReturnType
CSDKISE::process_key_type_char(const SclUIEventDesc& event_desc)
{
- // patch for Chinese symbol ^
- // Chinese engine will regards ^ as ……
- // this patch is to avoid this
const sclchar * cur_lang = _language_manager.get_current_language();
if (cur_lang) {
if (0 == strcmp(cur_lang, "Chinese")) {
+ // patch for Chinese symbol ^
+ // Chinese engine will regards ^ as ……
+ // this patch is to avoid this
+
if (event_desc.key_event == '^') {
ise_forward_key_event(event_desc.key_event);
return SCL_EVENT_DONE;
}
}
+ if (0 == strcmp(cur_lang, "Korean")) {
+ if (process_korean_automata(false, SIPKEY_ERROR))
+ return SCL_EVENT_DONE;
+ }
}
// patch for Chinese symbol ^ end
/* If longkey symbol was pressed, let's flush the preedit buffer */
flush_imengine(cur_lang);
}
+ return SCL_EVENT_PASS_ON;
+}
+
+SCLEventReturnType
+CSDKISE::process_key_type_user(const SclUIEventDesc& event_desc)
+{
+ const sclchar * cur_lang = _language_manager.get_current_language();
+ if (cur_lang) {
+ if (0 == strcmp(cur_lang, "Korean")) {
+ typedef struct {
+ const char* key_id;
+ int sip_index;
+ bool is_consonant;
+ } CJI_key_table;
+ CJI_key_table table[] = {
+ { "SIPKEY_1", SIPKEY_IDX2, false },
+ { "SIPKEY_2", SIPKEY_IDX0, false },
+ { "SIPKEY_3", SIPKEY_IDX1, false },
+ { "SIPKEY_4", SIPKEY_IDX19, true },
+ { "SIPKEY_5", SIPKEY_IDX20, true },
+ { "SIPKEY_6", SIPKEY_IDX21, true },
+ { "SIPKEY_7", SIPKEY_IDX22, true },
+ { "SIPKEY_8", SIPKEY_IDX23, true },
+ { "SIPKEY_9", SIPKEY_IDX24, true },
+ { "SIPKEY_0", SIPKEY_IDX25, true },
+ };
+ bool found = false;
+ for (unsigned int loop = 0; loop < sizeof(table) / sizeof(CJI_key_table); loop++) {
+ if (strncmp((char*)(event_desc.key_value), table[loop].key_id,
+ strlen(table[loop].key_id)) == 0) {
+ found = true;
+ if (process_korean_automata(table[loop].is_consonant, table[loop].sip_index))
+ return SCL_EVENT_DONE;
+ }
+ }
+ if (!found) {
+ if (process_korean_automata(false, SIPKEY_ERROR))
+ return SCL_EVENT_DONE;
+ }
+ }
+ }
return SCL_EVENT_PASS_ON;
}
ret = process_key_type_char(event_desc);
break;
case KEY_TYPE_STRING:
+ if (strcmp(_language_manager.get_current_language(), "Korean") == 0) {
+ process_korean_automata(false, SIPKEY_ERROR);
+ }
if (event_desc.key_modifier != KEY_MODIFIER_MULTITAP_START &&
event_desc.key_modifier != KEY_MODIFIER_MULTITAP_REPEAT) {
flush_imengine(cur_lang);
break;
case KEY_TYPE_MODECHANGE:
{
+ if (strcmp(_language_manager.get_current_language(), "Korean") == 0) {
+ process_korean_automata(false, SIPKEY_ERROR);
+ }
flush_imengine(cur_lang);
}
break;
case KEY_TYPE_CONTROL:
- /* Do not flush when the entered key is one of : BACKSPACE / SHIFT / CAPSLOCK / SHIFTLOCK */
- if (event_desc.key_event != MVK_BackSpace &&
- event_desc.key_event != MVK_Shift_L &&
- event_desc.key_event != MVK_Caps_Lock &&
- event_desc.key_event != MVK_Shift_Lock &&
- event_desc.key_event != MVK_space &&
- event_desc.key_event != MVK_Return) {
- flush_imengine(cur_lang);
- }
- if (event_desc.key_event == MVK_space) {
- if (_language_manager.get_enabled_languages_num() > 1) {
- if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_LEFT) {
- /* If flick event upon space key was detected, perform a language change and don't proceed anymore */
- _language_manager.select_previous_language();
- g_keyboard_state.disable_force_latin = TRUE;
- ret = SCL_EVENT_DONE;
- }
- if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_RIGHT) {
- /* If flick event upon space key was detected, perform a language change and don't proceed anymore */
- _language_manager.select_next_language();
- g_keyboard_state.disable_force_latin = TRUE;
- ret = SCL_EVENT_DONE;
+ {
+ /* Do not flush when the entered key is one of : BACKSPACE / SHIFT / CAPSLOCK / SHIFTLOCK */
+ if (event_desc.key_event != MVK_BackSpace &&
+ event_desc.key_event != MVK_Shift_L &&
+ event_desc.key_event != MVK_Caps_Lock &&
+ event_desc.key_event != MVK_Shift_Lock &&
+ event_desc.key_event != MVK_space &&
+ event_desc.key_event != MVK_Return) {
+ flush_imengine(cur_lang);
}
- } else {
- if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_LEFT ||
- event_desc.key_modifier == KEY_MODIFIER_DIRECTION_LEFT_RETURN) {
- /* If flick event upon space key was detected, perform a cursor movement and don't proceed anymore */
- ise_send_event(MVK_Left, 0);
- ret = SCL_EVENT_DONE;
+ if (event_desc.key_event == MVK_space) {
+ if (_language_manager.get_enabled_languages_num() > 1) {
+ if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_LEFT) {
+ /* If flick event upon space key was detected, perform a language change and don't proceed anymore */
+ _language_manager.select_previous_language();
+ g_keyboard_state.disable_force_latin = TRUE;
+ ret = SCL_EVENT_DONE;
+ }
+ if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_RIGHT) {
+ /* If flick event upon space key was detected, perform a language change and don't proceed anymore */
+ _language_manager.select_next_language();
+ g_keyboard_state.disable_force_latin = TRUE;
+ ret = SCL_EVENT_DONE;
+ }
+ } else {
+ if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_LEFT ||
+ event_desc.key_modifier == KEY_MODIFIER_DIRECTION_LEFT_RETURN) {
+ /* If flick event upon space key was detected, perform a cursor movement and don't proceed anymore */
+ ise_send_event(MVK_Left, 0);
+ ret = SCL_EVENT_DONE;
+ }
+ if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_RIGHT ||
+ event_desc.key_modifier == KEY_MODIFIER_DIRECTION_RIGHT_RETURN) {
+ /* If flick event upon space key was detected, perform a cursor movement and don't proceed anymore */
+ ise_send_event(MVK_Right, 0);
+ ret = SCL_EVENT_DONE;
+ }
+ }
}
- if (event_desc.key_modifier == KEY_MODIFIER_DIRECTION_RIGHT ||
- event_desc.key_modifier == KEY_MODIFIER_DIRECTION_RIGHT_RETURN) {
- /* If flick event upon space key was detected, perform a cursor movement and don't proceed anymore */
- ise_send_event(MVK_Right, 0);
- ret = SCL_EVENT_DONE;
+ if (strcmp(_language_manager.get_current_language(), "Korean") == 0) {
+ if (event_desc.key_event == MVK_BackSpace) {
+ if (process_korean_automata(false, SIPKEY_BACKSPACE))
+ ret = SCL_EVENT_DONE;
+ }
+ else {
+ if (process_korean_automata(false, SIPKEY_ERROR))
+ ret = SCL_EVENT_DONE;
+ }
}
}
- }
- break;
+ break;
+ case KEY_TYPE_USER:
+ ret = process_key_type_user(event_desc);
+ break;
default:
break;
}
g_core.set_keyboard_ise_by_uuid(get_lang_table()[loop].keyboard_ise_uuid);
g_core.send_imengine_event(-1, get_lang_table()[loop].keyboard_ise_uuid,
get_lang_table()[loop].language_command, get_lang_table()[loop].language_code);
+ flush_imengine(language);
}
/* This is to update the screen only for once, not everytime we request a UI update */
return ret;
}
+sclboolean CSDKISE::reset_language(const sclchar *language)
+{
+ sclboolean ret = FALSE;
+
+ if (language) {
+ sclint loop;
+ for (loop = 0; loop < get_lang_table_size(); loop++) {
+ if (strcmp(language, get_lang_table()[loop].language) == 0) {
+ flush_imengine(language);
+ ret = TRUE;
+ }
+ }
+ }
+
+ return ret;
+}
+
static inline int get_lang_id(const sclchar* language) {
if (language == NULL) return -1;
bRet = true;
}
}
+ if (strcmp(_language_manager.get_current_language(), "Korean") == 0) {
+ process_korean_automata(false, SIPKEY_ERROR);
+ }
return bRet;
}