--- /dev/null
+Choe Hwanjin <krisna (at) kldp.org>
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+SUBDIRS = hangul test
+
+EXTRA_DIST = \
+ pyhangul/Makefile \
+ pyhangul/pyhangul.c \
+ pyhangul/setup.py
--- /dev/null
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.57)
+AC_INIT(libhangul, 0.0.1, http://kldp.net/projects/hangul/)
+AM_INIT_AUTOMAKE
+AC_CONFIG_SRCDIR([hangul/hangul.h])
+AC_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_RANLIB
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_CHECK_HEADERS([locale.h stdint.h stdlib.h string.h wchar.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_C_CONST
+AC_C_INLINE
+
+# Checks for library functions.
+AC_CONFIG_FILES([
+Makefile
+hangul/Makefile
+test/Makefile
+])
+AC_OUTPUT
--- /dev/null
+
+noinst_LIBRARIES = libhangul.a
+
+libhangul_a_CFLAGS =
+
+libhangul_a_SOURCES = \
+ hangulctype.c \
+ hangulinputcontext.c \
+ hangulkeyboard.h \
+ hangul.h
+
+libhangul_a_LIBADD =
--- /dev/null
+/* libhangul
+ * Copyright (C) 2004 Choe Hwanjin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef _HANGUL_H_
+#define _HANGUL_H_
+
+#include <wchar.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* hangulctype.c */
+enum {
+ HANGUL_CHOSEONG_FILLER = 0x115f, /* hangul choseong filler */
+ HANGUL_JUNGSEONG_FILLER = 0x1160 /* hangul jungseong filler */
+};
+
+bool hangul_is_choseong(wchar_t ch);
+bool hangul_is_jungseong(wchar_t ch);
+bool hangul_is_jongseong(wchar_t ch);
+
+wchar_t hangul_choseong_to_cjamo(wchar_t ch);
+wchar_t hangul_jungseong_to_cjamo(wchar_t ch);
+wchar_t hangul_jongseong_to_cjamo(wchar_t ch);
+
+wchar_t hangul_choseong_to_jongseong(wchar_t ch);
+wchar_t hangul_jongseong_to_choseong(wchar_t ch);
+void hangul_jongseong_dicompose(wchar_t ch, wchar_t* jong, wchar_t* cho);
+
+wchar_t hangul_jamo_to_syllable(wchar_t choseong,
+ wchar_t jungseong,
+ wchar_t jongseong);
+
+/* hangulinputcontext.c */
+typedef struct _HangulJamoCombination HangulJamoCombination;
+typedef struct _HangulBuffer HangulBuffer;
+typedef struct _HangulInputContext HangulInputContext;
+
+enum {
+ HANGUL_KEYBOARD_2,
+ HANGUL_KEYBOARD_32,
+ HANGUL_KEYBOARD_3FINAL,
+ HANGUL_KEYBOARD_390,
+ HANGUL_KEYBOARD_3NOSHIFT
+};
+
+enum {
+ HANGUL_OUTPUT_SYLLABLE,
+ HANGUL_OUTPUT_JAMO
+};
+
+enum {
+ HANGUL_INPUT_FILTER_2,
+ HANGUL_INPUT_FILTER_3
+};
+
+struct _HangulJamoCombination {
+ uint32_t key;
+ wchar_t code;
+};
+
+struct _HangulBuffer {
+ wchar_t choseong;
+ wchar_t jungseong;
+ wchar_t jongseong;
+
+ wchar_t stack[12];
+ int index;
+};
+
+struct _HangulInputContext {
+ int type;
+ const wchar_t *keyboard_table;
+ const HangulJamoCombination *combination_table;
+ int combination_table_size;
+ HangulBuffer buffer;
+ int output_mode;
+
+ wchar_t preedit_string[64];
+ wchar_t commit_string[64];
+};
+
+HangulInputContext* hangul_ic_new(int keyboard);
+void hangul_ic_delete(HangulInputContext *hic);
+bool hangul_ic_filter(HangulInputContext *hic, int ascii, bool capslock);
+void hangul_ic_reset(HangulInputContext *hic);
+bool hangul_ic_backspace(HangulInputContext *hic);
+
+void hangul_ic_set_output_mode(HangulInputContext *hic, int mode);
+void hangul_ic_set_keyboard(HangulInputContext *hic, int keyboard);
+const wchar_t* hangul_ic_get_preedit_string(HangulInputContext *hic);
+const wchar_t* hangul_ic_get_commit_string(HangulInputContext *hic);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HANGUL_H_ */
--- /dev/null
+/* libhangul
+ * Copyright (C) 2004 Choe Hwanjin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <wchar.h>
+
+#include "hangul.h"
+
+bool
+hangul_is_choseong(wchar_t ch)
+{
+ return ch >= 0x1100 && ch <= 0x1159;
+}
+
+bool
+hangul_is_jungseong(wchar_t ch)
+{
+ return ch >= 0x1161 && ch <= 0x11a2;
+}
+
+bool
+hangul_is_jongseong(wchar_t ch)
+{
+ return ch >= 0x11a7 && ch <= 0x11f9;
+}
+
+wchar_t
+hangul_choseong_to_cjamo(wchar_t ch)
+{
+ static wchar_t table[] = {
+ 0x3131, /* 0x1100 */
+ 0x3132, /* 0x1101 */
+ 0x3134, /* 0x1102 */
+ 0x3137, /* 0x1103 */
+ 0x3138, /* 0x1104 */
+ 0x3139, /* 0x1105 */
+ 0x3141, /* 0x1106 */
+ 0x3142, /* 0x1107 */
+ 0x3143, /* 0x1108 */
+ 0x3145, /* 0x1109 */
+ 0x3146, /* 0x110a */
+ 0x3147, /* 0x110b */
+ 0x3148, /* 0x110c */
+ 0x3149, /* 0x110d */
+ 0x314a, /* 0x110e */
+ 0x314b, /* 0x110f */
+ 0x314c, /* 0x1110 */
+ 0x314d, /* 0x1111 */
+ 0x314e, /* 0x1112 */
+ };
+
+ if (ch < 0x1100 || ch > 0x1112)
+ return ch;
+ return table[ch - 0x1100];
+}
+
+wchar_t
+hangul_jungseong_to_cjamo(wchar_t ch)
+{
+ static wchar_t table[] = {
+ 0x314f, /* 0x1161 */
+ 0x3150, /* 0x1162 */
+ 0x3151, /* 0x1163 */
+ 0x3152, /* 0x1164 */
+ 0x3153, /* 0x1165 */
+ 0x3154, /* 0x1166 */
+ 0x3155, /* 0x1167 */
+ 0x3156, /* 0x1168 */
+ 0x3157, /* 0x1169 */
+ 0x3158, /* 0x116a */
+ 0x3159, /* 0x116b */
+ 0x315a, /* 0x116c */
+ 0x315b, /* 0x116d */
+ 0x315c, /* 0x116e */
+ 0x315d, /* 0x116f */
+ 0x315e, /* 0x1170 */
+ 0x315f, /* 0x1171 */
+ 0x3160, /* 0x1172 */
+ 0x3161, /* 0x1173 */
+ 0x3162, /* 0x1174 */
+ 0x3163 /* 0x1175 */
+ };
+
+ if (ch < 0x1161 || ch > 0x1175)
+ return 0;
+ return table[ch - 0x1161];
+}
+
+wchar_t
+hangul_jongseong_to_cjamo(wchar_t ch)
+{
+ static wchar_t table[] = {
+ 0x3131, /* 0x11a8 */
+ 0x3132, /* 0x11a9 */
+ 0x3133, /* 0x11aa */
+ 0x3134, /* 0x11ab */
+ 0x3135, /* 0x11ac */
+ 0x3136, /* 0x11ad */
+ 0x3137, /* 0x11ae */
+ 0x3139, /* 0x11af */
+ 0x313a, /* 0x11b0 */
+ 0x313b, /* 0x11b1 */
+ 0x313c, /* 0x11b2 */
+ 0x313d, /* 0x11b3 */
+ 0x313e, /* 0x11b4 */
+ 0x313f, /* 0x11b5 */
+ 0x3140, /* 0x11b6 */
+ 0x3141, /* 0x11b7 */
+ 0x3142, /* 0x11b8 */
+ 0x3144, /* 0x11b9 */
+ 0x3145, /* 0x11ba */
+ 0x3146, /* 0x11bb */
+ 0x3147, /* 0x11bc */
+ 0x3148, /* 0x11bd */
+ 0x314a, /* 0x11be */
+ 0x314b, /* 0x11bf */
+ 0x314c, /* 0x11c0 */
+ 0x314d, /* 0x11c1 */
+ 0x314e /* 0x11c2 */
+ };
+
+ if (ch < 0x11a8 || ch > 0x11c2)
+ return 0;
+ return table[ch - 0x11a8];
+}
+
+wchar_t
+hangul_choseong_to_jongseong(wchar_t ch)
+{
+ static wchar_t table[] = {
+ 0x11a8, /* choseong kiyeok -> jongseong kiyeok */
+ 0x11a9, /* choseong ssangkiyeok -> jongseong ssangkiyeok */
+ 0x11ab, /* choseong nieun -> jongseong nieun */
+ 0x11ae, /* choseong tikeut -> jongseong tikeut */
+ 0x0, /* choseong ssangtikeut -> jongseong tikeut */
+ 0x11af, /* choseong rieul -> jongseong rieul */
+ 0x11b7, /* choseong mieum -> jongseong mieum */
+ 0x11b8, /* choseong pieup -> jongseong pieup */
+ 0x0, /* choseong ssangpieup -> jongseong pieup */
+ 0x11ba, /* choseong sios -> jongseong sios */
+ 0x11bb, /* choseong ssangsios -> jongseong ssangsios */
+ 0x11bc, /* choseong ieung -> jongseong ieung */
+ 0x11bd, /* choseong cieuc -> jongseong cieuc */
+ 0x0, /* choseong ssangcieuc -> jongseong cieuc */
+ 0x11be, /* choseong chieuch -> jongseong chieuch */
+ 0x11bf, /* choseong khieukh -> jongseong khieukh */
+ 0x11c0, /* choseong thieuth -> jongseong thieuth */
+ 0x11c1, /* choseong phieuph -> jongseong phieuph */
+ 0x11c2 /* choseong hieuh -> jongseong hieuh */
+ };
+ if (ch < 0x1100 || ch > 0x1112)
+ return 0;
+ return table[ch - 0x1100];
+}
+
+wchar_t
+hangul_jongseong_to_choseong(wchar_t ch)
+{
+ static wchar_t table[] = {
+ 0x1100, /* jongseong kiyeok -> choseong kiyeok */
+ 0x1101, /* jongseong ssangkiyeok -> choseong ssangkiyeok */
+ 0x1109, /* jongseong kiyeok-sios -> choseong sios */
+ 0x1102, /* jongseong nieun -> choseong nieun */
+ 0x110c, /* jongseong nieun-cieuc -> choseong cieuc */
+ 0x1112, /* jongseong nieun-hieuh -> choseong hieuh */
+ 0x1103, /* jongseong tikeut -> choseong tikeut */
+ 0x1105, /* jongseong rieul -> choseong rieul */
+ 0x1100, /* jongseong rieul-kiyeok -> choseong kiyeok */
+ 0x1106, /* jongseong rieul-mieum -> choseong mieum */
+ 0x1107, /* jongseong rieul-pieup -> choseong pieup */
+ 0x1109, /* jongseong rieul-sios -> choseong sios */
+ 0x1110, /* jongseong rieul-thieuth -> choseong thieuth */
+ 0x1111, /* jongseong rieul-phieuph -> choseong phieuph */
+ 0x1112, /* jongseong rieul-hieuh -> choseong hieuh */
+ 0x1106, /* jongseong mieum -> choseong mieum */
+ 0x1107, /* jongseong pieup -> choseong pieup */
+ 0x1109, /* jongseong pieup-sios -> choseong sios */
+ 0x1109, /* jongseong sios -> choseong sios */
+ 0x110a, /* jongseong ssangsios -> choseong ssangsios */
+ 0x110b, /* jongseong ieung -> choseong ieung */
+ 0x110c, /* jongseong cieuc -> choseong cieuc */
+ 0x110e, /* jongseong chieuch -> choseong chieuch */
+ 0x110f, /* jongseong khieukh -> choseong khieukh */
+ 0x1110, /* jongseong thieuth -> choseong thieuth */
+ 0x1111, /* jongseong phieuph -> choseong phieuph */
+ 0x1112 /* jongseong hieuh -> choseong hieuh */
+ };
+ if (ch < 0x11a8 || ch > 0x11c2)
+ return 0;
+ return table[ch - 0x11a8];
+}
+
+void
+hangul_jongseong_dicompose(wchar_t ch, wchar_t* jong, wchar_t* cho)
+{
+ static wchar_t table[][2] = {
+ { 0, 0x1100 }, /* jong kiyeok = cho kiyeok */
+ { 0x11a8, 0x1100 }, /* jong ssangkiyeok = jong kiyeok + cho kiyeok */
+ { 0x11a8, 0x1109 }, /* jong kiyeok-sios = jong kiyeok + cho sios */
+ { 0, 0x1102 }, /* jong nieun = cho nieun */
+ { 0x11ab, 0x110c }, /* jong nieun-cieuc = jong nieun + cho cieuc */
+ { 0x11ab, 0x1112 }, /* jong nieun-hieuh = jong nieun + cho hieuh */
+ { 0, 0x1103 }, /* jong tikeut = cho tikeut */
+ { 0, 0x1105 }, /* jong rieul = cho rieul */
+ { 0x11af, 0x1100 }, /* jong rieul-kiyeok = jong rieul + cho kiyeok */
+ { 0x11af, 0x1106 }, /* jong rieul-mieum = jong rieul + cho mieum */
+ { 0x11af, 0x1107 }, /* jong rieul-pieup = jong rieul + cho pieup */
+ { 0x11af, 0x1109 }, /* jong rieul-sios = jong rieul + cho sios */
+ { 0x11af, 0x1110 }, /* jong rieul-thieuth = jong rieul + cho thieuth */
+ { 0x11af, 0x1111 }, /* jong rieul-phieuph = jong rieul + cho phieuph */
+ { 0x11af, 0x1112 }, /* jong rieul-hieuh = jong rieul + cho hieuh */
+ { 0, 0x1106 }, /* jong mieum = cho mieum */
+ { 0, 0x1107 }, /* jong pieup = cho pieup */
+ { 0x11b8, 0x1109 }, /* jong pieup-sios = jong pieup + cho sios */
+ { 0, 0x1109 }, /* jong sios = cho sios */
+ { 0x11ba, 0x1109 }, /* jong ssangsios = jong sios + cho sios */
+ { 0, 0x110b }, /* jong ieung = cho ieung */
+ { 0, 0x110c }, /* jong cieuc = cho cieuc */
+ { 0, 0x110e }, /* jong chieuch = cho chieuch */
+ { 0, 0x110f }, /* jong khieukh = cho khieukh */
+ { 0, 0x1110 }, /* jong thieuth = cho thieuth */
+ { 0, 0x1111 }, /* jong phieuph = cho phieuph */
+ { 0, 0x1112 } /* jong hieuh = cho hieuh */
+ };
+
+ *jong = table[ch - 0x11a8][0];
+ *cho = table[ch - 0x11a8][1];
+}
+
+wchar_t
+hangul_jamo_to_syllable(wchar_t choseong, wchar_t jungseong, wchar_t jongseong)
+{
+ static wchar_t hangul_base = 0xac00;
+ static wchar_t choseong_base = 0x1100;
+ static wchar_t jungseong_base = 0x1161;
+ static wchar_t jongseong_base = 0x11a7;
+ static int njungseong = 21;
+ static int njongseong = 28;
+ wchar_t ch;
+
+ /* we use 0x11a7 like a Jongseong filler */
+ if (jongseong == 0)
+ jongseong = 0x11a7; /* Jongseong filler */
+
+ if (!(choseong >= 0x1100 && choseong <= 0x1112))
+ return 0;
+ if (!(jungseong >= 0x1161 && jungseong <= 0x1175))
+ return 0;
+ if (!(jongseong >= 0x11a7 && jongseong <= 0x11c2))
+ return 0;
+
+ choseong -= choseong_base;
+ jungseong -= jungseong_base;
+ jongseong -= jongseong_base;
+
+ ch = ((choseong * njungseong) + jungseong) * njongseong + jongseong
+ + hangul_base;
+ return ch;
+}
--- /dev/null
+/* libhangul
+ * Copyright (C) 2004 Choe Hwanjin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "hangul.h"
+#include "hangulkeyboard.h"
+
+#define N_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
+
+static void hangul_buffer_push(HangulBuffer *buffer, wchar_t ch);
+static wchar_t hangul_buffer_pop (HangulBuffer *buffer);
+static wchar_t hangul_buffer_peek(HangulBuffer *buffer);
+
+static void hangul_buffer_clear(HangulBuffer *buffer);
+static int hangul_buffer_get_string(HangulBuffer *buffer, wchar_t*buf, int buflen);
+static int hangul_buffer_get_jamo_string(HangulBuffer *buffer, wchar_t *buf, int buflen);
+
+static wchar_t hangul_ic_translate_jamo(HangulInputContext *hic, int ascii);
+static wchar_t hangul_ic_combine_jamo(HangulInputContext *hic, wchar_t first, wchar_t second);
+
+static void
+hangul_buffer_push(HangulBuffer *buffer, wchar_t ch)
+{
+ if (hangul_is_choseong(ch)) {
+ buffer->choseong = ch;
+ } else if (hangul_is_jungseong(ch)) {
+ buffer->jungseong = ch;
+ } else if (hangul_is_jongseong(ch)) {
+ buffer->jongseong = ch;
+ } else {
+ }
+
+ buffer->stack[++buffer->index] = ch;
+}
+
+static wchar_t
+hangul_buffer_pop(HangulBuffer *buffer)
+{
+ return buffer->stack[buffer->index--];
+}
+
+static wchar_t
+hangul_buffer_peek(HangulBuffer *buffer)
+{
+ return buffer->stack[buffer->index];
+}
+
+static void
+hangul_buffer_clear(HangulBuffer *buffer)
+{
+ buffer->choseong = 0;
+ buffer->jungseong = 0;
+ buffer->jongseong = 0;
+
+ buffer->index = -1;
+ buffer->stack[0] = 0;
+ buffer->stack[1] = 0;
+ buffer->stack[2] = 0;
+ buffer->stack[3] = 0;
+ buffer->stack[4] = 0;
+ buffer->stack[5] = 0;
+ buffer->stack[6] = 0;
+ buffer->stack[7] = 0;
+ buffer->stack[8] = 0;
+ buffer->stack[9] = 0;
+ buffer->stack[10] = 0;
+ buffer->stack[11] = 0;
+}
+
+static int
+hangul_buffer_get_jamo_string(HangulBuffer *buffer, wchar_t *buf, int buflen)
+{
+ int n = 0;
+
+ if (buffer->choseong) {
+ buf[n++] = buffer->choseong;
+ } else {
+ buf[n++] = HANGUL_CHOSEONG_FILLER;
+ }
+
+ if (buffer->jungseong) {
+ buf[n++] = buffer->jungseong;
+ } else {
+ buf[n++] = HANGUL_JUNGSEONG_FILLER;
+ }
+
+ if (buffer->jongseong) {
+ buf[n++] = buffer->jongseong;
+ }
+
+ buf[n] = L'\0';
+
+ return n;
+}
+
+static int
+hangul_buffer_get_string(HangulBuffer *buffer, wchar_t *buf, int buflen)
+{
+ wchar_t ch = L'\0';
+ int n = 0;
+
+ if (buffer->choseong) {
+ if (buffer->jungseong) {
+ /* have cho, jung, jong or no jong */
+ ch = hangul_jamo_to_syllable(buffer->choseong,
+ buffer->jungseong,
+ buffer->jongseong);
+ buf[n++] = ch;
+ } else {
+ if (buffer->jongseong) {
+ /* have cho, jong */
+ ch = hangul_choseong_to_cjamo(buffer->choseong);
+ buf[n++] = ch;
+ ch = hangul_jongseong_to_cjamo(buffer->jongseong);
+ buf[n++] = ch;
+ } else {
+ /* have cho */
+ ch = hangul_choseong_to_cjamo(buffer->choseong);
+ buf[n++] = ch;
+ }
+ }
+ } else {
+ if (buffer->jungseong) {
+ if (buffer->jongseong) {
+ /* have jung, jong */
+ ch = hangul_jungseong_to_cjamo(buffer->jungseong);
+ buf[n++] = ch;
+ ch = hangul_jongseong_to_cjamo(buffer->jongseong);
+ buf[n++] = ch;
+ } else {
+ /* have jung */
+ ch = hangul_jungseong_to_cjamo(buffer->jungseong);
+ buf[n++] = ch;
+ }
+ } else {
+ if (buffer->jongseong) {
+ /* have jong */
+ ch = hangul_jongseong_to_cjamo(buffer->jongseong);
+ buf[n++] = ch;
+ } else {
+ /* have nothing */
+ buf[n] = L'\0';
+ }
+ }
+ }
+ buf[n] = L'\0';
+
+ return n;
+}
+
+static bool
+hangul_buffer_backspace(HangulBuffer *buffer)
+{
+ if (buffer->index >= 0) {
+ wchar_t ch = hangul_buffer_pop(buffer);
+ if (ch == 0)
+ return false;
+
+ if (hangul_is_choseong(ch)) {
+ ch = hangul_buffer_peek(buffer);
+ buffer->choseong = hangul_is_choseong(ch) ? ch : 0;
+ return true;
+ } else if (hangul_is_jungseong(ch)) {
+ ch = hangul_buffer_peek(buffer);
+ buffer->jungseong = hangul_is_jungseong(ch) ? ch : 0;
+ return true;
+ } else if (hangul_is_jongseong(ch)) {
+ ch = hangul_buffer_peek(buffer);
+ buffer->jongseong = hangul_is_jongseong(ch) ? ch : 0;
+ return true;
+ }
+ }
+ return false;
+}
+
+static wchar_t
+hangul_ic_translate_jamo(HangulInputContext *hic, int ascii)
+{
+ wchar_t ch = ascii;
+
+ if (ascii >= '!' && ascii <= '~') {
+ ch = hic->keyboard_table[ascii - '!'];
+ }
+
+ return ch;
+}
+
+static wchar_t
+hangul_ic_combine_jamo(HangulInputContext *hic, wchar_t first, wchar_t second)
+{
+ int min, max, mid;
+ uint32_t key;
+
+ /* make key */
+ key = first << 16 | second;
+
+ /* binary search in table */
+ min = 0;
+ max = hic->combination_table_size - 1;
+
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (hic->combination_table[mid].key < key)
+ min = mid + 1;
+ else if (hic->combination_table[mid].key > key)
+ max = mid - 1;
+ else
+ return hic->combination_table[mid].code;
+ }
+ return 0;
+}
+
+static inline void
+hangul_ic_push(HangulInputContext *hic, wchar_t ch)
+{
+ hangul_buffer_push(&hic->buffer, ch);
+}
+
+static inline wchar_t
+hangul_ic_pop(HangulInputContext *hic)
+{
+ return hangul_buffer_pop(&hic->buffer);
+}
+
+static inline wchar_t
+hangul_ic_peek(HangulInputContext *hic)
+{
+ return hangul_buffer_peek(&hic->buffer);
+}
+
+static inline void
+hangul_ic_save_preedit_string(HangulInputContext *hic)
+{
+ if (hic->output_mode == HANGUL_OUTPUT_JAMO) {
+ hangul_buffer_get_jamo_string(&hic->buffer,
+ hic->preedit_string,
+ N_ELEMENTS(hic->preedit_string));
+ } else {
+ hangul_buffer_get_string(&hic->buffer,
+ hic->preedit_string,
+ N_ELEMENTS(hic->preedit_string));
+ }
+}
+
+static inline void
+hangul_ic_save_commit_string(HangulInputContext *hic)
+{
+ if (hic->output_mode == HANGUL_OUTPUT_JAMO) {
+ hangul_buffer_get_jamo_string(&hic->buffer,
+ hic->commit_string,
+ N_ELEMENTS(hic->commit_string));
+ } else {
+ hangul_buffer_get_string(&hic->buffer,
+ hic->commit_string,
+ N_ELEMENTS(hic->commit_string));
+ }
+ hangul_buffer_clear(&hic->buffer);
+}
+
+static bool
+hangul_ic_filter_2(HangulInputContext *hic, wchar_t ch)
+{
+ wchar_t jong;
+ wchar_t combined;
+
+ if (hic->buffer.jongseong) {
+ if (hangul_is_choseong(ch)) {
+ jong = hangul_choseong_to_jongseong(ch);
+ combined = hangul_ic_combine_jamo(hic,
+ hic->buffer.jongseong, jong);
+ if (hangul_is_jongseong(combined)) {
+ hangul_ic_push(hic, combined);
+ } else {
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, ch);
+ }
+ } else if (hangul_is_jungseong(ch)) {
+ wchar_t pop, peek;
+ pop = hangul_ic_pop(hic);
+ peek = hangul_ic_peek(hic);
+
+ if (hangul_is_jungseong(peek)) {
+ hic->buffer.jongseong = 0;
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, hangul_jongseong_to_choseong(pop));
+ hangul_ic_push(hic, ch);
+ } else {
+ wchar_t choseong = 0, jongseong = 0;
+ hangul_jongseong_dicompose(hic->buffer.jongseong,
+ &jongseong, &choseong);
+ hangul_ic_push(hic, jongseong);
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, choseong);
+ hangul_ic_push(hic, ch);
+ }
+ } else {
+ goto none_hangul;
+ }
+ } else if (hic->buffer.jungseong) {
+ if (hangul_is_choseong(ch)) {
+ if (hic->buffer.choseong) {
+ jong = hangul_choseong_to_jongseong(ch);
+ if (hangul_is_jongseong(jong)) {
+ hangul_ic_push(hic, jong);
+ } else {
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, ch);
+ }
+ } else {
+ hangul_ic_push(hic, ch);
+ }
+ } else if (hangul_is_jungseong(ch)) {
+ combined = hangul_ic_combine_jamo(hic, hic->buffer.jungseong, ch);
+ if (hangul_is_jungseong(combined)) {
+ hangul_ic_push(hic, combined);
+ } else {
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, ch);
+ }
+ } else {
+ goto none_hangul;
+ }
+ } else if (hic->buffer.choseong) {
+ if (hangul_is_choseong(ch)) {
+ combined = hangul_ic_combine_jamo(hic, hic->buffer.choseong, ch);
+ if (hangul_is_choseong(combined)) {
+ hangul_ic_push(hic, combined);
+ } else {
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, ch);
+ }
+ } else if (hangul_is_jungseong(ch)) {
+ hangul_ic_push(hic, ch);
+ } else {
+ goto none_hangul;
+ }
+ } else {
+ if (hangul_is_choseong(ch)) {
+ hangul_ic_push(hic, ch);
+ } else if (hangul_is_jungseong(ch)) {
+ hangul_ic_push(hic, ch);
+ } else {
+ goto none_hangul;
+ }
+ }
+
+ hangul_ic_save_preedit_string(hic);
+ return true;
+
+none_hangul:
+ hangul_ic_save_commit_string(hic);
+ return false;
+}
+
+static bool
+hangul_ic_filter_3(HangulInputContext *hic, wchar_t ch)
+{
+ if (hangul_is_choseong(ch)) {
+ if (hic->buffer.choseong == 0) {
+ hangul_ic_push(hic, ch);
+ } else {
+ wchar_t choseong = 0;
+ if (hangul_is_choseong(hangul_ic_peek(hic))) {
+ choseong = hangul_ic_combine_jamo(hic,
+ hic->buffer.choseong, ch);
+ }
+ if (choseong) {
+ hangul_ic_push(hic, choseong);
+ } else {
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, ch);
+ }
+ }
+ } else if (hangul_is_jungseong(ch)) {
+ if (hic->buffer.jungseong == 0) {
+ hangul_ic_push(hic, ch);
+ } else {
+ wchar_t jungseong = 0;
+ if (hangul_is_jungseong(hangul_ic_peek(hic))) {
+ jungseong = hangul_ic_combine_jamo(hic,
+ hic->buffer.jungseong, ch);
+ }
+ if (jungseong) {
+ hangul_ic_push(hic, jungseong);
+ } else {
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, ch);
+ }
+ }
+ } else if (hangul_is_jongseong(ch)) {
+ if (hic->buffer.jongseong == 0) {
+ hangul_ic_push(hic, ch);
+ } else {
+ wchar_t jongseong = 0;
+ if (hangul_is_jongseong(hangul_ic_peek(hic))) {
+ jongseong = hangul_ic_combine_jamo(hic,
+ hic->buffer.jongseong, ch);
+ if (jongseong) {
+ hangul_ic_push(hic, jongseong);
+ } else {
+ hangul_ic_save_commit_string(hic);
+ hangul_ic_push(hic, ch);
+ }
+ }
+ }
+ } else {
+ hangul_ic_save_commit_string(hic);
+ return false;
+ }
+
+ hangul_ic_save_preedit_string(hic);
+ return true;
+}
+
+bool
+hangul_ic_filter(HangulInputContext *hic, int ascii, bool capslock)
+{
+ wchar_t ch;
+
+ if (hic == NULL)
+ return false;
+
+ if (capslock) {
+ if (isupper(ascii)) {
+ ascii = tolower(ascii);
+ } else {
+ ascii = toupper(ascii);
+ }
+ }
+
+ ch = hangul_ic_translate_jamo(hic, ascii);
+
+ hic->preedit_string[0] = 0;
+ hic->commit_string[0] = 0;
+
+ if (hic->type == HANGUL_INPUT_FILTER_2)
+ return hangul_ic_filter_2(hic, ch);
+ else
+ return hangul_ic_filter_3(hic, ch);
+}
+
+const wchar_t*
+hangul_ic_get_preedit_string(HangulInputContext *hic)
+{
+ if (hic == NULL)
+ return NULL;
+
+ return hic->preedit_string;
+}
+
+const wchar_t*
+hangul_ic_get_commit_string(HangulInputContext *hic)
+{
+ if (hic == NULL)
+ return NULL;
+
+ return hic->commit_string;
+}
+
+void
+hangul_ic_reset(HangulInputContext *hic)
+{
+ if (hic == NULL)
+ return;
+
+ hangul_ic_save_commit_string(hic);
+}
+
+bool
+hangul_ic_backspace(HangulInputContext *hic)
+{
+ int ret;
+
+ if (hic == NULL)
+ return false;
+
+ ret = hangul_buffer_backspace(&hic->buffer);
+ if (ret)
+ hangul_ic_save_preedit_string(hic);
+ return ret;
+}
+
+void
+hangul_ic_set_output_mode(HangulInputContext *hic, int mode)
+{
+ if (hic == NULL)
+ return;
+
+ hic->output_mode = mode;
+}
+
+void
+hangul_ic_set_keyboard(HangulInputContext *hic, int keyboard)
+{
+ if (hic == NULL)
+ return;
+
+ switch (keyboard) {
+ case HANGUL_KEYBOARD_2:
+ hic->type = HANGUL_INPUT_FILTER_2;
+ hic->keyboard_table = hangul_keyboard_table_2;
+ hic->combination_table = hangul_combination_table_default;
+ hic->combination_table_size = N_ELEMENTS(hangul_combination_table_default);
+ break;
+ case HANGUL_KEYBOARD_32:
+ hic->type = HANGUL_INPUT_FILTER_3;
+ hic->keyboard_table = hangul_keyboard_table_32;
+ hic->combination_table = hangul_combination_table_default;
+ hic->combination_table_size = N_ELEMENTS(hangul_combination_table_default);
+ break;
+ case HANGUL_KEYBOARD_3FINAL:
+ hic->type = HANGUL_INPUT_FILTER_3;
+ hic->keyboard_table = hangul_keyboard_table_3final;
+ hic->combination_table = hangul_combination_table_default;
+ hic->combination_table_size = N_ELEMENTS(hangul_combination_table_default);
+ break;
+ case HANGUL_KEYBOARD_390:
+ hic->type = HANGUL_INPUT_FILTER_3;
+ hic->keyboard_table = hangul_keyboard_table_390;
+ hic->combination_table = hangul_combination_table_default;
+ hic->combination_table_size = N_ELEMENTS(hangul_combination_table_default);
+ break;
+ case HANGUL_KEYBOARD_3NOSHIFT:
+ hic->type = HANGUL_INPUT_FILTER_3;
+ hic->keyboard_table = hangul_keyboard_table_3sun;
+ hic->combination_table = hangul_combination_table_default;
+ hic->combination_table_size = N_ELEMENTS(hangul_combination_table_default);
+ break;
+ default:
+ hic->type = HANGUL_INPUT_FILTER_2;
+ hic->keyboard_table = hangul_keyboard_table_2;
+ hic->combination_table = hangul_combination_table_default;
+ hic->combination_table_size = N_ELEMENTS(hangul_combination_table_default);
+ break;
+ }
+}
+
+HangulInputContext*
+hangul_ic_new(int keyboard)
+{
+ HangulInputContext *hic;
+
+ hic = malloc(sizeof(HangulInputContext));
+ if (hic == NULL)
+ return NULL;
+
+ hic->output_mode = HANGUL_OUTPUT_SYLLABLE;
+
+ hangul_ic_set_output_mode(hic, HANGUL_OUTPUT_SYLLABLE);
+ hangul_ic_set_keyboard(hic, keyboard);
+
+ hangul_buffer_clear(&hic->buffer);
+
+ return hic;
+}
+
+void
+hangul_ic_delete(HangulInputContext *hic)
+{
+ if (hic == NULL)
+ return;
+
+ free(hic);
+}
--- /dev/null
+#include "hangul.h"
+
+static const wchar_t hangul_keyboard_table_2[] = {
+ 0x0021, /* exclam: exclamation mark */
+ 0x0022, /* quotedbl: quotation mark */
+ 0x0023, /* numbersign: number sign */
+ 0x0024, /* dollar: dollar sign */
+ 0x0025, /* percent: percent sign */
+ 0x0026, /* ampersand: ampersand */
+ 0x0027, /* apostrophe: apostrophe */
+ 0x0028, /* parenleft: left parenthesis */
+ 0x0029, /* parenright: right parenthesis */
+ 0x002a, /* asterisk: asterisk */
+ 0x002b, /* plus: plus sign */
+ 0x002c, /* comma: comma */
+ 0x002d, /* minus: minus sign */
+ 0x002e, /* period: period */
+ 0x002f, /* slash: slash */
+ 0x0030, /* 0: 0 */
+ 0x0031, /* 1: 1 */
+ 0x0032, /* 2: 2 */
+ 0x0033, /* 3: 3 */
+ 0x0034, /* 4: 4 */
+ 0x0035, /* 5: 5 */
+ 0x0036, /* 6: 6 */
+ 0x0037, /* 7: 7 */
+ 0x0038, /* 8: 8 */
+ 0x0039, /* 9: 9 */
+ 0x003a, /* colon: colon */
+ 0x003b, /* semicolon: semicolon */
+ 0x003c, /* less: less-than sign */
+ 0x003d, /* equal: equals sign */
+ 0x003e, /* greater: greater-than sign */
+ 0x003f, /* question: question mark */
+ 0x0040, /* at: commercial at */
+ 0x1106, /* A: choseong mieum */
+ 0x1172, /* B: jungseong yu */
+ 0x110e, /* C: choseong chieuch */
+ 0x110b, /* D: choseong ieung */
+ 0x1104, /* E: choseong ssangtikeut */
+ 0x1105, /* F: choseong rieul */
+ 0x1112, /* G: choseong hieuh */
+ 0x1169, /* H: jungseong o */
+ 0x1163, /* I: jungseong ya */
+ 0x1165, /* J: jungseong eo */
+ 0x1161, /* K: jungseong a */
+ 0x1175, /* L: jungseong i */
+ 0x1173, /* M: jungseong eu */
+ 0x116e, /* N: jungseong u */
+ 0x1164, /* O: jungseong yae */
+ 0x1168, /* P: jungseong ye */
+ 0x1108, /* Q: choseong ssangpieup */
+ 0x1101, /* R: choseong ssangkiyeok */
+ 0x1102, /* S: choseong nieun */
+ 0x110a, /* T: choseong ssangsios */
+ 0x1167, /* U: jungseong yeo */
+ 0x1111, /* V: choseong phieuph */
+ 0x110d, /* W: choseong ssangcieuc */
+ 0x1110, /* X: choseong thieuth */
+ 0x116d, /* Y: jungseong yo */
+ 0x110f, /* Z: choseong khieukh */
+ 0x005b, /* bracketleft: left bracket */
+ 0x005c, /* backslash: backslash */
+ 0x005d, /* bracketright: right bracket */
+ 0x005e, /* asciicircum: circumflex accent */
+ 0x005f, /* underscore: underscore */
+ 0x0060, /* quoteleft: grave accent */
+ 0x1106, /* a: choseong mieum */
+ 0x1172, /* b: jungseong yu */
+ 0x110e, /* c: choseong chieuch */
+ 0x110b, /* d: choseong ieung */
+ 0x1103, /* e: choseong tikeut */
+ 0x1105, /* f: choseong rieul */
+ 0x1112, /* g: choseong hieuh */
+ 0x1169, /* h: jungseong o */
+ 0x1163, /* i: jungseong ya */
+ 0x1165, /* j: jungseong eo */
+ 0x1161, /* k: jungseong a */
+ 0x1175, /* l: jungseong i */
+ 0x1173, /* m: jungseong eu */
+ 0x116e, /* n: jungseong u */
+ 0x1162, /* o: jungseong ae */
+ 0x1166, /* p: jungseong e */
+ 0x1107, /* q: choseong pieup */
+ 0x1100, /* r: choseong kiyeok */
+ 0x1102, /* s: choseong nieun */
+ 0x1109, /* t: choseong sios */
+ 0x1167, /* u: jungseong yeo */
+ 0x1111, /* v: choseong phieuph */
+ 0x110c, /* w: choseong cieuc */
+ 0x1110, /* x: choseong thieuth */
+ 0x116d, /* y: jungseong yo */
+ 0x110f, /* z: choseong khieukh */
+ 0x007b, /* braceleft: left brace */
+ 0x007c, /* bar: vertical bar */
+ 0x007d, /* braceright: right brace */
+ 0x007e /* asciitilde: tilde */
+};
+
+static const wchar_t hangul_keyboard_table_32[] = {
+ 0x0021, /* exclam: exclamation mark */
+ 0x0022, /* quotedbl: quotation mark */
+ 0x0023, /* numbersign: number sign */
+ 0x0024, /* dollar: dollar sign */
+ 0x0025, /* percent: percent sign */
+ 0x0026, /* ampersand: ampersand */
+ 0x0027, /* apostrophe: apostrophe */
+ 0x0028, /* parenleft: left parenthesis */
+ 0x0029, /* parenright: right parenthesis */
+ 0x002a, /* asterisk: asterisk */
+ 0x002b, /* plus: plus sign */
+ 0x002c, /* comma: comma */
+ 0x002d, /* minus: minus sign */
+ 0x002e, /* period: period */
+ 0x002f, /* slash: slash */
+ 0x0030, /* 0: 0 */
+ 0x0031, /* 1: 1 */
+ 0x0032, /* 2: 2 */
+ 0x0033, /* 3: 3 */
+ 0x0034, /* 4: 4 */
+ 0x0035, /* 5: 5 */
+ 0x0036, /* 6: 6 */
+ 0x0037, /* 7: 7 */
+ 0x0038, /* 8: 8 */
+ 0x0039, /* 9: 9 */
+ 0x003a, /* colon: colon */
+ 0x003b, /* semicolon: semicolon */
+ 0x003c, /* less: less-than sign */
+ 0x003d, /* equal: equals sign */
+ 0x003e, /* greater: greater-than sign */
+ 0x003f, /* question: question mark */
+ 0x0040, /* at: commercial at */
+ 0x11b7, /* A: jongseong mieum */
+ 0x1172, /* B: jungseong yu */
+ 0x11be, /* C: jongseong chieuch */
+ 0x11bc, /* D: jongseong ieung */
+ 0x11ae, /* E: jongseong tikeut */
+ 0x11af, /* F: jongseong rieul */
+ 0x11c2, /* G: jongseong hieuh */
+ 0x1169, /* H: jungseong o */
+ 0x1163, /* I: jungseong ya */
+ 0x1165, /* J: jungseong eo */
+ 0x1161, /* K: jungseong a */
+ 0x1175, /* L: jungseong i */
+ 0x1173, /* M: jungseong eu */
+ 0x116e, /* N: jungseong u */
+ 0x1164, /* O: jungseong yae */
+ 0x1168, /* P: jungseong ye */
+ 0x11b8, /* Q: jongseong pieup */
+ 0x11a8, /* R: jongseong kiyeok */
+ 0x11ab, /* S: jongseong nieun */
+ 0x11ba, /* T: jongseong sios */
+ 0x1167, /* U: jungseong yeo */
+ 0x11c1, /* V: jongseong phieuph */
+ 0x11bd, /* W: jongseong cieuc */
+ 0x11c0, /* X: jongseong thieuth */
+ 0x116d, /* Y: jungseong yo */
+ 0x11bf, /* Z: jongseong khieukh */
+ 0x002a, /* bracketleft: left bracket */
+ 0x005c, /* backslash: backslash */
+ 0x005d, /* bracketright:right bracket */
+ 0x005e, /* asciicircum: circumflex accent */
+ 0x005f, /* underscore: underscore */
+ 0x0060, /* quoteleft: grave accent */
+ 0x1106, /* a: choseong mieum */
+ 0x1172, /* b: jungseong yu */
+ 0x110e, /* c: choseong chieuch */
+ 0x110b, /* d: choseong ieung */
+ 0x1103, /* e: choseong tikeut */
+ 0x1105, /* f: choseong rieul */
+ 0x1112, /* g: choseong hieuh */
+ 0x1169, /* h: jungseong o */
+ 0x1163, /* i: jungseong ya */
+ 0x1165, /* j: jungseong eo */
+ 0x1161, /* k: jungseong a */
+ 0x1175, /* l: jungseong i */
+ 0x1173, /* m: jungseong eu */
+ 0x116e, /* n: jungseong u */
+ 0x1162, /* o: jungseong ae */
+ 0x1166, /* p: jungseong e */
+ 0x1107, /* q: choseong pieup */
+ 0x1100, /* r: choseong kiyeok */
+ 0x1102, /* s: choseong nieun */
+ 0x1109, /* t: choseong sios */
+ 0x1167, /* u: jungseong yeo */
+ 0x1111, /* v: choseong phieuph */
+ 0x110c, /* w: choseong cieuc */
+ 0x1110, /* x: choseong thieuth */
+ 0x116d, /* y: jungseong yo */
+ 0x110f, /* z: choseong khieukh */
+ 0x007b, /* braceleft: left brace */
+ 0x007c, /* bar: vertical bar */
+ 0x007d, /* braceright: right brace */
+ 0x203b, /* asciitilde: tilde */
+};
+
+static const wchar_t hangul_keyboard_table_390[] = {
+ 0x11bd, /* exclam: jongseong cieuc */
+ 0x0022, /* quotedbl: quotatioin mark */
+ 0x0023, /* numbersign: number sign */
+ 0x0024, /* dollar: dollar sign */
+ 0x0025, /* percent: percent sign */
+ 0x0026, /* ampersand: ampersand */
+ 0x1110, /* apostrophe: choseong thieuth */
+ 0x0028, /* parenleft: left parenthesis */
+ 0x0029, /* parenright: right parenthesis */
+ 0x002a, /* asterisk: asterisk */
+ 0x002b, /* plus: plus sign */
+ 0x002c, /* comma: comma */
+ 0x002d, /* minus: minus sign */
+ 0x002e, /* period: period */
+ 0x1169, /* slash: jungseong o */
+ 0x110f, /* 0: choseong khieukh */
+ 0x11c2, /* 1: jongseong hieuh */
+ 0x11bb, /* 2: jongseong ssangsios */
+ 0x11b8, /* 3: jongseong pieup */
+ 0x116d, /* 4: jungseong yo */
+ 0x1172, /* 5: jungseong yu */
+ 0x1163, /* 6: jungseong ya */
+ 0x1168, /* 7: jungseong ye */
+ 0x1174, /* 8: jungseong yi */
+ 0x116e, /* 9: jungseong u */
+ 0x003a, /* colon: colon */
+ 0x1107, /* semicolon: choseong pieup */
+ 0x0032, /* less: 2 */
+ 0x003d, /* equal: euals sign */
+ 0x0033, /* greater: 3 */
+ 0x003f, /* question: question mark */
+ 0x0040, /* at: commertial at */
+ 0x11ae, /* A: jongseong tikeut */
+ 0x0021, /* B: exclamation mark */
+ 0x11b1, /* C: jongseong rieul-mieum */
+ 0x11b0, /* D: jongseong rieul-kiyeok */
+ 0x11bf, /* E: jongseong khieukh */
+ 0x11a9, /* F: jongseong ssangkiyeok */
+ 0x002f, /* G: slash */
+ 0x0027, /* H: apostrophe */
+ 0x0038, /* I: 8 */
+ 0x0034, /* J: 4 */
+ 0x0035, /* K: 5 */
+ 0x0036, /* L: 6 */
+ 0x0031, /* M: 1 */
+ 0x0030, /* N: 0 */
+ 0x0039, /* O: 9 */
+ 0x003e, /* P: greater-than sign */
+ 0x11c1, /* Q: jongseong phieuph */
+ 0x1164, /* R: jungseong yae */
+ 0x11ad, /* S: jongseong nieun-hieuh */
+ 0x003b, /* T: semicolon */
+ 0x0037, /* U: 7 */
+ 0x11b6, /* V: jongseong rieul-hieuh */
+ 0x11c0, /* W: jongseong thikeuth */
+ 0x11b9, /* X: jongseong pieup-sios */
+ 0x003c, /* Y: less-than sign */
+ 0x11be, /* Z: jongseong chieuch */
+ 0x005b, /* bracketleft: left bracket */
+ 0x005c, /* backslash: backslash */
+ 0x005d, /* bracketright: right bracket */
+ 0x005e, /* asciicircum: circumflex accent */
+ 0x005f, /* underscore: underscore */
+ 0x0060, /* quoteleft: grave accent */
+ 0x11bc, /* a: jongseong ieung */
+ 0x116e, /* b: jungseong u */
+ 0x1166, /* c: jungseong e */
+ 0x1175, /* d: jungseong i */
+ 0x1167, /* e: jungseong yeo */
+ 0x1161, /* f: jungseong a */
+ 0x1173, /* g: jungseong eu */
+ 0x1102, /* h: choseong nieun */
+ 0x1106, /* i: choseong mieum */
+ 0x110b, /* j: choseong ieung */
+ 0x1100, /* k: choseong kiyeok */
+ 0x110c, /* l: choseong cieuc */
+ 0x1112, /* m: choseong hieuh */
+ 0x1109, /* n: choseong sios */
+ 0x110e, /* o: choseong chieuch */
+ 0x1111, /* p: choseong phieuph */
+ 0x11ba, /* q: jongseong sios */
+ 0x1162, /* r: jungseong ae */
+ 0x11ab, /* s: jongseong nieun */
+ 0x1165, /* t: jungseong eo */
+ 0x1103, /* u: choseong tikeut */
+ 0x1169, /* v: jungseong o */
+ 0x11af, /* w: jongseong rieul */
+ 0x11a8, /* x: jongseong kiyeok */
+ 0x1105, /* y: choseong rieul */
+ 0x11b7, /* z: jongseong mieum */
+ 0x007b, /* braceleft: left brace */
+ 0x007c, /* bar: vertical line(bar) */
+ 0x007d, /* braceright: right brace */
+ 0x007e, /* asciitilde: tilde */
+};
+
+static const wchar_t hangul_keyboard_table_3final[] = {
+ 0x11a9, /* exclam: jongseong ssangkiyeok */
+ 0x00b7, /* quotedbl: middle dot */
+ 0x11bd, /* numbersign: jognseong cieuc */
+ 0x11b5, /* dollar: jongseong rieul-phieuph */
+ 0x11b4, /* percent: jongseong rieul-thieuth */
+ 0x201c, /* ampersand: left double quotation mark */
+ 0x1110, /* apostrophe: choseong thieuth */
+ 0x0027, /* parenleft: apostrophe */
+ 0x007e, /* parenright: Tilde */
+ 0x201d, /* asterisk: right double quotation mark */
+ 0x002b, /* plus: plus sign */
+ 0x002c, /* comma: comma */
+ 0x0029, /* minus: right parenthesis */
+ 0x002e, /* period: period */
+ 0x1169, /* slash: jungseong o */
+ 0x110f, /* 0: choseong khieukh */
+ 0x11c2, /* 1: jongseong hieuh */
+ 0x11bb, /* 2: jongseong ssangsios */
+ 0x11b8, /* 3: jongseong pieup */
+ 0x116d, /* 4: jungseong yo */
+ 0x1172, /* 5: jungseong yu */
+ 0x1163, /* 6: jungseong ya */
+ 0x1168, /* 7: jungseong ye */
+ 0x1174, /* 8: jungseong yi */
+ 0x116e, /* 9: jungseong u */
+ 0x0034, /* colon: 4 */
+ 0x1107, /* semicolon: choseong pieup */
+ 0x002c, /* less: comma */
+ 0x003e, /* equal: greater-than sign */
+ 0x002e, /* greater: period */
+ 0x0021, /* question: exclamation mark */
+ 0x11b0, /* at: jongseong rieul-kiyeok */
+ 0x11ae, /* A: jongseong tikeut */
+ 0x003f, /* B: question mark */
+ 0x11bf, /* C: jongseong khieukh */
+ 0x11b2, /* D: jongseong rieul-pieup */
+ 0x11ac, /* E: jongseong nieun-cieuc */
+ 0x11b1, /* F: jongseong rieul-mieum */
+ 0x1164, /* G: jungseong yae */
+ 0x0030, /* H: 0 */
+ 0x0037, /* I: 7 */
+ 0x0031, /* J: 1 */
+ 0x0032, /* K: 2 */
+ 0x0033, /* L: 3 */
+ 0x0022, /* M: double quotation mark */
+ 0x002d, /* N: minus sign */
+ 0x0038, /* O: 8 */
+ 0x0039, /* P: 9 */
+ 0x11c1, /* Q: jongseong phieuph */
+ 0x11b6, /* R: jongseong rieul-hieuh */
+ 0x11ad, /* S: jongseong nieun-hieuh */
+ 0x11b3, /* T: jongseong rieul-sios */
+ 0x0036, /* U: 6 */
+ 0x11aa, /* V: jongseong kiyeok-sios */
+ 0x11c0, /* W: jongseong thikeuth */
+ 0x11b9, /* X: jongseong pieup-sios */
+ 0x0035, /* Y: 5 */
+ 0x11be, /* Z: jongseong chieuch */
+ 0x0028, /* bracketleft: left parenthesis */
+ 0x003a, /* backslash: colon */
+ 0x003c, /* bracketright: less-than sign */
+ 0x003d, /* asciicircum: equals sign */
+ 0x003b, /* underscore: semicolon */
+ 0x002a, /* quoteleft: asterisk */
+ 0x11bc, /* a: jongseong ieung */
+ 0x116e, /* b: jungseong u */
+ 0x1166, /* c: jungseong e */
+ 0x1175, /* d: jungseong i */
+ 0x1167, /* e: jungseong yeo */
+ 0x1161, /* f: jungseong a */
+ 0x1173, /* g: jungseong eu */
+ 0x1102, /* h: choseong nieun */
+ 0x1106, /* i: choseong mieum */
+ 0x110b, /* j: choseong ieung */
+ 0x1100, /* k: choseong kiyeok */
+ 0x110c, /* l: choseong cieuc */
+ 0x1112, /* m: choseong hieuh */
+ 0x1109, /* n: choseong sios */
+ 0x110e, /* o: choseong chieuch */
+ 0x1111, /* p: choseong phieuph */
+ 0x11ba, /* q: jongseong sios */
+ 0x1162, /* r: jungseong ae */
+ 0x11ab, /* s: jongseong nieun */
+ 0x1165, /* t: jungseong eo */
+ 0x1103, /* u: choseong tikeut */
+ 0x1169, /* v: jungseong o */
+ 0x11af, /* w: jongseong rieul */
+ 0x11a8, /* x: jongseong kiyeok */
+ 0x1105, /* y: choseong rieul */
+ 0x11b7, /* z: jongseong mieum */
+ 0x0025, /* braceleft: percent sign */
+ 0x005c, /* bar: backslash */
+ 0x002f, /* braceright: slash */
+ 0x203b, /* asciitilde: reference mark */
+};
+
+static const wchar_t hangul_keyboard_table_3sun[] = {
+ 0x0021, /* exclam: exclamation mark */
+ 0x0022, /* quotedbl: quotatioin mark */
+ 0x0023, /* numbersign: number sign */
+ 0x0024, /* dollar: dollar sign */
+ 0x0025, /* percent: percent sign */
+ 0x0026, /* ampersand: ampersand */
+ 0x1110, /* apostrophe: choseong thieuth */
+ 0x0028, /* parenleft: left parenthesis */
+ 0x0029, /* parenright: right parenthesis */
+ 0x002a, /* asterisk: asterisk */
+ 0x002b, /* plus: plus sign */
+ 0x002c, /* comma: comma */
+ 0x11bd, /* minus: jongseong cieuc */
+ 0x002e, /* period: period */
+ 0x11ae, /* slash: jongseong tikeut */
+ 0x1164, /* 0: choseong yae */
+ 0x11c2, /* 1: jongseong hieuh */
+ 0x11bb, /* 2: jongseong ssangsios */
+ 0x11b8, /* 3: jongseong pieup */
+ 0x116d, /* 4: jungseong yo */
+ 0x1172, /* 5: jungseong yu */
+ 0x1163, /* 6: jungseong ya */
+ 0x1168, /* 7: jungseong ye */
+ 0x1174, /* 8: jungseong yi */
+ 0x110f, /* 9: choseong khieukh */
+ 0x003a, /* colon: colon */
+ 0x1107, /* semicolon: choseong pieup */
+ 0x0032, /* less: 2 */
+ 0x11be, /* equal: jongseong chieuch */
+ 0x0033, /* greater: 3 */
+ 0x003f, /* question: question mark */
+ 0x0040, /* at: commertial at */
+ 0x11bc, /* A: jongseong ieung */
+ 0x0021, /* B: exclamation mark */
+ 0x005c, /* C: backslash */
+ 0x005d, /* D: right bracket */
+ 0x1167, /* E: jungseong yeo */
+ 0x1161, /* F: jungseong a */
+ 0x002f, /* G: slash */
+ 0x0027, /* H: apostrophe */
+ 0x0038, /* I: 8 */
+ 0x0034, /* J: 4 */
+ 0x0035, /* K: 5 */
+ 0x0036, /* L: 6 */
+ 0x0031, /* M: 1 */
+ 0x0030, /* N: 0 */
+ 0x0039, /* O: 9 */
+ 0x003e, /* P: greater-than sign */
+ 0x11ba, /* Q: jongseong sios */
+ 0x1162, /* R: jungseong ae */
+ 0x005b, /* S: left bracket */
+ 0x003b, /* T: semicolon */
+ 0x0037, /* U: 7 */
+ 0x1169, /* V: jungseong o */
+ 0x11af, /* W: jongseong rieul */
+ 0x003d, /* X: equals sign */
+ 0x003c, /* Y: less-than sign */
+ 0x002d, /* Z: minus sign */
+ 0x11c0, /* bracketleft: jongseong thieuth */
+ 0x11bf, /* backslash: jongseong khieukh */
+ 0x11c1, /* bracketright: jongseong phieuph */
+ 0x005e, /* asciicircum: circumflex accent */
+ 0x005f, /* underscore: underscore */
+ 0x0060, /* quoteleft: grave accent */
+ 0x11bc, /* a: jongseong ieung */
+ 0x116e, /* b: jungseong u */
+ 0x1166, /* c: jungseong e */
+ 0x1175, /* d: jungseong i */
+ 0x1167, /* e: jungseong yeo */
+ 0x1161, /* f: jungseong a */
+ 0x1173, /* g: jungseong eu */
+ 0x1102, /* h: choseong nieun */
+ 0x1106, /* i: choseong mieum */
+ 0x110b, /* j: choseong ieung */
+ 0x1100, /* k: choseong kiyeok */
+ 0x110c, /* l: choseong cieuc */
+ 0x1112, /* m: choseong hieuh */
+ 0x1109, /* n: choseong sios */
+ 0x110e, /* o: choseong chieuch */
+ 0x1111, /* p: choseong phieuph */
+ 0x11ba, /* q: jongseong sios */
+ 0x1162, /* r: jungseong ae */
+ 0x11ab, /* s: jongseong nieun */
+ 0x1165, /* t: jungseong eo */
+ 0x1103, /* u: choseong tikeut */
+ 0x1169, /* v: jungseong o */
+ 0x11af, /* w: jongseong rieul */
+ 0x11a8, /* x: jongseong kiyeok */
+ 0x1105, /* y: choseong rieul */
+ 0x11b7, /* z: jongseong mieum */
+ 0x007b, /* braceleft: left brace */
+ 0x007c, /* bar: vertical line(bar) */
+ 0x007d, /* braceright: right brace */
+ 0x007e, /* asciitilde: tilde */
+};
+
+static const wchar_t hangul_keyboard_table_3yet[] = {
+ 0x11bd, /* exclam: jongseong cieuc */
+ 0x0022, /* quotedbl: quotatioin mark */
+ 0x0023, /* numbersign: number sign */
+ 0x0024, /* dollar: dollar sign */
+ 0x0025, /* percent: percent sign */
+ 0x0026, /* ampersand: ampersand */
+ 0x1110, /* apostrophe: choseong thieuth */
+ 0x0028, /* parenleft: left parenthesis */
+ 0x0029, /* parenright: right parenthesis */
+ 0x002a, /* asterisk: asterisk */
+ 0x002b, /* plus: plus sign */
+ 0x002c, /* comma: comma */
+ 0x002d, /* minus: minus sign */
+ 0x002e, /* period: period */
+ 0x1169, /* slash: jungseong o */
+ 0x110f, /* 0: choseong khieukh */
+ 0x11c2, /* 1: jongseong hieuh */
+ 0x11bb, /* 2: jongseong ssangsios */
+ 0x11b8, /* 3: jongseong pieup */
+ 0x116d, /* 4: jungseong yo */
+ 0x1172, /* 5: jungseong yu */
+ 0x1163, /* 6: jungseong ya */
+ 0x1168, /* 7: jungseong ye */
+ 0x1174, /* 8: jungseong yi */
+ 0x116e, /* 9: jungseong u */
+ 0x003a, /* colon: colon */
+ 0x1107, /* semicolon: choseong pieup */
+ 0x113c, /* less: choseong chitueumsios */
+ 0x003d, /* equal: euals sign */
+ 0x113e, /* greater: choseong ceongchieumsios */
+ 0x003f, /* question: question mark */
+ 0x11eb, /* at: jongseong pansios */
+ 0x11ae, /* A: jongseong tikeut */
+ 0x116e, /* B: jungseong u */
+ 0x11b1, /* C: jongseong rieul-mieum */
+ 0x11b0, /* D: jongseong rieul-kiyeok */
+ 0x11bf, /* E: jongseong khieukh */
+ 0x11a9, /* F: jongseong ssangkiyeok */
+ 0x119e, /* G: jungseong araea */
+ 0x1102, /* H: choseong nieun */
+ 0x1154, /* I: choseong chitueumchieuch */
+ 0x114c, /* J: choseong yesieung */
+ 0x114e, /* K: choseong chitueumcieuc */
+ 0x1150, /* L: choseong ceongchieumcieuc */
+ 0x1159, /* M: choseong yeorinhieuh */
+ 0x1140, /* N: choseong pansios */
+ 0x1155, /* O: choseong ceongchieumchieuch */
+ 0x1111, /* P: choseong phieuph */
+ 0x11c1, /* Q: jongseong phieuph */
+ 0x1164, /* R: jungseong yae */
+ 0x11ad, /* S: jongseong nieun-hieuh */
+ 0x1165, /* T: jungseong eo */
+ 0x302e, /* U: single dot tone mark */
+ 0x11b6, /* V: jongseong rieul-hieuh */
+ 0x11c0, /* W: jongseong thikeuth */
+ 0x11b9, /* X: jongseong pieup-sios */
+ 0x302f, /* Y: double dot tone mark */
+ 0x11be, /* Z: jongseong chieuch */
+ 0x005b, /* bracketleft: left bracket */
+ 0x005c, /* backslash: backslash */
+ 0x005d, /* bracketright: right bracket */
+ 0x005e, /* asciicircum: circumflex accent */
+ 0x005f, /* underscore: underscore */
+ 0x11f9, /* quoteleft: jongseong yeorinhieuh */
+ 0x11bc, /* a: jongseong ieung */
+ 0x116e, /* b: jungseong u */
+ 0x1166, /* c: jungseong e */
+ 0x1175, /* d: jungseong i */
+ 0x1167, /* e: jungseong yeo */
+ 0x1161, /* f: jungseong a */
+ 0x1173, /* g: jungseong eu */
+ 0x1102, /* h: choseong nieun */
+ 0x1106, /* i: choseong mieum */
+ 0x110b, /* j: choseong ieung */
+ 0x1100, /* k: choseong kiyeok */
+ 0x110c, /* l: choseong cieuc */
+ 0x1112, /* m: choseong hieuh */
+ 0x1109, /* n: choseong sios */
+ 0x110e, /* o: choseong chieuch */
+ 0x1111, /* p: choseong phieuph */
+ 0x11ba, /* q: jongseong sios */
+ 0x1162, /* r: jungseong ae */
+ 0x11ab, /* s: jongseong nieun */
+ 0x1165, /* t: jungseong eo */
+ 0x1103, /* u: choseong tikeut */
+ 0x1169, /* v: jungseong o */
+ 0x11af, /* w: jongseong rieul */
+ 0x11a8, /* x: jongseong kiyeok */
+ 0x1105, /* y: choseong rieul */
+ 0x11b7, /* z: jongseong mieum */
+ 0x007b, /* braceleft: left brace */
+ 0x007c, /* bar: vertical line(bar) */
+ 0x007d, /* braceright: right brace */
+ 0x11f0, /* asciitilde: jongseong yesieung */
+};
+
+static const HangulJamoCombination hangul_combination_table_default[] = {
+ { 0x11001100, 0x1101 }, /* choseong kiyeok + kiyeok = ssangkiyeok */
+ { 0x11031103, 0x1104 }, /* choseong tikeut + tikeut = ssangtikeut */
+ { 0x11071107, 0x1108 }, /* choseong pieup + pieup = ssangpieup */
+ { 0x11091109, 0x110a }, /* choseong sios + sios = ssangsios */
+ { 0x110c110c, 0x110d }, /* choseong cieuc + cieuc = ssangcieuc */
+ { 0x11691161, 0x116a }, /* jungseong o + a = wa */
+ { 0x11691162, 0x116b }, /* jungseong o + ae = wae */
+ { 0x11691175, 0x116c }, /* jungseong o + i = oe */
+ { 0x116e1165, 0x116f }, /* jungseong u + eo = weo */
+ { 0x116e1166, 0x1170 }, /* jungseong u + e = we */
+ { 0x116e1175, 0x1171 }, /* jungseong u + i = wi */
+ { 0x11731175, 0x1174 }, /* jungseong eu + i = yi */
+ { 0x11a811a8, 0x11a9 }, /* jongseong kiyeok + kiyeok = ssangekiyeok */
+ { 0x11a811ba, 0x11aa }, /* jongseong kiyeok + sios = kiyeok-sois */
+ { 0x11ab11bd, 0x11ac }, /* jongseong nieun + cieuc = nieun-cieuc */
+ { 0x11ab11c2, 0x11ad }, /* jongseong nieun + hieuh = nieun-hieuh */
+ { 0x11af11a8, 0x11b0 }, /* jongseong rieul + kiyeok = rieul-kiyeok */
+ { 0x11af11b7, 0x11b1 }, /* jongseong rieul + mieum = rieul-mieum */
+ { 0x11af11b8, 0x11b2 }, /* jongseong rieul + pieup = rieul-pieup */
+ { 0x11af11ba, 0x11b3 }, /* jongseong rieul + sios = rieul-sios */
+ { 0x11af11c0, 0x11b4 }, /* jongseong rieul + thieuth = rieul-thieuth */
+ { 0x11af11c1, 0x11b5 }, /* jongseong rieul + phieuph = rieul-phieuph */
+ { 0x11af11c2, 0x11b6 }, /* jongseong rieul + hieuh = rieul-hieuh */
+ { 0x11b811ba, 0x11b9 }, /* jongseong pieup + sios = pieup-sios */
+ { 0x11ba11ba, 0x11bb }, /* jongseong sios + sios = ssangsios */
+};
--- /dev/null
+
+all:
+ python setup.py build
+
+clean:
+ rm -rf build
+
+install:
+ python setup.py install
--- /dev/null
+#include <Python.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "../hangul/hangul.h"
+
+static PyObject *_pyhangul_error;
+
+// User defined Object
+typedef struct {
+ PyObject_HEAD
+} PY_HANGUL;
+
+typedef struct {
+ PyObject_HEAD
+
+ HangulInputContext *hic;
+} PY_HANGULIC;
+
+extern PyTypeObject PY_HANGULIC_Type;
+
+static PyObject *_create_ic(PY_HANGUL *self, PyObject *args)
+{
+ PY_HANGULIC *imObject;
+ int keyboard;
+
+ if(!PyArg_ParseTuple(args,"i",&keyboard)) {
+ PyErr_SetString(_pyhangul_error,
+ "Usage: create_ic(keyboard)\n"
+ "\tkeyboard: hangul2, hangul3{2,90,f,s}");
+ return NULL;
+ }
+
+ imObject = PyObject_NEW(PY_HANGULIC, &PY_HANGULIC_Type);
+ if(imObject == NULL) {
+ PyErr_SetString(_pyhangul_error,"Fail to create PY_HANGULIC Object");
+ return NULL;
+ }
+
+ imObject->hic = hangul_ic_new(keyboard);
+
+ return (PyObject *)imObject;
+}
+
+static PyMethodDef _pyhangul_methods[] = {
+ { "create_ic", (PyCFunction) _create_ic, METH_VARARGS, NULL },
+ { NULL, NULL, 0, NULL }
+};
+
+void inithangul(void)
+{
+ PyObject *m, *d;
+
+ m = Py_InitModule("hangul", _pyhangul_methods);
+ PyModule_AddIntConstant(m, "hangul2", HANGUL_KEYBOARD_2);
+ PyModule_AddIntConstant(m, "hangul32", HANGUL_KEYBOARD_32);
+ PyModule_AddIntConstant(m, "hangul390", HANGUL_KEYBOARD_390);
+ PyModule_AddIntConstant(m, "hangul3f", HANGUL_KEYBOARD_3FINAL);
+ PyModule_AddIntConstant(m, "hangul3s", HANGUL_KEYBOARD_3NOSHIFT);
+ //PyModule_AddIntConstant(m, "Hangul3_Yetgeul", HANGUL_KEYBOARD_3YETGUL);
+
+ d = PyModule_GetDict(m);
+ _pyhangul_error = PyErr_NewException("_pyhangul.error", NULL, NULL);
+ PyDict_SetItemString(d, "error", _pyhangul_error);
+}
+
+// im's member function
+static PyObject *_pyhangulic_filter(PY_HANGULIC *self, PyObject *args)
+{
+ int ret;
+ int ascii, capslock;
+
+ if(!PyArg_ParseTuple(args,"ii", &ascii, &capslock)) {
+ PyErr_SetString(_pyhangul_error,"Usage: filter(ascii, capslock)");
+ return NULL;
+ }
+
+ ret = hangul_ic_filter(self->hic, ascii, capslock);
+
+ return Py_BuildValue("i", ret);
+}
+
+static PyObject *_pyhangulic_reset(PY_HANGULIC *self, PyObject *args)
+{
+ hangul_ic_reset(self->hic);
+
+ return Py_None;
+}
+
+static PyObject *_pyhangulic_backspace(PY_HANGULIC *self, PyObject *args)
+{
+ int ret;
+
+ ret = hangul_ic_backspace(self->hic);
+
+ return Py_BuildValue("i", ret);
+}
+
+static PyObject *_pyhangulic_preedit_string(PY_HANGULIC *self, PyObject *args)
+{
+ int len;
+ const wchar_t *str;
+
+ str = hangul_ic_get_preedit_string(self->hic);
+ len = wcslen(str);
+ return PyUnicode_FromWideChar(str, len);
+}
+
+static PyObject *_pyhangulic_commit_string(PY_HANGULIC *self, PyObject *args)
+{
+ int len;
+ const wchar_t *str;
+
+ str = hangul_ic_get_commit_string(self->hic);
+ len = wcslen(str);
+ return PyUnicode_FromWideChar(str, len);
+}
+
+// PY_HANGULIC methods
+static PyMethodDef PY_HANGULIC_methods[] = {
+ { "filter", (PyCFunction)_pyhangulic_filter, METH_VARARGS, NULL},
+ { "reset", (PyCFunction)_pyhangulic_reset, METH_VARARGS, NULL},
+ { "backspace", (PyCFunction)_pyhangulic_backspace, METH_VARARGS, NULL},
+ { "preedit_string",(PyCFunction)_pyhangulic_preedit_string, METH_VARARGS, NULL},
+ { "commit_string", (PyCFunction)_pyhangulic_commit_string, METH_VARARGS, NULL},
+ { NULL, NULL, 0, NULL }
+};
+
+// PY_HANGULIC dealloc
+static void PY_HANGULIC_dealloc(PY_HANGULIC *self)
+{
+ hangul_ic_delete(self->hic);
+ self->hic = NULL;
+ PyMem_Free((char *) self);
+}
+
+// PY_HANGULIC getattr
+static PyObject * PY_HANGULIC_getattr(PY_HANGULIC *self, char *name)
+{
+ PyObject *res;
+ res = Py_FindMethod(PY_HANGULIC_methods, (PyObject *)self, name);
+ if(res != NULL)
+ return res;
+ PyErr_Clear();
+ PyErr_SetString(_pyhangul_error,"UnKnown method");
+ return NULL;
+}
+
+// PY_HANGULIC repr
+static PyObject * PY_HANGULIC_repr(PY_HANGULIC *self)
+{
+ char buf[300];
+ sprintf(buf,"<Class pyhangul at %lx>",(long)self);
+ return PyString_FromString(buf);
+}
+
+
+// PY_HANGUL Type
+PyTypeObject PY_HANGULIC_Type = {
+#ifndef MS_WIN32
+ PyObject_HEAD_INIT(&PyType_Type)
+#else
+ PyObject_HEAD_INIT(NULL)
+#endif
+ 0,
+ "hangul.hangulic",
+ sizeof(PY_HANGULIC),
+ 0,
+ (destructor)PY_HANGULIC_dealloc,
+ 0,
+ (getattrfunc)PY_HANGULIC_getattr,
+ 0,
+ 0,
+ (reprfunc)PY_HANGULIC_repr,
+};
--- /dev/null
+#!/usr/bin/env python
+
+import sys
+from distutils.core import setup, Extension
+
+classifiers = """\
+Development Status :: 5 - Production/Stable
+Intended Audience :: Developers
+License :: OSI Approved :: GNU GPL
+Programming Language :: Python
+Programming Language :: C
+Topic :: Software Development :: Libraries :: Python Modules
+Operating System :: Microsoft :: Windows
+Operating System :: Unix
+"""
+
+if sys.platform == "win32": # for MinGW
+ include_dirs = [r'\MinGW\include', r'..']
+ library_dirs = [r'\MinGW\lib', r'..']
+ libraries = []
+ data_files = []
+
+else:
+ include_dirs = [
+ '/usr/include'
+ '/usr/local/include'
+ ]
+ library_dirs = [
+ '/usr/lib',
+ '/usr/local/lib',
+ '../hangul'
+ ]
+ libraries = ['hangul']
+ data_files = []
+
+if sys.version_info < (2, 3):
+ _setup = setup
+ def setup(**kwargs):
+ if kwargs.has_key("classifiers"):
+ del kwargs["classifiers"]
+ _setup(**kwargs)
+
+setup(name = "pyhangul",
+ version = "0.0.1",
+ description="libhangul for Python.",
+ author = "Joon-cheol Park",
+ author_email="jooncheol@gmail.com",
+ license = "GPL",
+ url="http://hangul.kldp.net",
+ ext_modules=[Extension("hangul", ["pyhangul.c"],
+ include_dirs = include_dirs,
+ library_dirs = library_dirs,
+ libraries = libraries)],
+ classifiers = filter(None, classifiers.split("\n")),
+ data_files=data_files
+ )
+
--- /dev/null
+
+noinst_PROGRAMS = test
+
+test_CFLAGS =
+test_SOURCES = test.c
+test_LDADD = ../hangul/libhangul.a
--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <wchar.h>
+
+#include "../hangul/hangul.h"
+
+int
+main(int argc, char *argv[])
+{
+ int n;
+ int ascii;
+ int keyboard = HANGUL_KEYBOARD_2;
+ char commit[32] = { '\0', };
+ HangulInputContext *hic;
+
+ if (argc > 1) {
+ keyboard = atoi(argv[1]);
+ }
+
+ setlocale(LC_CTYPE, "");
+
+ hic = hangul_ic_new(keyboard);
+ if (hic == NULL) {
+ printf("hic is null\n");
+ return -1;
+ }
+
+ for (ascii = getchar(); ascii != EOF; ascii = getchar()) {
+ int ret = hangul_ic_filter(hic, ascii, 0);
+ n = wcstombs(commit, hangul_ic_get_commit_string(hic), sizeof(commit));
+ commit[n] = '\0';
+ if (strlen(commit) > 0) {
+ printf("%s", commit);
+ }
+ if (!ret) {
+ printf("%c", ascii);
+ }
+ }
+ hangul_ic_reset(hic);
+ n = wcstombs(commit, hangul_ic_get_commit_string(hic), sizeof(commit));
+ commit[n] = '\0';
+ if (strlen(commit) > 0) {
+ printf("%s", commit);
+ }
+
+ hangul_ic_delete(hic);
+
+ return 0;
+}