From: HyungKyu Song Date: Fri, 15 Feb 2013 15:18:33 +0000 (+0900) Subject: Tizen 2.0 Release X-Git-Tag: accepted/tizen_2.0/20130215.203213^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_2.0;p=framework%2Fuifw%2Fisf.git Tizen 2.0 Release --- diff --git a/ABOUT-NLS b/ABOUT-NLS new file mode 100644 index 0000000..2f50c66 --- /dev/null +++ b/ABOUT-NLS @@ -0,0 +1,768 @@ +Notes on the Free Translation Project +************************************* + +Free software is going international! The Free Translation Project is +a way to get maintainers of free software, translators, and users all +together, so that will gradually become able to speak many languages. +A few packages already provide translations for their messages. + + If you found this `ABOUT-NLS' file inside a distribution, you may +assume that the distributed package does use GNU `gettext' internally, +itself available at your nearest GNU archive site. But you do _not_ +need to install GNU `gettext' prior to configuring, installing or using +this package with messages translated. + + Installers will find here some useful hints. These notes also +explain how users should proceed for getting the programs to use the +available translations. They tell how people wanting to contribute and +work at translations should contact the appropriate team. + + When reporting bugs in the `intl/' directory or bugs which may be +related to internationalization, you should tell about the version of +`gettext' which is used. The information can be found in the +`intl/VERSION' file, in internationalized packages. + +Quick configuration advice +========================== + +If you want to exploit the full power of internationalization, you +should configure it using + + ./configure --with-included-gettext + +to force usage of internationalizing routines provided within this +package, despite the existence of internationalizing capabilities in the +operating system where this package is being installed. So far, only +the `gettext' implementation in the GNU C library version 2 provides as +many features (such as locale alias, message inheritance, automatic +charset conversion or plural form handling) as the implementation here. +It is also not possible to offer this additional functionality on top +of a `catgets' implementation. Future versions of GNU `gettext' will +very likely convey even more functionality. So it might be a good idea +to change to GNU `gettext' as soon as possible. + + So you need _not_ provide this option if you are using GNU libc 2 or +you have installed a recent copy of the GNU gettext package with the +included `libintl'. + +INSTALL Matters +=============== + +Some packages are "localizable" when properly installed; the programs +they contain can be made to speak your own native language. Most such +packages use GNU `gettext'. Other packages have their own ways to +internationalization, predating GNU `gettext'. + + By default, this package will be installed to allow translation of +messages. It will automatically detect whether the system already +provides the GNU `gettext' functions. If not, the GNU `gettext' own +library will be used. This library is wholly contained within this +package, usually in the `intl/' subdirectory, so prior installation of +the GNU `gettext' package is _not_ required. Installers may use +special options at configuration time for changing the default +behaviour. The commands: + + ./configure --with-included-gettext + ./configure --disable-nls + +will respectively bypass any pre-existing `gettext' to use the +internationalizing routines provided within this package, or else, +_totally_ disable translation of messages. + + When you already have GNU `gettext' installed on your system and run +configure without an option for your new package, `configure' will +probably detect the previously built and installed `libintl.a' file and +will decide to use this. This might be not what is desirable. You +should use the more recent version of the GNU `gettext' library. I.e. +if the file `intl/VERSION' shows that the library which comes with this +package is more recent, you should use + + ./configure --with-included-gettext + +to prevent auto-detection. + + The configuration process will not test for the `catgets' function +and therefore it will not be used. The reason is that even an +emulation of `gettext' on top of `catgets' could not provide all the +extensions of the GNU `gettext' library. + + Internationalized packages have usually many `po/LL.po' files, where +LL gives an ISO 639 two-letter code identifying the language. Unless +translations have been forbidden at `configure' time by using the +`--disable-nls' switch, all available translations are installed +together with the package. However, the environment variable `LINGUAS' +may be set, prior to configuration, to limit the installed set. +`LINGUAS' should then contain a space separated list of two-letter +codes, stating which languages are allowed. + +Using This Package +================== + +As a user, if your language has been installed for this package, you +only have to set the `LANG' environment variable to the appropriate +`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, +and `CC' is an ISO 3166 two-letter country code. For example, let's +suppose that you speak German and live in Germany. At the shell +prompt, merely execute `setenv LANG de_DE' (in `csh'), +`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). +This can be done from your `.login' or `.profile' file, once and for +all. + + You might think that the country code specification is redundant. +But in fact, some languages have dialects in different countries. For +example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The +country code serves to distinguish the dialects. + + The locale naming convention of `LL_CC', with `LL' denoting the +language and `CC' denoting the country, is the one use on systems based +on GNU libc. On other systems, some variations of this scheme are +used, such as `LL' or `LL_CC.ENCODING'. You can get the list of +locales supported by your system for your country by running the command +`locale -a | grep '^LL''. + + Not all programs have translations for all languages. By default, an +English message is shown in place of a nonexistent translation. If you +understand other languages, you can set up a priority list of languages. +This is done through a different environment variable, called +`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' +for the purpose of message handling, but you still need to have `LANG' +set to the primary language; this is required by other parts of the +system libraries. For example, some Swedish users who would rather +read translations in German than English for when Swedish is not +available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. + + Special advice for Norwegian users: The language code for Norwegian +bokma*l changed from `no' to `nb' recently (in 2003). During the +transition period, while some message catalogs for this language are +installed under `nb' and some older ones under `no', it's recommended +for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and +older translations are used. + + In the `LANGUAGE' environment variable, but not in the `LANG' +environment variable, `LL_CC' combinations can be abbreviated as `LL' +to denote the language's main dialect. For example, `de' is equivalent +to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' +(Portuguese as spoken in Portugal) in this context. + +Translating Teams +================= + +For the Free Translation Project to be a success, we need interested +people who like their own language and write it well, and who are also +able to synergize with other translators speaking the same language. +Each translation team has its own mailing list. The up-to-date list of +teams can be found at the Free Translation Project's homepage, +`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" +area. + + If you'd like to volunteer to _work_ at translating messages, you +should become a member of the translating team for your own language. +The subscribing address is _not_ the same as the list itself, it has +`-request' appended. For example, speakers of Swedish can send a +message to `sv-request@li.org', having this message body: + + subscribe + + Keep in mind that team members are expected to participate +_actively_ in translations, or at solving translational difficulties, +rather than merely lurking around. If your team does not exist yet and +you want to start one, or if you are unsure about what to do or how to +get started, please write to `translation@iro.umontreal.ca' to reach the +coordinator for all translator teams. + + The English team is special. It works at improving and uniformizing +the terminology in use. Proven linguistic skill are praised more than +programming skill, here. + +Available Packages +================== + +Languages are not equally supported in all packages. The following +matrix shows the current state of internationalization, as of January +2004. The matrix shows, in regard of each package, for which languages +PO files have been submitted to translation coordination, with a +translation percentage of at least 50%. + + Ready PO files af am ar az be bg bs ca cs da de el en en_GB eo es + +----------------------------------------------------+ + a2ps | [] [] [] [] | + aegis | () | + ant-phone | () | + anubis | | + ap-utils | | + aspell | [] | + bash | [] [] [] [] | + batchelor | | + bfd | [] [] | + binutils | [] [] | + bison | [] [] [] | + bluez-pin | [] [] [] | + clisp | | + clisp | [] [] [] | + console-tools | [] [] | + coreutils | [] [] [] [] | + cpio | [] [] [] | + darkstat | [] () [] | + diffutils | [] [] [] [] [] [] [] | + e2fsprogs | [] [] [] | + enscript | [] [] [] [] | + error | [] [] [] [] [] | + fetchmail | [] () [] [] [] [] | + fileutils | [] [] [] | + findutils | [] [] [] [] [] [] [] | + flex | [] [] [] [] | + fslint | | + gas | [] | + gawk | [] [] [] [] | + gbiff | [] | + gcal | [] | + gcc | [] [] | + gettext | [] [] [] [] [] | + gettext-examples | [] [] [] [] | + gettext-runtime | [] [] [] [] [] | + gettext-tools | [] [] [] | + gimp-print | [] [] [] [] [] | + gliv | | + glunarclock | [] [] | + gnubiff | [] | + gnucash | [] () [] [] | + gnucash-glossary | [] () [] | + gnupg | [] () [] [] [] [] | + gpe-aerial | [] | + gpe-beam | [] [] | + gpe-calendar | [] [] | + gpe-clock | [] [] | + gpe-conf | [] [] | + gpe-contacts | [] [] | + gpe-edit | [] | + gpe-go | [] | + gpe-login | [] [] | + gpe-ownerinfo | [] [] | + gpe-sketchbook | [] [] | + gpe-su | [] [] | + gpe-taskmanager | [] [] | + gpe-timesheet | [] | + gpe-today | [] [] | + gpe-todo | [] [] | + gphoto2 | [] [] [] [] | + gprof | [] [] [] | + gpsdrive | () () () | + gramadoir | [] | + grep | [] [] [] [] [] [] | + gretl | [] | + gtick | [] () | + hello | [] [] [] [] [] [] | + id-utils | [] [] | + indent | [] [] [] [] | + iso_3166 | [] [] [] [] [] [] [] [] [] [] | + iso_3166_1 | [] [] [] [] [] [] | + iso_3166_2 | | + iso_3166_3 | [] | + iso_4217 | [] [] [] [] | + iso_639 | | + jpilot | [] [] [] | + jtag | | + jwhois | [] | + kbd | [] [] [] [] [] | + latrine | () | + ld | [] [] | + libc | [] [] [] [] [] [] | + libgpewidget | [] [] | + libiconv | [] [] [] [] [] | + lifelines | [] () | + lilypond | [] | + lingoteach | | + lingoteach_lessons | () () | + lynx | [] [] [] [] | + m4 | [] [] [] [] | + mailutils | [] [] | + make | [] [] [] | + man-db | [] () [] [] () | + minicom | [] [] [] | + mysecretdiary | [] [] [] | + nano | [] () [] [] [] | + nano_1_0 | [] () [] [] [] | + opcodes | [] | + parted | [] [] [] [] [] | + ptx | [] [] [] [] [] | + python | | + radius | [] | + recode | [] [] [] [] [] [] [] | + rpm | [] [] | + screem | | + scrollkeeper | [] [] [] [] [] [] | + sed | [] [] [] [] [] [] | + sh-utils | [] [] [] | + shared-mime-info | | + sharutils | [] [] [] [] [] [] | + silky | () | + skencil | [] () [] | + sketch | [] () [] | + soundtracker | [] [] [] | + sp | [] | + tar | [] [] [] [] | + texinfo | [] [] [] | + textutils | [] [] [] [] | + tin | () () | + tp-robot | | + tuxpaint | [] [] [] [] [] [] [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] [] [] [] | + vorbis-tools | [] [] [] [] | + wastesedge | () | + wdiff | [] [] [] [] | + wget | [] [] [] [] [] [] | + xchat | [] [] [] [] | + xfree86_xkb_xml | [] [] | + xpad | [] | + +----------------------------------------------------+ + af am ar az be bg bs ca cs da de el en en_GB eo es + 4 0 0 1 9 4 1 40 41 60 78 17 1 5 13 68 + + et eu fa fi fr ga gl he hr hu id is it ja ko lg + +-------------------------------------------------+ + a2ps | [] [] [] () () | + aegis | | + ant-phone | [] | + anubis | [] | + ap-utils | [] | + aspell | [] [] | + bash | [] [] | + batchelor | [] [] | + bfd | [] | + binutils | [] [] | + bison | [] [] [] [] | + bluez-pin | [] [] [] [] [] | + clisp | | + clisp | [] | + console-tools | | + coreutils | [] [] [] [] [] [] | + cpio | [] [] [] [] | + darkstat | () [] [] [] | + diffutils | [] [] [] [] [] [] [] | + e2fsprogs | | + enscript | [] [] | + error | [] [] [] [] | + fetchmail | [] | + fileutils | [] [] [] [] [] [] | + findutils | [] [] [] [] [] [] [] [] [] [] [] | + flex | [] [] [] | + fslint | [] | + gas | [] | + gawk | [] [] [] | + gbiff | [] | + gcal | [] | + gcc | [] | + gettext | [] [] [] | + gettext-examples | [] [] | + gettext-runtime | [] [] [] [] [] | + gettext-tools | [] [] [] | + gimp-print | [] [] | + gliv | () | + glunarclock | [] [] [] [] | + gnubiff | [] | + gnucash | () [] | + gnucash-glossary | [] | + gnupg | [] [] [] [] [] [] [] | + gpe-aerial | [] | + gpe-beam | [] | + gpe-calendar | [] [] [] | + gpe-clock | [] | + gpe-conf | [] | + gpe-contacts | [] [] | + gpe-edit | [] [] | + gpe-go | [] | + gpe-login | [] [] | + gpe-ownerinfo | [] [] [] | + gpe-sketchbook | [] | + gpe-su | [] | + gpe-taskmanager | [] | + gpe-timesheet | [] [] [] | + gpe-today | [] [] | + gpe-todo | [] [] | + gphoto2 | [] [] [] | + gprof | [] [] | + gpsdrive | () () () | + gramadoir | [] [] | + grep | [] [] [] [] [] [] [] [] [] [] [] | + gretl | [] [] | + gtick | [] [] [] | + hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | + id-utils | [] [] [] [] | + indent | [] [] [] [] [] [] [] [] [] | + iso_3166 | [] [] [] [] [] [] [] | + iso_3166_1 | [] [] [] [] [] | + iso_3166_2 | | + iso_3166_3 | | + iso_4217 | [] [] [] [] [] [] | + iso_639 | | + jpilot | [] () | + jtag | [] | + jwhois | [] [] [] [] | + kbd | [] | + latrine | [] | + ld | [] | + libc | [] [] [] [] [] [] | + libgpewidget | [] [] [] [] | + libiconv | [] [] [] [] [] [] [] [] [] | + lifelines | () | + lilypond | [] | + lingoteach | [] [] | + lingoteach_lessons | | + lynx | [] [] [] [] | + m4 | [] [] [] [] | + mailutils | | + make | [] [] [] [] [] [] | + man-db | () () | + minicom | [] [] [] [] | + mysecretdiary | [] [] | + nano | [] [] [] [] | + nano_1_0 | [] [] [] [] | + opcodes | [] | + parted | [] [] [] | + ptx | [] [] [] [] [] [] [] | + python | | + radius | [] | + recode | [] [] [] [] [] [] | + rpm | [] [] | + screem | | + scrollkeeper | [] | + sed | [] [] [] [] [] [] [] [] [] | + sh-utils | [] [] [] [] [] [] [] | + shared-mime-info | [] [] [] | + sharutils | [] [] [] [] [] | + silky | () [] () () | + skencil | [] | + sketch | [] | + soundtracker | [] [] | + sp | [] () | + tar | [] [] [] [] [] [] [] [] [] | + texinfo | [] [] [] [] | + textutils | [] [] [] [] [] [] | + tin | [] () | + tp-robot | [] | + tuxpaint | [] [] [] [] [] [] [] [] [] | + unicode-han-tra... | | + unicode-transla... | [] [] | + util-linux | [] [] [] [] () [] | + vorbis-tools | [] | + wastesedge | () | + wdiff | [] [] [] [] [] [] | + wget | [] [] [] [] [] [] [] | + xchat | [] [] [] | + xfree86_xkb_xml | [] [] | + xpad | [] [] | + +-------------------------------------------------+ + et eu fa fi fr ga gl he hr hu id is it ja ko lg + 22 2 1 26 106 28 24 8 10 41 33 1 26 33 12 0 + + lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru + +-----------------------------------------------------+ + a2ps | [] [] () () [] [] [] | + aegis | () () () | + ant-phone | [] [] | + anubis | [] [] [] [] [] [] | + ap-utils | [] () [] | + aspell | [] | + bash | [] [] [] | + batchelor | [] | + bfd | [] | + binutils | [] | + bison | [] [] [] [] [] | + bluez-pin | [] [] [] | + clisp | | + clisp | [] | + console-tools | [] | + coreutils | [] [] | + cpio | [] [] [] [] [] | + darkstat | [] [] [] [] | + diffutils | [] [] [] [] [] [] | + e2fsprogs | [] | + enscript | [] [] [] [] | + error | [] [] [] | + fetchmail | [] [] () [] | + fileutils | [] [] [] | + findutils | [] [] [] [] [] | + flex | [] [] [] [] | + fslint | [] [] | + gas | | + gawk | [] [] [] | + gbiff | [] [] | + gcal | | + gcc | | + gettext | [] [] [] | + gettext-examples | [] [] [] | + gettext-runtime | [] [] [] [] | + gettext-tools | [] [] | + gimp-print | [] | + gliv | [] [] [] | + glunarclock | [] [] [] [] | + gnubiff | [] | + gnucash | [] [] () [] | + gnucash-glossary | [] [] | + gnupg | [] | + gpe-aerial | [] [] [] [] | + gpe-beam | [] [] [] [] | + gpe-calendar | [] [] [] [] | + gpe-clock | [] [] [] [] | + gpe-conf | [] [] [] [] | + gpe-contacts | [] [] [] [] | + gpe-edit | [] [] [] [] | + gpe-go | [] [] [] | + gpe-login | [] [] [] [] | + gpe-ownerinfo | [] [] [] [] | + gpe-sketchbook | [] [] [] [] | + gpe-su | [] [] [] [] | + gpe-taskmanager | [] [] [] [] | + gpe-timesheet | [] [] [] [] | + gpe-today | [] [] [] [] | + gpe-todo | [] [] [] [] | + gphoto2 | [] | + gprof | [] [] | + gpsdrive | () () [] | + gramadoir | () [] | + grep | [] [] [] [] [] | + gretl | | + gtick | [] [] [] | + hello | [] [] [] [] [] [] [] [] [] [] | + id-utils | [] [] [] [] | + indent | [] [] [] [] | + iso_3166 | [] [] [] | + iso_3166_1 | [] [] | + iso_3166_2 | | + iso_3166_3 | [] | + iso_4217 | [] [] [] [] [] [] [] [] | + iso_639 | [] | + jpilot | () () | + jtag | | + jwhois | [] [] [] [] () | + kbd | [] [] [] | + latrine | [] | + ld | | + libc | [] [] [] [] | + libgpewidget | [] [] [] | + libiconv | [] [] [] [] [] | + lifelines | | + lilypond | | + lingoteach | | + lingoteach_lessons | | + lynx | [] [] [] | + m4 | [] [] [] [] [] | + mailutils | [] [] [] | + make | [] [] [] [] | + man-db | [] | + minicom | [] [] [] [] | + mysecretdiary | [] [] [] | + nano | [] [] [] [] [] | + nano_1_0 | [] [] [] [] [] [] | + opcodes | [] [] | + parted | [] [] [] [] | + ptx | [] [] [] [] [] [] [] [] | + python | | + radius | [] [] | + recode | [] [] [] [] | + rpm | [] [] [] | + screem | | + scrollkeeper | [] [] [] [] [] | + sed | [] [] [] | + sh-utils | [] [] | + shared-mime-info | [] [] | + sharutils | [] [] | + silky | () | + skencil | [] [] | + sketch | [] [] | + soundtracker | | + sp | | + tar | [] [] [] [] [] [] | + texinfo | [] [] [] [] | + textutils | [] [] | + tin | | + tp-robot | [] | + tuxpaint | [] [] [] [] [] [] [] [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] [] | + vorbis-tools | [] [] [] | + wastesedge | | + wdiff | [] [] [] [] [] | + wget | [] [] [] | + xchat | [] [] [] | + xfree86_xkb_xml | [] [] | + xpad | [] [] | + +-----------------------------------------------------+ + lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru + 1 2 0 3 12 0 10 69 6 7 1 40 26 36 76 63 + + sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu + +-----------------------------------------------------+ + a2ps | [] [] [] [] | 16 + aegis | | 0 + ant-phone | | 3 + anubis | [] [] | 9 + ap-utils | () | 3 + aspell | | 4 + bash | | 9 + batchelor | | 3 + bfd | [] [] | 6 + binutils | [] [] [] | 8 + bison | [] [] | 14 + bluez-pin | [] [] [] | 14 + clisp | | 0 + clisp | | 5 + console-tools | | 3 + coreutils | [] [] [] [] | 16 + cpio | [] [] | 14 + darkstat | [] [] [] () () | 12 + diffutils | [] [] [] | 23 + e2fsprogs | [] [] | 6 + enscript | [] [] | 12 + error | [] [] [] | 15 + fetchmail | [] [] | 11 + fileutils | [] [] [] [] [] | 17 + findutils | [] [] [] [] [] [] | 29 + flex | [] [] | 13 + fslint | | 3 + gas | [] | 3 + gawk | [] [] | 12 + gbiff | | 4 + gcal | [] [] | 4 + gcc | [] | 4 + gettext | [] [] [] [] [] | 16 + gettext-examples | [] [] [] [] [] | 14 + gettext-runtime | [] [] [] [] [] [] [] [] | 22 + gettext-tools | [] [] [] [] [] [] | 14 + gimp-print | [] [] | 10 + gliv | | 3 + glunarclock | [] [] [] | 13 + gnubiff | | 3 + gnucash | [] [] | 9 + gnucash-glossary | [] [] [] | 8 + gnupg | [] [] [] [] | 17 + gpe-aerial | [] | 7 + gpe-beam | [] | 8 + gpe-calendar | [] [] [] [] | 13 + gpe-clock | [] [] [] | 10 + gpe-conf | [] [] | 9 + gpe-contacts | [] [] [] | 11 + gpe-edit | [] [] [] [] [] | 12 + gpe-go | | 5 + gpe-login | [] [] [] [] [] | 13 + gpe-ownerinfo | [] [] [] [] | 13 + gpe-sketchbook | [] [] | 9 + gpe-su | [] [] [] | 10 + gpe-taskmanager | [] [] [] | 10 + gpe-timesheet | [] [] [] [] | 12 + gpe-today | [] [] [] [] [] | 13 + gpe-todo | [] [] [] [] | 12 + gphoto2 | [] [] [] | 11 + gprof | [] [] | 9 + gpsdrive | [] [] | 3 + gramadoir | [] | 5 + grep | [] [] [] [] | 26 + gretl | | 3 + gtick | | 7 + hello | [] [] [] [] [] | 34 + id-utils | [] [] | 12 + indent | [] [] [] [] | 21 + iso_3166 | [] [] [] [] [] [] [] | 27 + iso_3166_1 | [] [] [] | 16 + iso_3166_2 | | 0 + iso_3166_3 | | 2 + iso_4217 | [] [] [] [] [] [] | 24 + iso_639 | | 1 + jpilot | [] [] [] [] [] | 9 + jtag | [] | 2 + jwhois | () [] [] | 11 + kbd | [] [] | 11 + latrine | | 2 + ld | [] [] | 5 + libc | [] [] [] [] | 20 + libgpewidget | [] [] [] [] | 13 + libiconv | [] [] [] [] [] [] [] [] | 27 + lifelines | [] | 2 + lilypond | [] | 3 + lingoteach | | 2 + lingoteach_lessons | () | 0 + lynx | [] [] [] | 14 + m4 | [] [] | 15 + mailutils | | 5 + make | [] [] [] | 16 + man-db | [] | 5 + minicom | | 11 + mysecretdiary | [] [] | 10 + nano | [] [] [] [] | 17 + nano_1_0 | [] [] [] | 17 + opcodes | [] [] | 6 + parted | [] [] [] | 15 + ptx | [] [] | 22 + python | | 0 + radius | | 4 + recode | [] [] [] | 20 + rpm | [] [] | 9 + screem | [] [] | 2 + scrollkeeper | [] [] [] | 15 + sed | [] [] [] [] [] [] | 24 + sh-utils | [] [] | 14 + shared-mime-info | [] [] | 7 + sharutils | [] [] [] [] | 17 + silky | () | 3 + skencil | [] | 6 + sketch | [] | 6 + soundtracker | [] [] | 7 + sp | [] | 3 + tar | [] [] [] [] [] | 24 + texinfo | [] [] [] | 14 + textutils | [] [] [] [] | 16 + tin | | 1 + tp-robot | | 2 + tuxpaint | [] [] [] [] [] | 29 + unicode-han-tra... | | 0 + unicode-transla... | | 2 + util-linux | [] [] | 15 + vorbis-tools | | 8 + wastesedge | | 0 + wdiff | [] [] [] | 18 + wget | [] [] [] [] [] [] [] [] | 24 + xchat | [] [] [] [] [] | 15 + xfree86_xkb_xml | [] [] [] [] [] | 11 + xpad | | 5 + +-----------------------------------------------------+ + 63 teams sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu + 131 domains 47 19 28 83 0 0 59 13 1 1 11 0 22 22 0 1373 + + Some counters in the preceding matrix are higher than the number of +visible blocks let us expect. This is because a few extra PO files are +used for implementing regional variants of languages, or language +dialects. + + For a PO file in the matrix above to be effective, the package to +which it applies should also have been internationalized and +distributed as such by its maintainer. There might be an observable +lag between the mere existence a PO file and its wide availability in a +distribution. + + If January 2004 seems to be old, you may fetch a more recent copy of +this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date +matrix with full percentage details can be found at +`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. + +Using `gettext' in new packages +=============================== + +If you are writing a freely available program and want to +internationalize it you are welcome to use GNU `gettext' in your +package. Of course you have to respect the GNU Library General Public +License which covers the use of the GNU `gettext' library. This means +in particular that even non-free programs can use `libintl' as a shared +library, whereas only free software can use `libintl' as a static +library or use modified versions of `libintl'. + + Once the sources are changed appropriately and the setup can handle +the use of `gettext' the only thing missing are the translations. The +Free Translation Project is also available for packages which are not +developed inside the GNU project. Therefore the information given above +applies also for every other Free Software Project. Contact +`translation@iro.umontreal.ca' to make the `.pot' files available to +the translation teams. + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..17e7a1f --- /dev/null +++ b/AUTHORS @@ -0,0 +1,43 @@ + +Main authors: +============= + James Su + +Developers: +=========== + LiuCougar + Sehwan Park + Hengliang Luo + Haifeng Deng + Shuo Liu + Jihoon Kim + Jihoon Lee + +zh_TW.po: +========= + Tetralet + Jim Huang + +ja.po: +====== +Yukiko Bando + +ko.po: +====== +Kitae + +de.po: +====== +Jan Hefti + +fr.po: +====== +Damien Menanteau + +it.po: +====== +Federico Zenith + +pa.po +====== +Amanpreet Singh Alam diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4ef65b3 --- /dev/null +++ b/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..13efaca --- /dev/null +++ b/ChangeLog @@ -0,0 +1,77 @@ +2008-08-22 16:30 Haifeng Deng + + 1. : Add NewISE + 2. : Add IDM\src into ISF + +2008-08-15 10:30 Haifeng Deng + + 1. : Add SConscript and control.in for xo build + 2. : Add IDM\input_driver\IDM_Camera into ISF + +2008-07-18 17:03 Wei Ye + + Merge the function of helper manager server into SocketFrontEnd. + +2008-07-16 14:30 Haifeng Deng + + 1. : Delete docs, tests, X11 FrontEnd, X11 Utility, RawCode IMEngine, FrontEnd Setup, Panel Setup and IMEngine Setup + 2. : Move SetupUI into Panel process£¬delete Setup Helper£¬only reserve setup function for each ISE + +2007-06-26 14:25 James Su + + * .: Make 1.4.7 branch. + +2007-06-26 03:40 James Su + + * : Bump verison to 1.4.7. + +2007-06-26 02:37 James Su + + * : Fix include file issue. + +2007-06-22 18:44 James Su + + * : Update po files. + +2007-06-22 17:15 James Su + + * : Fix high power consumption issue. + +2007-06-22 02:35 James Su + + * : Add missing headers. + +2007-06-22 02:33 James Su + + * : Add missing header. + +2007-06-22 00:10 James Su + + * : Use svn2cl to generate ChangeLog. + +2007-06-21 23:47 James Su + + * : Fix buggy implementation of Socket read/write/wait methods. + copied from trunk. + +2007-06-19 06:21 James Su + + * : Add some debug message. Avoid a already focused IC to be + focused again. + +2007-06-17 07:18 James Su + + * : Make 1.4 branch. + +2007-06-17 07:15 James Su + + * : Move scim-trunk (the head) to scim/trunk. + +2007-06-17 07:13 James Su + + * : Rename scim to trunk. + +2007-06-17 07:09 James Su + + * : Initial import scim 1.4 branch into svn as trunk. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..7d1c323 --- /dev/null +++ b/INSTALL @@ -0,0 +1,365 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..d1fc456 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,67 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +AUX_DIST = $(ac_aux_dir)/config.guess \ + $(ac_aux_dir)/config.sub \ + $(ac_aux_dir)/compile \ + $(ac_aux_dir)/depcomp \ + $(ac_aux_dir)/install-sh \ + $(ac_aux_dir)/ltconfig \ + $(ac_aux_dir)/ltmain.sh \ + $(ac_aux_dir)/missing + +EXTRA_DIST = config.rpath \ + mkinstalldirs \ + bootstrap \ + scim.spec \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in + +AUTOMAKE_OPTIONS = gnu +SUBDIRS = ism/m4 ism/src ism/utils ism/modules ism/configs po/scim po/isfsetting_efl po/kbwizard_efl ism/extras ism/data ism/demos + +MAINTAINERCLEANFILES = Makefile.in \ + aclocal.m4 \ + configure \ + config.h.in \ + $(AUX_DIST) + +DISTCLEANFILES = isf.pc scim.pc scim-gtkutils.pc intltool-extract intltool-merge intltool-update + +CLEANFILES = *.bak + +ACLOCAL = aclocal -I $(ac_aux_dir)/ism + +pkgconfigdir = $(libdir)/pkgconfig + +if SCIM_BUILD_GTK_UTILS +GTK_UTILS_PKGCONFIG = scim-gtkutils.pc +endif + +pkgconfig_DATA = isf.pc scim.pc \ + $(GTK_UTILS_PKGCONFIG) + +ACLOCAL_AMFLAGS = -I ism/m4 + +.PHONY: update-ChangeLog + +update-ChangeLog: + /bin/sh $(top_srcdir)/svn2cl.sh --authors=$(top_srcdir)/developers -f $(top_srcdir)/ChangeLog + +uninstall-local: + rm -rf @SCIM_MODULE_PATH@ diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..f38e3cc --- /dev/null +++ b/autogen.sh @@ -0,0 +1,2 @@ +#!/bin/sh +./bootstrap diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..bbc1b36 --- /dev/null +++ b/bootstrap @@ -0,0 +1,33 @@ +#! /bin/sh +# bootstrap -- Use this script to create generated files from the CVS dist +# Copyright (C) 2000 Gary V. Vaughan +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser 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 + +## @start 1 +#! /bin/sh + +set -x +aclocal -I ism/m4 +autoheader +libtoolize -c --automake +automake --add-missing --copy --include-deps +autoconf +if [ -f "arm-linux.cache" ] +then + rm arm-linux.cache +fi +echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache +## @end 1 diff --git a/compile b/compile new file mode 100755 index 0000000..1b1d232 --- /dev/null +++ b/compile @@ -0,0 +1,142 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2005-05-14.22 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; +esac + +ofile= +cfile= +eat= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/config.rpath b/config.rpath new file mode 100755 index 0000000..4db13e5 --- /dev/null +++ b/config.rpath @@ -0,0 +1,548 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2003 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + mingw* | pw32* | os2*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + newsos6) + ;; + linux*) + case $CC in + icc|ecc) + wl='-Wl,' + ;; + ccc) + wl='-Wl,' + ;; + esac + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + sco3.2v5*) + ;; + solaris*) + wl='-Wl,' + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + case "$host_os" in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = yes; then + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + bsdi4*) + ;; + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then + hardcode_direct=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd1*) + ld_shlibs=no + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10* | hpux11*) + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=no + ;; + ia64*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=no + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + *) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + openbsd*) + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + sco3.2v5*) + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4.2uw2*) + hardcode_direct=yes + hardcode_minus_L=no + ;; + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) + ;; + sysv5*) + hardcode_libdir_flag_spec= + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. +libname_spec='lib$name' +case "$host_os" in + aix3*) + ;; + aix4* | aix5*) + ;; + amigaos*) + ;; + beos*) + ;; + bsdi4*) + ;; + cygwin* | mingw* | pw32*) + shrext=.dll + ;; + darwin* | rhapsody*) + shrext=.dylib + ;; + dgux*) + ;; + freebsd1*) + ;; + freebsd*) + ;; + gnu*) + ;; + hpux9* | hpux10* | hpux11*) + case "$host_cpu" in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + ;; + irix5* | irix6* | nonstopux*) + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux*) + ;; + netbsd*) + ;; + newsos6) + ;; + nto-qnx) + ;; + openbsd*) + ;; + os2*) + libname_spec='$name' + shrext=.dll + ;; + osf3* | osf4* | osf5*) + ;; + sco3.2v5*) + ;; + solaris*) + ;; + sunos4*) + ;; + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + ;; + sysv4*MP*) + ;; + uts4*) + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <= 0]) + +# Check privilege control library +PKG_CHECK_MODULES(PRIVILEGE_CONTROL, [libprivilege-control >= 0]) + +# Check syspopup-caller library +PKG_CHECK_MODULES(SYSPOPUP, [syspopup-caller]) + +# Check if we should build isf-setting-efl +PKG_CHECK_MODULES(VCONF, [vconf], + [ISF_HAS_VCONF=yes], + [ISF_HAS_VCONF=no]) + +if test "$ISF_HAS_VCONF" = "yes"; then + AC_DEFINE(HAVE_VCONF,1,[Have VConf functions.]) +fi + +# Check if we should build scim-panel-gtk daemon +PKG_CHECK_MODULES(GTK2, [gtk+-2.0 >= 2.4.0 pango >= 1.1.0 gdk-pixbuf-2.0 >= 2.4.0], + [SCIM_HAS_GTK2=yes], + [SCIM_HAS_GTK2=no]) + +SCIM_HAS_GTK2_2=no +if test "$SCIM_HAS_GTK2" = "yes"; then + if $PKG_CONFIG --exists "gtk+-2.0 >= 2.2" ; then + SCIM_HAS_GTK2_2=yes + GTK_VERSION=2.2.0 + AC_DEFINE(GDK_MULTIHEAD_SAFE,1,[Force use of GDK's multihead-safe APIs.]) + fi + if $PKG_CONFIG --exists "gtk+-2.0 >= 2.3.5" ; then + SCIM_HAS_GTK2_4=yes + GTK_VERSION=2.3.5 + AC_DEFINE(HAVE_GTK_DRAW_INSERTION_CURSOR,1,[Have gtk_draw_insertion_cursor ().]) + fi + GTK_BINARY_VERSION=`$PKG_CONFIG --variable=gtk_binary_version gtk+-2.0` + GTK_LIBDIR=`$PKG_CONFIG --variable=libdir gtk+-2.0` + if test -z "$GTK_LIBDIR)"; then + GTK_LIBDIR="$libdir" + fi + GTK_IM_MODULEDIR=$GTK_LIBDIR/gtk-2.0/$GTK_BINARY_VERSION/immodules + AC_SUBST(GTK_LIBDIR) + AC_SUBST(GTK_IM_MODULEDIR) + AC_SUBST(GTK_VERSION) + AC_SUBST(GTK_BINARY_VERSION) +fi + +# Check if we have gthread +PKG_CHECK_MODULES(GTHREAD2,[gthread-2.0 >= 2.0.0], + [SCIM_HAS_GTHREAD2=yes], + [SCIM_HAS_GTHREAD2=no]) + +# Checks for X11 header files. +AC_PATH_XTRA + +# Add -lX11 to X_LIBS +if test "$have_x" = "yes"; then + X_LIBS="$X_LIBS -lX11" +fi + +case $host_cpu in + *arm* ) TARGET=ARM;; + * ) TARGET=X86;; +esac +AM_CONDITIONAL(ARM, test x$TARGET = xARM) + +########################################################### +## Definiation of compile args. ## +########################################################### +AC_ARG_WITH(gtk-im-module-dir, + AS_HELP_STRING([--with-gtk-im-module-dir=dir], + [Select gtk immodule dir]), + GTK_IM_MODULEDIR=$with_gtk_im_module_dir) + +AC_ARG_WITH(efl-im-module-dir, + AS_HELP_STRING([--with-efl-im-module-dir=dir], + [Select efl immodule dir]), + EFL_IM_MODULEDIR=$with_efl_im_module_dir) + +AC_ARG_ENABLE(ld-version-script, + [ --enable-ld-version-script Use ld version script to limit exported symbols], + enable_ld_version_script=yes, + enable_ld_version_script=no) + +AC_ARG_ENABLE(debug, + [ --enable-debug Turn on debugging], + enable_debug=yes, + enable_debug=no) + +AC_ARG_ENABLE(x86, + [ --enable-x86 Build for x86 host], + enable_x86=yes, + enable_x86=no) + +AC_ARG_ENABLE(hash-map, + [ --enable-hash-map Use hast_map instead of std::map internally], + enable_hash_map=yes, + enable_hash_map=no) + +AC_ARG_ENABLE(config-simple, + [ --disable-config-simple Do not build Simple Config module], + enable_config_simple=no, + enable_config_simple=yes) + +AC_ARG_ENABLE(config-socket, + [ --disable-config-socket Do not build Socket Config module], + enable_config_socket=no, + enable_config_socket=yes) + +AC_ARG_ENABLE(frontend-x11, + [ --disable-frontend-x11 Do not build X11 FrontEnd module], + enable_frontend_x11=no, + enable_frontend_x11=yes) + +AC_ARG_ENABLE(frontend-socket, + [ --disable-frontend-socket Do not build Socket FrontEnd module], + enable_frontend_socket=no, + enable_frontend_socket=yes) + +AC_ARG_ENABLE(im-socket, + [ --disable-im-socket Do not build Socket IMEngine module], + enable_im_socket=no, + enable_im_socket=yes) + +AC_ARG_ENABLE(filter-sctc, + [ --disable-filter-sctc Do not build Simplified/Traditional Chinese conversion Filter module], + enable_filter_sctc=no, + enable_filter_sctc=yes) + +AC_ARG_ENABLE(gtk2-immodule, + [ --disable-gtk2-immodule Do not build GTK2 IMModule], + enable_gtk2_immodule=no, + enable_gtk2_immodule=yes) + +AC_ARG_ENABLE(panel-gtk, + [ --disable-panel-gtk Do not build GTK2 Panel], + enable_panel_gtk=no, + enable_panel_gtk=check) + +AC_ARG_ENABLE(efl-immodule, + [ --disable-efl-immodule Do not build EFL IMModule], + enable_efl_immodule=no, + enable_efl_immodule=yes) + +AC_ARG_ENABLE(panel-efl, + [ --disable-panel-efl Do not build EFL Panel], + enable_panel_efl=no, + enable_panel_efl=check) + +AC_ARG_ENABLE(setting-efl, + [ --disable-setting-efl Do not build EFL Setting], + enable_setting_efl=no, + enable_setting_efl=check) + +AC_ARG_ENABLE(tray-icon, + [ --disable-tray-icon Do not build Tray Icon], + enable_tray_icon=no, + enable_tray_icon=yes) + +if test "$have_x" = "yes"; then + SCIM_BUILD_X11_UTILS=1 + enable_x11_utils=yes +else + SCIM_BUILD_X11_UTILS=0 + enable_x11_utils=no +fi + +if test "$enable_hash_map" = "yes"; then + AC_DEFINE(ENABLE_HASH_MAP,1,[Use hash map instead of map in libscim]) +fi + +if test "$enable_debug" = "yes"; then + AC_DEFINE(ENABLE_DEBUG,1,[Define this to enable the debug facility in libscim]) + CFLAGS="$CFLAGS -g" + CXXFLAGS="$CXXFLAGS -g" +fi + +if test "$enable_x86" = "yes"; then + AC_DEFINE(ENABLE_X86_HOST,1,[Build for x86 host]) +fi + +if test "$enable_tests" = "yes"; then + SCIM_BUILD_TESTS=1 +else + SCIM_BUILD_TESTS=0 + enable_tests=no +fi + +if test "$enable_config_simple" = "yes"; then + SCIM_BUILD_CONFIG_SIMPLE=1 +else + SCIM_BUILD_CONFIG_SIMPLE=0 + enable_config_simple=no +fi + +if test "$enable_config_socket" = "yes" -a "$socket_ok" = "yes"; then + SCIM_BUILD_CONFIG_SOCKET=1 +else + SCIM_BUILD_CONFIG_SOCKET=0 + enable_config_socket=no +fi + +if test "$enable_frontend_x11" = "yes" -a "$have_x" = "yes"; then + SCIM_BUILD_FRONTEND_X11=1 +else + SCIM_BUILD_FRONTEND_X11=0 + enable_frontend_x11=no +fi + +if test "$enable_frontend_socket" = "yes" -a "$socket_ok" = "yes"; then + SCIM_BUILD_FRONTEND_SOCKET=1 +else + SCIM_BUILD_FRONTEND_SOCKET=0 + enable_frontend_socket=no +fi + +if test "$enable_im_rawcode" = "yes"; then + SCIM_BUILD_IMENGINE_RAWCODE=1 +else + SCIM_BUILD_IMENGINE_RAWCODE=0 + enable_im_rawcode=no +fi + +if test "$enable_im_socket" = "yes" -a "$socket_ok" = "yes"; then + SCIM_BUILD_IMENGINE_SOCKET=1 +else + SCIM_BUILD_IMENGINE_SOCKET=0 + enable_im_socket=no +fi + +if test "$enable_filter_sctc" = "yes"; then + SCIM_BUILD_FILTER_SCTC=1 +else + SCIM_BUILD_FILTER_SCTC=0 + enable_filter_sctc=no +fi + +if test "$enable_gtk2_immodule" = "yes" -a "$SCIM_HAS_GTK2" = "yes"; then + SCIM_BUILD_GTK2_IMMODULE=1 +else + SCIM_BUILD_GTK2_IMMODULE=0 + enable_gtk2_immodule=no +fi + +if test "$SCIM_HAS_GTK2" = "yes"; then + enable_gtk_utils=yes + SCIM_BUILD_GTK_UTILS=1 +else + enable_gtk_utils=no + SCIM_BUILD_GTK_UTILS=0 +fi + +if test "$enable_tray_icon" = "yes"; then + if test "$SCIM_HAS_GTK2_2" = "yes" -a "$no_x" != "yes"; then + enable_tray_icon=yes + AC_DEFINE(ENABLE_TRAY_ICON,1,[Enable the TrayIcon code.]) + fi +else + enable_tray_icon=no +fi + +SCIM_BUILD_PANEL_GTK=0 +if test "$enable_panel_gtk" != "no"; then + enable_panel_gtk=no + if test "$SCIM_HAS_GTHREAD2" = "yes" -a "$SCIM_HAS_GTK2" = "yes"; then + SCIM_BUILD_PANEL_GTK=1 + enable_panel_gtk=yes + fi +fi + +if test "$enable_efl_immodule" = "yes" -a "$ISF_HAS_EFL" = "yes"; then + ISF_BUILD_EFL_IMMODULE=1 +else + ISF_BUILD_EFL_IMMODULE=0 + enable_efl_immodule=no +fi + +ISF_BUILD_PANEL_EFL=0 +if test "$enable_panel_efl" != "no"; then + enable_panel_efl=no + if test "$ISF_HAS_EFL" = "yes"; then + ISF_BUILD_PANEL_EFL=1 + enable_panel_efl=yes + fi +fi + +ISF_BUILD_SETTING_EFL=0 +if test "$enable_setting_efl" != "no"; then + enable_setting_efl=no + if test "$ISF_HAS_EFL" = "yes" -a "$ISF_HAS_VCONF" = "yes"; then + ISF_BUILD_SETTING_EFL=1 + enable_setting_efl=yes + fi +fi + +#if nothing needs libscim-gtkutils, just disable it +if test "$enable_panel_gtk" != "yes"; then + enable_gtk_utils=no + SCIM_BUILD_GTK_UTILS=0 +fi + +AM_CONDITIONAL(SCIM_LD_VERSION_SCRIPT, + [test "$enable_ld_version_script" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_TESTS, + [test "$enable_tests" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_CONFIG_SIMPLE, + [test "$enable_config_simple" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_CONFIG_SOCKET, + [test "$enable_config_socket" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_FRONTEND_X11, + [test "$enable_frontend_x11" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_FRONTEND_SOCKET, + [test "$enable_frontend_socket" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_IMENGINE_SOCKET, + [test "$enable_im_socket" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_IMENGINE_RAWCODE, + [test "$enable_im_rawcode" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_GTK2_IMMODULE, + [test "$enable_gtk2_immodule" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_FILTER_SCTC, + [test "$enable_filter_sctc" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_GTK_UTILS, + [test "$enable_gtk_utils" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_X11_UTILS, + [test "$enable_x11_utils" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_TRAY_ICON, + [test "$enable_tray_icon" = "yes"]) + +AM_CONDITIONAL(SCIM_BUILD_PANEL_GTK, + [test "$enable_panel_gtk" = "yes"]) + +AM_CONDITIONAL(ISF_BUILD_EFL_IMMODULE, + [test "$enable_efl_immodule" = "yes"]) + +AM_CONDITIONAL(ISF_BUILD_PANEL_EFL, + [test "$enable_panel_efl" = "yes"]) + +AM_CONDITIONAL(ISF_BUILD_SETTING_EFL, + [test "$enable_setting_efl" = "yes"]) + +AM_CONDITIONAL(ISF_BUILD_WITH_GCONF, + [test "$ISF_HAS_GCONF" = "yes"]) + +AC_SUBST(SCIM_BUILD_TESTS) +AC_SUBST(SCIM_BUILD_CONFIG_SIMPLE) +AC_SUBST(SCIM_BUILD_CONFIG_SOCKET) +AC_SUBST(SCIM_BUILD_FRONTEND_X11) +AC_SUBST(SCIM_BUILD_FRONTEND_SOCKET) +AC_SUBST(SCIM_BUILD_IMENGINE_RAWCODE) +AC_SUBST(SCIM_BUILD_IMENGINE_TABLE) +AC_SUBST(SCIM_BUILD_IMENGINE_SOCKET) +AC_SUBST(SCIM_BUILD_FILTER_SCTC) +AC_SUBST(SCIM_BUILD_GTK2_IMMODULE) +AC_SUBST(SCIM_BUILD_SCIM_SETUP) +AC_SUBST(SCIM_BUILD_PANEL_GTK) +AC_SUBST(SCIM_BUILD_GTK_UTILS) +AC_SUBST(SCIM_BUILD_X11_UTILS) +AC_SUBST(ISF_BUILD_EFL_IMMODULE) +AC_SUBST(ISF_BUILD_PANEL_EFL) +AC_SUBST(ISF_BUILD_SETTING_EFL) +AC_SUBST(ISF_BUILD_WITH_GCONF) + +# Output All necessary Paths. +SCIM_BINDIR="$prefix/bin" +SCIM_DATADIR="$datadir/scim" +SCIM_SYSCONFDIR="$sysconfdir" +SCIM_ICONDIR="$datadir/scim/icons" +SCIM_MODULE_PATH="$libdir/scim$SCIM_EPOCH" +SCIM_LIBEXECDIR="$libdir/scim$SCIM_EPOCH" +SCIM_LOCALEDIR="/usr/share/locale" +SCIM_TEMPDIR="/tmp" + +AC_SUBST(SCIM_BINDIR) +AC_SUBST(SCIM_DATADIR) +AC_SUBST(SCIM_SYSCONFDIR) +AC_SUBST(SCIM_ICONDIR) +AC_SUBST(SCIM_MODULE_PATH) +AC_SUBST(SCIM_LIBEXECDIR) +AC_SUBST(SCIM_LOCALEDIR) +AC_SUBST(SCIM_TEMPDIR) + +########################################################### +## Output files. ## +########################################################### +AC_SUBST(ac_aux_dir) +AC_CONFIG_FILES([Makefile + ism/m4/Makefile + po/scim/Makefile.in + po/isfsetting_efl/Makefile.in + po/kbwizard_efl/Makefile.in + ism/src/Makefile + ism/src/scim_types.h + ism/utils/Makefile + ism/data/Makefile + ism/data/icons/Makefile + ism/data/pixmaps/Makefile + ism/modules/Makefile + ism/modules/frontend/imdkit/Makefile + ism/modules/frontend/Makefile + ism/modules/imengine/Makefile + ism/modules/filter/Makefile + ism/modules/config/Makefile + ism/configs/Makefile + ism/extras/Makefile + ism/extras/gtk2_immodule/Makefile + ism/extras/gtk_panel/Makefile + ism/extras/efl_immodule/Makefile + ism/extras/efl_panel/Makefile + ism/extras/efl_setting/Makefile + ism/demos/Makefile + intltool-extract + intltool-merge + intltool-update + isf.pc + scim.pc + scim-gtkutils.pc + scim.spec]) +AC_OUTPUT + +AC_MSG_RESULT([ +Build options: + Version $ISF_VERSION + Install prefix $prefix + Build shared libs $enable_shared + Build static libs $enable_static + Enable debug $enable_debug + Build for x86 host $enable_x86 + Enable ld version script $enable_ld_version_script + +Module options: + Simple config module $enable_config_simple + Socket config module $enable_config_socket + + X11 FrontEnd module $enable_frontend_x11 + Socket FrontEnd module $enable_frontend_socket + + Socket IMEngine module $enable_im_socket + + SCTC Filter module $enable_filter_sctc + + GTK2 Utility Library $enable_gtk_utils + X11 Utility Library $enable_x11_utils + + GTK2 IMModule $enable_gtk2_immodule + GTK2 IMModule dir $GTK_IM_MODULEDIR + GTK2 Panel GUI $enable_panel_gtk + + EFL IMModule $enable_efl_immodule + EFL IMModule dir $EFL_IM_MODULEDIR + EFL Panel GUI $enable_panel_efl + EFL Setting $enable_setting_efl + + Enable TrayIcon $enable_tray_icon +]) + diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..04701da --- /dev/null +++ b/depcomp @@ -0,0 +1,530 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2005-07-09.11 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mecanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..4d4a951 --- /dev/null +++ b/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/intltool-extract.in b/intltool-extract.in new file mode 100644 index 0000000..4352680 --- /dev/null +++ b/intltool-extract.in @@ -0,0 +1,516 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Extractor +# +# Copyright (C) 2000-2001, 2003 Free Software Foundation. +# +# Intltool 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. +# +# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Darin Adler +# + +## Release information +my $PROGRAM = "intltool-extract"; +my $PACKAGE = "intltool"; +my $VERSION = "0.33"; + +## Loaded modules +use strict; +use File::Basename; +use Getopt::Long; + +## Scalars used by the option stuff +my $TYPE_ARG = "0"; +my $LOCAL_ARG = "0"; +my $HELP_ARG = "0"; +my $VERSION_ARG = "0"; +my $UPDATE_ARG = "0"; +my $QUIET_ARG = "0"; +my $SRCDIR_ARG = "."; + +my $FILE; +my $OUTFILE; + +my $gettext_type = ""; +my $input; +my %messages = (); +my %loc = (); +my %count = (); +my %comments = (); +my $strcount = 0; + +## Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +## Always print first +$| = 1; + +## Handle options +GetOptions ( + "type=s" => \$TYPE_ARG, + "local|l" => \$LOCAL_ARG, + "help|h" => \$HELP_ARG, + "version|v" => \$VERSION_ARG, + "update" => \$UPDATE_ARG, + "quiet|q" => \$QUIET_ARG, + "srcdir=s" => \$SRCDIR_ARG, + ) or &error; + +&split_on_argument; + + +## Check for options. +## This section will check for the different options. + +sub split_on_argument { + + if ($VERSION_ARG) { + &version; + + } elsif ($HELP_ARG) { + &help; + + } elsif ($LOCAL_ARG) { + &place_local; + &extract; + + } elsif ($UPDATE_ARG) { + &place_normal; + &extract; + + } elsif (@ARGV > 0) { + &place_normal; + &message; + &extract; + + } else { + &help; + + } +} + +sub place_normal { + $FILE = $ARGV[0]; + $OUTFILE = "$FILE.h"; +} + +sub place_local { + $FILE = $ARGV[0]; + $OUTFILE = fileparse($FILE, ()); + if (!-e "tmp/") { + system("mkdir tmp/"); + } + $OUTFILE = "./tmp/$OUTFILE.h" +} + +sub determine_type { + if ($TYPE_ARG =~ /^gettext\/(.*)/) { + $gettext_type=$1 + } +} + +## Sub for printing release information +sub version{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) $VERSION +Copyright (C) 2000, 2003 Free Software Foundation, Inc. +Written by Kenneth Christiansen, 2000. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +## Sub for printing usage information +sub help { + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... [FILENAME] +Generates a header file from an XML source file. + +It grabs all strings between <_translatable_node> and its end tag in +XML files. Read manpage (man ${PROGRAM}) for more info. + + --type=TYPE Specify the file type of FILENAME. Currently supports: + "gettext/glade", "gettext/ini", "gettext/keys" + "gettext/rfc822deb", "gettext/schemas", + "gettext/scheme", "gettext/xml" + -l, --local Writes output into current working directory + (conflicts with --update) + --update Writes output into the same directory the source file + reside (conflicts with --local) + --srcdir Root of the source tree + -v, --version Output version information and exit + -h, --help Display this help and exit + -q, --quiet Quiet mode + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + +## Sub for printing error messages +sub error{ + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + +sub message { + print "Generating C format header file for translation.\n" unless $QUIET_ARG; +} + +sub extract { + &determine_type; + + &convert; + + open OUT, ">$OUTFILE"; + &msg_write; + close OUT; + + print "Wrote $OUTFILE\n" unless $QUIET_ARG; +} + +sub convert { + + ## Reading the file + { + local (*IN); + local $/; #slurp mode + open (IN, "<$SRCDIR_ARG/$FILE") || die "can't open $SRCDIR_ARG/$FILE: $!"; + $input = ; + } + + &type_ini if $gettext_type eq "ini"; + &type_keys if $gettext_type eq "keys"; + &type_xml if $gettext_type eq "xml"; + &type_glade if $gettext_type eq "glade"; + &type_scheme if $gettext_type eq "scheme"; + &type_schemas if $gettext_type eq "schemas"; + &type_rfc822deb if $gettext_type eq "rfc822deb"; +} + +sub entity_decode_minimal +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + + return $_; +} + +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + s/<//g; + + return $_; +} + +sub escape_char +{ + return '\"' if $_ eq '"'; + return '\n' if $_ eq "\n"; + return '\\' if $_ eq '\\'; + + return $_; +} + +sub escape +{ + my ($string) = @_; + return join "", map &escape_char, split //, $string; +} + +sub type_ini { + ### For generic translatable desktop files ### + while ($input =~ /^_.*=(.*)$/mg) { + $messages{$1} = []; + } +} + +sub type_keys { + ### For generic translatable mime/keys files ### + while ($input =~ /^\s*_\w+=(.*)$/mg) { + $messages{$1} = []; + } +} + +sub type_xml { + ### For generic translatable XML files ### + + while ($input =~ /(?:[^\n]*\n?[^\n]*)?\s_$w+\s*=\s*\"([^"]*)\"/sg) { # " + $messages{entity_decode_minimal($2)} = []; + $comments{entity_decode_minimal($2)} = $1 if (defined($1)); + } + + while ($input =~ /(?:\s*)?<_($w+)(?: xml:space="($w+)")?[^>]*>(.*?)<\/_\2>/sg) { + $_ = $4; + if (!defined($3) || $3 ne "preserve") { + s/\s+/ /g; + s/^ //; + s/ $//; + } + $messages{$_} = []; + $comments{$_} = $1 if (defined($1)); + } +} + +sub type_schemas { + ### For schemas XML files ### + + # FIXME: We should handle escaped < (less than) + while ($input =~ / + \s* + (\s*(?:\s*)?(.*?)\s*<\/default>\s*)? + (\s*(?:\s*)?(.*?)\s*<\/short>\s*)? + (\s*(?:\s*)?(.*?)\s*<\/long>\s*)? + <\/locale> + /sgx) { + my @totranslate = ($3,$6,$9); + my @eachcomment = ($2,$5,$8); + foreach (@totranslate) { + my $currentcomment = shift @eachcomment; + next if !$_; + s/\s+/ /g; + $messages{entity_decode_minimal($_)} = []; + $comments{entity_decode_minimal($_)} = $currentcomment if (defined($currentcomment)); + } + } +} + +sub type_rfc822deb { + ### For rfc822-style Debian configuration files ### + + my $lineno = 1; + my $type = ''; + while ($input =~ /\G(.*?)(^|\n)(_+)([^:]+):[ \t]*(.*?)(?=\n\S|$)/sg) + { + my ($pre, $newline, $underscore, $tag, $text) = ($1, $2, $3, $4, $5); + while ($pre =~ m/\n/g) + { + $lineno ++; + } + $lineno += length($newline); + my @str_list = rfc822deb_split(length($underscore), $text); + for my $str (@str_list) + { + $strcount++; + $messages{$str} = []; + $loc{$str} = $lineno; + $count{$str} = $strcount; + my $usercomment = ''; + while($pre =~ s/(^|\n)#([^\n]*)$//s) + { + $usercomment = "\n" . $2 . $usercomment; + } + $comments{$str} = $tag . $usercomment; + } + $lineno += ($text =~ s/\n//g); + } +} + +sub rfc822deb_split { + # Debian defines a special way to deal with rfc822-style files: + # when a value contain newlines, it consists of + # 1. a short form (first line) + # 2. a long description, all lines begin with a space, + # and paragraphs are separated by a single dot on a line + # This routine returns an array of all paragraphs, and reformat + # them. + # When first argument is 2, the string is a comma separated list of + # values. + my $type = shift; + my $text = shift; + $text =~ s/^[ \t]//mg; + return (split(/, */, $text, 0)) if $type ne 1; + return ($text) if $text !~ /\n/; + + $text =~ s/([^\n]*)\n//; + my @list = ($1); + my $str = ''; + for my $line (split (/\n/, $text)) + { + chomp $line; + if ($line =~ /^\.\s*$/) + { + # New paragraph + $str =~ s/\s*$//; + push(@list, $str); + $str = ''; + } + elsif ($line =~ /^\s/) + { + # Line which must not be reformatted + $str .= "\n" if length ($str) && $str !~ /\n$/; + $line =~ s/\s+$//; + $str .= $line."\n"; + } + else + { + # Continuation line, remove newline + $str .= " " if length ($str) && $str !~ /\n$/; + $str .= $line; + } + } + $str =~ s/\s*$//; + push(@list, $str) if length ($str); + return @list; +} + +sub type_glade { + ### For translatable Glade XML files ### + + my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message"; + + while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) { + # Glade sometimes uses tags that normally mark translatable things for + # little bits of non-translatable content. We work around this by not + # translating strings that only includes something like label4 or window1. + $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label|dialog)[0-9]+$/; + } + + while ($input =~ /(..[^<]*)<\/items>/sg) { + for my $item (split (/\n/, $1)) { + $messages{entity_decode($item)} = []; + } + } + + ## handle new glade files + while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"(?:\s+[^>]*comments\s*=\s*"([^"]*)")?[^>]*>([^<]+)<\/\1>/sg) { + $messages{entity_decode($3)} = [] unless $3 =~ /^(window|label)[0-9]+$/; + if (defined($2) and !($3 =~ /^(window|label)[0-9]+$/)) { + $comments{entity_decode($3)} = entity_decode($2) ; + } + } + while ($input =~ /]*)"\s+description="([^>]+)"\/>/sg) { + $messages{entity_decode_minimal($2)} = []; + } +} + +sub type_scheme { + my ($line, $i, $state, $str, $trcomment, $char); + for $line (split(/\n/, $input)) { + $i = 0; + $state = 0; # 0 - nothing, 1 - string, 2 - translatable string + while ($i < length($line)) { + if (substr($line,$i,1) eq "\"") { + if ($state == 2) { + $comments{$str} = $trcomment if ($trcomment); + $messages{$str} = []; + $str = ''; + $state = 0; $trcomment = ""; + } elsif ($state == 1) { + $str = ''; + $state = 0; $trcomment = ""; + } else { + $state = 1; + $str = ''; + if ($i>0 && substr($line,$i-1,1) eq '_') { + $state = 2; + } + } + } elsif (!$state) { + if (substr($line,$i,1) eq ";") { + $trcomment = substr($line,$i+1); + $trcomment =~ s/^;*\s*//; + $i = length($line); + } elsif ($trcomment && substr($line,$i,1) !~ /\s|\(|\)|_/) { + $trcomment = ""; + } + } else { + if (substr($line,$i,1) eq "\\") { + $char = substr($line,$i+1,1); + if ($char ne "\"" && $char ne "\\") { + $str = $str . "\\"; + } + $i++; + } + $str = $str . substr($line,$i,1); + } + $i++; + } + } +} + +sub msg_write { + my @msgids; + if (%count) + { + @msgids = sort { $count{$a} <=> $count{$b} } keys %count; + } + else + { + @msgids = sort keys %messages; + } + for my $message (@msgids) + { + my $offsetlines = 1; + $offsetlines++ if $message =~ /%/; + if (defined ($comments{$message})) + { + while ($comments{$message} =~ m/\n/g) + { + $offsetlines++; + } + } + print OUT "# ".($loc{$message} - $offsetlines). " \"$FILE\"\n" + if defined $loc{$message}; + print OUT "/* ".$comments{$message}." */\n" + if defined $comments{$message}; + print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/; + + my @lines = split (/\n/, $message, -1); + for (my $n = 0; $n < @lines; $n++) + { + if ($n == 0) + { + print OUT "char *s = N_(\""; + } + else + { + print OUT " \""; + } + + print OUT escape($lines[$n]); + + if ($n < @lines - 1) + { + print OUT "\\n\"\n"; + } + else + { + print OUT "\");\n"; + } + } + } +} + diff --git a/intltool-merge.in b/intltool-merge.in new file mode 100644 index 0000000..7c96d98 --- /dev/null +++ b/intltool-merge.in @@ -0,0 +1,1315 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Merger +# +# Copyright (C) 2000, 2003 Free Software Foundation. +# Copyright (C) 2000, 2001 Eazel, Inc +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Maciej Stachowiak +# Kenneth Christiansen +# Darin Adler +# +# Proper XML UTF-8'ification written by Cyrille Chepelov +# + +## Release information +my $PROGRAM = "intltool-merge"; +my $PACKAGE = "intltool"; +my $VERSION = "0.33"; + +## Loaded modules +use strict; +use Getopt::Long; +use Text::Wrap; +use File::Basename; + +my $must_end_tag = -1; +my $last_depth = -1; +my $translation_depth = -1; +my @tag_stack = (); +my @entered_tag = (); +my @translation_strings = (); +my $leading_space = ""; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $BA_STYLE_ARG = 0; +my $XML_STYLE_ARG = 0; +my $KEYS_STYLE_ARG = 0; +my $DESKTOP_STYLE_ARG = 0; +my $SCHEMAS_STYLE_ARG = 0; +my $RFC822DEB_STYLE_ARG = 0; +my $QUIET_ARG = 0; +my $PASS_THROUGH_ARG = 0; +my $UTF8_ARG = 0; +my $MULTIPLE_OUTPUT = 0; +my $cache_file; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "quiet|q" => \$QUIET_ARG, + "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility + "ba-style|b" => \$BA_STYLE_ARG, + "xml-style|x" => \$XML_STYLE_ARG, + "keys-style|k" => \$KEYS_STYLE_ARG, + "desktop-style|d" => \$DESKTOP_STYLE_ARG, + "schemas-style|s" => \$SCHEMAS_STYLE_ARG, + "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG, + "pass-through|p" => \$PASS_THROUGH_ARG, + "utf8|u" => \$UTF8_ARG, + "multiple-output|m" => \$MULTIPLE_OUTPUT, + "cache|c=s" => \$cache_file + ) or &error; + +my $PO_DIR; +my $FILE; +my $OUTFILE; + +my %po_files_by_lang = (); +my %translations = (); +my $iconv = $ENV{"ICONV"} || $ENV{"INTLTOOL_ICONV"} || "/usr/bin/iconv"; + +# Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +# XML quoted string contents +my $q = "[^\\\"]*"; + +## Check for options. + +if ($VERSION_ARG) +{ + &print_version; +} +elsif ($HELP_ARG) +{ + &print_help; +} +elsif ($BA_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &ba_merge_translations; + &finalize; +} +elsif ($XML_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &xml_merge_output; + &finalize; +} +elsif ($KEYS_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &keys_merge_translations; + &finalize; +} +elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &desktop_merge_translations; + &finalize; +} +elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &schemas_merge_translations; + &finalize; +} +elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &rfc822deb_merge_translations; + &finalize; +} +else +{ + &print_help; +} + +exit; + +## Sub for printing release information +sub print_version +{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) ${VERSION} +Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen. + +Copyright (C) 2000-2003 Free Software Foundation, Inc. +Copyright (C) 2000-2001 Eazel, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +## Sub for printing usage information +sub print_help +{ + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE +Generates an output file that includes some localized attributes from an +untranslated source file. + +Mandatory options: (exactly one must be specified) + -b, --ba-style includes translations in the bonobo-activation style + -d, --desktop-style includes translations in the desktop style + -k, --keys-style includes translations in the keys style + -s, --schemas-style includes translations in the schemas style + -r, --rfc822deb-style includes translations in the RFC822 style + -x, --xml-style includes translations in the standard xml style + +Other options: + -u, --utf8 convert all strings to UTF-8 before merging + (default for everything except RFC822 style) + -p, --pass-through deprecated, does nothing and issues a warning + -m, --multiple-output output one localized file per locale, instead of + a single file containing all localized elements + -c, --cache=FILE specify cache file name + (usually \$top_builddir/po/.intltool-merge-cache) + -q, --quiet suppress most messages + --help display this help and exit + --version output version information and exit + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + + +## Sub for printing error messages +sub print_error +{ + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + + +sub print_message +{ + print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG; +} + + +sub preparation +{ + $PO_DIR = $ARGV[0]; + $FILE = $ARGV[1]; + $OUTFILE = $ARGV[2]; + + &gather_po_files; + &get_translation_database; +} + +# General-purpose code for looking up translations in .po files + +sub po_file2lang +{ + my ($tmp) = @_; + $tmp =~ s/^.*\/(.*)\.po$/$1/; + return $tmp; +} + +sub gather_po_files +{ + for my $po_file (glob "$PO_DIR/*.po") { + $po_files_by_lang{po_file2lang($po_file)} = $po_file; + } +} + +sub get_local_charset +{ + my ($encoding) = @_; + my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "/usr/lib/charset.alias"; + + # seek character encoding aliases in charset.alias (glib) + + if (open CHARSET_ALIAS, $alias_file) + { + while () + { + next if /^\#/; + return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i) + } + + close CHARSET_ALIAS; + } + + # if not found, return input string + + return $encoding; +} + +sub get_po_encoding +{ + my ($in_po_file) = @_; + my $encoding = ""; + + open IN_PO_FILE, $in_po_file or die; + while () + { + ## example: "Content-Type: text/plain; charset=ISO-8859-1\n" + if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) + { + $encoding = $1; + last; + } + } + close IN_PO_FILE; + + if (!$encoding) + { + print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG; + $encoding = "ISO-8859-1"; + } + + system ("$iconv -f $encoding -t UTF-8 /dev/null"); + if ($?) { + $encoding = get_local_charset($encoding); + } + + return $encoding +} + +sub utf8_sanity_check +{ + print STDERR "Warning: option --pass-through has been removed.\n" if $PASS_THROUGH_ARG; + $UTF8_ARG = 1; +} + +sub get_translation_database +{ + if ($cache_file) { + &get_cached_translation_database; + } else { + &create_translation_database; + } +} + +sub get_newest_po_age +{ + my $newest_age; + + foreach my $file (values %po_files_by_lang) + { + my $file_age = -M $file; + $newest_age = $file_age if !$newest_age || $file_age < $newest_age; + } + + $newest_age = 0 if !$newest_age; + + return $newest_age; +} + +sub create_cache +{ + print "Generating and caching the translation database\n" unless $QUIET_ARG; + + &create_translation_database; + + open CACHE, ">$cache_file" || die; + print CACHE join "\x01", %translations; + close CACHE; +} + +sub load_cache +{ + print "Found cached translation database\n" unless $QUIET_ARG; + + my $contents; + open CACHE, "<$cache_file" || die; + { + local $/; + $contents = ; + } + close CACHE; + %translations = split "\x01", $contents; +} + +sub get_cached_translation_database +{ + my $cache_file_age = -M $cache_file; + if (defined $cache_file_age) + { + if ($cache_file_age <= &get_newest_po_age) + { + &load_cache; + return; + } + print "Found too-old cached translation database\n" unless $QUIET_ARG; + } + + &create_cache; +} + +sub create_translation_database +{ + for my $lang (keys %po_files_by_lang) + { + my $po_file = $po_files_by_lang{$lang}; + + if ($UTF8_ARG) + { + my $encoding = get_po_encoding ($po_file); + + if (lc $encoding eq "utf-8") + { + open PO_FILE, "<$po_file"; + } + else + { + print STDERR "WARNING: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;; + + open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|"; + } + } + else + { + open PO_FILE, "<$po_file"; + } + + my $nextfuzzy = 0; + my $inmsgid = 0; + my $inmsgstr = 0; + my $msgid = ""; + my $msgstr = ""; + + while () + { + $nextfuzzy = 1 if /^#, fuzzy/; + + if (/^msgid "((\\.|[^\\])*)"/ ) + { + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + $msgid = ""; + $msgstr = ""; + + if ($nextfuzzy) { + $inmsgid = 0; + } else { + $msgid = unescape_po_string($1); + $inmsgid = 1; + } + $inmsgstr = 0; + $nextfuzzy = 0; + } + + if (/^msgstr "((\\.|[^\\])*)"/) + { + $msgstr = unescape_po_string($1); + $inmsgstr = 1; + $inmsgid = 0; + } + + if (/^"((\\.|[^\\])*)"/) + { + $msgid .= unescape_po_string($1) if $inmsgid; + $msgstr .= unescape_po_string($1) if $inmsgstr; + } + } + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + } +} + +sub finalize +{ +} + +sub unescape_one_sequence +{ + my ($sequence) = @_; + + return "\\" if $sequence eq "\\\\"; + return "\"" if $sequence eq "\\\""; + return "\n" if $sequence eq "\\n"; + return "\r" if $sequence eq "\\r"; + return "\t" if $sequence eq "\\t"; + return "\b" if $sequence eq "\\b"; + return "\f" if $sequence eq "\\f"; + return "\a" if $sequence eq "\\a"; + return chr(11) if $sequence eq "\\v"; # vertical tab, see ascii(7) + + return chr(hex($1)) if ($sequence =~ /\\x([0-9a-fA-F]{2})/); + return chr(oct($1)) if ($sequence =~ /\\([0-7]{3})/); + + # FIXME: Is \0 supported as well? Kenneth and Rodney don't want it, see bug #48489 + + return $sequence; +} + +sub unescape_po_string +{ + my ($string) = @_; + + $string =~ s/(\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\.)/unescape_one_sequence($1)/eg; + + return $string; +} + +## NOTE: deal with < - < but not > - > because it seems its ok to have +## > in the entity. For further info please look at #84738. +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + s/</; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!"; + + while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) + { + print OUTPUT $1; + + my $node = $2 . "\n"; + + my @strings = (); + $_ = $node; + while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) { + push @strings, entity_decode($3); + } + print OUTPUT; + + my %langs; + for my $string (@strings) + { + for my $lang (keys %po_files_by_lang) + { + $langs{$lang} = 1 if $translations{$lang, $string}; + } + } + + for my $lang (sort keys %langs) + { + $_ = $node; + s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s; + s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg; + print OUTPUT; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + + +## XML (non-bonobo-activation) merge code + + +# Process tag attributes +# Only parameter is a HASH containing attributes -> values mapping +sub getAttributeString +{ + my $sub = shift; + my $do_translate = shift || 0; + my $language = shift || ""; + my $result = ""; + my $translate = shift; + foreach my $e (reverse(sort(keys %{ $sub }))) { + my $key = $e; + my $string = $sub->{$e}; + my $quote = '"'; + + $string =~ s/^[\s]+//; + $string =~ s/[\s]+$//; + + if ($string =~ /^'.*'$/) + { + $quote = "'"; + } + $string =~ s/^['"]//g; + $string =~ s/['"]$//g; + + if ($do_translate && $key =~ /^_/) { + $key =~ s|^_||g; + if ($language) { + + # Handle translation + # + my $decode_string = entity_decode($string); + my $translation = $translations{$language, $decode_string}; + if ($translation) { + $translation = entity_encode($translation); + $string = $translation; + $$translate = 2; + } else { + $$translate = 2; # we still want translations for deep nesting (FIXME: this will cause + # problems since we might get untranslated duplicated entries, but with xml:lang set) + # Fix would be to set it here to eg. 3, and do a check in traverse() to see if any of the containing tags + # really need translation, and only emit "translation" if there is (this means parsing same data twice) + } + } else { + $$translate = 2 if ($translate && (!$$translate)); # watch not to "overwrite" if $translate == 2 + } + } + + $result .= " $key=$quote$string$quote"; + } + return $result; +} + +# Returns a translatable string from XML node, it works on contents of every node in XML::Parser tree +# doesn't support nesting of translatable tags (i.e. <_blah>this <_doh>doesn't work -- besides +# can you define the correct semantics for this?) +# + +sub getXMLstring +{ + my $ref = shift; + my @list = @{ $ref }; + my $result = ""; + + my $count = scalar(@list); + my $attrs = $list[0]; + my $index = 1; + + while ($index < $count) { + my $type = $list[$index]; + my $content = $list[$index+1]; + if (! $type ) { + # We've got CDATA + if ($content) { + # lets strip the whitespace here, and *ONLY* here + $content =~ s/\s+/ /gs if (!((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/))); + $result .= ($content); + } else { + #print "no cdata content when expected it\n"; # is this possible, is this ok? + # what to do if this happens? + # Did I mention that I hate XML::Parser tree style? + } + } else { + # We've got another element + $result .= "<$type"; + $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements + if ($content) { + my $subresult = getXMLstring($content); + if ($subresult) { + $result .= ">".$subresult . ""; + } else { + $result .= "/>"; + } + } else { + $result .= "/>"; + } + } + $index += 2; + } + return $result; +} + +# Translate list of nodes if necessary +sub translate_subnodes +{ + my $fh = shift; + my $content = shift; + my $language = shift || ""; + my $singlelang = shift || 0; + + my @nodes = @{ $content }; + + my $count = scalar(@nodes); + my $index = 0; + while ($index < $count) { + my $type = $nodes[$index]; + my $rest = $nodes[$index+1]; + if ($singlelang) { + my $oldMO = $MULTIPLE_OUTPUT; + $MULTIPLE_OUTPUT = 1; + traverse($fh, $type, $rest, $language); + $MULTIPLE_OUTPUT = $oldMO; + } else { + traverse($fh, $type, $rest, $language); + } + $index += 2; + } +} + +sub traverse +{ + my $fh = shift; + my $nodename = shift; + my $content = shift; + my $language = shift || ""; + + if (!$nodename) { + if ($content =~ /^[\s]*$/) { + $leading_space .= $content; + } + print $fh $content; + } else { + # element + my @all = @{ $content }; + my $attrs = shift @all; + my $translate = 0; + my $outattr = getAttributeString($attrs, 1, $language, \$translate); + + if ($nodename =~ /^_/) { + $translate = 1; + $nodename =~ s/^_//; + } + my $lookup = ''; + print $fh "<$nodename", $outattr; + if ($translate) { + $lookup = getXMLstring($content); + if (!((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/))) { + $lookup =~ s/^\s+//s; + $lookup =~ s/\s+$//s; + } + + if ($lookup || $translate == 2) { + my $translation = $translations{$language, $lookup}; + if ($MULTIPLE_OUTPUT && ($translation || $translate == 2)) { + $translation = $lookup if (!$translation); + print $fh " xml:lang=\"", $language, "\"" if $language; + print $fh ">"; + if ($translate == 2) { + translate_subnodes($fh, \@all, $language, 1); + } else { + print $fh $translation; + } + print $fh ""; + + return; # this means there will be no same translation with xml:lang="$language"... + # if we want them both, just remove this "return" + } else { + print $fh ">"; + if ($translate == 2) { + translate_subnodes($fh, \@all, $language, 1); + } else { + print $fh $lookup; + } + print $fh ""; + } + } else { + print $fh "/>"; + } + + for my $lang (sort keys %po_files_by_lang) { + if ($MULTIPLE_OUTPUT && $lang ne "$language") { + next; + } + if ($lang) { + # Handle translation + # + my $translate = 0; + my $localattrs = getAttributeString($attrs, 1, $lang, \$translate); + my $translation = $translations{$lang, $lookup}; + if ($translate && !$translation) { + $translation = $lookup; + } + + if ($translation || $translate) { + print $fh "\n"; + $leading_space =~ s/.*\n//g; + print $fh $leading_space; + print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs, ">"; + if ($translate == 2) { + translate_subnodes($fh, \@all, $lang, 1); + } else { + print $fh $translation; + } + print $fh ""; + } + } + } + + } else { + my $count = scalar(@all); + if ($count > 0) { + print $fh ">"; + my $index = 0; + while ($index < $count) { + my $type = $all[$index]; + my $rest = $all[$index+1]; + traverse($fh, $type, $rest, $language); + $index += 2; + } + print $fh ""; + } else { + print $fh "/>"; + } + } + } +} + +sub intltool_tree_cdatastart +{ + my $expat = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + push @$clist, 0 => $expat->original_string(); +} + +sub intltool_tree_cdataend +{ + my $expat = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + $clist->[$pos] .= $expat->original_string(); +} + +sub intltool_tree_char +{ + my $expat = shift; + my $text = shift; + my $clist = $expat->{Curlist}; + my $pos = $#$clist; + + # Use original_string so that we retain escaped entities + # in CDATA sections. + # + if ($pos > 0 and $clist->[$pos - 1] eq '0') { + $clist->[$pos] .= $expat->original_string(); + } else { + push @$clist, 0 => $expat->original_string(); + } +} + +sub intltool_tree_start +{ + my $expat = shift; + my $tag = shift; + my @origlist = (); + + # Use original_string so that we retain escaped entities + # in attribute values. We must convert the string to an + # @origlist array to conform to the structure of the Tree + # Style. + # + my @original_array = split /\x/, $expat->original_string(); + my $source = $expat->original_string(); + + # Remove leading tag. + # + $source =~ s|^\s*<\s*(\S+)||s; + + # Grab attribute key/value pairs and push onto @origlist array. + # + while ($source) + { + if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s; + push @origlist, $1; + push @origlist, '"' . $2 . '"'; + } + elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/) + { + $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s; + push @origlist, $1; + push @origlist, "'" . $2 . "'"; + } + else + { + last; + } + } + + my $ol = [ { @origlist } ]; + + push @{ $expat->{Lists} }, $expat->{Curlist}; + push @{ $expat->{Curlist} }, $tag => $ol; + $expat->{Curlist} = $ol; +} + +sub readXml +{ + my $filename = shift || return; + if(!-f $filename) { + die "ERROR Cannot find filename: $filename\n"; + } + + my $ret = eval 'require XML::Parser'; + if(!$ret) { + die "You must have XML::Parser installed to run $0\n\n"; + } + my $xp = new XML::Parser(Style => 'Tree'); + $xp->setHandlers(Char => \&intltool_tree_char); + $xp->setHandlers(Start => \&intltool_tree_start); + $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart); + $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend); + my $tree = $xp->parsefile($filename); + +# Hello thereHowdydo +# would be: +# [foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, [{}, +# 0, "Howdy", ref, [{}]], 0, "do" ] ] + + return $tree; +} + +sub print_header +{ + my $infile = shift; + my $fh = shift; + my $source; + + if(!-f $infile) { + die "ERROR Cannot find filename: $infile\n"; + } + + print $fh qq{\n}; + { + local $/; + open DOCINPUT, "<${FILE}" or die; + $source = ; + close DOCINPUT; + } + if ($source =~ /()/s) + { + print $fh "$1\n"; + } + elsif ($source =~ /(]*>)/s) + { + print $fh "$1\n"; + } +} + +sub parseTree +{ + my $fh = shift; + my $ref = shift; + my $language = shift || ""; + + my $name = shift @{ $ref }; + my $cont = shift @{ $ref }; + traverse($fh, $name, $cont, $language); +} + +sub xml_merge_output +{ + my $source; + + if ($MULTIPLE_OUTPUT) { + for my $lang (sort keys %po_files_by_lang) { + if ( ! -e $lang ) { + mkdir $lang or die "Cannot create subdirectory $lang: $!\n"; + } + open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n"; + my $tree = readXml($FILE); + print_header($FILE, \*OUTPUT); + parseTree(\*OUTPUT, $tree, $lang); + close OUTPUT; + print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG; + } + } + open OUTPUT, ">$OUTFILE" or die "Cannot open $OUTFILE: $!\n"; + my $tree = readXml($FILE); + print_header($FILE, \*OUTPUT); + parseTree(\*OUTPUT, $tree); + close OUTPUT; + print "CREATED $OUTFILE\n" unless $QUIET_ARG; +} + +sub keys_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/[$lang]$1=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub desktop_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/${1}[$lang]=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub schemas_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die; + + # FIXME: support attribute translations + + # Empty nodes never need translation, so unmark all of them. + # For example, <_foo/> is just replaced by . + $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; + + while ($source =~ s/ + (.*?) + (\s+)((\s*) + (\s*(?:\s*)?(.*?)\s*<\/default>)?(\s*) + (\s*(?:\s*)?(.*?)\s*<\/short>)?(\s*) + (\s*(?:\s*)?(.*?)\s*<\/long>)?(\s*) + <\/locale>) + //sx) + { + print OUTPUT $1; + + my $locale_start_spaces = $2 ? $2 : ''; + my $default_spaces = $4 ? $4 : ''; + my $short_spaces = $7 ? $7 : ''; + my $long_spaces = $10 ? $10 : ''; + my $locale_end_spaces = $13 ? $13 : ''; + my $c_default_block = $3 ? $3 : ''; + my $default_string = $6 ? $6 : ''; + my $short_string = $9 ? $9 : ''; + my $long_string = $12 ? $12 : ''; + + print OUTPUT "$locale_start_spaces$c_default_block"; + + $default_string =~ s/\s+/ /g; + $default_string = entity_decode($default_string); + $short_string =~ s/\s+/ /g; + $short_string = entity_decode($short_string); + $long_string =~ s/\s+/ /g; + $long_string = entity_decode($long_string); + + for my $lang (sort keys %po_files_by_lang) + { + my $default_translation = $translations{$lang, $default_string}; + my $short_translation = $translations{$lang, $short_string}; + my $long_translation = $translations{$lang, $long_string}; + + next if (!$default_translation && !$short_translation && + !$long_translation); + + print OUTPUT "\n$locale_start_spaces"; + + print OUTPUT "$default_spaces"; + + if ($default_translation) + { + $default_translation = entity_encode($default_translation); + print OUTPUT "$default_translation"; + } + + print OUTPUT "$short_spaces"; + + if ($short_translation) + { + $short_translation = entity_encode($short_translation); + print OUTPUT "$short_translation"; + } + + print OUTPUT "$long_spaces"; + + if ($long_translation) + { + $long_translation = entity_encode($long_translation); + print OUTPUT "$long_translation"; + } + + print OUTPUT "$locale_end_spaces"; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + +sub rfc822deb_merge_translations +{ + my %encodings = (); + for my $lang (keys %po_files_by_lang) { + $encodings{$lang} = ($UTF8_ARG ? 'UTF-8' : get_po_encoding($po_files_by_lang{$lang})); + } + + my $source; + + $Text::Wrap::huge = 'overflow'; + $Text::Wrap::break = qr/\n|\s(?=\S)/; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">${OUTFILE}" or die; + + while ($source =~ /(^|\n+)(_*)([^:\s]+)(:[ \t]*)(.*?)(?=\n[\S\n]|$)/sg) + { + my $sep = $1; + my $non_translated_line = $3.$4; + my $string = $5; + my $underscore = length($2); + next if $underscore eq 0 && $non_translated_line =~ /^#/; + # Remove [] dummy strings + my $stripped = $string; + $stripped =~ s/\[\s[^\[\]]*\],/,/g if $underscore eq 2; + $stripped =~ s/\[\s[^\[\]]*\]$//; + $non_translated_line .= $stripped; + + print OUTPUT $sep.$non_translated_line; + + if ($underscore) + { + my @str_list = rfc822deb_split($underscore, $string); + + for my $lang (sort keys %po_files_by_lang) + { + my $is_translated = 1; + my $str_translated = ''; + my $first = 1; + + for my $str (@str_list) + { + my $translation = $translations{$lang, $str}; + + if (!$translation) + { + $is_translated = 0; + last; + } + + # $translation may also contain [] dummy + # strings, mostly to indicate an empty string + $translation =~ s/\[\s[^\[\]]*\]$//; + + if ($first) + { + if ($underscore eq 2) + { + $str_translated .= $translation; + } + else + { + $str_translated .= + Text::Tabs::expand($translation) . + "\n"; + } + } + else + { + if ($underscore eq 2) + { + $str_translated .= ', ' . $translation; + } + else + { + $str_translated .= Text::Tabs::expand( + Text::Wrap::wrap(' ', ' ', $translation)) . + "\n .\n"; + } + } + $first = 0; + + # To fix some problems with Text::Wrap::wrap + $str_translated =~ s/(\n )+\n/\n .\n/g; + } + next unless $is_translated; + + $str_translated =~ s/\n \.\n$//; + $str_translated =~ s/\s+$//; + + $_ = $non_translated_line; + s/^(\w+):\s*.*/$sep${1}-$lang.$encodings{$lang}: $str_translated/s; + print OUTPUT; + } + } + } + print OUTPUT "\n"; + + close OUTPUT; + close INPUT; +} + +sub rfc822deb_split +{ + # Debian defines a special way to deal with rfc822-style files: + # when a value contain newlines, it consists of + # 1. a short form (first line) + # 2. a long description, all lines begin with a space, + # and paragraphs are separated by a single dot on a line + # This routine returns an array of all paragraphs, and reformat + # them. + # When first argument is 2, the string is a comma separated list of + # values. + my $type = shift; + my $text = shift; + $text =~ s/^[ \t]//mg; + return (split(/, */, $text, 0)) if $type ne 1; + return ($text) if $text !~ /\n/; + + $text =~ s/([^\n]*)\n//; + my @list = ($1); + my $str = ''; + + for my $line (split (/\n/, $text)) + { + chomp $line; + if ($line =~ /^\.\s*$/) + { + # New paragraph + $str =~ s/\s*$//; + push(@list, $str); + $str = ''; + } + elsif ($line =~ /^\s/) + { + # Line which must not be reformatted + $str .= "\n" if length ($str) && $str !~ /\n$/; + $line =~ s/\s+$//; + $str .= $line."\n"; + } + else + { + # Continuation line, remove newline + $str .= " " if length ($str) && $str !~ /\n$/; + $str .= $line; + } + } + + $str =~ s/\s*$//; + push(@list, $str) if length ($str); + + return @list; +} + diff --git a/intltool-update.in b/intltool-update.in new file mode 100644 index 0000000..ebfa181 --- /dev/null +++ b/intltool-update.in @@ -0,0 +1,1063 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Updater +# +# Copyright (C) 2000-2003 Free Software Foundation. +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Maciej Stachowiak +# Darin Adler + +## Release information +my $PROGRAM = "intltool-update"; +my $VERSION = "0.33"; +my $PACKAGE = "intltool"; + +## Loaded modules +use strict; +use Getopt::Long; +use Cwd; +use File::Copy; +use File::Find; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $DIST_ARG = 0; +my $POT_ARG = 0; +my $HEADERS_ARG = 0; +my $MAINTAIN_ARG = 0; +my $REPORT_ARG = 0; +my $VERBOSE = 0; +my $GETTEXT_PACKAGE = ""; +my $OUTPUT_FILE = ""; + +my @languages; +my %varhash = (); +my %po_files_by_lang = (); + +# Regular expressions to categorize file types. +# FIXME: Please check if the following is correct + +my $xml_support = +"xml(?:\\.in)*|". # http://www.w3.org/XML/ (Note: .in is not required) +"ui|". # Bonobo specific - User Interface desc. files +"lang|". # ? +"glade2?(?:\\.in)*|". # Glade specific - User Interface desc. files (Note: .in is not required) +"scm(?:\\.in)*|". # ? (Note: .in is not required) +"oaf(?:\\.in)+|". # DEPRECATED: Replaces by Bonobo .server files +"etspec|". # ? +"server(?:\\.in)+|". # Bonobo specific +"sheet(?:\\.in)+|". # ? +"schemas(?:\\.in)+|". # GConf specific +"pong(?:\\.in)+|". # DEPRECATED: PONG is not used [by GNOME] any longer. +"kbd(?:\\.in)+"; # GOK specific. + +my $ini_support = +"icon(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec +"desktop(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec +"caves(?:\\.in)+|". # GNOME Games specific +"directory(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec +"soundlist(?:\\.in)+|". # GNOME specific +"keys(?:\\.in)+|". # GNOME Mime database specific +"theme(?:\\.in)+"; # http://www.freedesktop.org/Standards/icon-theme-spec + +my $buildin_gettext_support = +"c|y|cs|cc|cpp|c\\+\\+|h|hh|gob|py"; + +## Always flush buffer when printing +$| = 1; + +## Sometimes the source tree will be rooted somewhere else. +my $SRCDIR = "."; +my $POTFILES_in; + +$SRCDIR = $ENV{"srcdir"} if $ENV{"srcdir"}; +$POTFILES_in = "<$SRCDIR/POTFILES.in"; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "dist|d" => \$DIST_ARG, + "pot|p" => \$POT_ARG, + "headers|s" => \$HEADERS_ARG, + "maintain|m" => \$MAINTAIN_ARG, + "report|r" => \$REPORT_ARG, + "verbose|x" => \$VERBOSE, + "gettext-package|g=s" => \$GETTEXT_PACKAGE, + "output-file|o=s" => \$OUTPUT_FILE, + ) or &Console_WriteError_InvalidOption; + +&Console_Write_IntltoolHelp if $HELP_ARG; +&Console_Write_IntltoolVersion if $VERSION_ARG; + +my $arg_count = ($DIST_ARG > 0) + + ($POT_ARG > 0) + + ($HEADERS_ARG > 0) + + ($MAINTAIN_ARG > 0) + + ($REPORT_ARG > 0); + +&Console_Write_IntltoolHelp if $arg_count > 1; + +# --version and --help don't require a module name +my $MODULE = $GETTEXT_PACKAGE || &FindPackageName; + +if ($POT_ARG) +{ + &GenerateHeaders; + &GeneratePOTemplate; +} +elsif ($HEADERS_ARG) +{ + &GenerateHeaders; +} +elsif ($MAINTAIN_ARG) +{ + &FindLeftoutFiles; +} +elsif ($REPORT_ARG) +{ + &GenerateHeaders; + &GeneratePOTemplate; + &Console_Write_CoverageReport; +} +elsif ((defined $ARGV[0]) && $ARGV[0] =~ /^[a-z]/) +{ + my $lang = $ARGV[0]; + + ## Report error if the language file supplied + ## to the command line is non-existent + &Console_WriteError_NotExisting("$SRCDIR/$lang.po") + if ! -s "$SRCDIR/$lang.po"; + + if (!$DIST_ARG) + { + print "Working, please wait..." if $VERBOSE; + &GenerateHeaders; + &GeneratePOTemplate; + } + &POFile_Update ($lang, $OUTPUT_FILE); + &Console_Write_TranslationStatus ($lang, $OUTPUT_FILE); +} +else +{ + &Console_Write_IntltoolHelp; +} + +exit; + +######### + +sub Console_Write_IntltoolVersion +{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) $VERSION +Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler. + +Copyright (C) 2000-2003 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +sub Console_Write_IntltoolHelp +{ + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... LANGCODE +Updates PO template files and merge them with the translations. + +Mode of operation (only one is allowed): + -p, --pot generate the PO template only + -s, --headers generate the header files in POTFILES.in + -m, --maintain search for left out files from POTFILES.in + -r, --report display a status report for the module + -d, --dist merge LANGCODE.po with existing PO template + +Extra options: + -g, --gettext-package=NAME override PO template name, useful with --pot + -o, --output-file=FILE write merged translation to FILE + -x, --verbose display lots of feedback + --help display this help and exit + --version output version information and exit + +Examples of use: +${PROGRAM} --pot just create a new PO template +${PROGRAM} xy create new PO template and merge xy.po with it + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + +sub echo_n +{ + my $str = shift; + my $ret = `echo "$str"`; + + $ret =~ s/\n$//; # do we need the "s" flag? + + return $ret; +} + +sub POFile_DetermineType ($) +{ + my $type = $_; + my $gettext_type; + + my $xml_regex = "(?:" . $xml_support . ")"; + my $ini_regex = "(?:" . $ini_support . ")"; + my $buildin_regex = "(?:" . $buildin_gettext_support . ")"; + + if ($type =~ /\[type: gettext\/([^\]].*)]/) + { + $gettext_type=$1; + } + elsif ($type =~ /schemas(\.in)+$/) + { + $gettext_type="schemas"; + } + elsif ($type =~ /glade2?(\.in)*$/) + { + $gettext_type="glade"; + } + elsif ($type =~ /scm(\.in)*$/) + { + $gettext_type="scheme"; + } + elsif ($type =~ /keys(\.in)+$/) + { + $gettext_type="keys"; + } + + # bucket types + + elsif ($type =~ /$xml_regex$/) + { + $gettext_type="xml"; + } + elsif ($type =~ /$ini_regex$/) + { + $gettext_type="ini"; + } + elsif ($type =~ /$buildin_regex$/) + { + $gettext_type="buildin"; + } + else + { + $gettext_type="unknown"; + } + + return "gettext\/$gettext_type"; +} + +sub TextFile_DetermineEncoding ($) +{ + my $gettext_code="ASCII"; # All files are ASCII by default + my $filetype=`file $_ | cut -d ' ' -f 2`; + + if ($? eq "0") + { + if ($filetype =~ /^(ISO|UTF)/) + { + chomp ($gettext_code = $filetype); + } + elsif ($filetype =~ /^XML/) + { + $gettext_code="UTF-8"; # We asume that .glade and other .xml files are UTF-8 + } + } + + return $gettext_code; +} + +sub isNotValidMissing +{ + my ($file) = @_; + + return if $file =~ /^\{arch\}\/.*$/; + return if $file =~ /^$varhash{"PACKAGE"}-$varhash{"VERSION"}\/.*$/; +} + +sub FindLeftoutFiles +{ + my (@buf_i18n_plain, + @buf_i18n_xml, + @buf_i18n_xml_unmarked, + @buf_i18n_ini, + @buf_potfiles, + @buf_potfiles_ignore, + @buf_allfiles, + @buf_allfiles_sorted, + @buf_potfiles_sorted + ); + + ## Search and find all translatable files + find sub { + push @buf_i18n_plain, "$File::Find::name" if /\.($buildin_gettext_support)$/; + push @buf_i18n_xml, "$File::Find::name" if /\.($xml_support)$/; + push @buf_i18n_ini, "$File::Find::name" if /\.($ini_support)$/; + push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/; + }, ".."; + + + open POTFILES, $POTFILES_in or die "$PROGRAM: there's no POTFILES.in!\n"; + @buf_potfiles = grep !/^(#|\s*$)/, ; + close POTFILES; + + foreach (@buf_potfiles) { + s/^\[.*]\s*//; + } + + print "Searching for missing translatable files...\n" if $VERBOSE; + + ## Check if we should ignore some found files, when + ## comparing with POTFILES.in + foreach my $ignore ("POTFILES.skip", "POTFILES.ignore") + { + (-s $ignore) or next; + + if ("$ignore" eq "POTFILES.ignore") + { + print "The usage of POTFILES.ignore is deprecated. Please consider moving the\n". + "content of this file to POTFILES.skip.\n"; + } + + print "Found $ignore: Ignoring files...\n" if $VERBOSE; + open FILE, "<$ignore" or die "ERROR: Failed to open $ignore!\n"; + + while () + { + push @buf_potfiles_ignore, $_ unless /^(#|\s*$)/; + } + close FILE; + + @buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles); + } + + foreach my $file (@buf_i18n_plain) + { + my $in_comment = 0; + my $in_macro = 0; + + open FILE, "<$file"; + while () + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-) + { + warn "mismatched quotes at line $. in $file\n"; + s-$match.*--; + } + } + } + + if (/\.GetString ?\(QUOTEDTEXT/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + ## Remove the first 3 chars and add newline + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + + if (/_\(QUOTEDTEXT/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + ## Remove the first 3 chars and add newline + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_xml) + { + open FILE, "<$file"; + + while () + { + # FIXME: share the pattern matching code with intltool-extract + if (/\s_(.*)=\"/ || /<_[^>]+>/ || /translatable=\"yes\"/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_ini) + { + open FILE, "<$file"; + while () + { + if (/_(.*)=/) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_xml_unmarked) + { + if (defined isNotValidMissing (unpack("x3 A*", $file))) { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + } + + + @buf_allfiles_sorted = sort (@buf_allfiles); + @buf_potfiles_sorted = sort (@buf_potfiles); + + my %in2; + foreach (@buf_potfiles_sorted) + { + $in2{$_} = 1; + } + + my @result; + + foreach (@buf_allfiles_sorted) + { + if (!exists($in2{$_})) + { + push @result, $_ + } + } + + my @buf_potfiles_notexist; + + foreach (@buf_potfiles_sorted) + { + chomp (my $dummy = $_); + if ("$dummy" ne "" and ! -f "../$dummy") + { + push @buf_potfiles_notexist, $_; + } + } + + ## Save file with information about the files missing + ## if any, and give information about this procedure. + if (@result + @buf_potfiles_notexist > 0) + { + if (@result) + { + print "\n" if $VERBOSE; + unlink "missing"; + open OUT, ">missing"; + print OUT @result; + close OUT; + warn "\e[1mThe following files contain translations and are currently not in use. Please\e[0m\n". + "\e[1mconsider adding these to the POTFILES.in file, located in the po/ directory.\e[0m\n\n"; + print STDERR @result, "\n"; + warn "If some of these files are left out on purpose then please add them to\n". + "POTFILES.skip instead of POTFILES.in. A file \e[1m'missing'\e[0m containing this list\n". + "of left out files has been written in the current directory.\n"; + } + if (@buf_potfiles_notexist) + { + unlink "notexist"; + open OUT, ">notexist"; + print OUT @buf_potfiles_notexist; + close OUT; + warn "\n" if ($VERBOSE or @result); + warn "\e[1mThe following files do not exist anymore:\e[0m\n\n"; + warn @buf_potfiles_notexist, "\n"; + warn "Please remove them from POTFILES.in or POTFILES.skip. A file \e[1m'notexist'\e[0m\n". + "containing this list of absent files has been written in the current directory.\n"; + } + } + + ## If there is nothing to complain about, notify the user + else { + print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE; + } +} + +sub Console_WriteError_InvalidOption +{ + ## Handle invalid arguments + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit 1; +} + +sub GenerateHeaders +{ + my $EXTRACT = "@INTLTOOL_EXTRACT@"; + chomp $EXTRACT; + + $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"}; + + ## Generate the .h header files, so we can allow glade and + ## xml translation support + if (! -x "$EXTRACT") + { + print STDERR "\n *** The intltool-extract script wasn't found!" + ."\n *** Without it, intltool-update can not generate files.\n"; + exit; + } + else + { + open (FILE, $POTFILES_in) or die "$PROGRAM: POTFILES.in not found.\n"; + + while () + { + chomp; + next if /^\[\s*encoding/; + + ## Find xml files in POTFILES.in and generate the + ## files with help from the extract script + + my $gettext_type= &POFile_DetermineType ($1); + + if (/\.($xml_support|$ini_support)$/ || /^\[/) + { + s/^\[[^\[].*]\s*//; + + my $filename = "../$_"; + + if ($VERBOSE) + { + system ($EXTRACT, "--update", "--srcdir=$SRCDIR", + "--type=$gettext_type", $filename); + } + else + { + system ($EXTRACT, "--update", "--type=$gettext_type", + "--srcdir=$SRCDIR", "--quiet", $filename); + } + } + } + close FILE; + } +} + +# +# Generate .pot file from POTFILES.in +# +sub GeneratePOTemplate +{ + my $XGETTEXT = $ENV{"XGETTEXT"} || "/scratchbox/devkits/slp-tools/bin/xgettext"; + my $XGETTEXT_ARGS = $ENV{"XGETTEXT_ARGS"} || ''; + chomp $XGETTEXT; + + if (! -x $XGETTEXT) + { + print STDERR " *** xgettext is not found on this system!\n". + " *** Without it, intltool-update can not extract strings.\n"; + exit; + } + + print "Building $MODULE.pot...\n" if $VERBOSE; + + open INFILE, $POTFILES_in; + unlink "POTFILES.in.temp"; + open OUTFILE, ">POTFILES.in.temp" or die("Cannot open POTFILES.in.temp for writing"); + + my $gettext_support_nonascii = 0; + + # checks for GNU gettext >= 0.12 + my $dummy = `$XGETTEXT --version --from-code=UTF-8 >/dev/null 2>/dev/null`; + if ($? == 0) + { + $gettext_support_nonascii = 1; + } + else + { + # urge everybody to upgrade gettext + print STDERR "WARNING: This version of gettext does not support extracting non-ASCII\n". + " strings. That means you should install a version of gettext\n". + " that supports non-ASCII strings (such as GNU gettext >= 0.12),\n". + " or have to let non-ASCII strings untranslated. (If there is any)\n"; + } + + my $encoding = "ASCII"; + my $forced_gettext_code; + my @temp_headers; + my $encoding_problem_is_reported = 0; + + while () + { + next if (/^#/ or /^\s*$/); + + chomp; + + my $gettext_code; + + if (/^\[\s*encoding:\s*(.*)\s*\]/) + { + $forced_gettext_code=$1; + } + elsif (/\.($xml_support|$ini_support)$/ || /^\[/) + { + s/^\[.*]\s*//; + print OUTFILE "../$_.h\n"; + push @temp_headers, "../$_.h"; + $gettext_code = &TextFile_DetermineEncoding ("../$_.h") if ($gettext_support_nonascii and not defined $forced_gettext_code); + } + else + { + if ($SRCDIR eq ".") { + print OUTFILE "../$_\n"; + } else { + print OUTFILE "$SRCDIR/../$_\n"; + } + $gettext_code = &TextFile_DetermineEncoding ("../$_") if ($gettext_support_nonascii and not defined $forced_gettext_code); + } + + next if (! $gettext_support_nonascii); + + if (defined $forced_gettext_code) + { + $encoding=$forced_gettext_code; + } + elsif (defined $gettext_code and "$encoding" ne "$gettext_code") + { + if ($encoding eq "ASCII") + { + $encoding=$gettext_code; + } + elsif ($gettext_code ne "ASCII") + { + # Only report once because the message is quite long + if (! $encoding_problem_is_reported) + { + print STDERR "WARNING: You should use the same file encoding for all your project files,\n". + " but $PROGRAM thinks that most of the source files are in\n". + " $encoding encoding, while \"$_\" is (likely) in\n". + " $gettext_code encoding. If you are sure that all translatable strings\n". + " are in same encoding (say UTF-8), please \e[1m*prepend*\e[0m the following\n". + " line to POTFILES.in:\n\n". + " [encoding: UTF-8]\n\n". + " and make sure that configure.in/ac checks for $PACKAGE >= 0.27 .\n". + "(such warning message will only be reported once.)\n"; + $encoding_problem_is_reported = 1; + } + } + } + } + + close OUTFILE; + close INFILE; + + unlink "$MODULE.pot"; + my @xgettext_argument=("$XGETTEXT", + "--add-comments", + "--directory\=\.", + "--output\=$MODULE\.pot", + "--files-from\=\.\/POTFILES\.in\.temp"); + my $XGETTEXT_KEYWORDS = &FindPOTKeywords; + push @xgettext_argument, $XGETTEXT_KEYWORDS; + push @xgettext_argument, "--from-code\=$encoding" if ($gettext_support_nonascii); + push @xgettext_argument, $XGETTEXT_ARGS if $XGETTEXT_ARGS; + my $xgettext_command = join ' ', @xgettext_argument; + + # intercept xgettext error message + print "Running $xgettext_command\n" if $VERBOSE; + my $xgettext_error_msg = `$xgettext_command 2>\&1`; + my $command_failed = $?; + + unlink "POTFILES.in.temp"; + + print "Removing generated header (.h) files..." if $VERBOSE; + unlink foreach (@temp_headers); + print "done.\n" if $VERBOSE; + + if (! $command_failed) + { + if (! -e "$MODULE.pot") + { + print "None of the files in POTFILES.in contain strings marked for translation.\n" if $VERBOSE; + } + else + { + print "Wrote $MODULE.pot\n" if $VERBOSE; + } + } + else + { + if ($xgettext_error_msg =~ /--from-code/) + { + # replace non-ASCII error message with a more useful one. + print STDERR "ERROR: xgettext failed to generate PO template file because there is non-ASCII\n". + " string marked for translation. Please make sure that all strings marked\n". + " for translation are in uniform encoding (say UTF-8), then \e[1m*prepend*\e[0m the\n". + " following line to POTFILES.in and rerun $PROGRAM:\n\n". + " [encoding: UTF-8]\n\n"; + } + else + { + print STDERR "$xgettext_error_msg"; + if (-e "$MODULE.pot") + { + # is this possible? + print STDERR "ERROR: xgettext failed but still managed to generate PO template file.\n". + " Please consult error message above if there is any.\n"; + } + else + { + print STDERR "ERROR: xgettext failed to generate PO template file. Please consult\n". + " error message above if there is any.\n"; + } + } + exit (1); + } +} + +sub POFile_Update +{ + -f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n"; + + my $MSGMERGE = $ENV{"MSGMERGE"} || "/usr/bin/msgmerge"; + my ($lang, $outfile) = @_; + + print "Merging $SRCDIR/$lang.po with $MODULE.pot..." if $VERBOSE; + + my $infile = "$SRCDIR/$lang.po"; + $outfile = "$SRCDIR/$lang.po" if ($outfile eq ""); + + # I think msgmerge won't overwrite old file if merge is not successful + system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot"); +} + +sub Console_WriteError_NotExisting +{ + my ($file) = @_; + + ## Report error if supplied language file is non-existing + print STDERR "$PROGRAM: $file does not exist!\n"; + print STDERR "Try '$PROGRAM --help' for more information.\n"; + exit; +} + +sub GatherPOFiles +{ + my @po_files = glob ("./*.po"); + + @languages = map (&POFile_GetLanguage, @po_files); + + foreach my $lang (@languages) + { + $po_files_by_lang{$lang} = shift (@po_files); + } +} + +sub POFile_GetLanguage ($) +{ + s/^(.*\/)?(.+)\.po$/$2/; + return $_; +} + +sub Console_Write_TranslationStatus +{ + my ($lang, $output_file) = @_; + my $MSGFMT = $ENV{"MSGFMT"} || "/usr/bin/msgfmt"; + + $output_file = "$SRCDIR/$lang.po" if ($output_file eq ""); + + system ("$MSGFMT", "-o", "/dev/null", "--statistics", $output_file); +} + +sub Console_Write_CoverageReport +{ + my $MSGFMT = $ENV{"MSGFMT"} || "/usr/bin/msgfmt"; + + &GatherPOFiles; + + foreach my $lang (@languages) + { + print "$lang: "; + &POFile_Update ($lang, ""); + } + + print "\n\n * Current translation support in $MODULE \n\n"; + + foreach my $lang (@languages) + { + print "$lang: "; + system ("$MSGFMT", "-o", "/dev/null", "--statistics", "$SRCDIR/$lang.po"); + } +} + +sub SubstituteVariable +{ + my ($str) = @_; + + # always need to rewind file whenever it has been accessed + seek (CONF, 0, 0); + + # cache each variable. varhash is global to we can add + # variables elsewhere. + while () + { + if (/^(\w+)=(.*)$/) + { + ($varhash{$1} = $2) =~ s/^["'](.*)["']$/$1/; + } + } + + if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/) + { + my $rest = $3; + my $untouched = $1; + my $sub = $varhash{$2}; + + return SubstituteVariable ("$untouched$sub$rest"); + } + + # We're using Perl backticks ` and "echo -n" here in order to + # expand any shell escapes (such as backticks themselves) in every variable + return echo_n ($str); +} + +sub CONF_Handle_Open +{ + my $base_dirname = getcwd(); + $base_dirname =~ s@.*/@@; + + my ($conf_in, $src_dir); + + if ($base_dirname =~ /^po(-.+)?$/) + { + if (-f "Makevars") + { + my $makefile_source; + + local (*IN); + open (IN, ") + { + if (/^top_builddir[ \t]*=/) + { + $src_dir = $_; + $src_dir =~ s/^top_builddir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; + + chomp $src_dir; + if (-f "$src_dir" . "/configure.ac") { + $conf_in = "$src_dir" . "/configure.ac" . "\n"; + } else { + $conf_in = "$src_dir" . "/configure.in" . "\n"; + } + last; + } + } + close IN; + + $conf_in || die "Cannot find top_builddir in Makevars."; + } + elsif (-f "../configure.ac") + { + $conf_in = "../configure.ac"; + } + elsif (-f "../configure.in") + { + $conf_in = "../configure.in"; + } + else + { + my $makefile_source; + + local (*IN); + open (IN, ") + { + if (/^top_srcdir[ \t]*=/) + { + $src_dir = $_; + $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; + + chomp $src_dir; + $conf_in = "$src_dir" . "/configure.in" . "\n"; + + last; + } + } + close IN; + + $conf_in || die "Cannot find top_srcdir in Makefile."; + } + + open (CONF, "<$conf_in"); + } + else + { + print STDERR "$PROGRAM: Unable to proceed.\n" . + "Make sure to run this script inside the po directory.\n"; + exit; + } +} + +sub FindPackageName +{ + my $version; + my $domain = &FindMakevarsDomain; + my $name = $domain || "untitled"; + + &CONF_Handle_Open; + + my $conf_source; { + local (*IN); + open (IN, "<&CONF") || return $name; + seek (IN, 0, 0); + local $/; # slurp mode + $conf_source = ; + close IN; + } + + # priority for getting package name: + # 1. GETTEXT_PACKAGE + # 2. first argument of AC_INIT (with >= 2 arguments) + # 3. first argument of AM_INIT_AUTOMAKE (with >= 2 argument) + + # /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m + # the \s makes this not work, why? + if ($conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+),([^,\)]+)/m) + { + ($name, $version) = ($1, $2); + $name =~ s/[\[\]\s]//g; + $version =~ s/[\[\]\s]//g; + $varhash{"AC_PACKAGE_NAME"} = $name; + $varhash{"PACKAGE"} = $name; + $varhash{"AC_PACKAGE_VERSION"} = $version; + $varhash{"VERSION"} = $version; + } + + if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)/m) + { + ($name, $version) = ($1, $2); + $name =~ s/[\[\]\s]//g; + $version =~ s/[\[\]\s]//g; + $varhash{"AC_PACKAGE_NAME"} = $name; + $varhash{"PACKAGE"} = $name; + $varhash{"AC_PACKAGE_VERSION"} = $version; + $varhash{"VERSION"} = $version; + } + + # \s makes this not work, why? + $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m; + + # prepend '$' to auto* internal variables, usually they are + # used in configure.in/ac without the '$' + $name =~ s/AC_/\$AC_/g; + $name =~ s/\$\$/\$/g; + + $name = $domain if $domain; + + $name = SubstituteVariable ($name); + $name =~ s/^["'](.*)["']$/$1/; + + return $name if $name; +} + + +sub FindPOTKeywords +{ + + my $keywords = "--keyword\=\_ --keyword\=N\_ --keyword\=U\_ --keyword\=Q\_"; + my $varname = "XGETTEXT_OPTIONS"; + my $make_source; { + local (*IN); + open (IN, "; + close IN; + } + + $keywords = $1 if $make_source =~ /^$varname[ ]*=\[?([^\n\]]+)/m; + + return $keywords; +} + +sub FindMakevarsDomain +{ + + my $domain = ""; + my $makevars_source; { + local (*IN); + open (IN, "; + close IN; + } + + $domain = $1 if $makevars_source =~ /^DOMAIN[ ]*=\[?([^\n\]\$]+)/m; + $domain =~ s/^\s+//; + $domain =~ s/\s+$//; + + return $domain; +} diff --git a/isf.manifest b/isf.manifest new file mode 100755 index 0000000..db5b143 --- /dev/null +++ b/isf.manifest @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/isf.pc.in b/isf.pc.in new file mode 100644 index 0000000..9778aab --- /dev/null +++ b/isf.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +localedir=/usr/share/locale +datadir=@datadir@ +sysconfdir=@sysconfdir@ + + +Name: ISF +Description: Input Service Framework +Version: @ISF_VERSION@ +Requires: +Libs: -L${libdir} -lscim@SCIM_EPOCH@ +Cflags: -I${includedir}/scim@SCIM_EPOCH@ diff --git a/ism/ChangeLog.Samsung b/ism/ChangeLog.Samsung new file mode 100755 index 0000000..7be3c8e --- /dev/null +++ b/ism/ChangeLog.Samsung @@ -0,0 +1,93 @@ +2009-10-26 Following files have been removed by Samsung +- extras/ism_context/ism_context.cpp +- extras/ism_context/ism_context.h +- extras/ism_context/Makefile.am +- src/ism_newise.cpp +- src/ism_newise.h +- src/ism_newise_module.cpp +- src/ism_newise_module.h +- src/scim_newise_launcher.cpp + +2009-10-07 Following files have been changed by Samsung +- configs/config +- configs/global +- extras/gtk2_immodule/gtkimcontextscim.cpp +- extras/gtk2_immodule/gtkimcontextscim.h +- extras/gtk2_immodule/imscim.cpp +- extras/gtk2_immodule/Makefile.am +- extras/panel/Makefile.am +- extras/panel/scim_panel_gtk.cpp +- extras/Makefile.am +- module/config/Makefile.am +- module/config/scim_socket_config.cpp +- module/filter/Makefile.am +- module/frontend/Makefile.am +- module/frontend/scim_socket_frontend.cpp +- module/frontend/scim_socket_frontend.h +- module/IMEngine/Makefile.am +- module/Makefile.am +- src/ltdl.cpp +- src/Makefile.am +- src/scim.cpp +- src/scim_backend.cpp +- src/scim_backend.h +- src/scim_compose_key.cpp +- src/scim_config_path.h +- src/scim_debug.cpp +- src/scim_debug.h +- src/scim_event.cpp +- src/scim_frontend.cpp +- src/scim_frontend.h +- src/scim_global_config.cpp +- src/scim_global_config.h +- src/scim_helper.cpp +- src/scim_helper.h +- src/scim_helper_launcher.cpp +- src/scim_helper_manager.cpp +- src/scim_helper_manager.h +- src/scim_helper_module.cpp +- src/scim_helper_module.h +- src/scim_hotkey.cpp +- src/scim_hotkey.h +- src/scim_imengine.cpp +- src/scim_imengine.h +- src/scim_keyboard_layout_data.h +- src/scim_launcher.cpp +- src/scim_lookup_table.h +- src/scim_panel_agent.cpp +- src/scim_panel_agent.h +- src/scim_panel_client.cpp +- src/scim_panel_client.h +- src/scim_signals.h +- src/scim_socket.cpp +- src/scim_socket.h +- src/scim_trans_commands.h +- src/scim_transaction.cpp +- src/scim_transaction.h +- src/scim_utility.cpp +- src/scim_utility.h +- utils/Makefile.am +- utils/scimkeyselection.cpp +- utils/scimstringview.c +- utils/scimstringview.h + +2009-10-07 Following files have been added by Samsung +- extras/ism_context/ism_context.cpp +- extras/ism_context/ism_context.h +- extras/ism_context/Makefile.am +- extras/panel/ise_setup_win.cpp +- extras/panel/ise_setup_win.h +- extras/panel/isf_lang_win.cpp +- extras/panel/isf_lang_win.h +- extras/panel/isf_setup_utility.cpp +- extras/panel/isf_setup_utility.h +- extras/panel/isf_setup_win.cpp +- extras/panel/isf_setup_win.h +- extras/panel/scim-setup.desktop.in +- extras/panel/scim-setup.in +- src/ism_newise.cpp +- src/ism_newise.h +- src/ism_newise_module.cpp +- src/ism_newise_module.h +- src/scim_newise_launcher.cpp + diff --git a/ism/configs/Makefile.am b/ism/configs/Makefile.am new file mode 100644 index 0000000..6b9eb49 --- /dev/null +++ b/ism/configs/Makefile.am @@ -0,0 +1,11 @@ +MAINTAINERCLEANFILES = Makefile.in + +CLEANFILES = *.bak + +if SCIM_BUILD_CONFIG_SIMPLE +configdir = $(sysconfdir)/scim +config_DATA = config global +config_source_data = $(foreach file, $(config_DATA), $(srcdir)/$(file)) +endif + +EXTRA_DIST = $(config_DATA) diff --git a/ism/configs/config b/ism/configs/config new file mode 100755 index 0000000..67a99ae --- /dev/null +++ b/ism/configs/config @@ -0,0 +1,28 @@ +# This file is encoded in UTF-8 encoding. +/DefaultIMEngineFactory/~other = d75857a5-4148-4745-89e2-1da7ddaf7999 +/FrontEnd/OnTheSpot = true +/FrontEnd/ChangeFactoryGlobally = false +/FrontEnd/SharedInputMethod = true +/FrontEnd/Socket/ConfigReadOnly = false +/FrontEnd/Socket/MaxClients = 512 +/Hotkeys/FrontEnd/NextFactory = Control+Alt+Down,Shift+Control+KeyRelease+Shift_L,Shift+Control+KeyRelease+Shift_R +/Hotkeys/FrontEnd/PreviousFactory = Control+Alt+Up,Shift+Control+KeyRelease+Control_L,Shift+Control+KeyRelease+Control_R +/Hotkeys/FrontEnd/ShowFactoryMenu = Control+Alt+Right +/Hotkeys/FrontEnd/Trigger = Control+space,Hangul +/Hotkeys/FrontEnd/ValidKeyMask = Shift+Control+Alt+CapsLock+Meta+QuirkKanaRo +/Panel/Gtk/Color/ActiveBackground = light sky blue +/Panel/Gtk/Color/ActiveText = black +/Panel/Gtk/Color/NormalBackground = #DDDDFF +/Panel/Gtk/Color/NormalText = black +/Panel/Gtk/Color/HighlightText = #88BB09 +/Panel/Gtk/Font = Vodafone Rg Bold 22 +/Panel/Gtk/DefaultSticked = false +/Panel/Gtk/LookupTableEmbedded = true +/Panel/Gtk/LookupTableVertical = true +/Panel/Gtk/LookupTableStyle = 1 +/Panel/Gtk/LookupTableMode = 1 +/Panel/Gtk/ShowTrayIcon = true +/Panel/Gtk/ToolBar/AlwaysShow = false +/Panel/Gtk/ToolBar/HideTimeout = 2 +/Panel/Gtk/ToolBar/POS_X = -1 +/Panel/Gtk/ToolBar/POS_Y = -1 diff --git a/ism/configs/global b/ism/configs/global new file mode 100755 index 0000000..7913bcd --- /dev/null +++ b/ism/configs/global @@ -0,0 +1,12 @@ +/SupportedUnicodeLocales = en_US.UTF-8 +/DefaultPanelProgram = isf-panel-efl +/DefaultConfigModule = simple +/DefaultSocketFrontEndAddress = local:/tmp/scim-socket-frontend +/DefaultSocketIMEngineAddress = local:/tmp/scim-socket-frontend +/DefaultSocketConfigAddress = local:/tmp/scim-socket-frontend +/DefaultPanelSocketAddress = local:/tmp/scim-panel-socket +/DefaultHelperManagerSocketAddress = local:/tmp/scim-socket-frontend +/DefaultSocketTimeout = 5000 +/InitialIseType = 1 +/InitialIseUuid = 12aa3425-f88d-45f4-a509-cee8dfe904e3 +/InitialIseName = Tizen Keyboard diff --git a/ism/data/Makefile.am b/ism/data/Makefile.am new file mode 100644 index 0000000..8ce9648 --- /dev/null +++ b/ism/data/Makefile.am @@ -0,0 +1,24 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +SUBDIRS = icons pixmaps + +isfshelldir = /etc/profile.d/ +isfshell_DATA = isf.sh diff --git a/ism/data/icons/01_header_icon_cancel.png b/ism/data/icons/01_header_icon_cancel.png new file mode 100644 index 0000000..4fb54c3 Binary files /dev/null and b/ism/data/icons/01_header_icon_cancel.png differ diff --git a/ism/data/icons/01_header_icon_done.png b/ism/data/icons/01_header_icon_done.png new file mode 100644 index 0000000..d771640 Binary files /dev/null and b/ism/data/icons/01_header_icon_done.png differ diff --git a/ism/data/icons/01_list_select_all.png b/ism/data/icons/01_list_select_all.png new file mode 100755 index 0000000..de8b785 Binary files /dev/null and b/ism/data/icons/01_list_select_all.png differ diff --git a/ism/data/icons/ISF_candidate_bg.png b/ism/data/icons/ISF_candidate_bg.png new file mode 100755 index 0000000..558fe23 Binary files /dev/null and b/ism/data/icons/ISF_candidate_bg.png differ diff --git a/ism/data/icons/ISF_candidate_divider.png b/ism/data/icons/ISF_candidate_divider.png new file mode 100755 index 0000000..a7ffc0f Binary files /dev/null and b/ism/data/icons/ISF_candidate_divider.png differ diff --git a/ism/data/icons/ISF_icon_31_help.png b/ism/data/icons/ISF_icon_31_help.png new file mode 100755 index 0000000..cd38b96 Binary files /dev/null and b/ism/data/icons/ISF_icon_31_help.png differ diff --git a/ism/data/icons/ISF_icon_31_help_t.png b/ism/data/icons/ISF_icon_31_help_t.png new file mode 100755 index 0000000..57dae4e Binary files /dev/null and b/ism/data/icons/ISF_icon_31_help_t.png differ diff --git a/ism/data/icons/ISF_icon_help.png b/ism/data/icons/ISF_icon_help.png new file mode 100755 index 0000000..41ee9ab Binary files /dev/null and b/ism/data/icons/ISF_icon_help.png differ diff --git a/ism/data/icons/ISF_icon_option.png b/ism/data/icons/ISF_icon_option.png new file mode 100755 index 0000000..9b839d8 Binary files /dev/null and b/ism/data/icons/ISF_icon_option.png differ diff --git a/ism/data/icons/ISF_panel_bg.png b/ism/data/icons/ISF_panel_bg.png new file mode 100755 index 0000000..762847f Binary files /dev/null and b/ism/data/icons/ISF_panel_bg.png differ diff --git a/ism/data/icons/Makefile.am b/ism/data/icons/Makefile.am new file mode 100644 index 0000000..c10a2c5 --- /dev/null +++ b/ism/data/icons/Makefile.am @@ -0,0 +1,64 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in + +NOINST_ICONS = setup.xpm \ + full-letter.xpm \ + half-letter.xpm \ + help.xpm \ + up.xpm \ + down.xpm \ + left.xpm \ + right.xpm \ + pin-down.xpm \ + pin-up.xpm \ + full-punct.xpm \ + half-punct.xpm \ + trademark.xpm \ + menu.xpm + +INST_ICONS = up.png \ + down.png \ + left.png \ + right.png \ + 01_header_icon_cancel.png \ + 01_header_icon_done.png \ + 01_list_select_all.png \ + ISF_candidate_bg.png \ + ISF_candidate_divider.png \ + ISF_icon_31_help.png \ + ISF_icon_31_help_t.png \ + ISF_icon_help.png \ + ISF_icon_option.png \ + ISF_panel_bg.png + +SCTC_FILTER_ICONS = sctc.png \ + sctc-sc-to-tc.png \ + sctc-tc-to-sc.png + +if SCIM_BUILD_FILTER_SCTC +INST_SCTC_ICONS = $(SCTC_FILTER_ICONS) +endif + +EXTRA_DIST = $(NOINST_ICONS) \ + $(INST_ICONS) \ + $(SCTC_FILTER_ICONS) + +icondir = @SCIM_ICONDIR@ +icon_DATA = $(INST_ICONS) $(INST_SCTC_ICONS) + diff --git a/ism/data/icons/down.png b/ism/data/icons/down.png new file mode 100755 index 0000000..3bd8f69 Binary files /dev/null and b/ism/data/icons/down.png differ diff --git a/ism/data/icons/down.xpm b/ism/data/icons/down.xpm new file mode 100755 index 0000000..c000009 --- /dev/null +++ b/ism/data/icons/down.xpm @@ -0,0 +1,86 @@ +/* XPM */ +static const char *down_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 64 1", +" c #000000", +". c #03060c", +"X c #050b12", +"o c #060f19", +"O c #001f03", +"+ c #05141e", +"@ c #071620", +"# c #0b293e", +"$ c #070144", +"% c #0b0265", +"& c #0c026b", +"* c #0c0271", +"= c #0d324c", +"- c #0d3652", +"; c #026f0c", +": c #02710c", +"> c #144059", +", c #18425f", +"< c #0d4864", +"1 c #0e5775", +"2 c #114560", +"3 c #124d6f", +"4 c #254a64", +"5 c #600a01", +"6 c #6d0b02", +"7 c #106589", +"8 c #10698f", +"9 c #337f9e", +"0 c #0e8fb6", +"q c #0e96bd", +"w c #1697b7", +"e c #1299bb", +"r c #1f95b2", +"t c #2b91ae", +"y c #2695b1", +"u c #0e9ec3", +"i c #0fa0c4", +"p c #0eadcb", +"a c #14a5c9", +"s c #1ca2c3", +"d c #1babca", +"f c #1bb2ce", +"g c #1db4d0", +"h c #1bbad1", +"j c #2ab4d1", +"k c #15c1da", +"l c #64a3bd", +"z c #46b8d5", +"x c #53b7d4", +"c c #54bdd7", +"v c #40d1db", +"b c #5fc0d8", +"n c #46dbe6", +"m c #48dfe9", +"M c #8fcce2", +"N c #a0cbdf", +"B c #a7dcec", +"V c #bfdfee", +"C c #d3e5f0", +"Z c #dfeff8", +"A c #e0f1fb", +"S c #eff3fc", +"D c white", +"F c None", +/* pixels */ +"FFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFF", +"FFFFF3334,=FFFFF", +"FFFFF3NSCl+FFFFF", +"FFFFF3AcMt+FFFFF", +"FFFFF3Spvy+FFFFF", +"FFFFF4Aqmr+FFFFF", +"F-3344Vqhe12># F", +"FF-9ABc0qkms7.FF", +"FFF-9Duqims7oFFF", +"FFFF=tDams7XFFFF", +"FFFFF=9As7XFFFFF", +"FFFFFF-87oFFFFFF", +"FFFFFFF-.FFFFFFF", +"FFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFF" +}; diff --git a/ism/data/icons/full-letter.png b/ism/data/icons/full-letter.png new file mode 100755 index 0000000..9c3450c Binary files /dev/null and b/ism/data/icons/full-letter.png differ diff --git a/ism/data/icons/full-letter.xpm b/ism/data/icons/full-letter.xpm new file mode 100755 index 0000000..93abc2a --- /dev/null +++ b/ism/data/icons/full-letter.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char *full_letter_xpm[]={ +"16 16 2 1", +". c None", +"# c #0000ff", +"................", +".....######.....", +"....#.....##....", +"...#........#...", +"..#..........#..", +".##...........#.", +".#............#.", +".#............#.", +".#............#.", +".#............#.", +".#...........##.", +"..#..........#..", +"...#........#...", +"....##.....#....", +".....######.....", +"................"}; diff --git a/ism/data/icons/full-punct.png b/ism/data/icons/full-punct.png new file mode 100755 index 0000000..79c56ee Binary files /dev/null and b/ism/data/icons/full-punct.png differ diff --git a/ism/data/icons/full-punct.xpm b/ism/data/icons/full-punct.xpm new file mode 100755 index 0000000..0cd0352 --- /dev/null +++ b/ism/data/icons/full-punct.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * full_punct_xpm[] = { +"16 16 2 1", +" c None", +". c #1520EF", +" ", +" ", +" ", +" ", +" .... ... ", +" .. .. ..... ", +" . . ..... ", +" . . ..... ", +" .. .. .... ", +" .... ... ", +" .. ", +" ... ", +" ... ", +" ", +" ", +" "}; diff --git a/ism/data/icons/half-letter.png b/ism/data/icons/half-letter.png new file mode 100755 index 0000000..cba4197 Binary files /dev/null and b/ism/data/icons/half-letter.png differ diff --git a/ism/data/icons/half-letter.xpm b/ism/data/icons/half-letter.xpm new file mode 100755 index 0000000..3f238cf --- /dev/null +++ b/ism/data/icons/half-letter.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char *half_letter_xpm[]={ +"16 16 2 1", +". c None", +"# c #0000ff", +"................", +"................", +"..........##....", +"..........#.#...", +"..........#..#..", +"..........#...#.", +"..........#...#.", +".........#....#.", +".........#....#.", +"........#.....#.", +".......#.....##.", +".....##......#..", +"...##.......#...", +"....##.....#....", +".....######.....", +"................"}; diff --git a/ism/data/icons/half-punct.png b/ism/data/icons/half-punct.png new file mode 100755 index 0000000..44bda4a Binary files /dev/null and b/ism/data/icons/half-punct.png differ diff --git a/ism/data/icons/half-punct.xpm b/ism/data/icons/half-punct.xpm new file mode 100755 index 0000000..6828d5a --- /dev/null +++ b/ism/data/icons/half-punct.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * half_punct_xpm[] = { +"16 16 2 1", +" c None", +". c #1520EF", +" ", +" ", +" ", +" ", +" ", +" ", +" .. .. ", +" .... .... ", +" .... .... ", +" .. ... ", +" . ", +" . ", +" .. ", +" ", +" ", +" "}; diff --git a/ism/data/icons/help.png b/ism/data/icons/help.png new file mode 100755 index 0000000..5858f03 Binary files /dev/null and b/ism/data/icons/help.png differ diff --git a/ism/data/icons/help.xpm b/ism/data/icons/help.xpm new file mode 100755 index 0000000..d3caf9f --- /dev/null +++ b/ism/data/icons/help.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static const char *help_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 16 1", +" c black", +". c #00385b", +"X c #003e66", +"o c #00406a", +"O c #004572", +"+ c #00528c", +"@ c #005896", +"# c #005a99", +"$ c #2a82bf", +"% c #2982c0", +"& c #408fc6", +"* c #4f97ca", +"= c #66a7d1", +"- c #6baad2", +"; c #8bbbdc", +": c None", +/* pixels */ +"::::...... :::::", +":::.$+ ++ :::", +"::X-+ :::.$++ ::", +"::O* :::::.$+ ::", +"::.$+ ::::X&+ ::", +":::.++ :::o&+ ::", +":::: ::.=+ :::", +"::::::::.;# ::::", +":::::::.=# :::::", +"::::::.$+ ::::::", +"::::::.$+ ::::::", +"::::::: :::::::", +"::::::::::::::::", +":::::::..:::::::", +"::::::.=+ ::::::", +"::::::: :::::::" +}; diff --git a/ism/data/icons/keyboard.png b/ism/data/icons/keyboard.png new file mode 100755 index 0000000..1bfc2a5 Binary files /dev/null and b/ism/data/icons/keyboard.png differ diff --git a/ism/data/icons/left.png b/ism/data/icons/left.png new file mode 100755 index 0000000..23bbb1c Binary files /dev/null and b/ism/data/icons/left.png differ diff --git a/ism/data/icons/left.xpm b/ism/data/icons/left.xpm new file mode 100755 index 0000000..50e3c23 --- /dev/null +++ b/ism/data/icons/left.xpm @@ -0,0 +1,59 @@ +/* XPM */ +static const char * left_xpm[] = { +"16 16 40 1", +" c None", +". c #000000", +"+ c #0A121F", +"@ c #071728", +"# c #105375", +"$ c #155678", +"% c #1CA2C3", +"& c #16597A", +"* c #138DB0", +"= c #3CD7E1", +"- c #0A263B", +"; c #081E31", +"> c #48DFE9", +", c #0EA0C5", +"' c #159ABC", +") c #2A98B3", +"! c #178EAC", +"~ c #061625", +"{ c #0E97BF", +"] c #26BDD3", +"^ c #43D5DE", +"/ c #2CC7D5", +"( c #19B3CE", +"_ c #091A2B", +": c #124C6E", +"< c #819EBA", +"[ c #DDEFF8", +"} c #59C3DA", +"| c #1197B9", +"1 c #58ACC5", +"2 c #FDFBFD", +"3 c #71D1E0", +"4 c #9DDAEB", +"5 c #CDEBF6", +"6 c #80C2DB", +"7 c #1A4C6B", +"8 c #114760", +"9 c #E2F0F9", +"0 c #7DA0B8", +"a c #20374F", +" ", +" . ", +" +. ", +" @#. ", +" @$%. ", +" @&*=&---.. ", +" ;$*>,'')!!. ", +" ~$*=,{]^^/(_ ", +" :<[}({||||1_ ", +" $<23(45256_ ", +" 7<2}8$#### ", +" 7<9. ", +" 70. ", +" :a ", +" $ ", +" "}; diff --git a/ism/data/icons/menu.png b/ism/data/icons/menu.png new file mode 100755 index 0000000..9bb9759 Binary files /dev/null and b/ism/data/icons/menu.png differ diff --git a/ism/data/icons/menu.xpm b/ism/data/icons/menu.xpm new file mode 100755 index 0000000..6f24c93 --- /dev/null +++ b/ism/data/icons/menu.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static const char *menu_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 4 1", +" c black", +". c #1F4AEA", +"X c gray100", +"o c None", +/* pixels */ +"oooooooooooooooo", +"oo ooo", +"oo XXXXXXXXX ooo", +"oo X X ooo", +"oo XXXXXXXXX ooo", +"oo X . X ooo", +"oo XXXXX..XX ooo", +"oo X .X.X ooo", +"oo XXXXX.XX. ooo", +"oo X .XXX.ooo", +"oo XXXXX.XXXX.oo", +"oo X .XXX...o", +"oo XXXXX.X.X.ooo", +"oo .. .X.oo", +"oooooooo.oo.X.oo", +"oooooooooooo..oo" +}; diff --git a/ism/data/icons/pin-down.png b/ism/data/icons/pin-down.png new file mode 100755 index 0000000..52cc382 Binary files /dev/null and b/ism/data/icons/pin-down.png differ diff --git a/ism/data/icons/pin-down.xpm b/ism/data/icons/pin-down.xpm new file mode 100755 index 0000000..c767735 --- /dev/null +++ b/ism/data/icons/pin-down.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char * pin_down_xpm[] = { +"16 16 4 1", +" c None", +". c #000000", +"+ c #FFFFFF", +"@ c #B4B6B4", +" ", +" ", +" .... ", +" ..++++. ", +" ...++++++. ", +" .+.+++@@@. ", +" .++.++@@@.. ", +" .++..+@@... ", +" .++++..... ", +" .+++@@@@.. ", +" .+@@@@... ", +" .@@@@... ", +" ...... ", +" ", +" ", +" "}; diff --git a/ism/data/icons/pin-up.png b/ism/data/icons/pin-up.png new file mode 100755 index 0000000..0e2887b Binary files /dev/null and b/ism/data/icons/pin-up.png differ diff --git a/ism/data/icons/pin-up.xpm b/ism/data/icons/pin-up.xpm new file mode 100755 index 0000000..79e8539 --- /dev/null +++ b/ism/data/icons/pin-up.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char * pin_up_xpm[] = { +"16 16 4 1", +" c None", +". c #000000", +"+ c #FFFFFF", +"@ c #B4B6B4", +" ", +" ", +" ", +" ", +" .. . ", +" .+. .. ", +" .++...+. ", +" ++++++.@+@+@+. ", +" @@@@@@.@+@+@+. ", +" .......@@.@.@. ", +" .@...... ", +" ... .. ", +" .. . ", +" ", +" ", +" "}; diff --git a/ism/data/icons/rawcode.png b/ism/data/icons/rawcode.png new file mode 100755 index 0000000..3c328bf Binary files /dev/null and b/ism/data/icons/rawcode.png differ diff --git a/ism/data/icons/right.png b/ism/data/icons/right.png new file mode 100755 index 0000000..f2d3bca Binary files /dev/null and b/ism/data/icons/right.png differ diff --git a/ism/data/icons/right.xpm b/ism/data/icons/right.xpm new file mode 100755 index 0000000..257739b --- /dev/null +++ b/ism/data/icons/right.xpm @@ -0,0 +1,62 @@ +/* XPM */ +static const char * right_xpm[] = { +"16 16 43 1", +" c None", +". c #000000", +"+ c #0B293E", +"@ c #03060C", +"# c #144059", +"$ c #106589", +"% c #060F19", +"& c #114560", +"* c #1CA2C3", +"= c #050B12", +"- c #0D324C", +"; c #05141E", +"> c #0E5775", +", c #48DFE9", +"' c #18425F", +") c #64A3BD", +"! c #2B91AE", +"~ c #2695B1", +"{ c #1F95B2", +"] c #1299BB", +"^ c #15C1DA", +"/ c #254A64", +"( c #D3E5F0", +"_ c #8FCCE2", +": c #40D1DB", +"< c #1BBAD1", +"[ c #0E96BD", +"} c #0FA0C4", +"| c #124D6F", +"1 c #EFF3FC", +"2 c #54BDD7", +"3 c #0EADCB", +"4 c #0E8FB6", +"5 c #14A5C9", +"6 c #E0F1FB", +"7 c #10698F", +"8 c #0D3652", +"9 c #A0CBDF", +"0 c #BFDFEE", +"a c #0E9EC3", +"b c #FFFFFF", +"c c #337F9E", +"d c #A7DCEC", +" ", +" . ", +" +@ ", +" #$% ", +" &*$= ", +" -;;;;>,*$= ", +" ')!~{]^,*$% ", +" /(_:,<[},*$@ ", +" |123[[4[5678 ", +" |961602abc8 ", +" ||||//db!- ", +" /6c- ", +" |c8 ", +" |8 ", +" 8 ", +" "}; diff --git a/ism/data/icons/sctc-sc-to-tc.png b/ism/data/icons/sctc-sc-to-tc.png new file mode 100755 index 0000000..fc2698f Binary files /dev/null and b/ism/data/icons/sctc-sc-to-tc.png differ diff --git a/ism/data/icons/sctc-tc-to-sc.png b/ism/data/icons/sctc-tc-to-sc.png new file mode 100755 index 0000000..34763cf Binary files /dev/null and b/ism/data/icons/sctc-tc-to-sc.png differ diff --git a/ism/data/icons/sctc.png b/ism/data/icons/sctc.png new file mode 100755 index 0000000..18db9ec Binary files /dev/null and b/ism/data/icons/sctc.png differ diff --git a/ism/data/icons/setup.png b/ism/data/icons/setup.png new file mode 100755 index 0000000..dc6e937 Binary files /dev/null and b/ism/data/icons/setup.png differ diff --git a/ism/data/icons/setup.xpm b/ism/data/icons/setup.xpm new file mode 100755 index 0000000..9ac7859 --- /dev/null +++ b/ism/data/icons/setup.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static const char *setup_xpm[]={ +"16 16 15 1", +". c None", +"# c #000000", +"l c #303030", +"i c #585858", +"b c #646464", +"f c #787878", +"a c #808080", +"d c #a0a0a0", +"j c #b7b7b7", +"e c #b8b8b8", +"c c #c2c2c2", +"m c #cfcfcf", +"k c #e7e7e7", +"h c #ededed", +"g c #ffffff", +"...######.......", +"...#ab.cd##.....", +"....#efb.cd#....", +"###..##eb.c#....", +"#gc##..#b..d#...", +"#gh.c#ibc..j#...", +"#bgh......kcd##.", +"lgbfghh..kcmcdd#", +"#c.gbbbfdch.mcjd", +".##c.cccfbfgh.mc", +"...###d.ccdbfgh.", +"......####h.dbfg", +"..........##h.db", +"............##h.", +"..............##", +"................"}; diff --git a/ism/data/icons/trademark.png b/ism/data/icons/trademark.png new file mode 100755 index 0000000..645990d Binary files /dev/null and b/ism/data/icons/trademark.png differ diff --git a/ism/data/icons/trademark.xpm b/ism/data/icons/trademark.xpm new file mode 100755 index 0000000..3abb654 --- /dev/null +++ b/ism/data/icons/trademark.xpm @@ -0,0 +1,32 @@ +/* XPM */ +static const char * trademark_xpm[] = { +"24 24 5 1", +" c None", +". c #3D55FD", +"+ c #D71FEF", +"@ c #568C56", +"# c #F93E00", +" ", +" ", +" ...... +++ ", +" ... ... +++++++ ", +" .. ++ ++ ", +" .. ++ ", +" ..... ++ ", +" .... ++ ", +" .. ++ ", +" .. ++ ++ ", +" ... ... +++++++ ", +" ...... +++++ ", +" ", +" @@@@@@@@ ## ## ", +" @@@@@@@@ ## ## ", +" @@ ### ### ", +" @@ ### ### ", +" @@ ######## ", +" @@ ######## ", +" @@ ## ## ## ", +" @@ ## ## ## ", +" @@@@@@@@ ## ## ## ", +" @@@@@@@@ ## ## ## ", +" "}; diff --git a/ism/data/icons/up.png b/ism/data/icons/up.png new file mode 100755 index 0000000..c0f7166 Binary files /dev/null and b/ism/data/icons/up.png differ diff --git a/ism/data/icons/up.xpm b/ism/data/icons/up.xpm new file mode 100755 index 0000000..192cb6d --- /dev/null +++ b/ism/data/icons/up.xpm @@ -0,0 +1,87 @@ +/* XPM */ +static const char *up_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 65 1", +" c #000000", +". c #06101d", +"X c #0a121f", +"o c #061625", +"O c #071728", +"+ c #071a2b", +"@ c #091a2b", +"# c #081e31", +"$ c #082033", +"% c #0a263b", +"& c #2f0500", +"* c #323e01", +"= c #20374f", +"- c #18415d", +"; c #0f4b6a", +": c #0f5d7e", +"> c #114760", +", c #124c6e", +"< c #1a4c6b", +"1 c #105375", +"2 c #155678", +"3 c #16597a", +"4 c #214764", +"5 c #3c5c73", +"6 c #710c02", +"7 c #42556d", +"8 c #116c92", +"9 c #287c9f", +"0 c #14839f", +"q c #0e97bf", +"w c #178eac", +"e c #138db0", +"r c #1290b4", +"t c #1197b9", +"y c #159abc", +"u c #2294b1", +"i c #2a98b3", +"p c #0ea0c5", +"a c #14a5c9", +"s c #1ca2c3", +"d c #19b3ce", +"f c #1bb8d2", +"g c #26bdd3", +"h c #2cc7d5", +"j c #3cd7e1", +"k c #5486a3", +"l c #7da0b8", +"z c #4bbfd8", +"x c #58acc5", +"c c #50b3cf", +"v c #43d5de", +"b c #50c1d9", +"n c #59c3da", +"m c #48dfe9", +"M c #71d1e0", +"N c #c3162e", +"B c #819eba", +"V c #80c2db", +"C c #9ddaeb", +"Z c #b6dae9", +"A c #cdebf6", +"S c #ddeff8", +"D c #e2f0f9", +"F c #fdfbfd", +"G c None", +/* pixels */ +"GGGGGGGGGGGGGGGG", +"GGGGGGGGGGGGGGGG", +"GGGGGGG,oGGGGGGG", +"GGGGGG2B2#GGGGGG", +"GGGGGCtgy3 G", +"GGGGG2Atvy%GGGGG", +"GGGGG1Ftvi%GGGGG", +"GGGGG1Athw%GGGGG", +"GGGGG1Vxdw GGGGG", +"GGGGG1@@@ GGGGG", +"GGGGGGGGGGGGGGGG", +"GGGGGGGGGGGGGGGG" +}; diff --git a/ism/data/isf.sh b/ism/data/isf.sh new file mode 100755 index 0000000..34cee20 --- /dev/null +++ b/ism/data/isf.sh @@ -0,0 +1,5 @@ +export SCIM_MODULE_PATH=/opt/apps/scim/lib/scim-1.0 +export XMODIFIERS=@im=SCIM +export GTK_IM_MODULE_FILE=/opt/etc/gtk-2.0/gtk.immodules +export GTK_IM_MODULE=scim +export ECORE_IMF_MODULE=isf diff --git a/ism/data/pixmaps/B09_key_btn_01.png b/ism/data/pixmaps/B09_key_btn_01.png new file mode 100755 index 0000000..70a8858 Binary files /dev/null and b/ism/data/pixmaps/B09_key_btn_01.png differ diff --git a/ism/data/pixmaps/B09_key_btn_02.png b/ism/data/pixmaps/B09_key_btn_02.png new file mode 100755 index 0000000..02d12e4 Binary files /dev/null and b/ism/data/pixmaps/B09_key_btn_02.png differ diff --git a/ism/data/pixmaps/B09_key_btn_perss.png b/ism/data/pixmaps/B09_key_btn_perss.png new file mode 100755 index 0000000..400e110 Binary files /dev/null and b/ism/data/pixmaps/B09_key_btn_perss.png differ diff --git a/ism/data/pixmaps/B09_predictive_bg.png b/ism/data/pixmaps/B09_predictive_bg.png new file mode 100755 index 0000000..796ffc3 Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_bg.png differ diff --git a/ism/data/pixmaps/B09_predictive_horizon_line.png b/ism/data/pixmaps/B09_predictive_horizon_line.png new file mode 100755 index 0000000..530ef14 Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_horizon_line.png differ diff --git a/ism/data/pixmaps/B09_predictive_icon_arrow_down.png b/ism/data/pixmaps/B09_predictive_icon_arrow_down.png new file mode 100755 index 0000000..3d71005 Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_icon_arrow_down.png differ diff --git a/ism/data/pixmaps/B09_predictive_icon_arrow_down_press.png b/ism/data/pixmaps/B09_predictive_icon_arrow_down_press.png new file mode 100755 index 0000000..976fb72 Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_icon_arrow_down_press.png differ diff --git a/ism/data/pixmaps/B09_predictive_icon_arrow_up.png b/ism/data/pixmaps/B09_predictive_icon_arrow_up.png new file mode 100755 index 0000000..b7cf9c1 Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_icon_arrow_up.png differ diff --git a/ism/data/pixmaps/B09_predictive_icon_arrow_up_press.png b/ism/data/pixmaps/B09_predictive_icon_arrow_up_press.png new file mode 100755 index 0000000..7b787fc Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_icon_arrow_up_press.png differ diff --git a/ism/data/pixmaps/B09_predictive_on_bg.png b/ism/data/pixmaps/B09_predictive_on_bg.png new file mode 100755 index 0000000..dc47970 Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_on_bg.png differ diff --git a/ism/data/pixmaps/B09_predictive_vertical_line.png b/ism/data/pixmaps/B09_predictive_vertical_line.png new file mode 100755 index 0000000..73c6e03 Binary files /dev/null and b/ism/data/pixmaps/B09_predictive_vertical_line.png differ diff --git a/ism/data/pixmaps/Makefile.am b/ism/data/pixmaps/Makefile.am new file mode 100644 index 0000000..928f756 --- /dev/null +++ b/ism/data/pixmaps/Makefile.am @@ -0,0 +1,30 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak *.edj + + +# edjes +isf_candidate_theme1.edj : isf_candidate_theme1.edc + edje_cc $^ $@ + +isfsetting.edj : isfsetting.edc + edje_cc $^ $@ + +edjdir = @SCIM_DATADIR@ +edj_DATA = isf_candidate_theme1.edj isfsetting.edj diff --git a/ism/data/pixmaps/isf_candidate.edc b/ism/data/pixmaps/isf_candidate.edc new file mode 100755 index 0000000..060f7d7 --- /dev/null +++ b/ism/data/pixmaps/isf_candidate.edc @@ -0,0 +1,471 @@ + +#define FONT_NAME "Tizen" +#define FONT_SIZE 38 + +#define AUX_FONT_NAME "Tizen" +#define AUX_FONT_SIZE 38 + +#define COLOR_NORMAL_BUTTON 0 0 0 0 +#define COLOR_PRESS_BUTTON 166 166 166 255 + +#define COLOR_SELECT_TEXT 62 207 255 255 + + +color_classes { + color_class { + name: "text_color"; + color: COLOR_NORMAL_TEXT; + color2: COLOR_NORMAL_TEXT; + color3: COLOR_NORMAL_TEXT; + } + color_class { + name: "rect_color"; + color: COLOR_NORMAL_BUTTON; + } +} + + +collections { + group { name: "popup_line"; + images { + image: POPUP_LINE COMP; + } + + parts { + part { name: "bg"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + image.normal: POPUP_LINE; + } + } + } + } + + group { name: "seperate_line"; + images { + image: "B09_predictive_vertical_line.png" COMP; + } + + parts { + part { name: "bg"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + image.normal: "B09_predictive_vertical_line.png"; + } + } + } + } + + group { name: "scroller_bg"; + images { + image: "B09_predictive_on_bg.png" COMP; + } + + parts { + part { name: "bg"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + image.normal: "B09_predictive_on_bg.png"; + image.border: 6 6 6 6; + } + } + } + } + + group { name: "candidate_bg"; + images { + image: CANDIDATE_BG COMP; + } + + parts { + part { name: "bg"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + image.normal: CANDIDATE_BG; + image.border: BG_IMAGE_BORDER BG_IMAGE_BORDER 41 41; + } + } + } + } + + group { name: "candidate"; + images { + image: BUTTON_NORMAL_BG COMP; + image: BUTTON_PRESS_BG COMP; + } + + parts { + part { name: "bg"; + type: RECT; + mouse_events: 1; + description { state: "default" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + color_class: "rect_color"; + } + description { state: "pressed" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + color: COLOR_PRESS_BUTTON; + } + } + + part { name: "candidate"; + type: TEXT; + mouse_events: 0; + //effect: SHADOW; + description { state: "default" 0.0; + color: COLOR_NORMAL_TEXT; + color_class: "text_color"; + text { + text_class: "candidate_text_class"; + text: "Test"; + font: FONT_NAME; + size: FONT_SIZE; + align: 0.5 0.5; + } + rel1.to: "bg"; + rel1.relative: 0.0 0.0; + rel1.offset: 11 0; + rel2.to: "bg"; + rel2.relative: 1.0 1.0; + rel2.offset: -11 0; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + color: COLOR_PRESS_TEXT; + } + } + } + + programs { + program { name: "button_click"; + signal: "mouse,clicked,1"; + source: "bg"; + action: SIGNAL_EMIT "candidate,action,clicked" ""; + } + + program { name, "button_press"; + signal, "mouse,down,1"; + source, "bg"; + action, STATE_SET "pressed" 0.0; + target, "bg"; + target, "candidate"; + } + + program { name, "button_release"; + signal, "mouse,up,1"; + source, "bg"; + action, STATE_SET "default" 0.0; + target, "bg"; + target, "candidate"; + //after, "do_me"; + } + + program { name, "do_me"; + //signal, "*"; + //source, "button_release"; + action, SIGNAL_EMIT "candidate,action,clicked" ""; + } + } + } + + group { name: "more_button"; + + images { + image: BUTTON_NORMAL_BG COMP; + image: BUTTON_PRESS_BG COMP; + image: "B09_predictive_icon_arrow_down.png" COMP; + image: "B09_predictive_icon_arrow_down_press.png" COMP; + } + + parts { + part { name: "bg"; + mouse_events: 1; + description { state: "default" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + image.normal: BUTTON_NORMAL_BG; + image.border: BUTTON_IMAGE_BORDER BUTTON_IMAGE_BORDER BUTTON_IMAGE_BORDER BUTTON_IMAGE_BORDER; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + image.normal: BUTTON_PRESS_BG; + } + } + + part { name: "image"; + type: IMAGE; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "bg"; + rel1.relative: 0.25 0.1875; + rel2.to: "bg"; + rel2.relative: 0.75 0.8125; + image.normal: "B09_predictive_icon_arrow_down.png"; + fill.smooth: 1; + } + + description { state: "pressed" 0.0; + inherit: "default" 0.0; + image.normal: "B09_predictive_icon_arrow_down_press.png"; + } + } + + part { name: "button_text"; + type: TEXT; + mouse_events: 0; + effect: SHADOW; + description { state: "default" 0.0; + color: 255 255 255 255; + text { + //text_class: "button_text_class"; + //text: "Close"; + font: FONT_NAME; + size: FONT_SIZE; + align: 0.5 0.5; + } + rel1.to: "bg"; + rel1.relative: 0.0 0.0; + rel2.to: "bg"; + rel2.relative: 1.0 1.0; + } + } + } + + programs { + program { name: "button_click"; + signal: "mouse,clicked,1"; + source: "bg"; + action: SIGNAL_EMIT "button,action,clicked" ""; + } + + program { name, "button_press"; + signal, "mouse,down,1"; + source, "bg"; + action, STATE_SET "pressed" 0.0; + target, "bg"; + target, "image"; + } + + program { name, "button_release"; + signal, "mouse,up,1"; + source, "bg"; + action, STATE_SET "default" 0.0; + target, "bg"; + target, "image"; + } + } + } + + group { name: "close_button"; + + images { + image: BUTTON_NORMAL_BG COMP; + image: BUTTON_PRESS_BG COMP; + image: "B09_predictive_icon_arrow_up.png" COMP; + image: "B09_predictive_icon_arrow_up_press.png" COMP; + } + + parts { + part { name: "bg"; + mouse_events: 1; + description { state: "default" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + image.normal: BUTTON_NORMAL_BG; + image.border: BUTTON_IMAGE_BORDER BUTTON_IMAGE_BORDER BUTTON_IMAGE_BORDER BUTTON_IMAGE_BORDER; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + image.normal: BUTTON_PRESS_BG; + } + } + + part { name: "image"; + type: IMAGE; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "bg"; + rel1.relative: 0.25 0.1875; + rel2.to: "bg"; + rel2.relative: 0.75 0.8125; + image.normal: "B09_predictive_icon_arrow_up.png"; + fill.smooth: 1; + } + + description { state: "pressed" 0.0; + inherit: "default" 0.0; + image.normal: "B09_predictive_icon_arrow_up_press.png"; + } + } + + part { name: "button_text"; + type: TEXT; + mouse_events: 0; + effect: SHADOW; + description { state: "default" 0.0; + color: 255 255 255 255; + text { + //text_class: "button_text_class"; + //text: "Close"; + font: FONT_NAME; + size: FONT_SIZE; + align: 0.5 0.5; + } + rel1.to: "bg"; + rel1.relative: 0.0 0.0; + rel2.to: "bg"; + rel2.relative: 1.0 1.0; + } + } + } + + programs { + program { name: "button_click"; + signal: "mouse,clicked,1"; + source: "bg"; + action: SIGNAL_EMIT "button,action,clicked" ""; + } + + program { name, "button_press"; + signal, "mouse,down,1"; + source, "bg"; + action, STATE_SET "pressed" 0.0; + target, "bg"; + target, "image"; + } + + program { name, "button_release"; + signal, "mouse,up,1"; + source, "bg"; + action, STATE_SET "default" 0.0; + target, "bg"; + target, "image"; + } + } + } + + group { name: "aux"; + + parts { + part { name: "bg"; + type: RECT; + mouse_events: 1; + description { state: "default" 0.0; + color_class: "rect_color"; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + } + description { state: "pressed" 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + color: COLOR_PRESS_BUTTON; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + } + } + + part { name: "aux"; + type: TEXT; + mouse_events: 0; + //effect: SHADOW; + description { state: "default" 0.0; + color: COLOR_NORMAL_TEXT; + color_class: "text_color"; + text { + text: "aux"; + text_class: "aux_text_class"; + font: AUX_FONT_NAME; + size: AUX_FONT_SIZE; + align: 0.5 0.5; + } + rel1.to: "bg"; + rel1.relative: 0.0 0.0; + rel2.to: "bg"; + rel2.relative: 1.0 1.0; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + color: COLOR_PRESS_TEXT; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + color: COLOR_SELECT_TEXT; + } + } + } + + programs { + program { name: "select"; + signal, "aux,state,selected"; + source, "aux"; + action, STATE_SET "selected" 0.0; + target, "aux"; + target, "bg"; + } + + program { name: "unselect"; + signal, "aux,state,unselected"; + source, "aux"; + action, STATE_SET "default" 0.0; + target, "aux"; + target, "bg"; + } + + program { name: "button_click"; + signal, "mouse,clicked,1"; + source, "bg"; + //action, STATE_SET "selected" 0.0; + //target, "aux"; + //target, "bg"; + after, "do_me"; + } + + program { name, "button_press"; + signal, "mouse,down,1"; + source, "bg"; + script { + new st[31]; + new Float:vl; + get_state (PART:"aux", st, 30, vl); + if (!strcmp (st, "default")) + set_state (PART:"aux", "pressed", 0.0); + } + action, STATE_SET "pressed" 0.0; + target, "bg"; + target, "aux"; + } + + program { name, "button_release"; + signal, "mouse,up,1"; + source, "bg"; + script { + new st[31]; + new Float:vl; + get_state (PART:"aux", st, 30, vl); + if (!strcmp (st, "pressed")) + set_state (PART:"aux", "default", 0.0); + } + action, STATE_SET "default" 0.0; + target, "bg"; + target, "aux"; + } + + program { name, "do_me"; + signal, "*"; + source, "button_click"; + action, SIGNAL_EMIT "aux,action,clicked" ""; + } + } + } +} diff --git a/ism/data/pixmaps/isf_candidate_theme1.edc b/ism/data/pixmaps/isf_candidate_theme1.edc new file mode 100755 index 0000000..a3d98f3 --- /dev/null +++ b/ism/data/pixmaps/isf_candidate_theme1.edc @@ -0,0 +1,12 @@ +#define CANDIDATE_BG "B09_predictive_bg.png" +#define POPUP_LINE "B09_predictive_horizon_line.png" +#define BUTTON_NORMAL_BG "B09_key_btn_01.png" +#define BUTTON_PRESS_BG "B09_key_btn_perss.png" + +#define BUTTON_IMAGE_BORDER 8 +#define BG_IMAGE_BORDER 0 + +#define COLOR_NORMAL_TEXT 249 249 249 255 +#define COLOR_PRESS_TEXT 0 0 0 255 + +#include "isf_candidate.edc" diff --git a/ism/data/pixmaps/isfsetting.edc b/ism/data/pixmaps/isfsetting.edc new file mode 100644 index 0000000..1db2605 --- /dev/null +++ b/ism/data/pixmaps/isfsetting.edc @@ -0,0 +1,32 @@ +#define PADDING_X 25 +#define PADDING_Y 25 +collections { + group { + name : "isfsetting/languageview"; + parts { + part { + name:"top_padding"; + type: RECT; + scale: 1; + description { + state: "default" 0.0; + min: 0 PADDING_Y; + fixed: 0 1; + rel1 {relative: 0 0;} + rel2 {relative: 1 0;} + align: 0 0; + visible : 0; + } + } + part { + name:"content"; + type: SWALLOW; + scale :1; + description { + state : "default" 0.0; + rel1 {relative: 0.0 1.0; offset: PADDING_X 0 ;to_y:"top_padding";} + } + } + } + } +} diff --git a/ism/demos/Makefile.am b/ism/demos/Makefile.am new file mode 100644 index 0000000..5b19573 --- /dev/null +++ b/ism/demos/Makefile.am @@ -0,0 +1,52 @@ +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/data \ + -I$(top_srcdir)/ism/utils \ + -I$(top_srcdir)/ism/demos/include \ + -I$(includedir) \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" + + +noinst_HEADERS = + +if ISF_BUILD_SETTING_EFL +ISF_DEMO_EFL = isf-demo-efl +endif + +bin_PROGRAMS = $(ISF_DEMO_EFL) + +isf_demo_efl_SOURCES = isf_demo_efl.cpp \ + isf_imcontrol_efl.cpp \ + isf_layout_efl.cpp \ + isf_event_efl.cpp \ + isf_entry_event_efl.cpp \ + isf_autocapital_efl.cpp \ + isf_prediction_efl.cpp \ + isf_return_key_type_efl.cpp \ + isf_return_key_disable_efl.cpp \ + isf_imdata_set_efl.cpp \ + isf_focus_movement_efl.cpp + +isf_demo_efl_CXXFLAGS = @EFL_CFLAGS@ \ + @APPCORE_EFL_CFLAGS@ \ + @UIGADGET_CFLAGS@ \ + @VCONF_CFLAGS@ @PRIVILEGE_CONTROL_CFLAGS@ + +isf_demo_efl_LDFLAGS = @EFL_LIBS@ @LTLIBINTL@ -rpath $(libdir) \ + @VCONF_LIBS@ \ + @APPCORE_EFL_LIBS@ \ + @UIGADGET_LIBS@ @PRIVILEGE_CONTROL_LIBS@ + +#isf_demo_efl_LDADD = -lui-gadget diff --git a/ism/demos/include/isf_autocapital_efl.h b/ism/demos/include/isf_autocapital_efl.h new file mode 100644 index 0000000..684fd56 --- /dev/null +++ b/ism/demos/include/isf_autocapital_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_AUTOCAPITAL_H +#define __ISE_AUTOCAPITAL_H + +#include + +void ise_autocapital_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISE_AUTOCAPITAL_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_demo_efl.h b/ism/demos/include/isf_demo_efl.h new file mode 100644 index 0000000..e392648 --- /dev/null +++ b/ism/demos/include/isf_demo_efl.h @@ -0,0 +1,61 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_DEMO_EFL_H +#define __ISF_DEMO_EFL_H + + +#include +#include +#include + +struct appdata { + int root_w; + int root_h; + int root_x; + int root_y; + + Evas *evas; + Evas_Object *win_main; + Evas_Object *layout_main; // Layout widget based on EDJ + Evas_Object *naviframe; + + ui_gadget_h ug; + int is_frameview; + + // Add more variables here + Evas_Object *li; + Evas_Object *ev_li; + service_h data; +}; + +// Utility functions +Evas_Object *create_ef (Evas_Object *parent, const char *label, const char *guide_text); +void add_layout_to_naviframe (void *data, Evas_Object *lay_in, const char *title); + +#endif /* __ISF_DEMO_EFL_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_event_efl.h b/ism/demos/include/isf_event_efl.h new file mode 100644 index 0000000..94ee8a3 --- /dev/null +++ b/ism/demos/include/isf_event_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_EVENT_DEMO_H +#define __ISF_EVENT_DEMO_H + +#include + +void isf_event_demo_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISF_EVENT_DEMO_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_focus_movement_efl.h b/ism/demos/include/isf_focus_movement_efl.h new file mode 100644 index 0000000..fcc579c --- /dev/null +++ b/ism/demos/include/isf_focus_movement_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_FOCUS_MOVEMENT_H +#define __ISE_FOCUS_MOVEMENT_H + +#include + +void isf_focus_movement_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISE_FOCUS_MOVEMENT_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_imcontrol_efl.h b/ism/demos/include/isf_imcontrol_efl.h new file mode 100644 index 0000000..d4c97b8 --- /dev/null +++ b/ism/demos/include/isf_imcontrol_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_IMCONTROL_API_H +#define __ISF_IMCONTROL_API_H + +#include + +void imcontrolapi_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISF_IMCONTROL_API_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_imdata_set_efl.h b/ism/demos/include/isf_imdata_set_efl.h new file mode 100644 index 0000000..b8035b2 --- /dev/null +++ b/ism/demos/include/isf_imdata_set_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_IMDATA_SET_H +#define __ISE_IMDATA_SET_H + +#include + +void ise_imdata_set_bt (void *data, Evas_Object *obj, void *event_info); + +#endif + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_layout_efl.h b/ism/demos/include/isf_layout_efl.h new file mode 100644 index 0000000..da1967c --- /dev/null +++ b/ism/demos/include/isf_layout_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_LAYOUT_H +#define __ISE_LAYOUT_H + +#include + +void ise_layout_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISE_LAYOUT_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ \ No newline at end of file diff --git a/ism/demos/include/isf_prediction_efl.h b/ism/demos/include/isf_prediction_efl.h new file mode 100644 index 0000000..be4851d --- /dev/null +++ b/ism/demos/include/isf_prediction_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_PREDICTION_H +#define __ISE_PREDICTION_H + +#include + +void ise_prediction_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISE_PREDICTION_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_return_key_disable_efl.h b/ism/demos/include/isf_return_key_disable_efl.h new file mode 100644 index 0000000..3ae6034 --- /dev/null +++ b/ism/demos/include/isf_return_key_disable_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_RETURN_KEY_DISABLE_H +#define __ISE_RETURN_KEY_DISABLE_H + +#include + +void ise_return_key_disable_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISE_RETURN_KEY_DISABLE_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/include/isf_return_key_type_efl.h b/ism/demos/include/isf_return_key_type_efl.h new file mode 100644 index 0000000..ae320cf --- /dev/null +++ b/ism/demos/include/isf_return_key_type_efl.h @@ -0,0 +1,36 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_RETURN_KEY_TYPE_H +#define __ISE_RETURN_KEY_TYPE_H + +#include + +void ise_return_key_type_bt (void *data, Evas_Object *obj, void *event_info); + +#endif /* __ISE_RETURN_KEY_TYPE_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_autocapital_efl.cpp b/ism/demos/isf_autocapital_efl.cpp new file mode 100644 index 0000000..39705ae --- /dev/null +++ b/ism/demos/isf_autocapital_efl.cpp @@ -0,0 +1,102 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" +#include "isf_autocapital_efl.h" + +static Evas_Object *_create_ef_layout (Evas_Object *parent, const char *label, const char *guide_text, Elm_Autocapital_Type autocap, Eina_Bool caps_lock_mode) +{ + Evas_Object *ef = create_ef (parent, label, guide_text); + Evas_Object *en = elm_object_part_content_get (ef, "elm.swallow.content"); + elm_entry_autocapital_type_set (en, autocap); + + Ecore_IMF_Context *ic = (Ecore_IMF_Context *)elm_entry_imf_context_get (en); + if (ic) { + ecore_imf_context_input_panel_caps_lock_mode_set (ic, caps_lock_mode); + } + + return ef; +} + +static Evas_Object * create_inner_layout (void *data) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *bx = NULL; + Evas_Object *ef = NULL; + + Evas_Object *parent = ad->naviframe; + + bx = elm_box_add (parent); + evas_object_size_hint_weight_set (bx, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (bx, EVAS_HINT_FILL, 0.0); + evas_object_show (bx); + + /* Caps lock mode off */ + + /* NONE type */ + ef = _create_ef_layout (parent, _("NONE type"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_NONE, EINA_FALSE); + elm_box_pack_end (bx, ef); + + /* WORD type */ + ef = _create_ef_layout (parent, _("WORD type"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_WORD, EINA_FALSE); + elm_box_pack_end (bx, ef); + + /* Sentence type */ + ef = _create_ef_layout (parent, _("SENTENCE type"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_SENTENCE, EINA_FALSE); + elm_box_pack_end (bx, ef); + + /* ALLCHARACTER type */ + ef = _create_ef_layout (parent, _("ALLCHARACTER type"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_ALLCHARACTER, EINA_FALSE); + elm_box_pack_end (bx, ef); + + /* Caps lock mode ON */ + + /* NONE type */ + ef = _create_ef_layout (parent, _("NONE type - CAPS LOCK"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_NONE, EINA_TRUE); + elm_box_pack_end (bx, ef); + + /* WORD type */ + ef = _create_ef_layout (parent, _("WORD type - CAPS LOCK"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_WORD, EINA_TRUE); + elm_box_pack_end (bx, ef); + + /* Sentence type */ + ef = _create_ef_layout (parent, _("SENTENCE type - CAPS LOCK"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_SENTENCE, EINA_TRUE); + elm_box_pack_end (bx, ef); + + /* ALLCHARACTER type */ + ef = _create_ef_layout (parent, _("ALLCHARACTER type - CAPS LOCK"), _("click to enter"), ELM_AUTOCAPITAL_TYPE_ALLCHARACTER, EINA_TRUE); + elm_box_pack_end (bx, ef); + + return bx; +} + +void ise_autocapital_bt (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *lay_inner = create_inner_layout (data); + add_layout_to_naviframe (data, lay_inner, _("Autocapital")); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_demo_efl.cpp b/ism/demos/isf_demo_efl.cpp new file mode 100644 index 0000000..8bc98f4 --- /dev/null +++ b/ism/demos/isf_demo_efl.cpp @@ -0,0 +1,504 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include "isf_demo_efl.h" +#include "isf_imcontrol_efl.h" +#include "isf_layout_efl.h" +#include "isf_event_efl.h" +#include "isf_autocapital_efl.h" +#include "isf_prediction_efl.h" +#include "isf_return_key_type_efl.h" +#include "isf_return_key_disable_efl.h" +#include "isf_imdata_set_efl.h" +#include "isf_focus_movement_efl.h" + +#define BASE_THEME_WIDTH 720.0f + + +static void _quit_cb (void *data, Evas_Object *obj, void *event_info) +{ + elm_exit (); +} + +static void _list_click (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + if (ad == NULL) return; + + Evas_Object *li = ad->li; + if (li == NULL) return; + + Elm_Object_Item *it = (Elm_Object_Item *)elm_list_selected_item_get (li); + + if (it != NULL) + elm_list_item_selected_set (it, EINA_FALSE); +} + +static void layout_cb (ui_gadget_h ug, enum ug_mode mode, void *priv) +{ + struct appdata *ad = NULL; + Evas_Object *base = NULL; + + if ( ug == NULL || priv == NULL) + return; + + ad = (appdata *)priv; + + base = (Evas_Object *)ug_get_layout (ug); + if (base == NULL) + return; + + switch (mode) { + case UG_MODE_FULLVIEW: + evas_object_size_hint_weight_set (base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add (ad->win_main, base); + evas_object_show (base); + break; + case UG_MODE_FRAMEVIEW: + printf("please set ug mode to UG_MODE_FULLVIEW!\n"); + break; + default: + break; + } +} + +static void result_cb (ui_gadget_h ug, service_h s, void *priv) +{ + char *name = NULL; + service_get_extra_data (s, "name", &name); + printf ("get key [ %s ]\n", name); + + if (name) { + if (strcmp (name, "keyboard-setting-wizard-efl") == 0) { + char *desp = NULL; + service_get_extra_data (s, "description", &desp); + printf ("====================\nresult:%s\n====================\n", desp); + if (desp != NULL) + free (desp); + } + + free (name); + } +} + +static void destroy_cb (ui_gadget_h ug, void *priv) +{ + if (ug == NULL) + return; + + ug_destroy (ug); +} + +static void isfsetting_bt (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + struct ug_cbs cbs = {0, }; + + UG_INIT_EFL (ad->win_main, UG_OPT_INDICATOR_ENABLE); + + cbs.layout_cb = layout_cb; + cbs.result_cb = result_cb; + cbs.destroy_cb = destroy_cb; + cbs.priv = ad; + ad->ug = ug_create (NULL, "isfsetting-efl", + UG_MODE_FULLVIEW, + ad->data, &cbs); + service_destroy (ad->data); + ad->data = NULL; +} + +static void keyboard_setting_wizard_bt (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + struct ug_cbs cbs = {0, }; + + UG_INIT_EFL (ad->win_main, UG_OPT_INDICATOR_ENABLE); + + cbs.layout_cb = layout_cb; + cbs.result_cb = result_cb; + cbs.destroy_cb = destroy_cb; + cbs.priv = ad; + service_create (&ad->data); + service_add_extra_data (ad->data, "navi_btn_left", _("Previous")); + //service_add_extra_data (ad->data, "navi_btn_left", NULL); + service_add_extra_data (ad->data, "navi_btn_right", _("Next")); + ad->ug = ug_create (NULL, "keyboard-setting-wizard-efl", + UG_MODE_FULLVIEW, + ad->data, &cbs); + service_destroy (ad->data); + ad->data = NULL; +} + +static int create_demo_view (struct appdata *ad) +{ + Evas_Object *li = NULL; + + Evas_Object *l_button = elm_button_add (ad->naviframe); + elm_object_style_set (l_button, "naviframe/end_btn/default"); + evas_object_smart_callback_add (l_button, "clicked", _quit_cb, NULL); + + // Create list + ad->li = li = elm_list_add (ad->naviframe); + elm_list_mode_set (li, ELM_LIST_COMPRESS); + evas_object_smart_callback_add (ad->li, "selected", _list_click, ad); + + // Test ISF imcontrol API + elm_list_item_append (li, "ISF IM Control", NULL, NULL, imcontrolapi_bt, ad); + + // test ISF layout + elm_list_item_append (li, "ISF Layout", NULL, NULL, ise_layout_bt, ad); + + // Test autocapital type + elm_list_item_append (li, "ISF Autocapital", NULL, NULL, ise_autocapital_bt, ad); + + // Test prediction allow + elm_list_item_append (li, "ISF Prediction Allow", NULL, NULL, ise_prediction_bt, ad); + + // Test return key type + elm_list_item_append (li, "ISF Return Key Type", NULL, NULL, ise_return_key_type_bt, ad); + + // Test return key disable + elm_list_item_append (li, "ISF Return Key Disable", NULL, NULL, ise_return_key_disable_bt, ad); + + // Test imdata setting + elm_list_item_append (li, "ISF IM Data", NULL, NULL, ise_imdata_set_bt, ad); + + elm_list_item_append (li, "ISF Event", NULL, NULL, isf_event_demo_bt, ad); + + elm_list_item_append (li, "ISF Focus Movement", NULL, NULL, isf_focus_movement_bt, ad); + + elm_list_item_append (li, "ISF Setting", NULL, NULL, isfsetting_bt, ad); + elm_list_item_append (li, "Keyboard Setting Wizard", NULL, NULL, keyboard_setting_wizard_bt, ad); + // ISF preedit string and commit string on Label and Entry + + elm_list_go (li); + + elm_naviframe_item_push (ad->naviframe, _("ISF Demo"), l_button, NULL, li, NULL); + + return 0; +} + +static int lang_changed (void *data) +{ + struct appdata *ad = (appdata *)data; + + if (ad->layout_main == NULL) + return 0; + + ug_send_event (UG_EVENT_LANG_CHANGE); + return 0; +} + +static int _rotate_cb (enum appcore_rm m, void *data) +{ + struct appdata *ad = (struct appdata *)data; + if (ad == NULL || ad->win_main == NULL) + return 0; + + int r; + switch (m) { + case APPCORE_RM_PORTRAIT_NORMAL: + ug_send_event (UG_EVENT_ROTATE_PORTRAIT); + r = 0; + break; + case APPCORE_RM_PORTRAIT_REVERSE: + ug_send_event (UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN); + r = 180; + break; + case APPCORE_RM_LANDSCAPE_NORMAL: + ug_send_event (UG_EVENT_ROTATE_LANDSCAPE); + r = 270; + break; + case APPCORE_RM_LANDSCAPE_REVERSE: + ug_send_event (UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN); + r = 90; + break; + default: + r = -1; + break; + } + + if (r >= 0) + elm_win_rotation_with_resize_set (ad->win_main, r); + + return 0; +} + +static void win_del (void *data, Evas_Object *obj, void *event) +{ + elm_exit (); +} + +static Evas_Object* create_win (const char *name) +{ + Evas_Object *eo = NULL; + int w, h; + + eo = elm_win_util_standard_add (name, name); + if (eo != NULL) { + evas_object_smart_callback_add (eo, "delete,request", + win_del, NULL); + ecore_x_window_size_get (ecore_x_window_root_first_get (), &w, &h); + evas_object_resize (eo, w, h); + } + + return eo; +} + +static void +_vkbd_state_on (void *data, Evas_Object *obj, void *event_info) +{ + printf("[%s] input panel is shown\n", __func__); +} + +static void +_vkbd_state_off (void *data, Evas_Object *obj, void *event_info) +{ + printf("[%s] input panel is hidden\n", __func__); +} + +static Evas_Object* create_layout_main (Evas_Object *parent) +{ + Evas_Object *layout = elm_layout_add (parent); + elm_layout_theme_set (layout, "layout", "application", "default"); + evas_object_size_hint_weight_set (layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set (layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show (layout); + + /* Put the layout inside conformant for drawing indicator in app side */ + Evas_Object *conformant = elm_conformant_add (parent); + evas_object_size_hint_weight_set (conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set (conformant, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_win_resize_object_add (parent, conformant); + elm_win_conformant_set (parent, EINA_TRUE); + evas_object_show (conformant); + + evas_object_smart_callback_add(conformant, "virtualkeypad,state,on", _vkbd_state_on, NULL); + evas_object_smart_callback_add(conformant, "virtualkeypad,state,off", _vkbd_state_off, NULL); + + elm_object_content_set (conformant, layout); + + return layout; +} + +static Evas_Object* _create_naviframe_layout (Evas_Object *parent) +{ + Evas_Object *naviframe = elm_naviframe_add (parent); + elm_object_part_content_set (parent, "elm.swallow.content", naviframe); + + evas_object_show (naviframe); + + return naviframe; +} + +static Eina_Bool _keydown_event (void *data, int type, void *event) +{ + Ecore_Event_Key *ev = (Ecore_Event_Key *)event; + struct appdata *ad = (struct appdata *)data; + Elm_Object_Item *top_it, *bottom_it; + if (ad == NULL || ev == NULL) return ECORE_CALLBACK_RENEW; + + printf ("[ecore key down] keyname : '%s', key : '%s', string : '%s', compose : '%s'\n", ev->keyname, ev->key, ev->string, ev->compose); + + if (strcmp (ev->keyname, "XF86Stop") == 0) { + if (ug_send_key_event (UG_KEY_EVENT_END) == -1) { + top_it = elm_naviframe_top_item_get (ad->naviframe); + bottom_it = elm_naviframe_top_item_get (ad->naviframe); + if (top_it && bottom_it && (elm_object_item_content_get (top_it) == elm_object_item_content_get (bottom_it))) { + elm_exit (); + } else { + elm_naviframe_item_pop (ad->naviframe); + } + } + } + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool _keyup_event (void *data, int type, void *event) +{ + Ecore_Event_Key *ev = (Ecore_Event_Key *)event; + + printf ("[ecore key up] keyname : '%s', key : '%s', string : '%s', compose : '%s'\n", ev->keyname, ev->key, ev->string, ev->compose); + + return ECORE_CALLBACK_RENEW; +} + +static int app_create (void *data) +{ + struct appdata *ad = (struct appdata *)data; + + appcore_measure_start (); + + ad->win_main = create_win ("isf-demo-efl"); + evas_object_show (ad->win_main); + + ad->evas = evas_object_evas_get (ad->win_main); + /* get width and height of main window */ + evas_object_geometry_get (ad->win_main, NULL, NULL, &ad->root_w, &ad->root_h); + + if (ad->root_w >= 0) { + elm_config_scale_set (ad->root_w / BASE_THEME_WIDTH); + } + + ad->layout_main = create_layout_main (ad->win_main); + + // Indicator + elm_win_indicator_mode_set (ad->win_main, ELM_WIN_INDICATOR_SHOW); + + // Navigation Bar + ad->naviframe = _create_naviframe_layout (ad->layout_main); + + //init the content in layout_main. + create_demo_view (ad); + + lang_changed (ad); + + evas_object_show (ad->win_main); + + /* add system event callback */ + appcore_set_event_callback (APPCORE_EVENT_LANG_CHANGE, + lang_changed, ad); + + ecore_event_handler_add (ECORE_EVENT_KEY_DOWN, _keydown_event, ad); + ecore_event_handler_add (ECORE_EVENT_KEY_UP, _keyup_event, ad); + + appcore_set_rotation_cb (_rotate_cb, ad); + + appcore_measure_time (); + + return 0; +} + +static int app_exit (void *data) +{ + struct appdata *ad = (struct appdata *)data; + if (ad->li != NULL) + evas_object_del (ad->li); + + if (ad->ev_li != NULL) + evas_object_del (ad->ev_li); + + if (ad->layout_main != NULL) + evas_object_del (ad->layout_main); + + if (ad->win_main != NULL) + evas_object_del (ad->win_main); + + return 0; +} + +static int app_pause(void *data) +{ + return 0; +} + +static int app_resume (void *data) +{ + return 0; +} + +int main (int argc, char *argv[]) +{ + set_app_privilege ("isf", NULL, NULL); + + struct appdata ad; + struct appcore_ops ops; + + ops.create = app_create; + ops.terminate = app_exit; + ops.pause = app_pause; + ops.resume = app_resume; + ops.reset = NULL; + + memset (&ad, 0x0, sizeof (struct appdata)); + ops.data = &ad; + + int ret = -1; + try { + ret = appcore_efl_main ("isf-demo-efl", &argc, &argv, &ops); + } catch (...) { + printf ("Exception is thrown from appcore_efl_main ()!!!\n"); + } + + return ret; +} + +static void _focused_cb (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *ly = (Evas_Object *)data; + + elm_object_signal_emit (ly, "elm,state,guidetext,hide", "elm"); +} + +static void _unfocused_cb (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *ly = (Evas_Object *)data; + + if (elm_entry_is_empty (obj)) + elm_object_signal_emit (ly, "elm,state,guidetext,show", "elm"); +} + +// Utility functions +Evas_Object *create_ef (Evas_Object *parent, const char *label, const char *guide_text) +{ + Evas_Object *ef = NULL; + Evas_Object *en = NULL; + + ef = elm_layout_add (parent); + elm_layout_theme_set (ef, "layout", "editfield", "title"); + + en = elm_entry_add (parent); + elm_object_part_content_set (ef, "elm.swallow.content", en); + + elm_object_part_text_set (ef, "elm.text", label); + elm_object_part_text_set (ef, "elm.guidetext", guide_text); + evas_object_size_hint_weight_set (ef, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set (ef, EVAS_HINT_FILL, 0); + evas_object_smart_callback_add (en, "focused", _focused_cb, ef); + evas_object_smart_callback_add (en, "unfocused", _unfocused_cb, ef); + evas_object_show (ef); + + return ef; +} + +void add_layout_to_naviframe (void *data, Evas_Object *lay_in, const char *title) +{ + struct appdata *ad = (struct appdata *) data; + + Evas_Object *scroller = elm_scroller_add (ad->naviframe); + elm_scroller_bounce_set (scroller, EINA_FALSE, EINA_TRUE); + evas_object_show (scroller); + + elm_object_content_set (scroller, lay_in); + elm_naviframe_item_push (ad->naviframe, title, NULL, NULL, scroller, NULL); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_entry_event_efl.cpp b/ism/demos/isf_entry_event_efl.cpp new file mode 100644 index 0000000..4dcd446 --- /dev/null +++ b/ism/demos/isf_entry_event_efl.cpp @@ -0,0 +1,156 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include "isf_demo_efl.h" + + +static Evas_Object * _entry1 = NULL; +static Evas_Object * _entry2 = NULL; +static Evas_Object * _key_event_label = NULL; +static Evas_Object * _preedit_event_label = NULL; +static Evas_Object * _commit_event_label = NULL; +static Ecore_Event_Handler *_preedit_handler = NULL; +static Ecore_Event_Handler *_commit_handler = NULL; + + +static void _input_panel_event_callback (void *data, Ecore_IMF_Context *ctx, int value) +{ + if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) { + printf("[%s] ECORE_IMF_INPUT_PANEL_STATE_SHOW\n", __func__); + } else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + printf("[%s] ECORE_IMF_INPUT_PANEL_STATE_HIDE\n", __func__); + } +} + +static void _evas_key_up_cb (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + static char str [100]; + Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info; + + if (obj == _entry1) { + snprintf (str, sizeof(str),"entry 1 get keyEvent: %s", (char *)(ev->keyname)); + elm_object_text_set (_key_event_label, str); + } else if (obj == _entry2) { + snprintf (str, sizeof(str),"entry 2 get keyEvent: %s", (char *)(ev->keyname)); + elm_object_text_set (_key_event_label, str); + } +} + +static Eina_Bool _ecore_imf_event_changed_cb (void *data, int type, void *event) +{ + int len; + static char str [100]; + char *preedit_string = NULL; + Ecore_IMF_Context *imf_context = NULL; + + if (elm_object_focus_get (_entry1) == EINA_TRUE) { + imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get (_entry1); + ecore_imf_context_preedit_string_get (imf_context, &preedit_string, &len); + snprintf (str,sizeof(str), "entry 1 get preedit string: %s", preedit_string); + elm_object_text_set (_preedit_event_label, str); + } else if (elm_object_focus_get (_entry2) == EINA_TRUE) { + imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get (_entry2); + ecore_imf_context_preedit_string_get (imf_context, &preedit_string, &len); + snprintf (str, sizeof(str),"entry 2 get preedit string: %s", preedit_string); + elm_object_text_set (_preedit_event_label, str); + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool _ecore_imf_event_commit_cb (void *data, int type, void *event) +{ + static char str [100]; + Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event; + + if (elm_object_focus_get (_entry1) == EINA_TRUE) { + snprintf (str,sizeof(str), "entry 1 get commit string: %s",(char *)( ev->str)); + elm_object_text_set (_commit_event_label, str); + } else if (elm_object_focus_get (_entry2) == EINA_TRUE) { + snprintf (str,sizeof(str), "entry 2 get commit string: %s", (char *)(ev->str)); + elm_object_text_set (_commit_event_label, str); + } + return ECORE_CALLBACK_RENEW; +} + +void isf_entry_event_demo_bt (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *layout = NULL; + Ecore_IMF_Context *ic = NULL; + + layout = elm_layout_add (ad->naviframe); + evas_object_size_hint_weight_set (layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show (layout); + + _preedit_handler = ecore_event_handler_add (ECORE_IMF_EVENT_PREEDIT_CHANGED, _ecore_imf_event_changed_cb, NULL); + _commit_handler = ecore_event_handler_add (ECORE_IMF_EVENT_COMMIT, _ecore_imf_event_commit_cb, NULL); + + _entry1 = elm_entry_add (layout); + elm_entry_entry_set (_entry1, "ENTRY 1"); + evas_object_move (_entry1, 0, 100); + evas_object_resize (_entry1, ad->root_w, 50); + evas_object_show (_entry1); + evas_object_event_callback_add (_entry1, EVAS_CALLBACK_KEY_UP, _evas_key_up_cb, (void *)NULL); + + ic = (Ecore_IMF_Context *)elm_entry_imf_context_get (_entry1); + if (ic != NULL) + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, NULL); + + _entry2 = elm_entry_add (layout); + elm_entry_entry_set (_entry2, "ENTRY 2"); + evas_object_move (_entry2, 0, 150); + evas_object_resize (_entry2, ad->root_w, 50); + evas_object_show (_entry2); + evas_object_event_callback_add (_entry2, EVAS_CALLBACK_KEY_UP, _evas_key_up_cb, (void *)NULL); + + ic = (Ecore_IMF_Context *)elm_entry_imf_context_get (_entry2); + if (ic != NULL) + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, NULL); + + _key_event_label = elm_button_add (layout); + elm_object_text_set (_key_event_label, "KEY EVENT"); + evas_object_move (_key_event_label, 0, 200); + evas_object_resize (_key_event_label, ad->root_w, 50); + evas_object_show (_key_event_label); + + _preedit_event_label = elm_button_add (layout); + elm_object_text_set (_preedit_event_label, "PREEDIT EVENT"); + evas_object_move (_preedit_event_label, 0, 250); + evas_object_resize (_preedit_event_label, ad->root_w, 50); + evas_object_show (_preedit_event_label); + + _commit_event_label = elm_button_add (layout); + elm_object_text_set (_commit_event_label, "COMMIT EVENT"); + evas_object_move (_commit_event_label, 0, 300); + evas_object_resize (_commit_event_label, ad->root_w, 50); + evas_object_show (_commit_event_label); + + elm_naviframe_item_push (ad->naviframe, _("Entry Event"), NULL, NULL, layout, NULL); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_event_efl.cpp b/ism/demos/isf_event_efl.cpp new file mode 100644 index 0000000..260ded6 --- /dev/null +++ b/ism/demos/isf_event_efl.cpp @@ -0,0 +1,267 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" + + +static Ecore_IMF_Context* _imf_context[2]; +static Evas_Object *_label1 = NULL; +static Evas_Object *_label2 = NULL; +static Evas_Object *_key_event_label = NULL; +static Evas_Object *_preedit_event_label = NULL; +static Evas_Object *_commit_event_label = NULL; +static Evas_Object *_set_focus_button1 = NULL; +static Evas_Object *_set_focus_button2 = NULL; +static Evas_Object *_ise_show_button = NULL; +static Ecore_Event_Handler *_preedit_handler = NULL; +static Ecore_Event_Handler *_commit_handler = NULL; +static int focus_label_idx = 1; + + +void isf_entry_event_demo_bt (void *data, Evas_Object *obj, void *event_info); + + +static void _set_focus_button_bt (void *data, Evas_Object *obj, void *event_info) +{ + int i = (int) data; + + focus_label_idx = i; + + ecore_imf_context_focus_in (_imf_context[i-1]); +} + +static void _button_bt (void *data, Evas_Object *obj, void *event_info) +{ + if (_imf_context[focus_label_idx-1] != NULL) + ecore_imf_context_input_panel_show (_imf_context[focus_label_idx-1]); +} + +static void _key_up_cb (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + static char str [100]; + Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info; + + if (obj == _label1) { + snprintf (str, sizeof(str),"label 1 get key up event: %s", (char *)(ev->keyname)); + elm_object_text_set (_key_event_label, str); + } else if (obj == _label2) { + snprintf (str,sizeof(str), "label 2 get key up event: %s", (char *)(ev->keyname)); + elm_object_text_set (_key_event_label, str); + } +} + +static void _key_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + static char str [100]; + Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info; + + if (obj == _label1) { + snprintf (str, sizeof(str), "label 1 get key down event: %s", (char *)(ev->keyname)); + elm_object_text_set (_key_event_label, str); + } else if (obj == _label2) { + snprintf (str, sizeof(str),"label 2 get key down event: %s", (char *)(ev->keyname)); + elm_object_text_set (_key_event_label, str); + } +} + +static Eina_Bool _ecore_imf_event_changed_cb (void *data, int type, void *event) +{ + static char str [100]; + + char *preedit_string = NULL; + preedit_string = (char *)malloc (sizeof (char)*70); + int cursor_pos; + + ecore_imf_context_preedit_string_get (_imf_context[focus_label_idx-1], &preedit_string, &cursor_pos); + + if (preedit_string == NULL) + return ECORE_CALLBACK_CANCEL; + + snprintf (str,sizeof(str), "label %d get preedit string: %s", focus_label_idx, preedit_string); + + free (preedit_string); + elm_object_text_set (_preedit_event_label, str); + + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool _ecore_imf_event_commit_cb (void *data, int type, void *event) +{ + static char str [100]; + Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event; + + snprintf (str,sizeof(str), "label %d get commit string: %s", focus_label_idx, (char *)(ev->str)); + elm_object_text_set (_commit_event_label, str); + return ECORE_CALLBACK_CANCEL; +} + +static void nf_back_event_cb (void *data, Evas_Object *obj, void *event_info) +{ + evas_object_event_callback_del (_label1, EVAS_CALLBACK_KEY_UP, NULL); + evas_object_event_callback_del (_label2, EVAS_CALLBACK_KEY_UP, NULL); + + for(int i = 0; i < 2; i++) + { + if (_imf_context[i]) { + ecore_imf_context_del(_imf_context[i]); + _imf_context[i] = NULL; + } + } + + if (_preedit_handler != NULL) { + ecore_event_handler_del (_preedit_handler); + _preedit_handler = NULL; + } + + if (_commit_handler != NULL) { + ecore_event_handler_del (_commit_handler); + _commit_handler = NULL; + } +} + +static void isf_label_event_demo_bt (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *layout = NULL; + Evas *evas = NULL; + Ecore_Window ecore_win; + + layout = elm_layout_add (ad->naviframe); + evas_object_size_hint_weight_set (layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show (layout); + + evas = evas_object_evas_get(ad->win_main); + ecore_win = ecore_evas_window_get(ecore_evas_ecore_evas_get(evas)); + + const char *ctx_id = ecore_imf_context_default_id_get (); + + /* register preedit (composing) event handler */ + _preedit_handler = ecore_event_handler_add (ECORE_IMF_EVENT_PREEDIT_CHANGED, _ecore_imf_event_changed_cb, NULL); + /* register commit event handler */ + _commit_handler = ecore_event_handler_add (ECORE_IMF_EVENT_COMMIT, _ecore_imf_event_commit_cb, NULL); + + /* create label2 */ + _label1 = elm_label_add (layout); + elm_object_text_set (_label1, "LABEL 1"); + evas_object_move (_label1, 0, 100); + evas_object_resize (_label1, ad->root_w, 50); + evas_object_show (_label1); + evas_object_event_callback_add (_label1, EVAS_CALLBACK_KEY_UP, _key_up_cb, (void *)NULL); + evas_object_event_callback_add (_label1, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, (void *)NULL); + + /* create input context for label1 */ + _imf_context[0] = ecore_imf_context_add (ctx_id); + ecore_imf_context_client_window_set (_imf_context[0], (void *)ecore_win); + ecore_imf_context_client_canvas_set (_imf_context[0], evas_object_evas_get(_label1)); + ecore_imf_context_focus_in (_imf_context[0]); + + /* create label2 */ + _label2 = elm_label_add (layout); + elm_object_text_set (_label2, "LABEL 2"); + evas_object_move (_label2, 0, 150); + evas_object_resize (_label2, ad->root_w, 50); + evas_object_show (_label2); + evas_object_event_callback_add (_label2, EVAS_CALLBACK_KEY_UP, _key_up_cb, (void *)NULL); + evas_object_event_callback_add (_label2, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, (void *)NULL); + + /* create input context for label2 */ + _imf_context[1] = ecore_imf_context_add (ctx_id); + ecore_imf_context_client_window_set (_imf_context[1], (void *)ecore_win); + ecore_imf_context_client_canvas_set (_imf_context[1], evas_object_evas_get (_label2)); + + _key_event_label = elm_button_add (layout); + elm_object_text_set (_key_event_label, "KEY EVENT"); + evas_object_move (_key_event_label, 0, 200); + evas_object_resize (_key_event_label, ad->root_w, 50); + evas_object_show (_key_event_label); + + _preedit_event_label = elm_button_add (layout); + elm_object_text_set (_preedit_event_label, "PREEDIT EVENT"); + evas_object_move (_preedit_event_label, 0, 250); + evas_object_resize (_preedit_event_label, ad->root_w, 50); + evas_object_show (_preedit_event_label); + + _commit_event_label = elm_button_add (layout); + elm_object_text_set (_commit_event_label, "COMMIT EVENT"); + evas_object_move (_commit_event_label, 0, 300); + evas_object_resize (_commit_event_label, ad->root_w, 50); + evas_object_show (_commit_event_label); + + _set_focus_button1 = elm_button_add (layout); + elm_object_text_set (_set_focus_button1, "SET FOCUS TO LABEL 1"); + evas_object_move (_set_focus_button1, 0, 350); + evas_object_resize (_set_focus_button1, ad->root_w, 50); + evas_object_show (_set_focus_button1); + evas_object_smart_callback_add (_set_focus_button1, "clicked", _set_focus_button_bt, (void *)1); + + _set_focus_button2 = elm_button_add (layout); + elm_object_text_set (_set_focus_button2, "SET FOCUS TO LABEL 2"); + evas_object_move (_set_focus_button2, 0, 400); + evas_object_resize (_set_focus_button2, ad->root_w, 50); + evas_object_show (_set_focus_button2); + evas_object_smart_callback_add (_set_focus_button2, "clicked", _set_focus_button_bt, (void *)2); + + _ise_show_button = elm_button_add (layout); + elm_object_text_set (_ise_show_button, "ISE SHOW"); + evas_object_move (_ise_show_button, 0, 450); + evas_object_resize (_ise_show_button, ad->root_w, 50); + evas_object_show (_ise_show_button); + evas_object_smart_callback_add (_ise_show_button, "clicked", _button_bt, NULL); + + Elm_Object_Item *it = elm_naviframe_item_push (ad->naviframe, _("Label Event"), NULL, NULL, layout, NULL); + Evas_Object *back_btn = elm_object_item_part_content_get (it, "prev_btn"); + evas_object_smart_callback_add (back_btn, "clicked", nf_back_event_cb, ad); +} + +static void _list_click (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + if (ad == NULL) return; + + Evas_Object *li = ad->ev_li; + if (li == NULL) return; + + Elm_Object_Item *it = (Elm_Object_Item *)elm_list_selected_item_get (li); + + if (it != NULL) + elm_list_item_selected_set (it, EINA_FALSE); +} + +void isf_event_demo_bt (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + + ad->ev_li = elm_list_add (ad->naviframe); + elm_list_mode_set (ad->ev_li, ELM_LIST_COMPRESS); + evas_object_smart_callback_add (ad->ev_li, "selected", _list_click, ad); + elm_list_item_append (ad->ev_li, "Label Event", NULL, NULL, isf_label_event_demo_bt, ad); + elm_list_item_append (ad->ev_li, "Entry Event", NULL, NULL, isf_entry_event_demo_bt, ad); + elm_list_go (ad->ev_li); + + elm_naviframe_item_push (ad->naviframe, _("Event"), NULL, NULL, ad->ev_li, NULL); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_focus_movement_efl.cpp b/ism/demos/isf_focus_movement_efl.cpp new file mode 100644 index 0000000..2bdf113 --- /dev/null +++ b/ism/demos/isf_focus_movement_efl.cpp @@ -0,0 +1,97 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" + +static void +_entry_activated_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *parent = (Evas_Object *)data; + elm_object_focus_next (parent, ELM_FOCUS_NEXT); +} + +static Evas_Object *create_entry (Evas_Object *parent, const char *text, Elm_Input_Panel_Layout layout) +{ + Evas_Object *en; + en = elm_entry_add (parent); + evas_object_size_hint_weight_set (en, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (en, EVAS_HINT_FILL, 0.5); + elm_entry_input_panel_layout_set (en, layout); + elm_entry_single_line_set (en, EINA_TRUE); + elm_entry_input_panel_return_key_type_set (en, ELM_INPUT_PANEL_RETURN_KEY_TYPE_NEXT); + elm_object_text_set (en, text); + evas_object_smart_callback_add (en, "activated", _entry_activated_cb, parent); + evas_object_show (en); + + return en; +} + +static Evas_Object * create_inner_layout (void *data) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *bx = NULL; + Evas_Object *parent = ad->naviframe; + Evas_Object *en = NULL; + + bx = elm_box_add (parent); + evas_object_size_hint_weight_set (bx, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (bx, EVAS_HINT_FILL, 0.0); + evas_object_show (bx); + + /* First Name */ + en = create_entry (bx, "James", ELM_INPUT_PANEL_LAYOUT_NORMAL); + elm_box_pack_end (bx, en); + + /* Last Name */ + en = create_entry (bx, "Bond", ELM_INPUT_PANEL_LAYOUT_NORMAL); + elm_box_pack_end (bx, en); + + /* Phonenumber */ + en = create_entry (bx, "010-1234-5678", ELM_INPUT_PANEL_LAYOUT_PHONENUMBER); + elm_box_pack_end (bx, en); + + /* Email */ + en = create_entry (bx, "hell@hello.com", ELM_INPUT_PANEL_LAYOUT_EMAIL); + elm_box_pack_end (bx, en); + + /* Birthday */ + en = create_entry (bx, "801225", ELM_INPUT_PANEL_LAYOUT_NUMBER); + elm_box_pack_end (bx, en); + + /* Homepage */ + en = create_entry (bx, "hello.com", ELM_INPUT_PANEL_LAYOUT_URL); + elm_box_pack_end (bx, en); + + return bx; +} + +void isf_focus_movement_bt (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *lay_inner = create_inner_layout (data); + add_layout_to_naviframe (data, lay_inner, _("Focus Movement")); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_imcontrol_efl.cpp b/ism/demos/isf_imcontrol_efl.cpp new file mode 100644 index 0000000..8d8d5b3 --- /dev/null +++ b/ism/demos/isf_imcontrol_efl.cpp @@ -0,0 +1,244 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" + +static Ecore_IMF_Context *imf_context = NULL; +static Elm_Genlist_Item_Class itci; + +enum { + INPUT_PANEL_GEOMETRY_GET, + INPUT_PANEL_SHOW, + INPUT_PANEL_HIDE, + INPUT_PANEL_IMDATA_SET, + INPUT_PANEL_IMDATA_GET, + INPUT_PANEL_LAYOUT_SET, + INPUT_PANEL_LAYOUT_GET, + INPUT_PANEL_STATE_GET, + CONTROL_PANEL_SHOW, + CONTROL_PANEL_HIDE, +}; + +const char *api_list[]={ + "PANEL GEOMETRY GET", + "INPUT PANEL SHOW", + "INPUT PANEL HIDE", + "INPUT PANEL IMDATA SET", + "INPUT PANEL IMDATA GET", + "INPUT PANEL LAYOUT SET", + "INPUT PANEL LAYOUT GET", + "INPUT PANEL STATE GET", + "CTRL PANEL SHOW", + "CTRL PANEL HIDE", +}; + +static void test_input_panel_geometry_get (void *data, Evas_Object *obj, void *event_info) +{ + int x, y, w, h; + if (imf_context != NULL) { + ecore_imf_context_input_panel_geometry_get (imf_context, &x, &y, &w, &h); + printf ("x=%d \n", x); + printf ("y=%d \n", y); + printf ("width=%d \n", w); + printf ("height=%d \n", h); + } +} + +void test_input_panel_show (void *data, Evas_Object *obj, void *event_info) +{ + if (imf_context != NULL) { + ecore_imf_context_focus_in (imf_context); + ecore_imf_context_input_panel_show (imf_context); + } +} + +void test_input_panel_hide (void *data, Evas_Object *obj, void *event_info) +{ + if (imf_context != NULL) { + ecore_imf_context_focus_out (imf_context); + ecore_imf_context_input_panel_hide (imf_context); + } +} + +void test_input_panel_imdata_set (void *data, Evas_Object *obj, void *event_info) +{ + // need ISE to deal with the data + char buf[256] = "ur imdata"; + if (imf_context != NULL) + ecore_imf_context_input_panel_imdata_set (imf_context, buf, sizeof (buf)); +} + +void test_input_panel_imdata_get (void *data, Evas_Object *obj, void *event_info) +{ + int len = 256; + char* buf = (char*) malloc (len); + if (buf != NULL) { + memset (buf, '\0', len); + if (imf_context != NULL) { + ecore_imf_context_input_panel_imdata_get (imf_context, buf, &len); + printf ("get imdata %s, and len is %d ...\n", (char *)buf, len); + } + free (buf); + } +} + +void test_input_panel_layout_set (void *data, Evas_Object *obj, void *event_info) +{ + Ecore_IMF_Input_Panel_Layout layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL; + if (imf_context != NULL) + ecore_imf_context_input_panel_layout_set (imf_context, layout); +} + +void test_input_panel_layout_get (void *data, Evas_Object *obj, void *event_info) +{ + Ecore_IMF_Input_Panel_Layout layout; + if (imf_context != NULL) { + layout = ecore_imf_context_input_panel_layout_get (imf_context); + printf ("get layout : %d ...\n", (int)layout); + } +} + +void test_input_panel_state_get (void *data, Evas_Object *obj, void *event_info) +{ + Ecore_IMF_Input_Panel_State state; + + if (imf_context != NULL) { + state = ecore_imf_context_input_panel_state_get (imf_context); + printf ("ise state : %d \n", (int)state); + } +} + +void test_control_panel_show (void *data, Evas_Object *obj, void *event_info) +{ + if (imf_context != NULL) { + ecore_imf_context_control_panel_show (imf_context); + } +} + +void test_control_panel_hide (void *data, Evas_Object *obj, void *event_info) +{ + if (imf_context != NULL) { + ecore_imf_context_control_panel_hide (imf_context); + } +} + +char *gli_label_get (void *data, Evas_Object *obj, const char *part) +{ + int j = (int)data; + return strdup (api_list[j]); +} + +static void test_api (void *data, Evas_Object *obj, void *event_info) +{ + int j = (int)data; + switch (j) { + case INPUT_PANEL_GEOMETRY_GET: + test_input_panel_geometry_get (NULL, obj, event_info); + break; + case INPUT_PANEL_SHOW: + test_input_panel_show (NULL, obj, event_info); + break; + case INPUT_PANEL_HIDE: + test_input_panel_hide (NULL, obj, event_info); + break; + case INPUT_PANEL_IMDATA_SET: + test_input_panel_imdata_set (NULL,obj, event_info); + break; + case INPUT_PANEL_IMDATA_GET: + test_input_panel_imdata_get (NULL,obj, event_info); + break; + case INPUT_PANEL_LAYOUT_SET: + test_input_panel_layout_set (NULL,obj, event_info); + break; + case INPUT_PANEL_LAYOUT_GET: + test_input_panel_layout_get (NULL,obj, event_info); + break; + case INPUT_PANEL_STATE_GET: + test_input_panel_state_get (NULL, obj, event_info); + break; + case CONTROL_PANEL_SHOW: + test_control_panel_show (NULL, obj, event_info); + break; + case CONTROL_PANEL_HIDE: + test_control_panel_hide (NULL, obj, event_info); + break; + default: + break; + } +} + +static void _nf_back_event (void *data, Evas_Object *obj, void *event_info) +{ + if (imf_context) { + ecore_imf_context_del(imf_context); + imf_context = NULL; + } +} + +static Evas_Object *_create_imcontrolapi_list (Evas_Object *parent) +{ + int i, num; + + Evas_Object *gl = elm_genlist_add (parent); + + itci.item_style = "default"; + itci.func.text_get = gli_label_get; + itci.func.content_get = NULL; + itci.func.state_get = NULL; + itci.func.del = NULL; + + num = sizeof (api_list) / sizeof (char *); + for (i = 0; i < num; i++) { + elm_genlist_item_append (gl, &itci, + (void *)i/* item data */, NULL/* parent */, ELM_GENLIST_ITEM_NONE, test_api/* func */, + (void *)i/* func data */); + } + + return gl; +} + +void imcontrolapi_bt (void *data, Evas_Object *obj, void *event_info) +{ + const char *ctx_id = ecore_imf_context_default_id_get (); + if (ctx_id != NULL) { + imf_context = ecore_imf_context_add (ctx_id); + } else { + printf ("Cannot create imf context\n"); + return; + } + + struct appdata *ad = (struct appdata *)data; + Evas_Object *gl = NULL; + + gl = _create_imcontrolapi_list (ad->naviframe); + + Elm_Object_Item *navi_it = elm_naviframe_item_push (ad->naviframe, _("IM Control"), NULL, NULL, gl, NULL); + + Evas_Object *back_btn = elm_object_item_part_content_get (navi_it, "prev_btn"); + evas_object_smart_callback_add (back_btn, "clicked", _nf_back_event, ad); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_imdata_set_efl.cpp b/ism/demos/isf_imdata_set_efl.cpp new file mode 100644 index 0000000..08e1fab --- /dev/null +++ b/ism/demos/isf_imdata_set_efl.cpp @@ -0,0 +1,72 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" +#include "isf_imdata_set_efl.h" + + +static Evas_Object *_create_ef_layout (Evas_Object *parent, const char *label, const char *guide_text) +{ + Evas_Object *ef = create_ef (parent, label, guide_text); + return ef; +} + +static Evas_Object * create_inner_layout (void *data) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *bx = NULL; + Evas_Object *ef = NULL; + Evas_Object *en = NULL; + + Evas_Object *parent = ad->naviframe; + const char *imdata_ko = "LANG:ko_KR"; + const char *imdata_en = "LANG:en_US"; + + bx = elm_box_add (parent); + evas_object_size_hint_weight_set (bx, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (bx, EVAS_HINT_FILL, 0.0); + evas_object_show (bx); + + ef = _create_ef_layout (parent, _("ko_KR"), _("Korean Layout")); + elm_box_pack_end (bx, ef); + en = elm_object_part_content_get (ef, "elm.swallow.content"); + elm_entry_input_panel_imdata_set (en, imdata_ko, strlen (imdata_ko)); + + ef = _create_ef_layout (parent, _("en_US"), _("English layout")); + elm_box_pack_end (bx, ef); + en = elm_object_part_content_get (ef, "elm.swallow.content"); + elm_entry_input_panel_imdata_set (en, imdata_en, strlen (imdata_en)); + + return bx; +} + +void ise_imdata_set_bt (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *lay_inner = create_inner_layout (data); + add_layout_to_naviframe (data, lay_inner, _("IM Data")); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_layout_efl.cpp b/ism/demos/isf_layout_efl.cpp new file mode 100644 index 0000000..31ed012 --- /dev/null +++ b/ism/demos/isf_layout_efl.cpp @@ -0,0 +1,263 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" +#include "isf_layout_efl.h" +#include + +static void _rotate_cb (void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + + int angle = elm_win_rotation_get (ad->win_main); + if (angle == 0) { + elm_win_rotation_with_resize_set (ad->win_main, 270); + } else if (angle == 270) { + elm_win_rotation_with_resize_set (ad->win_main, 0); + } +} + +static void _input_panel_state_cb (void *data, Ecore_IMF_Context *ctx, int value) +{ + int x, y, w, h; + + if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) { + ecore_imf_context_input_panel_geometry_get (ctx, &x, &y, &w, &h); + printf ("[%s] Input panel is shown. ctx : %p\n", __func__, ctx); + printf ("x : %d, y : %d, w : %d, h : %d\n", x, y, w, h); + } else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + printf ("[%s] Input panel is hidden. ctx : %p\n", __func__, ctx); + } else if (value == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW) { + printf ("[%s] Input panel will be shown. ctx : %p\n", __func__, ctx); + } +} + +static void _input_panel_resize_cb (void *data, Ecore_IMF_Context *ctx, int value) +{ + int x, y, w, h; + + ecore_imf_context_input_panel_geometry_get (ctx, &x, &y, &w, &h); + printf ("[%s] x : %d, y : %d, w : %d, h : %d\n", __func__, x, y, w, h); +} + +static void _shift_mode_cb (void *data, Ecore_IMF_Context *ctx, int value) +{ + if (value == ECORE_IMF_INPUT_PANEL_SHIFT_MODE_OFF) { + printf ("[%s] Shift Mode : OFF\n", __func__); + } else if (value == ECORE_IMF_INPUT_PANEL_SHIFT_MODE_ON) { + printf ("[%s] Shift Mode : ON\n", __func__); + } +} + +static void _language_changed_cb (void *data, Ecore_IMF_Context *ctx, int value) +{ + char *locale; + + ecore_imf_context_input_panel_language_locale_get(ctx, &locale); + + printf ("[%s] language : %s\n", __func__, locale); + + if (locale) + free (locale); +} + +static void _candidate_panel_state_cb (void *data, Ecore_IMF_Context *ctx, int value) +{ + int x, y, w, h; + + if (value == ECORE_IMF_CANDIDATE_PANEL_SHOW) { + ecore_imf_context_candidate_panel_geometry_get (ctx, &x, &y, &w, &h); + printf ("[%s] Candidate window is shown\n", __func__); + printf ("[%s] x : %d, y : %d, w : %d, h : %d\n", __func__, x, y, w, h); + } else if (value == ECORE_IMF_CANDIDATE_PANEL_HIDE) { + printf ("[%s] Candidate window is hidden\n", __func__); + } +} + +static void _candidate_panel_geometry_changed_cb (void *data, Ecore_IMF_Context *ctx, int value) +{ + int x, y, w, h; + + ecore_imf_context_candidate_panel_geometry_get (ctx, &x, &y, &w, &h); + printf ("[%s] ctx : %p, x : %d, y : %d, w : %d, h : %d\n", __func__, ctx, x, y, w, h); +} + +static void +_key_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Key_Down *ev = (Evas_Event_Key_Down *)event_info; + printf ("[evas key down] keyname : '%s', key : '%s', string : '%s', compose : '%s'\n", ev->keyname, ev->key, ev->string, ev->compose); +} + +static void +_key_up_cb (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *)event_info; + printf ("[evas key up] keyname : '%s', key : '%s', string : '%s', compose : '%s'\n", ev->keyname, ev->key, ev->string, ev->compose); +} + +static void +_print_keyboard_geometry (Ecore_X_Window xwin) +{ + int sx, sy, sw, sh; + Ecore_X_Window zone; + + zone = ecore_x_e_illume_zone_get (xwin); + + if (!ecore_x_e_illume_keyboard_geometry_get (zone, &sx, &sy, &sw, &sh)) + sx = sy = sw = sh = 0; + + printf ("Keyboard geometry x : %d, y : %d, w : %d, h : %d\n", sx, sy, sw, sh); +} + +static Eina_Bool +_prop_change (void *data, int type, void *event) +{ + Ecore_X_Event_Window_Property *ev; + Ecore_X_Virtual_Keyboard_State vkb_state; + + ev = (Ecore_X_Event_Window_Property *)event; + + if (ev->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE) { + printf ("[ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE] "); + _print_keyboard_geometry (ev->win); + } else if (ev->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY) { + printf ("[ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY] "); + _print_keyboard_geometry (ev->win); + } + + return ECORE_CALLBACK_PASS_ON; +} + +static void entry_changed_cb(void *data, Evas_Object *obj, void *event_info) +{ + printf("[%s]\n", __func__); +} + +static void entry_preedit_changed_cb(void *data, Evas_Object *obj, void *event_info) +{ + printf("[%s]\n", __func__); +} + +static Evas_Object *_create_ef_layout(Evas_Object *parent, const char *label, const char *guide_text,Elm_Input_Panel_Layout layout) +{ + Evas_Object *ef = create_ef (parent, label, guide_text); + Ecore_IMF_Context *ic = NULL; + Evas_Object *en = elm_object_part_content_get (ef, "elm.swallow.content"); + elm_entry_input_panel_layout_set (en, layout); + evas_object_event_callback_add (en, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, NULL); + evas_object_event_callback_add (en, EVAS_CALLBACK_KEY_UP, _key_up_cb, NULL); + evas_object_smart_callback_add (en, "changed", entry_changed_cb, NULL); + evas_object_smart_callback_add (en, "preedit,changed", entry_preedit_changed_cb, NULL); + + ic = (Ecore_IMF_Context *)elm_entry_imf_context_get (en); + + if (ic != NULL) { + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_state_cb, NULL); + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, _input_panel_resize_cb, NULL); + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_INPUT_PANEL_SHIFT_MODE_EVENT, _shift_mode_cb, NULL); + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, _language_changed_cb, NULL); + + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_CANDIDATE_PANEL_STATE_EVENT, _candidate_panel_state_cb, NULL); + ecore_imf_context_input_panel_event_callback_add (ic, ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT, _candidate_panel_geometry_changed_cb, NULL); + } + + return ef; +} + +static Evas_Object * create_inner_layout (void *data) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *bx = NULL; + Evas_Object *ef = NULL; + Evas_Object *parent = ad->naviframe; + + bx = elm_box_add (parent); + evas_object_size_hint_weight_set (bx, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (bx, EVAS_HINT_FILL, 0.0); + evas_object_show (bx); + + /* Normal Layout */ + ef = _create_ef_layout (parent, _("NORMAL LAYOUT"), _("click to enter TEXT"), ELM_INPUT_PANEL_LAYOUT_NORMAL); + elm_box_pack_end (bx, ef); + + /* Number Layout */ + ef = _create_ef_layout (parent, _("NUMBER LAYOUT"), _("click to enter NUMBER"), ELM_INPUT_PANEL_LAYOUT_NUMBER); + elm_box_pack_end (bx, ef); + + /* Email Layout */ + ef = _create_ef_layout (parent, _("EMAIL LAYOUT"), _("click to enter EMAIL"), ELM_INPUT_PANEL_LAYOUT_EMAIL); + elm_box_pack_end (bx, ef); + + /* URL Layout */ + ef = _create_ef_layout (parent, _("URL LAYOUT"), _("click to enter URL"), ELM_INPUT_PANEL_LAYOUT_URL); + elm_box_pack_end (bx, ef); + + /* Phonenumber Layout */ + ef = _create_ef_layout (parent, _("PHONENUMBER LAYOUT"), _("click to enter PHONENUMBER"), ELM_INPUT_PANEL_LAYOUT_PHONENUMBER); + elm_box_pack_end (bx, ef); + + /* IP Layout */ + ef = _create_ef_layout (parent, _("IP LAYOUT"), _("click to enter IP"), ELM_INPUT_PANEL_LAYOUT_IP); + elm_box_pack_end (bx, ef); + + /* Month Layout */ + ef = _create_ef_layout (parent, _("MONTH LAYOUT"), _("click to enter MONTH"), ELM_INPUT_PANEL_LAYOUT_MONTH); + elm_box_pack_end (bx, ef); + + /* Number Only Layout */ + ef = _create_ef_layout (parent, _("NUMBERONLY LAYOUT"), _("click to enter NUMBERONLY"), ELM_INPUT_PANEL_LAYOUT_NUMBERONLY); + elm_box_pack_end (bx, ef); + + /* Password Layout */ + ef = _create_ef_layout (parent, _("PASSWORD LAYOUT"), _("click to enter PASSWORD"), ELM_INPUT_PANEL_LAYOUT_PASSWORD); + elm_box_pack_end (bx, ef); + + /* Terminal Layout */ + ef = _create_ef_layout (parent, _("TERMINAL LAYOUT"), _("click to enter TERMINAL"), ELM_INPUT_PANEL_LAYOUT_TERMINAL); + elm_box_pack_end (bx, ef); + + /* Click to rotate button */ + Evas_Object *rotate_btn = elm_button_add (parent); + elm_object_text_set (rotate_btn, "rotate"); + evas_object_smart_callback_add (rotate_btn, "clicked", _rotate_cb, (void *)ad); + evas_object_size_hint_weight_set (rotate_btn, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (rotate_btn, EVAS_HINT_FILL, 0); + evas_object_show (rotate_btn); + elm_box_pack_end (bx, rotate_btn); + + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, NULL); + + return bx; +} + +void ise_layout_bt (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *lay_inner = create_inner_layout (data); + add_layout_to_naviframe (data, lay_inner, _("Layout")); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_prediction_efl.cpp b/ism/demos/isf_prediction_efl.cpp new file mode 100644 index 0000000..93b8baf --- /dev/null +++ b/ism/demos/isf_prediction_efl.cpp @@ -0,0 +1,69 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" +#include "isf_prediction_efl.h" + +static Evas_Object *_create_ef_layout (Evas_Object *parent, const char *label, const char *guide_text, Eina_Bool allow) +{ + Evas_Object *ef = create_ef (parent, label, guide_text); + Evas_Object *en = elm_object_part_content_get (ef, "elm.swallow.content"); + elm_entry_prediction_allow_set (en, allow); + + return ef; +} + +static Evas_Object * create_inner_layout (void *data) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *bx = NULL; + Evas_Object *ef = NULL; + + Evas_Object *parent = ad->naviframe; + + bx = elm_box_add (parent); + evas_object_size_hint_weight_set (bx, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (bx, EVAS_HINT_FILL, 0.0); + evas_object_show (bx); + + /* Prediction allow : TRUE */ + ef = _create_ef_layout (parent, _("Prediction Allow : TRUE"), _("click to enter"), EINA_TRUE); + elm_box_pack_end (bx, ef); + + /* Prediction allow : FALSE */ + ef = _create_ef_layout (parent, _("Prediction Allow : FALSE"), _("click to enter"), EINA_FALSE); + elm_box_pack_end (bx, ef); + + return bx; +} + +void ise_prediction_bt (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *lay_inner = create_inner_layout (data); + add_layout_to_naviframe (data, lay_inner, _("Prediction Allow")); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_return_key_disable_efl.cpp b/ism/demos/isf_return_key_disable_efl.cpp new file mode 100644 index 0000000..578a5e6 --- /dev/null +++ b/ism/demos/isf_return_key_disable_efl.cpp @@ -0,0 +1,80 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" +#include "isf_return_key_disable_efl.h" + +static void +_cursor_changed_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *en = obj; + + int pos = elm_entry_cursor_pos_get (en); + + if (pos == 0) { + elm_entry_input_panel_return_key_disabled_set (en, EINA_TRUE); + } + else { + elm_entry_input_panel_return_key_disabled_set (en, EINA_FALSE); + } +} + +static Evas_Object *_create_ef_layout (Evas_Object *parent, const char *label, const char *guide_text) +{ + Evas_Object *ef = create_ef (parent, label, guide_text); + Evas_Object *en = elm_object_part_content_get (ef, "elm.swallow.content"); + evas_object_smart_callback_add (en, "cursor,changed", _cursor_changed_cb, NULL); + + return ef; +} + +static Evas_Object * create_inner_layout (void *data) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *bx = NULL; + Evas_Object *ef = NULL; + + Evas_Object *parent = ad->naviframe; + + bx = elm_box_add (parent); + evas_object_size_hint_weight_set (bx, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (bx, EVAS_HINT_FILL, 0.0); + evas_object_show (bx); + + /* Prediction allow : TRUE */ + ef = _create_ef_layout (parent, _("Return Key Disable"), _("Return Key will be activated when any key is pressed")); + elm_box_pack_end (bx, ef); + + return bx; +} + +void ise_return_key_disable_bt (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *lay_inner = create_inner_layout (data); + add_layout_to_naviframe (data, lay_inner, _("Return Key Disable")); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/demos/isf_return_key_type_efl.cpp b/ism/demos/isf_return_key_type_efl.cpp new file mode 100644 index 0000000..2a3451b --- /dev/null +++ b/ism/demos/isf_return_key_type_efl.cpp @@ -0,0 +1,98 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "isf_demo_efl.h" +#include "isf_return_key_type_efl.h" + + +static Evas_Object *_create_ef_layout (Evas_Object *parent, const char *label, const char *guide_text, Elm_Input_Panel_Return_Key_Type type) +{ + Evas_Object *ef = create_ef (parent, label, guide_text); + Evas_Object *en = elm_object_part_content_get (ef, "elm.swallow.content"); + elm_entry_input_panel_return_key_type_set (en, type); + + return ef; +} + +static Evas_Object * create_inner_layout (void *data) +{ + struct appdata *ad = (struct appdata *)data; + Evas_Object *bx = NULL; + Evas_Object *ef = NULL; + + Evas_Object *parent = ad->naviframe; + + bx = elm_box_add (parent); + evas_object_size_hint_weight_set (bx, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set (bx, EVAS_HINT_FILL, 0.0); + evas_object_show (bx); + + /* DEFAULT */ + ef = _create_ef_layout (parent, _("DEFAULT"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT); + elm_box_pack_end (bx, ef); + + /* DONE */ + ef = _create_ef_layout (parent, _("DONE"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE); + elm_box_pack_end (bx, ef); + + /* GO */ + ef = _create_ef_layout (parent, _("GO"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_GO); + elm_box_pack_end (bx, ef); + + /* JOIN */ + ef = _create_ef_layout (parent, _("JOIN"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_JOIN); + elm_box_pack_end (bx, ef); + + /* LOGIN */ + ef = _create_ef_layout (parent, _("LOGIN"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN); + elm_box_pack_end (bx, ef); + + /* NEXT */ + ef = _create_ef_layout (parent, _("NEXT"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_NEXT); + elm_box_pack_end (bx, ef); + + /* SEARCH */ + ef = _create_ef_layout (parent, _("SEARCH"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH); + elm_box_pack_end (bx, ef); + + /* SEND */ + ef = _create_ef_layout (parent, _("SEND"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_SEND); + elm_box_pack_end (bx, ef); + + /* SIGNIN */ + ef = _create_ef_layout (parent, _("SIGNIN"), _("click to enter"), ELM_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN); + elm_box_pack_end (bx, ef); + + return bx; +} + +void ise_return_key_type_bt (void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *lay_inner = create_inner_layout (data); + add_layout_to_naviframe (data, lay_inner, _("Return Key Type")); +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/Makefile.am b/ism/extras/Makefile.am new file mode 100644 index 0000000..3a91645 --- /dev/null +++ b/ism/extras/Makefile.am @@ -0,0 +1,21 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +SUBDIRS = gtk_panel gtk2_immodule efl_panel efl_immodule efl_setting diff --git a/ism/extras/efl_immodule/Makefile.am b/ism/extras/efl_immodule/Makefile.am new file mode 100644 index 0000000..d79f664 --- /dev/null +++ b/ism/extras/efl_immodule/Makefile.am @@ -0,0 +1,53 @@ +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/utils \ + -I$(includedir) \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" \ + -DSCIM_KEYBOARD_ICON_FILE=\"@SCIM_ICONDIR@/keyboard.png\" + +if ISF_BUILD_EFL_IMMODULE +CONFIG_EFL_IMMODULE = libisf-imf-module.la +endif + +noinst_HEADERS = isf_imf_context.h \ + isf_imf_control_ui.h \ + isf_imf_control.h + +moduledir = @EFL_IM_MODULEDIR@ +module_LTLIBRARIES = $(CONFIG_EFL_IMMODULE) + +libisf_imf_module_la_SOURCES = isf_imf_module.cpp \ + isf_imf_context.cpp \ + isf_imf_control_ui.cpp \ + isf_imf_control.cpp + +libisf_imf_module_la_CXXFLAGS = @EFL_CFLAGS@ \ + @UTILX_CFLAGS@ \ + @VCONF_CFLAGS@ \ + @DLOG_CFLAGS@\ + @SYSPOPUP_CFLAGS@ + +libisf_imf_module_la_LDFLAGS = -rpath $(moduledir) \ + -avoid-version \ + -module + +libisf_imf_module_la_LIBADD = -lstdc++ \ + $(LD_VERSION_SCRIPT_OPTION) \ + @EFL_LIBS@ \ + @UTILX_LIBS@ \ + @VCONF_LIBS@ \ + @DLOG_LIBS@ \ + @SYSPOPUP_LIBS@\ + $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la diff --git a/ism/extras/efl_immodule/isf_imf_context.cpp b/ism/extras/efl_immodule/isf_imf_context.cpp new file mode 100644 index 0000000..69c8772 --- /dev/null +++ b/ism/extras/efl_immodule/isf_imf_context.cpp @@ -0,0 +1,3652 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_BACKEND +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_HOTKEY +#define Uses_SCIM_PANEL_CLIENT + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scim_private.h" +#include "scim.h" +#include "isf_imf_context.h" +#include "isf_imf_control_ui.h" + +#ifndef CODESET +# define CODESET "INVALID" +#endif + +const double DOUBLE_SPACE_INTERVAL = 1.0; + +using namespace scim; + +struct _EcoreIMFContextISFImpl { + EcoreIMFContextISF *parent; + IMEngineInstancePointer si; + Ecore_X_Window client_window; + Evas *client_canvas; + Ecore_IMF_Input_Mode input_mode; + WideString preedit_string; + AttributeList preedit_attrlist; + Ecore_IMF_Autocapital_Type autocapital_type; + void *imdata; + int imdata_size; + int preedit_caret; + int cursor_x; + int cursor_y; + int cursor_top_y; + int cursor_pos; + bool use_preedit; + bool is_on; + bool shared_si; + bool preedit_started; + bool preedit_updating; + bool need_commit_preedit; + bool uppercase; + bool prediction_allow; + + EcoreIMFContextISFImpl *next; +}; + +/* Input Context handling functions. */ +static EcoreIMFContextISFImpl *new_ic_impl (EcoreIMFContextISF *parent); +static void delete_ic_impl (EcoreIMFContextISFImpl *impl); +static void delete_all_ic_impl (void); + +static EcoreIMFContextISF *find_ic (int id); + + +/* private functions */ +static void panel_slot_reload_config (int context); +static void panel_slot_exit (int context); +static void panel_slot_update_candidate_item_layout (int context, + const std::vector &row_items); +static void panel_slot_update_lookup_table_page_size(int context, + int page_size); +static void panel_slot_lookup_table_page_up (int context); +static void panel_slot_lookup_table_page_down (int context); +static void panel_slot_trigger_property (int context, + const String &property); +static void panel_slot_process_helper_event (int context, + const String &target_uuid, + const String &helper_uuid, + const Transaction &trans); +static void panel_slot_move_preedit_caret (int context, + int caret_pos); +static void panel_slot_update_preedit_caret (int context, + int caret); +static void panel_slot_select_aux (int context, + int aux_index); +static void panel_slot_select_candidate (int context, + int cand_index); +static void panel_slot_process_key_event (int context, + const KeyEvent &key); +static void panel_slot_commit_string (int context, + const WideString &wstr); +static void panel_slot_forward_key_event (int context, + const KeyEvent &key); +static void panel_slot_request_help (int context); +static void panel_slot_request_factory_menu (int context); +static void panel_slot_change_factory (int context, + const String &uuid); +static void panel_slot_reset_keyboard_ise (int context); +static void panel_slot_update_keyboard_ise (int context); +static void panel_slot_show_preedit_string (int context); +static void panel_slot_hide_preedit_string (int context); +static void panel_slot_update_preedit_string (int context, + const WideString &str, + const AttributeList &attrs); +static void panel_slot_get_surrounding_text (int context, + int maxlen_before, + int maxlen_after); +static void panel_slot_delete_surrounding_text (int context, + int offset, + int len); + +static void panel_req_focus_in (EcoreIMFContextISF *ic); +static void panel_req_update_factory_info (EcoreIMFContextISF *ic); +static void panel_req_update_spot_location (EcoreIMFContextISF *ic); +static void panel_req_update_cursor_position (EcoreIMFContextISF *ic, int cursor_pos); +static void panel_req_show_help (EcoreIMFContextISF *ic); +static void panel_req_show_factory_menu (EcoreIMFContextISF *ic); + +/* Panel iochannel handler*/ +static bool panel_initialize (void); +static void panel_finalize (void); +static Eina_Bool panel_iochannel_handler (void *data, + Ecore_Fd_Handler *fd_handler); + +/* utility functions */ +static bool filter_hotkeys (EcoreIMFContextISF *ic, + const KeyEvent &key); +static void turn_on_ic (EcoreIMFContextISF *ic); +static void turn_off_ic (EcoreIMFContextISF *ic); +static void set_ic_capabilities (EcoreIMFContextISF *ic); + +static void initialize (void); +static void finalize (void); + +static void open_next_factory (EcoreIMFContextISF *ic); +static void open_previous_factory (EcoreIMFContextISF *ic); +static void open_specific_factory (EcoreIMFContextISF *ic, + const String &uuid); +static void initialize_modifier_bits (Display *display); +static unsigned int scim_x11_keymask_scim_to_x11 (Display *display, uint16 scimkeymask); +static XKeyEvent createKeyEvent (bool press, int keycode, int modifiers, bool fake); +static void send_x_key_event (const KeyEvent &key, bool fake); + +static void attach_instance (const IMEngineInstancePointer &si); + +/* slot functions */ +static void slot_show_preedit_string (IMEngineInstanceBase *si); +static void slot_show_aux_string (IMEngineInstanceBase *si); +static void slot_show_lookup_table (IMEngineInstanceBase *si); + +static void slot_hide_preedit_string (IMEngineInstanceBase *si); +static void slot_hide_aux_string (IMEngineInstanceBase *si); +static void slot_hide_lookup_table (IMEngineInstanceBase *si); + +static void slot_update_preedit_caret (IMEngineInstanceBase *si, + int caret); +static void slot_update_preedit_string (IMEngineInstanceBase *si, + const WideString &str, + const AttributeList &attrs); +static void slot_update_aux_string (IMEngineInstanceBase *si, + const WideString &str, + const AttributeList &attrs); +static void slot_commit_string (IMEngineInstanceBase *si, + const WideString &str); +static void slot_forward_key_event (IMEngineInstanceBase *si, + const KeyEvent &key); +static void slot_update_lookup_table (IMEngineInstanceBase *si, + const LookupTable &table); + +static void slot_register_properties (IMEngineInstanceBase *si, + const PropertyList &properties); +static void slot_update_property (IMEngineInstanceBase *si, + const Property &property); +static void slot_beep (IMEngineInstanceBase *si); +static void slot_start_helper (IMEngineInstanceBase *si, + const String &helper_uuid); +static void slot_stop_helper (IMEngineInstanceBase *si, + const String &helper_uuid); +static void slot_send_helper_event (IMEngineInstanceBase *si, + const String &helper_uuid, + const Transaction &trans); +static bool slot_get_surrounding_text (IMEngineInstanceBase *si, + WideString &text, + int &cursor, + int maxlen_before, + int maxlen_after); +static bool slot_delete_surrounding_text (IMEngineInstanceBase *si, + int offset, + int len); + +static void slot_expand_candidate (IMEngineInstanceBase *si); +static void slot_contract_candidate (IMEngineInstanceBase *si); + +static void slot_set_candidate_style (IMEngineInstanceBase *si, + ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line, + ISF_CANDIDATE_MODE_T mode); + +static void reload_config_callback (const ConfigPointer &config); + +static void fallback_commit_string_cb (IMEngineInstanceBase *si, + const WideString &str); + +/* Local variables declaration */ +static String _language; +static EcoreIMFContextISFImpl *_used_ic_impl_list = 0; +static EcoreIMFContextISFImpl *_free_ic_impl_list = 0; +static EcoreIMFContextISF *_ic_list = 0; + +static KeyboardLayout _keyboard_layout = SCIM_KEYBOARD_Default; +static int _valid_key_mask = SCIM_KEY_AllMasks; + +static FrontEndHotkeyMatcher _frontend_hotkey_matcher; +static IMEngineHotkeyMatcher _imengine_hotkey_matcher; + +static IMEngineInstancePointer _default_instance; + +static ConfigModule *_config_module = 0; +static ConfigPointer _config; +static BackEndPointer _backend; + +static EcoreIMFContextISF *_focused_ic = 0; + +static bool _scim_initialized = false; + +static int _instance_count = 0; +static int _context_count = 0; + +static IMEngineFactoryPointer _fallback_factory; +static IMEngineInstancePointer _fallback_instance; +static PanelClient _panel_client; +static int _panel_client_id = 0; + +static Ecore_Fd_Handler *_panel_iochannel_read_handler = 0; +static Ecore_Fd_Handler *_panel_iochannel_err_handler = 0; + +static Ecore_X_Window _client_window = 0; +static Ecore_Event_Handler *_key_handler = 0; + +static bool _on_the_spot = true; +static bool _shared_input_method = false; +static double space_key_time = 0.0; + +static Eina_Bool autoperiod_allow = EINA_FALSE; +static Eina_Bool autocap_allow = EINA_FALSE; +static Eina_Bool desktop_mode = EINA_FALSE; + +static Display *__current_display = 0; +static int __current_alt_mask = Mod1Mask; +static int __current_meta_mask = 0; +static int __current_super_mask = 0; +static int __current_hyper_mask = 0; +static int __current_numlock_mask = Mod2Mask; + +extern Ecore_IMF_Context *input_panel_ctx; + +// A hack to shutdown the immodule cleanly even if im_module_exit () is not called when exiting. +class FinalizeHandler +{ +public: + FinalizeHandler () { + SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::FinalizeHandler ()\n"; + } + ~FinalizeHandler () { + SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::~FinalizeHandler ()\n"; + finalize (); + } +}; + +static FinalizeHandler _finalize_handler; + +ConfigPointer isf_imf_context_get_config (void) +{ + return _config; +} + +EcoreIMFContextISF * +get_focused_ic () +{ + return _focused_ic; +} + +int +get_panel_client_id (void) +{ + return _panel_client_id; +} + +Eina_Bool +get_desktop_mode () +{ + return desktop_mode; +} + +static unsigned int +get_time (void) +{ + unsigned int tint; + struct timeval tv; + struct timezone tz; /* is not used since ages */ + gettimeofday (&tv, &tz); + tint = tv.tv_sec * 1000; + tint = tint / 1000 * 1000; + tint = tint + tv.tv_usec / 1000; + return tint; +} + +/* Function Implementations */ +static EcoreIMFContextISFImpl * +new_ic_impl (EcoreIMFContextISF *parent) +{ + EcoreIMFContextISFImpl *impl = NULL; + + if (_free_ic_impl_list != NULL) { + impl = _free_ic_impl_list; + _free_ic_impl_list = _free_ic_impl_list->next; + } else { + impl = new EcoreIMFContextISFImpl; + if (impl == NULL) + return NULL; + } + + impl->uppercase = false; + impl->autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE; + impl->next = _used_ic_impl_list; + _used_ic_impl_list = impl; + + impl->parent = parent; + impl->imdata = NULL; + impl->imdata_size = 0; + + return impl; +} + +static void +delete_ic_impl (EcoreIMFContextISFImpl *impl) +{ + EcoreIMFContextISFImpl *rec = _used_ic_impl_list, *last = 0; + + for (; rec != 0; last = rec, rec = rec->next) { + if (rec == impl) { + if (last != 0) + last->next = rec->next; + else + _used_ic_impl_list = rec->next; + + rec->next = _free_ic_impl_list; + _free_ic_impl_list = rec; + + if (rec->imdata) { + free (rec->imdata); + rec->imdata = NULL; + } + + rec->imdata_size = 0; + rec->parent = 0; + rec->si.reset (); + rec->client_window = 0; + rec->preedit_string = WideString (); + rec->preedit_attrlist.clear (); + + return; + } + } +} + +static void +delete_all_ic_impl (void) +{ + EcoreIMFContextISFImpl *it = _used_ic_impl_list; + + while (it != 0) { + _used_ic_impl_list = it->next; + delete it; + it = _used_ic_impl_list; + } + + it = _free_ic_impl_list; + while (it != 0) { + _free_ic_impl_list = it->next; + delete it; + it = _free_ic_impl_list; + } +} + +static EcoreIMFContextISF * +find_ic (int id) +{ + EcoreIMFContextISFImpl *rec = _used_ic_impl_list; + + while (rec != 0) { + if (rec->parent && rec->parent->id == id) + return rec->parent; + rec = rec->next; + } + + return 0; +} + +static Eina_Bool +key_press_cb (void *data, int type, void *event) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + Evas_Event_Key_Down *ev = (Evas_Event_Key_Down *)event; + + if (!_focused_ic || !_focused_ic->ctx) return ECORE_CALLBACK_RENEW; + + if (!strcmp (ev->keyname, KEY_END)) { + LOGD ("END key is pressed\n"); +#ifdef ENABLE_BACKKEY + isf_imf_context_input_panel_instant_hide (_focused_ic->ctx); + return ECORE_CALLBACK_CANCEL; +#endif + } + + return ECORE_CALLBACK_RENEW; +} + +static void +_check_desktop_mode (Ecore_X_Window win) +{ + char *profile = ecore_x_e_window_profile_get (win); + if (profile && (strcmp (profile, "desktop") == 0)) { + desktop_mode = EINA_TRUE; + } else { + desktop_mode = EINA_FALSE; + } + + if (profile) + free (profile); +} + +static Eina_Bool +_x_prop_change (void *data, int type, void *event) +{ + Ecore_X_Event_Window_Property *e = (Ecore_X_Event_Window_Property *)event; + Ecore_X_Window xwin = (Ecore_X_Window)data; + + if (e->win != xwin) return ECORE_CALLBACK_PASS_ON; + + if (e->atom == ECORE_X_ATOM_E_PROFILE) { + _check_desktop_mode (e->win); + } + + return ECORE_CALLBACK_PASS_ON; +} + +int +register_key_handler () +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (!_key_handler) { + _key_handler = ecore_event_handler_add (ECORE_EVENT_KEY_DOWN, key_press_cb, NULL); + } + + return EXIT_SUCCESS; +} + +int +unregister_key_handler () +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (_key_handler) { + ecore_event_handler_del (_key_handler); + _key_handler = NULL; + } + + return EXIT_SUCCESS; +} + +static void +set_prediction_allow (IMEngineInstancePointer si, bool prediction) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (si) + si->set_prediction_allow (prediction); +} + +static void +autoperiod_insert (Ecore_IMF_Context *ctx) +{ + char *plain_str = NULL; + char *markup_str = NULL; + int cursor_pos = 0; + Eina_Unicode *ustr = NULL; + Ecore_IMF_Event_Delete_Surrounding ev; + + if (!ctx) return; + + Ecore_IMF_Input_Panel_Layout layout = ecore_imf_context_input_panel_layout_get(ctx); + if (layout != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL) + return; + + if (autoperiod_allow == EINA_FALSE) + return; + + if ((ecore_time_get() - space_key_time) > DOUBLE_SPACE_INTERVAL) + goto done; + + ecore_imf_context_surrounding_get (ctx, &markup_str, &cursor_pos); + if (!markup_str) goto done; + + // Convert into plain string + plain_str = evas_textblock_text_markup_to_utf8 (NULL, markup_str); + if (!plain_str) goto done; + + // Convert string from UTF-8 to unicode + ustr = eina_unicode_utf8_to_unicode (plain_str, NULL); + if (!ustr) goto done; + + if (cursor_pos < 2) goto done; + + if (((ustr[cursor_pos-2] != ':') && (ustr[cursor_pos-2] != ';') && + (ustr[cursor_pos-2] != '.') && (ustr[cursor_pos-2] != ',') && + (ustr[cursor_pos-2] != '?') && (ustr[cursor_pos-2] != '!') && + (ustr[cursor_pos-2] != ' ')) && ((ustr[cursor_pos-1] == ' ') || (ustr[cursor_pos-1] == '\240'))) { + ev.ctx = ctx; + ev.n_chars = 1; + ev.offset = -1; + ecore_imf_context_delete_surrounding_event_add (ctx, -1, 1); + ecore_imf_context_event_callback_call (ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev); + + ecore_imf_context_commit_event_add (ctx, "."); + ecore_imf_context_event_callback_call (ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)"."); + } + +done: + if (markup_str) free (markup_str); + if (plain_str) free (plain_str); + if (ustr) free (ustr); + space_key_time = ecore_time_get (); +} + +static Eina_Bool +analyze_surrounding_text (Ecore_IMF_Context *ctx) +{ + char *plain_str = NULL; + char *markup_str = NULL; + const char *puncs[] = {". ", ".\302\240", "! ", "!\302\240", "? ", "?\302\240", "¿ ", "¿\302\240", "¡ ", "¡\302\240" }; + Eina_Bool ret = EINA_FALSE; + int cursor_pos = 0; + int i = 0; + Eina_Unicode *tail = NULL; + Eina_Unicode *ustr = NULL; + const int punc_num = sizeof (puncs) / sizeof (puncs[0]); + Eina_Unicode *uni_puncs[punc_num]; + EcoreIMFContextISF *context_scim; + + if (!ctx) return EINA_FALSE; + context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + if (!context_scim || !context_scim->impl) return EINA_FALSE; + + switch (context_scim->impl->autocapital_type) { + case ECORE_IMF_AUTOCAPITAL_TYPE_NONE: + return EINA_FALSE; + case ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER: + return EINA_TRUE; + default: + break; + } + + if (context_scim->impl->cursor_pos == 0) + return EINA_TRUE; + + for (i = 0; i < punc_num; i++) { + uni_puncs[i] = eina_unicode_utf8_to_unicode (puncs[i], NULL); + } + + ecore_imf_context_surrounding_get (ctx, &markup_str, &cursor_pos); + if (!markup_str) goto done; + + if (cursor_pos == 0) { + ret = EINA_TRUE; + goto done; + } + + // Convert into plain string + plain_str = evas_textblock_text_markup_to_utf8 (NULL, markup_str); + if (!plain_str) goto done; + + // Convert string from UTF-8 to unicode + ustr = eina_unicode_utf8_to_unicode (plain_str, NULL); + if (!ustr) goto done; + + if (cursor_pos >= 1) { + if (context_scim->impl->autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD) { + if (ustr[cursor_pos-1] == ' ' || ustr[cursor_pos-1] == '\302\240') { + ret = EINA_TRUE; + goto done; + } + } + + // Check paragraph separator and carriage return
+ if ((ustr[cursor_pos-1] == 0x2029) || (ustr[cursor_pos-1] == '\n')) { + ret = EINA_TRUE; + goto done; + } + } + + // check punctuation + if (cursor_pos >= 2) { + tail = eina_unicode_strndup (ustr+cursor_pos-2, 2); + + if (tail) { + for (i = 0; i < punc_num; i++) { + if (!eina_unicode_strcmp (tail, uni_puncs[i])) { + ret = EINA_TRUE; + break; + } + } + free (tail); + tail = NULL; + } + } + +done: + if (ustr) free (ustr); + if (markup_str) free (markup_str); + if (plain_str) free (plain_str); + + for (i = 0; i < punc_num; i++) { + if (uni_puncs[i]) free (uni_puncs[i]); + } + + return ret; +} + +Eina_Bool +caps_mode_check (Ecore_IMF_Context *ctx, Eina_Bool force, Eina_Bool noti) +{ + Eina_Bool uppercase; + EcoreIMFContextISF *context_scim; + + if (!ctx) return EINA_FALSE; + context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + Ecore_IMF_Input_Panel_Layout layout = ecore_imf_context_input_panel_layout_get (ctx); + if (layout != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL) + return EINA_FALSE; + + // Check autocapital type + if (!context_scim || !context_scim->impl) + return EINA_FALSE; + + if (ecore_imf_context_input_panel_caps_lock_mode_get (ctx)) { + uppercase = EINA_TRUE; + } else { + if (autocap_allow == EINA_FALSE) + return EINA_FALSE; + + if (analyze_surrounding_text (ctx)) { + uppercase = EINA_TRUE; + } else { + uppercase = EINA_FALSE; + } + } + + if (force) { + context_scim->impl->uppercase = uppercase; + if (noti) + isf_imf_context_input_panel_caps_mode_set (ctx, uppercase); + } else { + if (context_scim->impl->uppercase != uppercase) { + context_scim->impl->uppercase = uppercase; + if (noti) + isf_imf_context_input_panel_caps_mode_set (ctx, uppercase); + } + } + + return uppercase; +} + +static void +window_to_screen_geometry_get (Ecore_X_Window client_win, int *x, int *y) +{ + Ecore_X_Window root_window, win; + int win_x, win_y; + int sum_x = 0, sum_y = 0; + + root_window = ecore_x_window_root_get (client_win); + win = client_win; + + while (root_window != win) { + ecore_x_window_geometry_get (win, &win_x, &win_y, NULL, NULL); + sum_x += win_x; + sum_y += win_y; + win = ecore_x_window_parent_get (win); + } + + if (x) + *x = sum_x; + if (y) + *y = sum_y; +} + +static void +evas_focus_out_cb (void *data, Evas *e, void *event_info) +{ + Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)data; + + if (!ctx) return; + + LOGD ("ctx : %p\n", ctx); + + if (input_panel_ctx == ctx && _scim_initialized) { + isf_imf_context_input_panel_instant_hide (ctx); + } +} + +static void autoperiod_allow_changed_cb (keynode_t *key, void* data) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + autoperiod_allow = vconf_keynode_get_bool (key); +} + +static void autocapital_allow_changed_cb (keynode_t *key, void* data) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + autocap_allow = vconf_keynode_get_bool (key); +} + +EAPI void context_scim_imdata_get (Ecore_IMF_Context *ctx, void* data, int* length) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (data && context_scim->impl->imdata) + memcpy (data, context_scim->impl->imdata, context_scim->impl->imdata_size); + + *length = context_scim->impl->imdata_size; +} + +/* Public functions */ +/** + * isf_imf_context_new + * + * This function will be called by Ecore IMF. + * Create a instance of type EcoreIMFContextISF. + * + * Return value: A pointer to the newly created EcoreIMFContextISF instance + */ +EAPI EcoreIMFContextISF * +isf_imf_context_new (void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + int val; + + EcoreIMFContextISF *context_scim = new EcoreIMFContextISF; + if (context_scim == NULL) { + std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n"; + return NULL; + } + + context_scim->id = _context_count++; + + if (!_scim_initialized) { + initialize (); + _scim_initialized = true; + isf_imf_input_panel_init (); + + /* get autoperiod allow vconf value */ + if (vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &val) == 0) { + if (val == EINA_TRUE) + autoperiod_allow = EINA_TRUE; + } + + vconf_notify_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb, NULL); + + /* get autocapital allow vconf value */ + if (vconf_get_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, &val) == 0) { + if (val == EINA_TRUE) + autocap_allow = EINA_TRUE; + } + + vconf_notify_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb, NULL); + } + + return context_scim; +} + +/** + * isf_imf_context_shutdown + * + * It will be called when the scim im module is unloaded by ecore. It will do some + * cleanup job. + */ +EAPI void +isf_imf_context_shutdown (void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (_scim_initialized) { + _scim_initialized = false; + + LOGD ("immodule shutdown\n"); + + vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb); + vconf_ignore_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb); + + isf_imf_input_panel_shutdown (); + finalize (); + } +} + +EAPI void +isf_imf_context_add (Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get (ctx); + + if (!context_scim) return; + + context_scim->impl = NULL; + + if (_backend.null ()) + return; + + IMEngineInstancePointer si; + + // Use the default instance if "shared input method" mode is enabled. + if (_shared_input_method && !_default_instance.null ()) { + si = _default_instance; + SCIM_DEBUG_FRONTEND(2) << "use default instance: " << si->get_id () << " " << si->get_factory_uuid () << "\n"; + } + + // Not in "shared input method" mode, or no default instance, create an instance. + if (si.null ()) { + IMEngineFactoryPointer factory = _backend->get_default_factory (_language, "UTF-8"); + if (factory.null ()) return; + si = factory->create_instance ("UTF-8", _instance_count++); + if (si.null ()) return; + attach_instance (si); + SCIM_DEBUG_FRONTEND(2) << "create new instance: " << si->get_id () << " " << si->get_factory_uuid () << "\n"; + } + + // If "shared input method" mode is enabled, and there is no default instance, + // then store this instance as default one. + if (_shared_input_method && _default_instance.null ()) { + SCIM_DEBUG_FRONTEND(2) << "update default instance.\n"; + _default_instance = si; + } + + context_scim->ctx = ctx; + context_scim->impl = new_ic_impl (context_scim); + if (context_scim->impl == NULL) { + std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n"; + return; + } + + context_scim->impl->si = si; + context_scim->impl->client_window = 0; + context_scim->impl->client_canvas = NULL; + context_scim->impl->preedit_caret = 0; + context_scim->impl->cursor_x = 0; + context_scim->impl->cursor_y = 0; + context_scim->impl->cursor_pos = -1; + context_scim->impl->cursor_top_y = 0; + context_scim->impl->is_on = true; + context_scim->impl->shared_si = _shared_input_method; + context_scim->impl->use_preedit = _on_the_spot; + context_scim->impl->preedit_started = false; + context_scim->impl->preedit_updating = false; + context_scim->impl->need_commit_preedit = false; + context_scim->impl->prediction_allow = true; + + if (!_ic_list) + context_scim->next = NULL; + else + context_scim->next = _ic_list; + _ic_list = context_scim; + + if (_shared_input_method) + context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); + + _panel_client.prepare (context_scim->id); + _panel_client.register_input_context (context_scim->id, si->get_factory_uuid ()); + set_ic_capabilities (context_scim); + _panel_client.send (); + + SCIM_DEBUG_FRONTEND(2) << "input context created: id = " << context_scim->id << "\n"; +} + +EAPI void +isf_imf_context_del (Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (!_ic_list) return; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get (ctx); + Ecore_IMF_Input_Panel_State input_panel_state = ecore_imf_context_input_panel_state_get (ctx); + + if (context_scim) { + if (context_scim->id != _ic_list->id) { + EcoreIMFContextISF * pre = _ic_list; + EcoreIMFContextISF * cur = _ic_list->next; + while (cur != NULL) { + if (cur->id == context_scim->id) { + pre->next = cur->next; + break; + } + pre = cur; + cur = cur->next; + } + } else { + _ic_list = _ic_list->next; + } + } + + if (context_scim && context_scim->impl) { + _panel_client.prepare (context_scim->id); + + if (context_scim == _focused_ic) + context_scim->impl->si->focus_out (); + + if (context_scim->impl->client_canvas) + evas_event_callback_del_full (context_scim->impl->client_canvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, evas_focus_out_cb, ctx); + + if (input_panel_ctx == ctx && _scim_initialized) { + LOGD ("ctx : %p\n", ctx); + if (input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW || + input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_SHOW) { + ecore_imf_context_input_panel_hide (ctx); + input_panel_event_callback_call (ECORE_IMF_INPUT_PANEL_STATE_EVENT, ECORE_IMF_INPUT_PANEL_STATE_HIDE); + } + } + + // Delete the instance. + // FIXME: + // In case the instance send out some helper event, + // and this context has been focused out, + // we need set the focused_ic to this context temporary. + EcoreIMFContextISF *old_focused = _focused_ic; + _focused_ic = context_scim; + context_scim->impl->si.reset (); + _focused_ic = old_focused; + + if (context_scim == _focused_ic) { + _panel_client.turn_off (context_scim->id); + _panel_client.focus_out (context_scim->id); + } + + _panel_client.remove_input_context (context_scim->id); + _panel_client.send (); + + if (context_scim->impl->client_window) + isf_imf_context_client_window_set (ctx, NULL); + + if (context_scim->impl) { + delete_ic_impl (context_scim->impl); + context_scim->impl = 0; + } + } + + isf_imf_context_input_panel_event_callback_clear (ctx); + + if (context_scim == _focused_ic) + _focused_ic = 0; + + if (context_scim) { + delete context_scim; + context_scim = 0; + } +} + +/** + * isf_imf_context_client_canvas_set + * @ctx: a #Ecore_IMF_Context + * @canvas: the client canvas + * + * This function will be called by Ecore IMF. + * + * Set the client canvas for the Input Method Context; this is the canvas + * in which the input appears. + * + * The canvas type can be determined by using the context canvas type. + * Actually only canvas with type "evas" (Evas *) is supported. This canvas + * may be used in order to correctly position status windows, and may also + * be used for purposes internal to the Input Method Context. + */ +EAPI void +isf_imf_context_client_canvas_set (Ecore_IMF_Context *ctx, void *canvas) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim->impl->client_canvas != (Evas*) canvas) { + context_scim->impl->client_canvas = (Evas*)canvas; + + LOGD ("ctx : %p, canvas : %p\n", ctx, canvas); + + evas_event_callback_add (context_scim->impl->client_canvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, evas_focus_out_cb, ctx); + } +} + +/** + * isf_imf_context_client_window_set + * @ctx: a #Ecore_IMF_Context + * @window: the client window + * + * This function will be called by Ecore IMF. + * + * Set the client window for the Input Method Context; this is the Ecore_X_Window + * when using X11, Ecore_Win32_Window when using Win32, etc. + * + * This window is used in order to correctly position status windows, + * and may also be used for purposes internal to the Input Method Context. + */ +EAPI void +isf_imf_context_client_window_set (Ecore_IMF_Context *ctx, void *window) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim->impl->client_window != (Ecore_X_Window)((Ecore_Window)window)) { + context_scim->impl->client_window = (Ecore_X_Window)((Ecore_Window)window); + + LOGD ("ctx : %p, client X win ID : %#x\n", ctx, context_scim->impl->client_window); + + if ((context_scim->impl->client_window != 0) && + (context_scim->impl->client_window != _client_window)) { + _client_window = context_scim->impl->client_window; + + _check_desktop_mode (_client_window); + + ecore_event_handler_add (ECORE_X_EVENT_WINDOW_PROPERTY, _x_prop_change, window); + } + } +} + +/** + * isf_imf_context_focus_in + * @ctx: a #Ecore_IMF_Context + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that the widget to which its correspond has gained focus. + */ +EAPI void +isf_imf_context_focus_in (Ecore_IMF_Context *ctx) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!context_scim) + return; + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n"; + + if (_focused_ic) { + if (_focused_ic == context_scim) { + SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n"; + return; + } + SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n"; + if (_focused_ic->ctx) + isf_imf_context_focus_out (_focused_ic->ctx); + } + + bool need_cap = false; + bool need_reset = false; + bool need_reg = false; + + if (context_scim && context_scim->impl) { + _focused_ic = context_scim; + isf_imf_context_control_focus_in (ctx); + + _panel_client.prepare (context_scim->id); + + // Handle the "Shared Input Method" mode. + if (_shared_input_method) { + SCIM_DEBUG_FRONTEND(2) << "shared input method.\n"; + IMEngineFactoryPointer factory = _backend->get_default_factory (_language, "UTF-8"); + if (!factory.null ()) { + if (_default_instance.null () || _default_instance->get_factory_uuid () != factory->get_uuid ()) { + _default_instance = factory->create_instance ("UTF-8", _default_instance.null () ? _instance_count++ : _default_instance->get_id ()); + attach_instance (_default_instance); + SCIM_DEBUG_FRONTEND(2) << "create new default instance: " << _default_instance->get_id () << " " << _default_instance->get_factory_uuid () << "\n"; + } + + context_scim->impl->shared_si = true; + context_scim->impl->si = _default_instance; + + context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); + context_scim->impl->preedit_string.clear (); + context_scim->impl->preedit_attrlist.clear (); + context_scim->impl->preedit_caret = 0; + context_scim->impl->preedit_started = false; + need_cap = true; + need_reset = true; + need_reg = true; + } + } else if (context_scim->impl->shared_si) { + SCIM_DEBUG_FRONTEND(2) << "exit shared input method.\n"; + IMEngineFactoryPointer factory = _backend->get_default_factory (_language, "UTF-8"); + if (!factory.null ()) { + context_scim->impl->si = factory->create_instance ("UTF-8", _instance_count++); + context_scim->impl->preedit_string.clear (); + context_scim->impl->preedit_attrlist.clear (); + context_scim->impl->preedit_caret = 0; + context_scim->impl->preedit_started = false; + attach_instance (context_scim->impl->si); + need_cap = true; + need_reg = true; + context_scim->impl->shared_si = false; + SCIM_DEBUG_FRONTEND(2) << "create new instance: " << context_scim->impl->si->get_id () << " " << context_scim->impl->si->get_factory_uuid () << "\n"; + } + } + + context_scim->impl->si->set_frontend_data (static_cast (context_scim)); + + if (need_reg) _panel_client.register_input_context (context_scim->id, context_scim->impl->si->get_factory_uuid ()); + if (need_cap) set_ic_capabilities (context_scim); + + panel_req_focus_in (context_scim); +// panel_req_update_spot_location (context_scim); +// panel_req_update_factory_info (context_scim); + + if (need_reset) context_scim->impl->si->reset (); + if (context_scim->impl->is_on) { + _panel_client.turn_on (context_scim->id); +// _panel_client.hide_preedit_string (context_scim->id); +// _panel_client.hide_aux_string (context_scim->id); +// _panel_client.hide_lookup_table (context_scim->id); + context_scim->impl->si->focus_in (); + context_scim->impl->si->set_layout (ecore_imf_context_input_panel_layout_get (ctx)); + set_prediction_allow (context_scim->impl->si, context_scim->impl->prediction_allow); + if (context_scim->impl->imdata) + context_scim->impl->si->set_imdata ((const char *)context_scim->impl->imdata, context_scim->impl->imdata_size); + } else { + _panel_client.turn_off (context_scim->id); + } + + _panel_client.send (); + } + + LOGD ("ctx : %p\n", ctx); + + if (ecore_imf_context_input_panel_enabled_get (ctx)) + ecore_imf_context_input_panel_show (ctx); + else + LOGD ("ctx : %p input panel enable : FALSE\n", ctx); +} + +/** + * isf_imf_context_focus_out + * @ctx: a #Ecore_IMF_Context + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that the widget to which its correspond has lost focus. + */ +EAPI void +isf_imf_context_focus_out (Ecore_IMF_Context *ctx) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!context_scim) return; + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n"; + + if (context_scim && context_scim->impl && context_scim == _focused_ic) { + + WideString wstr = context_scim->impl->preedit_string; + + LOGD ("ctx : %p\n", ctx); + + if (ecore_imf_context_input_panel_enabled_get (ctx)) + ecore_imf_context_input_panel_hide (ctx); + + if (context_scim->impl->need_commit_preedit) { + panel_slot_hide_preedit_string (context_scim->id); + + if (wstr.length ()) { + ecore_imf_context_commit_event_add (context_scim->ctx, utf8_wcstombs (wstr).c_str ()); + ecore_imf_context_event_callback_call (context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs (wstr).c_str ()); + } + _panel_client.prepare (context_scim->id); + _panel_client.reset_input_context (context_scim->id); + _panel_client.send (); + } + + _panel_client.prepare (context_scim->id); + context_scim->impl->si->focus_out (); + context_scim->impl->si->reset (); +// if (context_scim->impl->shared_si) context_scim->impl->si->reset (); + _panel_client.focus_out (context_scim->id); + _panel_client.send (); + _focused_ic = 0; + } +} + +/** + * isf_imf_context_reset + * @ctx: a #Ecore_IMF_Context + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that a change such as a change in cursor + * position has been made. This will typically cause the Input Method Context + * to clear the preedit state. + */ +EAPI void +isf_imf_context_reset (Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim == _focused_ic) { + WideString wstr = context_scim->impl->preedit_string; + + _panel_client.prepare (context_scim->id); + context_scim->impl->si->reset (); + _panel_client.reset_input_context (context_scim->id); + _panel_client.send (); + + if (context_scim->impl->need_commit_preedit) { + panel_slot_hide_preedit_string (context_scim->id); + + if (wstr.length ()) { + ecore_imf_context_commit_event_add (context_scim->ctx, utf8_wcstombs (wstr).c_str ()); + ecore_imf_context_event_callback_call (context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs (wstr).c_str ()); + } + } + } +} + +/** + * isf_imf_context_cursor_position_set + * @ctx: a #Ecore_IMF_Context + * @cursor_pos: New cursor position in characters. + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that a change in the cursor position has been made. + */ +EAPI void +isf_imf_context_cursor_position_set (Ecore_IMF_Context *ctx, int cursor_pos) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim == _focused_ic) { + if (context_scim->impl->cursor_pos != cursor_pos) { + LOGD ("ctx : %p, cursor pos : %d\n", ctx, cursor_pos); + context_scim->impl->cursor_pos = cursor_pos; + + caps_mode_check (ctx, EINA_FALSE, EINA_TRUE); + + if (context_scim->impl->preedit_updating) + return; + _panel_client.prepare (context_scim->id); + context_scim->impl->si->update_cursor_position (cursor_pos); + panel_req_update_cursor_position (context_scim, cursor_pos); + _panel_client.send (); + } + } +} + +/** + * isf_imf_context_cursor_location_set + * @ctx: a #Ecore_IMF_Context + * @x: x position of New cursor. + * @y: y position of New cursor. + * @w: the width of New cursor. + * @h: the height of New cursor. + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that a change in the cursor location has been made. + */ +EAPI void +isf_imf_context_cursor_location_set (Ecore_IMF_Context *ctx, int cx, int cy, int cw, int ch) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + Ecore_Evas *ee; + int canvas_x, canvas_y; + int new_cursor_x, new_cursor_y; + + if (cw == 0 && ch == 0) + return; + + if (context_scim && context_scim->impl && context_scim == _focused_ic) { + if (context_scim->impl->client_canvas) { + ee = ecore_evas_ecore_evas_get (context_scim->impl->client_canvas); + if (!ee) return; + + ecore_evas_geometry_get (ee, &canvas_x, &canvas_y, NULL, NULL); + } + else { + if (context_scim->impl->client_window) + window_to_screen_geometry_get (context_scim->impl->client_window, &canvas_x, &canvas_y); + else + return; + } + + new_cursor_x = canvas_x + cx; + new_cursor_y = canvas_y + cy + ch; + + // Don't update spot location while updating preedit string. + if (context_scim->impl->preedit_updating && (context_scim->impl->cursor_y == new_cursor_y)) + return; + + if (context_scim->impl->cursor_x != new_cursor_x || context_scim->impl->cursor_y != new_cursor_y) { + context_scim->impl->cursor_x = new_cursor_x; + context_scim->impl->cursor_y = new_cursor_y; + context_scim->impl->cursor_top_y = canvas_y + cy; + _panel_client.prepare (context_scim->id); + panel_req_update_spot_location (context_scim); + _panel_client.send (); + SCIM_DEBUG_FRONTEND(2) << "new cursor location = " << context_scim->impl->cursor_x << "," << context_scim->impl->cursor_y << "\n"; + } + } +} + +/** + * isf_imf_context_input_mode_set + * @ctx: a #Ecore_IMF_Context + * @input_mode: the input mode + * + * This function will be called by Ecore IMF. + * + * To set the input mode of input method. The definition of Ecore_IMF_Input_Mode + * is in Ecore_IMF.h. + */ +EAPI void +isf_imf_context_input_mode_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get (ctx); + if (context_scim && context_scim->impl) { + context_scim->impl->input_mode = input_mode; + } +} + +/** + * isf_imf_context_preedit_string_get + * @ctx: a #Ecore_IMF_Context + * @str: the preedit string + * @cursor_pos: the cursor position + * + * This function will be called by Ecore IMF. + * + * To get the preedit string of the input method. + */ +EAPI void +isf_imf_context_preedit_string_get (Ecore_IMF_Context *ctx, char** str, int *cursor_pos) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim->impl->is_on) { + String mbs = utf8_wcstombs (context_scim->impl->preedit_string); + + if (str) { + if (mbs.length ()) + *str = strdup (mbs.c_str ()); + else + *str = strdup (""); + } + + if (cursor_pos) { + *cursor_pos = context_scim->impl->preedit_caret; + } + } else { + if (str) + *str = strdup (""); + + if (cursor_pos) + *cursor_pos = 0; + } +} + +EAPI void +isf_imf_context_preedit_string_with_attributes_get (Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim->impl->is_on) { + String mbs = utf8_wcstombs (context_scim->impl->preedit_string); + + if (str) { + if (mbs.length ()) + *str = strdup (mbs.c_str ()); + else + *str = strdup (""); + } + + if (cursor_pos) { + *cursor_pos = context_scim->impl->preedit_caret; + } + + if (attrs) { + if (mbs.length ()) { + int start_index, end_index; + int wlen = context_scim->impl->preedit_string.length (); + Ecore_IMF_Preedit_Attr *attr = NULL; + AttributeList::const_iterator i; + bool *attrs_flag = new bool [mbs.length ()]; + memset (attrs_flag, 0, mbs.length () * sizeof (bool)); + for (i = context_scim->impl->preedit_attrlist.begin (); + i != context_scim->impl->preedit_attrlist.end (); ++i) { + start_index = i->get_start (); + end_index = i->get_end (); + if (end_index <= wlen && start_index < end_index && i->get_type () != SCIM_ATTR_DECORATE_NONE) { + start_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_start ()) - mbs.c_str (); + end_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_end ()) - mbs.c_str (); + if (i->get_type () == SCIM_ATTR_DECORATE) { + attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof (Ecore_IMF_Preedit_Attr)); + if (attr == NULL) + continue; + attr->start_index = start_index; + attr->end_index = end_index; + + if (i->get_value () == SCIM_ATTR_DECORATE_UNDERLINE) { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1; + *attrs = eina_list_append (*attrs, (void *)attr); + } else if (i->get_value () == SCIM_ATTR_DECORATE_REVERSE) { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; + *attrs = eina_list_append (*attrs, (void *)attr); + } else if (i->get_value () == SCIM_ATTR_DECORATE_HIGHLIGHT) { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3; + *attrs = eina_list_append (*attrs, (void *)attr); + } else if (i->get_value () == SCIM_ATTR_DECORATE_BGCOLOR1) { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB4; + *attrs = eina_list_append (*attrs, (void *)attr); + } else if (i->get_value () == SCIM_ATTR_DECORATE_BGCOLOR2) { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB5; + *attrs = eina_list_append (*attrs, (void *)attr); + } else if (i->get_value () == SCIM_ATTR_DECORATE_BGCOLOR3) { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB6; + *attrs = eina_list_append (*attrs, (void *)attr); + } else if (i->get_value () == SCIM_ATTR_DECORATE_BGCOLOR4) { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB7; + *attrs = eina_list_append (*attrs, (void *)attr); + } else { + free (attr); + } + switch(i->get_value()) + { + case SCIM_ATTR_DECORATE_UNDERLINE: + case SCIM_ATTR_DECORATE_REVERSE: + case SCIM_ATTR_DECORATE_HIGHLIGHT: + case SCIM_ATTR_DECORATE_BGCOLOR1: + case SCIM_ATTR_DECORATE_BGCOLOR2: + case SCIM_ATTR_DECORATE_BGCOLOR3: + case SCIM_ATTR_DECORATE_BGCOLOR4: + // Record which character has attribute. + for (int pos = start_index; pos < end_index; ++pos) + attrs_flag [pos] = 1; + break; + default: + break; + } + } else if (i->get_type () == SCIM_ATTR_FOREGROUND) { + SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_FOREGROUND\n"; + } else if (i->get_type () == SCIM_ATTR_BACKGROUND) { + SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_BACKGROUND\n"; + } + } + } + // Add underline for all characters which don't have attribute. + for (unsigned int pos = 0; pos < mbs.length (); ++pos) { + if (!attrs_flag [pos]) { + int begin_pos = pos; + while (pos < mbs.length () && !attrs_flag [pos]) + ++pos; + // use REVERSE style as default + attr = (Ecore_IMF_Preedit_Attr *)calloc (1, sizeof (Ecore_IMF_Preedit_Attr)); + if (attr == NULL) + continue; + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; + attr->start_index = begin_pos; + attr->end_index = pos; + *attrs = eina_list_append(*attrs, (void *)attr); + } + } + delete [] attrs_flag; + } + } + } else { + if (str) + *str = strdup (""); + + if (cursor_pos) + *cursor_pos = 0; + + if (attrs) + *attrs = NULL; + } +} + +/** + * isf_imf_context_use_preedit_set + * @ctx: a #Ecore_IMF_Context + * @use_preedit: Whether the IM context should use the preedit string. + * + * This function will be called by Ecore IMF. + * + * Set whether the IM context should use the preedit string to display feedback. + * If is 0 (default is 1), then the IM context may use some other method to + * display feedback, such as displaying it in a child of the root window. + */ +EAPI void +isf_imf_context_use_preedit_set (Ecore_IMF_Context* ctx, Eina_Bool use_preedit) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (use_preedit == EINA_TRUE ? "true" : "false") << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get (ctx); + + if (!_on_the_spot) return; + + if (context_scim && context_scim->impl) { + bool old = context_scim->impl->use_preedit; + context_scim->impl->use_preedit = use_preedit; + if (context_scim == _focused_ic) { + _panel_client.prepare (context_scim->id); + + if (old != use_preedit) + set_ic_capabilities (context_scim); + + if (context_scim->impl->preedit_string.length ()) + slot_show_preedit_string (context_scim->impl->si); + + _panel_client.send (); + } + } +} + +/** + * isf_imf_context_prediction_allow_set + * @ctx: a #Ecore_IMF_Context + * @prediction: Whether the IM context should use the prediction. + * + * This function will be called by Ecore IMF. + * + * Set whether the IM context should use the prediction. + */ +EAPI void +isf_imf_context_prediction_allow_set (Ecore_IMF_Context* ctx, Eina_Bool prediction) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (prediction == EINA_TRUE ? "true" : "false") << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim->impl->prediction_allow != prediction) { + context_scim->impl->prediction_allow = prediction; + set_prediction_allow (context_scim->impl->si, prediction); + } +} + +/** + * isf_imf_context_prediction_allow_get + * @ctx: a #Ecore_IMF_Context + * + * This function will be called by Ecore IMF. + * + * To get prediction allow flag for the IM context. + * + * Return value: the prediction allow flag for the IM context + */ +EAPI Eina_Bool +isf_imf_context_prediction_allow_get (Ecore_IMF_Context* ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + Eina_Bool ret = EINA_FALSE; + if (context_scim && context_scim->impl) { + ret = context_scim->impl->prediction_allow; + } else { + std::cerr << __FUNCTION__ << " failed!!!\n"; + } + return ret; +} + +/** + * isf_imf_context_autocapital_type_set + * @ctx: a #Ecore_IMF_Context + * @autocapital_type: the autocapital type for the IM context. + * + * This function will be called by Ecore IMF. + * + * Set autocapital type for the IM context. + */ +EAPI void +isf_imf_context_autocapital_type_set (Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << autocapital_type << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim && context_scim->impl && context_scim->impl->autocapital_type != autocapital_type) { + context_scim->impl->autocapital_type = autocapital_type; + } +} + +/** + * isf_imf_context_filter_event + * @ctx: a #Ecore_IMF_Context + * @type: The type of event defined by Ecore_IMF_Event_Type. + * @event: The event itself. + * Return value: %TRUE if the input method handled the key event. + * + * This function will be called by Ecore IMF. + * + * Allow an Ecore Input Context to internally handle an event. If this function + * returns 1, then no further processing should be done for this event. Input + * methods must be able to accept all types of events (simply returning 0 if + * the event was not handled), but there is no obligation of any events to be + * submitted to this function. + */ +EAPI Eina_Bool +isf_imf_context_filter_event (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get (ctx); + Eina_Bool ret = EINA_FALSE; + + if (ic == NULL || ic->impl == NULL) + return ret; + + KeyEvent key; + unsigned int timestamp; + + if (type == ECORE_IMF_EVENT_KEY_DOWN) { + Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; + timestamp = ev->timestamp; + scim_string_to_key (key, ev->key); + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask; + } else if (type == ECORE_IMF_EVENT_KEY_UP) { + Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event; + timestamp = ev->timestamp; + scim_string_to_key (key, ev->key); + key.mask = SCIM_KEY_ReleaseMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask; + } else if (type == ECORE_IMF_EVENT_MOUSE_UP) { + if (ecore_imf_context_input_panel_enabled_get (ctx)) { + LOGD ("[Mouse-up event] ctx : %p\n", ctx); + if (ic == _focused_ic) + ecore_imf_context_input_panel_show (ctx); + } + return EINA_FALSE; + } else { + return ret; + } + + key.mask &= _valid_key_mask; + + _panel_client.prepare (ic->id); + + ret = EINA_TRUE; + if (!filter_hotkeys (ic, key)) { + if (timestamp == 0) { + ret = EINA_FALSE; + // in case of generated event + if (type == ECORE_IMF_EVENT_KEY_DOWN) { + char code = key.get_ascii_code (); + if (isgraph (code)) { + char string[2] = {0}; + snprintf (string, sizeof (string), "%c", code); + + if (strlen (string) != 0) { + ecore_imf_context_commit_event_add (ic->ctx, string); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)string); + caps_mode_check (ctx, EINA_FALSE, EINA_TRUE); + ret = EINA_TRUE; + } + } + } + _panel_client.send (); + return ret; + } + + if (!_focused_ic || !_focused_ic->impl->is_on || + !_focused_ic->impl->si->process_key_event (key)) { + ret = EINA_FALSE; + } + } + + _panel_client.send (); + + return ret; +} + +/** + * Set up an ISE specific data + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[in] data pointer of data to sets up to ISE + * @param[in] length length of data + */ +EAPI void isf_imf_context_imdata_set (Ecore_IMF_Context *ctx, const void* data, int length) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " data length ( " << length << ") ...\n"; + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim == NULL || data == NULL || length <= 0) + return; + + if (context_scim && context_scim->impl) { + if (context_scim->impl->imdata) + free (context_scim->impl->imdata); + + context_scim->impl->imdata = calloc (1, length); + memcpy (context_scim->impl->imdata, data, length); + context_scim->impl->imdata_size = length; + + if (context_scim->impl->si && _focused_ic == context_scim) { + _panel_client.prepare (context_scim->id); + context_scim->impl->si->set_imdata ((const char *)data, length); + _panel_client.send (); + } + } + + isf_imf_context_input_panel_imdata_set (ctx, data, length); +} + +/** + * Get the ISE specific data from ISE + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[out] data pointer of data to return + * @param[out] length length of data + */ +EAPI void isf_imf_context_imdata_get (Ecore_IMF_Context *ctx, void* data, int* length) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + isf_imf_context_input_panel_imdata_get (ctx, data, length); +} + +/* Panel Slot functions */ +static void +panel_slot_reload_config (int context) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _config->reload (); +} + +static void +panel_slot_exit (int /* context */) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + finalize (); +} + +static void +panel_slot_update_candidate_item_layout (int context, const std::vector &row_items) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " row size=" << row_items.size () << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->update_candidate_item_layout (row_items); + _panel_client.send (); + } +} + +static void +panel_slot_update_lookup_table_page_size (int context, int page_size) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " page_size=" << page_size << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->update_lookup_table_page_size (page_size); + _panel_client.send (); + } +} + +static void +panel_slot_lookup_table_page_up (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->lookup_table_page_up (); + _panel_client.send (); + } +} + +static void +panel_slot_lookup_table_page_down (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->lookup_table_page_down (); + _panel_client.send (); + } +} + +static void +panel_slot_trigger_property (int context, const String &property) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " property=" << property << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->trigger_property (property); + _panel_client.send (); + } +} + +static void +panel_slot_process_helper_event (int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " target=" << target_uuid + << " helper=" << helper_uuid << " ic=" << ic << " ic->impl=" << (ic != NULL ? ic->impl : 0) << " ic-uuid=" + << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid () : "" ) << "\n"; + if (ic && ic->impl && ic->impl->si->get_factory_uuid () == target_uuid) { + _panel_client.prepare (ic->id); + SCIM_DEBUG_FRONTEND(2) << "call process_helper_event\n"; + ic->impl->si->process_helper_event (helper_uuid, trans); + _panel_client.send (); + } +} + +static void +panel_slot_move_preedit_caret (int context, int caret_pos) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " caret=" << caret_pos << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->move_preedit_caret (caret_pos); + _panel_client.send (); + } +} + +static void +panel_slot_update_preedit_caret (int context, int caret) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " caret=" << caret << " ic=" << ic << "\n"; + + if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret) { + ic->impl->preedit_caret = caret; + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + ecore_imf_context_preedit_start_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + } + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } else { + _panel_client.prepare (ic->id); + _panel_client.update_preedit_caret (ic->id, caret); + _panel_client.send (); + } + } +} + +static void +panel_slot_select_aux (int context, int aux_index) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " aux=" << aux_index << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->select_aux (aux_index); + _panel_client.send (); + } +} + +static void +panel_slot_select_candidate (int context, int cand_index) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " candidate=" << cand_index << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->select_candidate (cand_index); + _panel_client.send (); + } +} + +static int +_keyname_to_keycode (const char *keyname) +{ + int keycode = 0; + int keysym; + Display *display = (Display *)ecore_x_display_get (); + + keysym = XStringToKeysym (keyname); + + if (!strncmp (keyname, "Keycode-", 8)) { + keycode = atoi (keyname + 8); + } else { + keycode = XKeysymToKeycode (display, keysym); + } + + return keycode; +} + +static Eina_Bool +feed_key_event (EcoreIMFContextISF *ic, const KeyEvent &key, bool fake) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (key.code <= 0x7F || + (key.code >= SCIM_KEY_BackSpace && key.code <= SCIM_KEY_Delete) || + (key.code >= SCIM_KEY_Home && key.code <= SCIM_KEY_Hyper_R)) { + // ascii code and function keys + send_x_key_event (key, fake); + return EINA_TRUE; + } else { + return EINA_FALSE; + } +} + +static void +panel_slot_process_key_event (int context, const KeyEvent &key) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n"; + + if (feed_key_event (ic, key, false) == EINA_TRUE) return; + + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + + if (!filter_hotkeys (ic, key)) { + if (!_focused_ic || !_focused_ic->impl->is_on || + !_focused_ic->impl->si->process_key_event (key)) { + _fallback_instance->process_key_event (key); + } + } + + _panel_client.send (); + } +} + +static void +panel_slot_commit_string (int context, const WideString &wstr) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " str=" << utf8_wcstombs (wstr) << " ic=" << ic << "\n"; + + if (ic && ic->impl) { + if (_focused_ic != ic) + return; + + if (ic->impl->need_commit_preedit) + panel_slot_hide_preedit_string (ic->id); + ecore_imf_context_commit_event_add (ic->ctx, utf8_wcstombs (wstr).c_str ()); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs (wstr).c_str ()); + } +} + +static void +panel_slot_forward_key_event (int context, const KeyEvent &key) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n"; + + if (strlen (key.get_key_string ().c_str ()) >= 116) + return; + + feed_key_event (ic, key, true); +} + +static void +panel_slot_request_help (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + panel_req_show_help (ic); + _panel_client.send (); + } +} + +static void +panel_slot_request_factory_menu (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + panel_req_show_factory_menu (ic); + _panel_client.send (); + } +} + +static void +panel_slot_change_factory (int context, const String &uuid) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " factory=" << uuid << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->reset (); + open_specific_factory (ic, uuid); + _panel_client.send (); + } +} + +static void +panel_slot_reset_keyboard_ise (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + WideString wstr = ic->impl->preedit_string; + if (ic->impl->need_commit_preedit) { + panel_slot_hide_preedit_string (ic->id); + + if (wstr.length ()) { + ecore_imf_context_commit_event_add (ic->ctx, utf8_wcstombs (wstr).c_str ()); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs (wstr).c_str ()); + } + } + _panel_client.prepare (ic->id); + ic->impl->si->reset (); + _panel_client.send (); + } +} + +static void +panel_slot_update_keyboard_ise (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + + _backend->add_module (_config, "socket", false); +} + +static void +panel_slot_show_preedit_string (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << "\n"; + + if (ic && ic->impl && _focused_ic == ic) { + if (!ic->impl->is_on) + ic->impl->is_on = true; + + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + ecore_imf_context_preedit_start_event_add (_focused_ic->ctx); + ecore_imf_context_event_callback_call (_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + ic->impl->need_commit_preedit = true; + } + } else { + _panel_client.prepare (ic->id); + _panel_client.show_preedit_string (ic->id); + _panel_client.send (); + } + } +} + +static void +panel_slot_hide_preedit_string (int context) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = find_ic (context); + + if (ic && ic->impl && _focused_ic == ic) { + if (!ic->impl->is_on) + ic->impl->is_on = true; + + bool emit = false; + if (ic->impl->preedit_string.length ()) { + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + ic->impl->preedit_attrlist.clear (); + emit = true; + } + if (ic->impl->use_preedit) { + if (emit) { + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + if (ic->impl->preedit_started) { + ecore_imf_context_preedit_end_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + ic->impl->preedit_started = false; + ic->impl->need_commit_preedit = false; + } + } else { + _panel_client.prepare (ic->id); + _panel_client.hide_preedit_string (ic->id); + _panel_client.send (); + } + } +} + +static void +panel_slot_update_preedit_string (int context, + const WideString &str, + const AttributeList &attrs) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = find_ic (context); + + if (ic && ic->impl && _focused_ic == ic) { + if (!ic->impl->is_on) + ic->impl->is_on = true; + + if (ic->impl->preedit_string != str || str.length ()) { + ic->impl->preedit_string = str; + ic->impl->preedit_attrlist = attrs; + + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + ecore_imf_context_preedit_start_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + ic->impl->need_commit_preedit = true; + } + ic->impl->preedit_caret = str.length (); + ic->impl->preedit_updating = true; + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ic->impl->preedit_updating = false; + } else { + _panel_client.prepare (ic->id); + _panel_client.update_preedit_string (ic->id, str, attrs); + _panel_client.send (); + } + } + } +} + +static void +panel_slot_get_surrounding_text (int context, int maxlen_before, int maxlen_after) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = find_ic (context); + + if (ic && ic->impl && _focused_ic == ic && ic->impl->si) { + int cursor = 0; + WideString text = WideString (); + slot_get_surrounding_text (ic->impl->si, text, cursor, maxlen_before, maxlen_after); + _panel_client.prepare (ic->id); + _panel_client.update_surrounding_text (ic->id, text, cursor); + _panel_client.send (); + } +} + +static void +panel_slot_delete_surrounding_text (int context, int offset, int len) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = find_ic (context); + + if (ic && ic->impl && _focused_ic == ic && ic->impl->si) + slot_delete_surrounding_text (ic->impl->si, offset, len); +} + +static void +panel_slot_update_displayed_candidate_number (int context, int number) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " number=" << number << " ic=" << ic << "\n"; + if (ic && ic->impl && _focused_ic == ic && ic->impl->si) { + _panel_client.prepare (ic->id); + ic->impl->si->update_displayed_candidate_number (number); + _panel_client.send (); + } +} + +static void +panel_slot_candidate_more_window_show (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl && _focused_ic == ic && ic->impl->si) { + _panel_client.prepare (ic->id); + ic->impl->si->candidate_more_window_show (); + _panel_client.send (); + } +} + +static void +panel_slot_candidate_more_window_hide (int context) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl && _focused_ic == ic && ic->impl->si) { + _panel_client.prepare (ic->id); + ic->impl->si->candidate_more_window_hide (); + _panel_client.send (); + } +} + +static void +panel_slot_longpress_candidate (int context, int index) +{ + EcoreIMFContextISF *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " index=" << index << " ic=" << ic << "\n"; + if (ic && ic->impl && _focused_ic == ic && ic->impl->si) { + _panel_client.prepare (ic->id); + ic->impl->si->longpress_candidate (index); + _panel_client.send (); + } +} + +static void +panel_slot_update_client_id (int context, int client_id) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " client_id=" << client_id << "\n"; + + _panel_client_id = client_id; +} + +/* Panel Requestion functions. */ +static void +panel_req_show_help (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + String help; + + help = String (_("Smart Common Input Method platform ")) + + String (SCIM_VERSION) + + String (_("\n(C) 2002-2005 James Su \n\n")); + + if (ic && ic->impl) { + IMEngineFactoryPointer sf = _backend->get_factory (ic->impl->si->get_factory_uuid ()); + if (sf) { + help += utf8_wcstombs (sf->get_name ()); + help += String (_(":\n\n")); + + help += utf8_wcstombs (sf->get_help ()); + help += String (_("\n\n")); + + help += utf8_wcstombs (sf->get_credits ()); + } + _panel_client.show_help (ic->id, help); + } +} + +static void +panel_req_show_factory_menu (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + std::vector factories; + std::vector menu; + + _backend->get_factories_for_encoding (factories, "UTF-8"); + + for (size_t i = 0; i < factories.size (); ++ i) { + menu.push_back (PanelFactoryInfo ( + factories [i]->get_uuid (), + utf8_wcstombs (factories [i]->get_name ()), + factories [i]->get_language (), + factories [i]->get_icon_file ())); + } + + if (menu.size ()) + _panel_client.show_factory_menu (ic->id, menu); +} + +static void +panel_req_update_factory_info (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl && ic == _focused_ic) { + PanelFactoryInfo info; + if (ic->impl->is_on) { + IMEngineFactoryPointer sf = _backend->get_factory (ic->impl->si->get_factory_uuid ()); + if (sf) + info = PanelFactoryInfo (sf->get_uuid (), utf8_wcstombs (sf->get_name ()), sf->get_language (), sf->get_icon_file ()); + } else { + info = PanelFactoryInfo (String (""), String (_("English/Keyboard")), String ("C"), String (SCIM_KEYBOARD_ICON_FILE)); + } + _panel_client.update_factory_info (ic->id, info); + } +} + +static void +panel_req_focus_in (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _panel_client.focus_in (ic->id, ic->impl->si->get_factory_uuid ()); +} + +static void +panel_req_update_spot_location (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _panel_client.update_spot_location (ic->id, ic->impl->cursor_x, ic->impl->cursor_y, ic->impl->cursor_top_y); +} + +static void +panel_req_update_cursor_position (EcoreIMFContextISF *ic, int cursor_pos) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _panel_client.update_cursor_position (ic->id, cursor_pos); +} + +static bool +filter_hotkeys (EcoreIMFContextISF *ic, const KeyEvent &key) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + bool ret = false; + + _frontend_hotkey_matcher.push_key_event (key); + _imengine_hotkey_matcher.push_key_event (key); + + FrontEndHotkeyAction hotkey_action = _frontend_hotkey_matcher.get_match_result (); + + if (hotkey_action == SCIM_FRONTEND_HOTKEY_TRIGGER) { + if (!ic->impl->is_on) + turn_on_ic (ic); + else + turn_off_ic (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON) { + if (!ic->impl->is_on) + turn_on_ic (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF) { + if (ic->impl->is_on) + turn_off_ic (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_NEXT_FACTORY) { + open_next_factory (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY) { + open_previous_factory (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) { + panel_req_show_factory_menu (ic); + ret = true; + } else if (_imengine_hotkey_matcher.is_matched ()) { + ISEInfo info = _imengine_hotkey_matcher.get_match_result (); + ISE_TYPE type = info.type; + if (type == IMENGINE_T) + open_specific_factory (ic, info.uuid); + else if (type == HELPER_T) + _panel_client.start_helper (ic->id, info.uuid); + ret = true; + } + return ret; +} + +static bool +panel_initialize (void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + String display_name; + { + const char *p = getenv ("DISPLAY"); + if (p) display_name = String (p); + } + + if (_panel_client.open_connection (_config->get_name (), display_name) >= 0) { + int fd = _panel_client.get_connection_number (); + + _panel_iochannel_read_handler = ecore_main_fd_handler_add (fd, ECORE_FD_READ, panel_iochannel_handler, NULL, NULL, NULL); +// _panel_iochannel_err_handler = ecore_main_fd_handler_add (fd, ECORE_FD_ERROR, panel_iochannel_handler, NULL, NULL, NULL); + + SCIM_DEBUG_FRONTEND(2) << " Panel FD= " << fd << "\n"; + + EcoreIMFContextISF *context_scim = _ic_list; + while (context_scim != NULL) { + _panel_client.prepare (context_scim->id); + _panel_client.register_input_context (context_scim->id, context_scim->impl->si->get_factory_uuid ()); + _panel_client.send (); + context_scim = context_scim->next; + } + + if (_focused_ic) { + _panel_client.prepare (_focused_ic->id); + panel_req_focus_in (_focused_ic); + _panel_client.send (); + } + + return true; + } + std::cerr << "panel_initialize () failed!!!\n"; + return false; +} + +static void +panel_finalize (void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _panel_client.close_connection (); + + if (_panel_iochannel_read_handler) { + ecore_main_fd_handler_del (_panel_iochannel_read_handler); + _panel_iochannel_read_handler = 0; + } + if (_panel_iochannel_err_handler) { + ecore_main_fd_handler_del (_panel_iochannel_err_handler); + _panel_iochannel_err_handler = 0; + } +} + +static Eina_Bool +panel_iochannel_handler (void *data, Ecore_Fd_Handler *fd_handler) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (fd_handler == _panel_iochannel_read_handler) { + if (!_panel_client.filter_event ()) { + panel_finalize (); + panel_initialize (); + return ECORE_CALLBACK_CANCEL; + } + } else if (fd_handler == _panel_iochannel_err_handler) { + panel_finalize (); + panel_initialize (); + return ECORE_CALLBACK_CANCEL; + } + return ECORE_CALLBACK_RENEW; +} + +static void +turn_on_ic (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl && !ic->impl->is_on) { + ic->impl->is_on = true; + + if (ic == _focused_ic) { + panel_req_focus_in (ic); +// panel_req_update_spot_location (ic); + panel_req_update_factory_info (ic); + _panel_client.turn_on (ic->id); +// _panel_client.hide_preedit_string (ic->id); +// _panel_client.hide_aux_string (ic->id); +// _panel_client.hide_lookup_table (ic->id); + ic->impl->si->focus_in (); + ic->impl->si->set_layout (ecore_imf_context_input_panel_layout_get (ic->ctx)); + set_prediction_allow (ic->impl->si, ic->impl->prediction_allow); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { + ecore_imf_context_preedit_start_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ic->impl->preedit_started = true; + } + } +} + +static void +turn_off_ic (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl && ic->impl->is_on) { + ic->impl->is_on = false; + + if (ic == _focused_ic) { + ic->impl->si->focus_out (); + +// panel_req_update_factory_info (ic); + _panel_client.turn_off (ic->id); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ecore_imf_context_preedit_end_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + ic->impl->preedit_started = false; + } + } +} + +static void +set_ic_capabilities (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl) { + unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES; + + if (!_on_the_spot || !ic->impl->use_preedit) + cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT; + + ic->impl->si->update_client_capabilities (cap); + } +} + +static bool +check_socket_frontend (void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + SocketAddress address; + SocketClient client; + + uint32 magic; + + address.set_address (scim_get_default_socket_frontend_address ()); + + if (!client.connect (address)) + return false; + + if (!scim_socket_open_connection (magic, + String ("ConnectionTester"), + String ("SocketFrontEnd"), + client, + 1000)) { + return false; + } + + return true; +} + +void +initialize (void) +{ + std::vector config_list; + std::vector engine_list; + std::vector helper_list; + std::vector load_engine_list; + + std::vector::iterator it; + + bool manual = false; + bool socket = true; + String config_module_name = "simple"; + + SCIM_DEBUG_FRONTEND(1) << "Initializing Ecore ISF IMModule...\n"; + + // Get system language. + _language = scim_get_locale_language (scim_get_current_locale ()); + + if (socket) { + // If no Socket FrontEnd is running, then launch one. + // And set manual to false. + bool check_result = check_socket_frontend (); + if (!check_result) { + std::cerr << "Launching a ISF daemon with Socket FrontEnd...\n"; + //get modules list + scim_get_imengine_module_list (engine_list); + scim_get_helper_module_list (helper_list); + + for (it = engine_list.begin (); it != engine_list.end (); it++) { + if (*it != "socket") + load_engine_list.push_back (*it); + } + for (it = helper_list.begin (); it != helper_list.end (); it++) + load_engine_list.push_back (*it); + const char *new_argv [] = { "--no-stay", 0 }; + scim_launch (true, + config_module_name, + (load_engine_list.size () > 0 ? scim_combine_string_list (load_engine_list, ',') : "none"), + "socket", + (char **)new_argv); + manual = false; + } + + // If there is one Socket FrontEnd running and it's not manual mode, + // then just use this Socket Frontend. + if (!manual) { + for (int i = 0; i < 200; ++i) { + if (check_result) { + config_module_name = "socket"; + load_engine_list.clear (); + load_engine_list.push_back ("socket"); + break; + } + scim_usleep (50000); + check_result = check_socket_frontend (); + } + } + } + + if (config_module_name != "dummy") { + //load config module + SCIM_DEBUG_FRONTEND(1) << "Loading Config module: " << config_module_name << "...\n"; + _config_module = new ConfigModule (config_module_name); + + //create config instance + if (_config_module != NULL && _config_module->valid ()) + _config = _config_module->create_config (); + } + + if (_config.null ()) { + SCIM_DEBUG_FRONTEND(1) << "Config module cannot be loaded, using dummy Config.\n"; + + if (_config_module) delete _config_module; + _config_module = NULL; + + _config = new DummyConfig (); + config_module_name = "dummy"; + } + + reload_config_callback (_config); + _config->signal_connect_reload (slot (reload_config_callback)); + + // create backend + _backend = new CommonBackEnd (_config, load_engine_list.size () > 0 ? load_engine_list : engine_list); + + if (_backend.null ()) { + std::cerr << "Cannot create BackEnd Object!\n"; + } else { + _backend->initialize (_config, load_engine_list.size () > 0 ? load_engine_list : engine_list, false, false); + _fallback_factory = _backend->get_factory (SCIM_COMPOSE_KEY_FACTORY_UUID); + } + + if (_fallback_factory.null ()) + _fallback_factory = new DummyIMEngineFactory (); + + _fallback_instance = _fallback_factory->create_instance (String ("UTF-8"), 0); + _fallback_instance->signal_connect_commit_string (slot (fallback_commit_string_cb)); + + // Attach Panel Client signal. + _panel_client.signal_connect_reload_config (slot (panel_slot_reload_config)); + _panel_client.signal_connect_exit (slot (panel_slot_exit)); + _panel_client.signal_connect_update_candidate_item_layout (slot (panel_slot_update_candidate_item_layout)); + _panel_client.signal_connect_update_lookup_table_page_size (slot (panel_slot_update_lookup_table_page_size)); + _panel_client.signal_connect_lookup_table_page_up (slot (panel_slot_lookup_table_page_up)); + _panel_client.signal_connect_lookup_table_page_down (slot (panel_slot_lookup_table_page_down)); + _panel_client.signal_connect_trigger_property (slot (panel_slot_trigger_property)); + _panel_client.signal_connect_process_helper_event (slot (panel_slot_process_helper_event)); + _panel_client.signal_connect_move_preedit_caret (slot (panel_slot_move_preedit_caret)); + _panel_client.signal_connect_update_preedit_caret (slot (panel_slot_update_preedit_caret)); + _panel_client.signal_connect_select_aux (slot (panel_slot_select_aux)); + _panel_client.signal_connect_select_candidate (slot (panel_slot_select_candidate)); + _panel_client.signal_connect_process_key_event (slot (panel_slot_process_key_event)); + _panel_client.signal_connect_commit_string (slot (panel_slot_commit_string)); + _panel_client.signal_connect_forward_key_event (slot (panel_slot_forward_key_event)); + _panel_client.signal_connect_request_help (slot (panel_slot_request_help)); + _panel_client.signal_connect_request_factory_menu (slot (panel_slot_request_factory_menu)); + _panel_client.signal_connect_change_factory (slot (panel_slot_change_factory)); + _panel_client.signal_connect_reset_keyboard_ise (slot (panel_slot_reset_keyboard_ise)); + _panel_client.signal_connect_update_keyboard_ise (slot (panel_slot_update_keyboard_ise)); + _panel_client.signal_connect_show_preedit_string (slot (panel_slot_show_preedit_string)); + _panel_client.signal_connect_hide_preedit_string (slot (panel_slot_hide_preedit_string)); + _panel_client.signal_connect_update_preedit_string (slot (panel_slot_update_preedit_string)); + _panel_client.signal_connect_get_surrounding_text (slot (panel_slot_get_surrounding_text)); + _panel_client.signal_connect_delete_surrounding_text (slot (panel_slot_delete_surrounding_text)); + _panel_client.signal_connect_update_displayed_candidate_number (slot (panel_slot_update_displayed_candidate_number)); + _panel_client.signal_connect_candidate_more_window_show (slot (panel_slot_candidate_more_window_show)); + _panel_client.signal_connect_candidate_more_window_hide (slot (panel_slot_candidate_more_window_hide)); + _panel_client.signal_connect_longpress_candidate (slot (panel_slot_longpress_candidate)); + _panel_client.signal_connect_update_client_id (slot (panel_slot_update_client_id)); + + if (!panel_initialize ()) { + std::cerr << "Ecore IM Module: Cannot connect to Panel!\n"; + } +} + +static void +finalize (void) +{ + SCIM_DEBUG_FRONTEND(1) << "Finalizing Ecore ISF IMModule...\n"; + + // Reset this first so that the shared instance could be released correctly afterwards. + _default_instance.reset (); + + SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n"; + while (_used_ic_impl_list) { + // In case in "shared input method" mode, + // all contexts share only one instance, + // so we need point the reference pointer correctly before finalizing. + _used_ic_impl_list->si->set_frontend_data (static_cast (_used_ic_impl_list->parent)); + isf_imf_context_del (_used_ic_impl_list->parent->ctx); + } + + delete_all_ic_impl (); + + _fallback_instance.reset (); + _fallback_factory.reset (); + + SCIM_DEBUG_FRONTEND(2) << " Releasing BackEnd...\n"; + _backend.reset (); + + SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n"; + _config.reset (); + + if (_config_module) { + SCIM_DEBUG_FRONTEND(2) << " Deleting _config_module...\n"; + delete _config_module; + _config_module = 0; + } + + _focused_ic = NULL; + _ic_list = NULL; + + _scim_initialized = false; + + _panel_client.reset_signal_handler (); + panel_finalize (); +} + +static void +_popup_message (const char *_ptext) +{ + if (_ptext == NULL) + return; + + int ret = -1; + bundle *b = bundle_create (); + do { + ret = bundle_add (b, "0", "info"); // "0" means tickernoti style + if (0 != ret) + break; + ret = bundle_add (b, "1", _ptext); + if (0 != ret) + break; + ret = bundle_add (b, "2", "0"); // "2" means orientation of tickernoti + if (0 != ret) + break; + ret = bundle_add (b, "3", "2"); // "3" means timeout(second) of tickernoti + if (0 != ret) + break; + ret = syspopup_launch ((char *)"tickernoti-syspopup", b); + } + while (0); + bundle_free (b); +} + +static void +open_next_factory (EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; + IMEngineFactoryPointer sf = _backend->get_next_factory ("", "UTF-8", ic->impl->si->get_factory_uuid ()); + + if (!sf.null ()) { + turn_off_ic (ic); + ic->impl->si = sf->create_instance ("UTF-8", ic->impl->si->get_id ()); + ic->impl->si->set_frontend_data (static_cast (ic)); + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + attach_instance (ic->impl->si); + _backend->set_default_factory (_language, sf->get_uuid ()); + _panel_client.register_input_context (ic->id, sf->get_uuid ()); + _panel_client.set_candidate_style (ic->id, ONE_LINE_CANDIDATE, FIXED_CANDIDATE_WINDOW); + set_ic_capabilities (ic); + turn_on_ic (ic); + + if (_shared_input_method) { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + _popup_message (utf8_wcstombs (sf->get_name ()).c_str ()); + } +} + +static void +open_previous_factory (EcoreIMFContextISF *ic) +{ + if (ic == NULL) + return; + + SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; + IMEngineFactoryPointer sf = _backend->get_previous_factory ("", "UTF-8", ic->impl->si->get_factory_uuid ()); + + if (!sf.null ()) { + turn_off_ic (ic); + ic->impl->si = sf->create_instance ("UTF-8", ic->impl->si->get_id ()); + ic->impl->si->set_frontend_data (static_cast (ic)); + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + attach_instance (ic->impl->si); + _backend->set_default_factory (_language, sf->get_uuid ()); + _panel_client.register_input_context (ic->id, sf->get_uuid ()); + _panel_client.set_candidate_style (ic->id, ONE_LINE_CANDIDATE, FIXED_CANDIDATE_WINDOW); + set_ic_capabilities (ic); + turn_on_ic (ic); + + if (_shared_input_method) { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + _popup_message (utf8_wcstombs (sf->get_name ()).c_str ()); + } +} + +static void +open_specific_factory (EcoreIMFContextISF *ic, + const String &uuid) +{ + if (ic == NULL) + return; + + SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; + + // The same input method is selected, just turn on the IC. + if (ic->impl->si->get_factory_uuid () == uuid) { + turn_on_ic (ic); + return; + } + + IMEngineFactoryPointer sf = _backend->get_factory (uuid); + + if (uuid.length () && !sf.null ()) { + turn_off_ic (ic); + ic->impl->si = sf->create_instance ("UTF-8", ic->impl->si->get_id ()); + ic->impl->si->set_frontend_data (static_cast (ic)); + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + attach_instance (ic->impl->si); + _backend->set_default_factory (_language, sf->get_uuid ()); + _panel_client.register_input_context (ic->id, sf->get_uuid ()); + set_ic_capabilities (ic); + turn_on_ic (ic); + + if (_shared_input_method) { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + } else { + std::cerr << "open_specific_factory () is failed!!!!!!\n"; + // turn_off_ic comment out panel_req_update_factory_info () + //turn_off_ic (ic); + if (ic && ic->impl->is_on) { + ic->impl->is_on = false; + + if (ic == _focused_ic) { + ic->impl->si->focus_out (); + + panel_req_update_factory_info (ic); + _panel_client.turn_off (ic->id); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ecore_imf_context_preedit_end_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + ic->impl->preedit_started = false; + } + } + } +} + +static void initialize_modifier_bits (Display *display) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (__current_display == display) + return; + + __current_display = display; + + if (display == 0) { + __current_alt_mask = Mod1Mask; + __current_meta_mask = ShiftMask | Mod1Mask; + __current_super_mask = 0; + __current_hyper_mask = 0; + __current_numlock_mask = Mod2Mask; + return; + } + + XModifierKeymap *mods = NULL; + + ::KeyCode ctrl_l = XKeysymToKeycode (display, XK_Control_L); + ::KeyCode ctrl_r = XKeysymToKeycode (display, XK_Control_R); + ::KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L); + ::KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R); + ::KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L); + ::KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R); + ::KeyCode super_l = XKeysymToKeycode (display, XK_Super_L); + ::KeyCode super_r = XKeysymToKeycode (display, XK_Super_R); + ::KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L); + ::KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R); + ::KeyCode numlock = XKeysymToKeycode (display, XK_Num_Lock); + + int i, j; + + mods = XGetModifierMapping (display); + if (mods == NULL) + return; + + __current_alt_mask = 0; + __current_meta_mask = 0; + __current_super_mask = 0; + __current_hyper_mask = 0; + __current_numlock_mask = 0; + + /* We skip the first three sets for Shift, Lock, and Control. The + remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */ + for (i = 3; i < 8; i++) { + for (j = 0; j < mods->max_keypermod; j++) { + ::KeyCode code = mods->modifiermap [i * mods->max_keypermod + j]; + if (! code) continue; + if (code == alt_l || code == alt_r) + __current_alt_mask |= (1 << i); + else if (code == meta_l || code == meta_r) + __current_meta_mask |= (1 << i); + else if (code == super_l || code == super_r) + __current_super_mask |= (1 << i); + else if (code == hyper_l || code == hyper_r) + __current_hyper_mask |= (1 << i); + else if (code == numlock) + __current_numlock_mask |= (1 << i); + } + } + + /* Check whether there is a combine keys mapped to Meta */ + if (__current_meta_mask == 0) { + char buf [32]; + XKeyEvent xkey; + KeySym keysym_l, keysym_r; + + xkey.type = KeyPress; + xkey.display = display; + xkey.serial = 0L; + xkey.send_event = False; + xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0; + xkey.time = 0; + xkey.same_screen = False; + xkey.subwindow = None; + xkey.window = None; + xkey.root = DefaultRootWindow (display); + xkey.state = ShiftMask; + + xkey.keycode = meta_l; + XLookupString (&xkey, buf, 32, &keysym_l, 0); + xkey.keycode = meta_r; + XLookupString (&xkey, buf, 32, &keysym_r, 0); + + if ((meta_l == alt_l && keysym_l == XK_Meta_L) || (meta_r == alt_r && keysym_r == XK_Meta_R)) + __current_meta_mask = ShiftMask + __current_alt_mask; + else if ((meta_l == ctrl_l && keysym_l == XK_Meta_L) || (meta_r == ctrl_r && keysym_r == XK_Meta_R)) + __current_meta_mask = ShiftMask + ControlMask; + } + + XFreeModifiermap (mods); +} + +static unsigned int scim_x11_keymask_scim_to_x11 (Display *display, uint16 scimkeymask) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + unsigned int state = 0; + + initialize_modifier_bits (display); + + if (scimkeymask & SCIM_KEY_ShiftMask) state |= ShiftMask; + if (scimkeymask & SCIM_KEY_CapsLockMask) state |= LockMask; + if (scimkeymask & SCIM_KEY_ControlMask) state |= ControlMask; + if (scimkeymask & SCIM_KEY_AltMask) state |= __current_alt_mask; + if (scimkeymask & SCIM_KEY_MetaMask) state |= __current_meta_mask; + if (scimkeymask & SCIM_KEY_SuperMask) state |= __current_super_mask; + if (scimkeymask & SCIM_KEY_HyperMask) state |= __current_hyper_mask; + if (scimkeymask & SCIM_KEY_NumLockMask) state |= __current_numlock_mask; + + return state; +} + +static XKeyEvent createKeyEvent (bool press, int keycode, int modifiers, bool fake) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + XKeyEvent event; + Window focus_win; + Display *display = (Display *)ecore_x_display_get (); + int revert = RevertToParent; + + XGetInputFocus (display, &focus_win, &revert); + + event.display = display; + event.window = focus_win; + event.root = DefaultRootWindow (display); + event.subwindow = None; + if (fake) + event.time = 0; + else + event.time = get_time (); + + event.x = 1; + event.y = 1; + event.x_root = 1; + event.y_root = 1; + event.same_screen = True; + event.state = modifiers; + event.keycode = keycode; + if (press) + event.type = KeyPress; + else + event.type = KeyRelease; + event.send_event = False; + event.serial = 0; + + return event; +} + +static void send_x_key_event (const KeyEvent &key, bool fake) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + ::KeyCode keycode = 0; + ::KeySym keysym = 0; + int shift = 0; + char key_string[256] = {0}; + char keysym_str[256] = {0}; + + // Obtain the X11 display. + Display *display = (Display *)ecore_x_display_get (); + if (display == NULL) { + std::cerr << "ecore_x_display_get () failed\n"; + return; + } + + if (strncmp (key.get_key_string ().c_str (), "KeyRelease+", 11) == 0) { + snprintf (key_string, sizeof (key_string), "%s", key.get_key_string ().c_str () + 11); + } else { + snprintf (key_string, sizeof (key_string), "%s", key.get_key_string ().c_str ()); + } + + if (strncmp (key_string, "Shift+", 6) == 0) { + snprintf (keysym_str, sizeof (keysym_str), "%s", key_string + 6); + } else { + snprintf (keysym_str, sizeof (keysym_str), "%s", key_string); + } + + // get x keysym, keycode, keyname, and key + keysym = XStringToKeysym (keysym_str); + if (keysym == NoSymbol) + return; + + keycode = _keyname_to_keycode (keysym_str); + if (XkbKeycodeToKeysym (display, keycode, 0, 0) != keysym) { + if (XkbKeycodeToKeysym (display, keycode, 0, 1) == keysym) + shift = 1; + else + keycode = 0; + } else { + shift = 0; + } + + if (keycode == 0) { + static int mod = 0; + KeySym *keysyms; + int keycode_min, keycode_max, keycode_num; + int i; + + XDisplayKeycodes (display, &keycode_min, &keycode_max); + keysyms = XGetKeyboardMapping (display, keycode_min, + keycode_max - keycode_min + 1, + &keycode_num); + mod = (mod + 1) & 0x7; + i = (keycode_max - keycode_min - mod - 1) * keycode_num; + + keysyms[i] = keysym; + XChangeKeyboardMapping (display, keycode_min, keycode_num, + keysyms, (keycode_max - keycode_min)); + XFree (keysyms); + XSync (display, False); + keycode = keycode_max - mod - 1; + } + + unsigned int modifier = scim_x11_keymask_scim_to_x11 (display, key.mask); + + if (shift) + modifier |= ShiftMask; + + XKeyEvent event; + if (key.is_key_press ()) { + if (shift) { + event = createKeyEvent (true, XKeysymToKeycode (display, XK_Shift_L), modifier, fake); + XSendEvent (event.display, event.window, True, KeyPressMask, (XEvent *)&event); + } + + event = createKeyEvent (true, keycode, modifier, fake); + XSendEvent (event.display, event.window, True, KeyPressMask, (XEvent *)&event); + } else { + event = createKeyEvent (false, keycode, modifier, fake); + XSendEvent (event.display, event.window, True, KeyReleaseMask, (XEvent *)&event); + + if (shift) { + event = createKeyEvent (false, XKeysymToKeycode (display, XK_Shift_L), modifier, fake); + XSendEvent (event.display, event.window, True, KeyReleaseMask, (XEvent *)&event); + } + } +} + +static void +attach_instance (const IMEngineInstancePointer &si) +{ + si->signal_connect_show_preedit_string ( + slot (slot_show_preedit_string)); + si->signal_connect_show_aux_string ( + slot (slot_show_aux_string)); + si->signal_connect_show_lookup_table ( + slot (slot_show_lookup_table)); + + si->signal_connect_hide_preedit_string ( + slot (slot_hide_preedit_string)); + si->signal_connect_hide_aux_string ( + slot (slot_hide_aux_string)); + si->signal_connect_hide_lookup_table ( + slot (slot_hide_lookup_table)); + + si->signal_connect_update_preedit_caret ( + slot (slot_update_preedit_caret)); + si->signal_connect_update_preedit_string ( + slot (slot_update_preedit_string)); + si->signal_connect_update_aux_string ( + slot (slot_update_aux_string)); + si->signal_connect_update_lookup_table ( + slot (slot_update_lookup_table)); + + si->signal_connect_commit_string ( + slot (slot_commit_string)); + + si->signal_connect_forward_key_event ( + slot (slot_forward_key_event)); + + si->signal_connect_register_properties ( + slot (slot_register_properties)); + + si->signal_connect_update_property ( + slot (slot_update_property)); + + si->signal_connect_beep ( + slot (slot_beep)); + + si->signal_connect_start_helper ( + slot (slot_start_helper)); + + si->signal_connect_stop_helper ( + slot (slot_stop_helper)); + + si->signal_connect_send_helper_event ( + slot (slot_send_helper_event)); + + si->signal_connect_get_surrounding_text ( + slot (slot_get_surrounding_text)); + + si->signal_connect_delete_surrounding_text ( + slot (slot_delete_surrounding_text)); + + si->signal_connect_expand_candidate ( + slot (slot_expand_candidate)); + si->signal_connect_contract_candidate ( + slot (slot_contract_candidate)); + + si->signal_connect_set_candidate_style ( + slot (slot_set_candidate_style)); +} + +// Implementation of slot functions +static void +slot_show_preedit_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) { + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + ecore_imf_context_preedit_start_event_add (_focused_ic->ctx); + ecore_imf_context_event_callback_call (_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + } + //if (ic->impl->preedit_string.length ()) + // ecore_imf_context_preedit_changed_event_add (_focused_ic->ctx); + } else { + _panel_client.show_preedit_string (ic->id); + } + } +} + +static void +slot_show_aux_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.show_aux_string (ic->id); +} + +static void +slot_show_lookup_table (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.show_lookup_table (ic->id); +} + +static void +slot_hide_preedit_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) { + bool emit = false; + if (ic->impl->preedit_string.length ()) { + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + ic->impl->preedit_attrlist.clear (); + emit = true; + } + if (ic->impl->use_preedit) { + if (emit) { + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + if (ic->impl->preedit_started) { + ecore_imf_context_preedit_end_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + ic->impl->preedit_started = false; + } + } else { + _panel_client.hide_preedit_string (ic->id); + } + } +} + +static void +slot_hide_aux_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.hide_aux_string (ic->id); +} + +static void +slot_hide_lookup_table (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.hide_lookup_table (ic->id); +} + +static void +slot_update_preedit_caret (IMEngineInstanceBase *si, int caret) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret) { + ic->impl->preedit_caret = caret; + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + ecore_imf_context_preedit_start_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + } + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } else { + _panel_client.update_preedit_caret (ic->id, caret); + } + } +} + +static void +slot_update_preedit_string (IMEngineInstanceBase *si, + const WideString & str, + const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic && (ic->impl->preedit_string != str || str.length ())) { + ic->impl->preedit_string = str; + ic->impl->preedit_attrlist = attrs; + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + ecore_imf_context_preedit_start_event_add (_focused_ic->ctx); + ecore_imf_context_event_callback_call (_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + } + ic->impl->preedit_caret = str.length (); + ic->impl->preedit_updating = true; + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ic->impl->preedit_updating = false; + } else { + _panel_client.update_preedit_string (ic->id, str, attrs); + } + } +} + +static void +slot_update_aux_string (IMEngineInstanceBase *si, + const WideString & str, + const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_aux_string (ic->id, str, attrs); +} + +static void +slot_commit_string (IMEngineInstanceBase *si, + const WideString & str) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->ctx) { + if (strcmp (utf8_wcstombs (str).c_str (), " ") == 0) + autoperiod_insert (ic->ctx); + + ecore_imf_context_commit_event_add (ic->ctx, utf8_wcstombs (str).c_str ()); + ecore_imf_context_event_callback_call (ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs (str).c_str ()); + } +} + +static void +slot_forward_key_event (IMEngineInstanceBase *si, + const KeyEvent & key) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && _focused_ic == ic) { + if (!_fallback_instance->process_key_event (key)) { + feed_key_event (ic, key, true); + } + } +} + +static void +slot_update_lookup_table (IMEngineInstanceBase *si, + const LookupTable & table) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_lookup_table (ic->id, table); +} + +static void +slot_register_properties (IMEngineInstanceBase *si, + const PropertyList & properties) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.register_properties (ic->id, properties); +} + +static void +slot_update_property (IMEngineInstanceBase *si, + const Property & property) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_property (ic->id, property); +} + +static void +slot_beep (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + ecore_x_bell (0); +} + +static void +slot_start_helper (IMEngineInstanceBase *si, + const String &helper_uuid) +{ + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" + << (ic != NULL ? ic->id : -1) << " ic=" << ic + << " ic-uuid=" << ((ic != NULL ) ? ic->impl->si->get_factory_uuid () : "") << "...\n"; + + if (ic && ic->impl) + _panel_client.start_helper (ic->id, helper_uuid); +} + +static void +slot_stop_helper (IMEngineInstanceBase *si, + const String &helper_uuid) +{ + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" << (ic != NULL ? ic->id : -1) << " ic=" << ic << "...\n"; + + if (ic && ic->impl) + _panel_client.stop_helper (ic->id, helper_uuid); +} + +static void +slot_send_helper_event (IMEngineInstanceBase *si, + const String &helper_uuid, + const Transaction &trans) +{ + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" + << (ic != NULL ? ic->id : -1) << " ic=" << ic + << " ic-uuid=" << ((ic != NULL) ? ic->impl->si->get_factory_uuid () : "") << "...\n"; + + if (ic && ic->impl) + _panel_client.send_helper_event (ic->id, helper_uuid, trans); +} + +static bool +slot_get_surrounding_text (IMEngineInstanceBase *si, + WideString &text, + int &cursor, + int maxlen_before, + int maxlen_after) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) { + char *surrounding = NULL; + int cursor_index; + if (ecore_imf_context_surrounding_get (_focused_ic->ctx, &surrounding, &cursor_index)) { + SCIM_DEBUG_FRONTEND(2) << "Surrounding text: " << surrounding <<"\n"; + SCIM_DEBUG_FRONTEND(2) << "Cursor Index : " << cursor_index <<"\n"; + WideString before = utf8_mbstowcs (String (surrounding)); + if (cursor_index > before.length()) + return false; + WideString after = before; + before = before.substr (0, cursor_index); + after = after.substr (cursor_index, after.length () - cursor_index); + if (maxlen_before > 0 && ((unsigned int)maxlen_before) < before.length ()) + before = WideString (before.begin () + (before.length () - maxlen_before), before.end ()); + else if (maxlen_before == 0) + before = WideString (); + if (maxlen_after > 0 && ((unsigned int)maxlen_after) < after.length ()) + after = WideString (after.begin (), after.begin () + maxlen_after); + else if (maxlen_after == 0) + after = WideString (); + text = before + after; + cursor = before.length (); + return true; + } + } + return false; +} + +static bool +slot_delete_surrounding_text (IMEngineInstanceBase *si, + int offset, + int len) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) { + Ecore_IMF_Event_Delete_Surrounding ev; + ev.ctx = _focused_ic->ctx; + ev.n_chars = len; + ev.offset = offset; + ecore_imf_context_delete_surrounding_event_add (_focused_ic->ctx, offset, len); + ecore_imf_context_event_callback_call (_focused_ic->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev); + return true; + } + return false; +} + +static void +slot_expand_candidate (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.expand_candidate (ic->id); +} + +static void +slot_contract_candidate (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.contract_candidate (ic->id); +} + +static void +slot_set_candidate_style (IMEngineInstanceBase *si, ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line, ISF_CANDIDATE_MODE_T mode) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.set_candidate_style (ic->id, portrait_line, mode); +} + +static void +reload_config_callback (const ConfigPointer &config) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _frontend_hotkey_matcher.load_hotkeys (config); + _imengine_hotkey_matcher.load_hotkeys (config); + + KeyEvent key; + scim_string_to_key (key, + config->read (String (SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK), + String ("Shift+Control+Alt+Lock"))); + + _valid_key_mask = (key.mask > 0) ? (key.mask) : 0xFFFF; + _valid_key_mask |= SCIM_KEY_ReleaseMask; + // Special treatment for two backslash keys on jp106 keyboard. + _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask; + + _on_the_spot = config->read (String (SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot); + _shared_input_method = config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method); + + // Get keyboard layout setting + // Flush the global config first, in order to load the new configs from disk. + scim_global_config_flush (); + + _keyboard_layout = scim_get_default_keyboard_layout (); +} + +static void +fallback_commit_string_cb (IMEngineInstanceBase *si, + const WideString &str) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (_focused_ic && _focused_ic->impl) { + ecore_imf_context_commit_event_add (_focused_ic->ctx, utf8_wcstombs (str).c_str ()); + ecore_imf_context_event_callback_call (_focused_ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs (str).c_str ()); + } +} + +/* +vi:ts=4:expandtab:nowrap +*/ diff --git a/ism/extras/efl_immodule/isf_imf_context.h b/ism/extras/efl_immodule/isf_imf_context.h new file mode 100644 index 0000000..cc1c027 --- /dev/null +++ b/ism/extras/efl_immodule/isf_imf_context.h @@ -0,0 +1,83 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_IMF_CONTEXT_H +#define __ISF_IMF_CONTEXT_H + +#include +#include +#include + +#define LOG_TAG "immodule" + +typedef struct _EcoreIMFContextISF EcoreIMFContextISF; +typedef struct _EcoreIMFContextISFImpl EcoreIMFContextISFImpl; + +struct _EcoreIMFContextISF { + Ecore_IMF_Context *ctx; + + EcoreIMFContextISFImpl *impl; + + int id; /* Input Context id*/ + struct _EcoreIMFContextISF *next; +}; + +int register_key_handler (); +int unregister_key_handler (); + +int get_panel_client_id (); +Eina_Bool get_desktop_mode (); +Eina_Bool caps_mode_check (Ecore_IMF_Context *ctx, Eina_Bool force, Eina_Bool noti); + +EcoreIMFContextISF *get_focused_ic (); + +void context_scim_imdata_get (Ecore_IMF_Context *ctx, void* data, int* length); + +void isf_imf_context_add (Ecore_IMF_Context *ctx); +void isf_imf_context_del (Ecore_IMF_Context *ctx); +void isf_imf_context_client_window_set (Ecore_IMF_Context *ctx, void *window); +void isf_imf_context_client_canvas_set (Ecore_IMF_Context *ctx, void *window); +void isf_imf_context_focus_in (Ecore_IMF_Context *ctx); +void isf_imf_context_focus_out (Ecore_IMF_Context *ctx); +void isf_imf_context_reset (Ecore_IMF_Context *ctx); +void isf_imf_context_cursor_position_set (Ecore_IMF_Context *ctx, int cursor_pos); +void isf_imf_context_cursor_location_set (Ecore_IMF_Context *ctx, int x, int y, int w, int h); +void isf_imf_context_input_mode_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); +void isf_imf_context_preedit_string_get (Ecore_IMF_Context *ctx, char** str, int *cursor_pos); +void isf_imf_context_preedit_string_with_attributes_get (Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos); +void isf_imf_context_use_preedit_set (Ecore_IMF_Context* ctx, Eina_Bool use_preedit); +Eina_Bool isf_imf_context_filter_event (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); +void isf_imf_context_prediction_allow_set (Ecore_IMF_Context* ctx, Eina_Bool prediction); +void isf_imf_context_autocapital_type_set (Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type); +void isf_imf_context_imdata_set (Ecore_IMF_Context* ctx, const void *data, int len); +void isf_imf_context_imdata_get (Ecore_IMF_Context* ctx, void *data, int *len); + +EcoreIMFContextISF* isf_imf_context_new (void); +void isf_imf_context_shutdown (void); + +#endif /* __ISF_IMF_CONTEXT_H */ + +/* +vi:ts=4:expandtab:nowrap +*/ diff --git a/ism/extras/efl_immodule/isf_imf_control.cpp b/ism/extras/efl_immodule/isf_imf_control.cpp new file mode 100644 index 0000000..f62abdc --- /dev/null +++ b/ism/extras/efl_immodule/isf_imf_control.cpp @@ -0,0 +1,334 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_TRANSACTION +#define Uses_ISF_IMCONTROL_CLIENT + +#include +#include +#include +#include "isf_imf_control.h" +#include "scim.h" + + +using namespace scim; + + +//#define IMFCONTROLDBG(str...) printf(str) +#define IMFCONTROLDBG(str...) +#define IMFCONTROLERR(str...) printf(str) + + +static Ecore_Fd_Handler *_read_handler = 0; +static IMControlClient _imcontrol_client; + + +extern void ecore_ise_process_data (Transaction &trans, int cmd); + + +static int isf_socket_wait_for_data_internal (int socket_id, int timeout) +{ + fd_set fds; + struct timeval tv; + struct timeval begin_tv; + int ret; + + int m_id = socket_id; + + if (timeout >= 0) { + gettimeofday (&begin_tv, 0); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + } + + while (1) { + FD_ZERO (&fds); + FD_SET (m_id, &fds); + + ret = select (m_id + 1, &fds, NULL, NULL, (timeout >= 0) ? &tv : NULL); + if (timeout > 0) { + int elapsed; + struct timeval cur_tv; + gettimeofday (&cur_tv, 0); + elapsed = (cur_tv.tv_sec - begin_tv.tv_sec) * 1000 + + (cur_tv.tv_usec - begin_tv.tv_usec) / 1000; + timeout = timeout - elapsed; + if (timeout > 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + } else { + tv.tv_sec = 0; + tv.tv_usec = 0; + timeout = 0; + } + } + if (ret > 0) { + return ret; + } else if (ret == 0) { + if (timeout == 0) + return ret; + else + continue; + } + + if (errno == EINTR) + continue; + + return ret; + } +} + +static Eina_Bool ecore_ise_input_handler (void *data, Ecore_Fd_Handler *fd_handler) +{ + int cmd; + int timeout = 0; + Transaction trans; + + if (fd_handler == NULL) + return ECORE_CALLBACK_RENEW; + + int fd = ecore_main_fd_handler_fd_get (fd_handler); + if (_imcontrol_client.is_connected () && + isf_socket_wait_for_data_internal (fd, timeout) > 0) { + trans.clear (); + if (!trans.read_from_socket (fd, timeout)) { + IMFCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + _isf_imf_control_finalize (); + return ECORE_CALLBACK_CANCEL; + } + + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST) { + while (trans.get_command (cmd)) { + ecore_ise_process_data (trans, cmd); + } + } + return ECORE_CALLBACK_RENEW; + } + IMFCONTROLERR ("ecore_ise_input_handler is failed!!!\n"); + _isf_imf_control_finalize (); + return ECORE_CALLBACK_CANCEL; +} + +static void connect_panel (void) +{ + if (!_imcontrol_client.is_connected ()) { + _imcontrol_client.open_connection (); + int fd = _imcontrol_client.get_panel2imclient_connection_number (); + if (fd > 0) { + _read_handler = ecore_main_fd_handler_add (fd, ECORE_FD_READ, ecore_ise_input_handler, NULL, NULL, NULL); + } + } +} + +EAPI void _isf_imf_control_finalize (void) +{ + IMFCONTROLDBG ("%s ...\n", __FUNCTION__); + + _imcontrol_client.close_connection (); + + if (_read_handler) { + ecore_main_fd_handler_del (_read_handler); + _read_handler = 0; + } +} + +EAPI int _isf_imf_context_input_panel_show (int client_id, int context, void *data, int length, bool &input_panel_show) +{ + int temp = 0; + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.show_ise (client_id, context, data, length, &temp); + input_panel_show = (bool)temp; + return 0; +} + +EAPI int _isf_imf_context_input_panel_hide (int client_id, int context) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.hide_ise (client_id, context); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_control_panel_show (void) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.show_control_panel (); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_control_panel_hide (void) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.hide_control_panel (); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_input_panel_language_set (Ecore_IMF_Input_Panel_Lang lang) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.set_ise_language (lang); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_input_panel_language_locale_get (char **locale) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.get_ise_language_locale (locale); + return 0; +} + +EAPI int _isf_imf_context_input_panel_imdata_set (const void *data, int len) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.set_imdata ((const char *)data, len); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_input_panel_imdata_get (void *data, int *len) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.get_imdata ((char *)data, len); + return 0; +} + +EAPI int _isf_imf_context_input_panel_geometry_get (int *x, int *y, int *w, int *h) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.get_ise_window_geometry (x, y, w, h); + return 0; +} + +EAPI int _isf_imf_context_input_panel_return_key_type_set (Ecore_IMF_Input_Panel_Return_Key_Type type) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.set_return_key_type ((int)type); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_input_panel_return_key_type_get (Ecore_IMF_Input_Panel_Return_Key_Type &type) +{ + int temp = 0; + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.get_return_key_type (temp); + type = (Ecore_IMF_Input_Panel_Return_Key_Type)temp; + return 0; +} + +EAPI int _isf_imf_context_input_panel_return_key_disabled_set (Eina_Bool disabled) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.set_return_key_disable ((int)disabled); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_input_panel_return_key_disabled_get (Eina_Bool &disabled) +{ + int temp = 0; + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.get_return_key_disable (temp); + disabled = (Eina_Bool)temp; + return 0; +} + +EAPI int _isf_imf_context_input_panel_layout_set (Ecore_IMF_Input_Panel_Layout layout) +{ + int layout_temp = layout; + + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.set_layout (layout_temp); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_input_panel_layout_get (Ecore_IMF_Input_Panel_Layout *layout) +{ + int layout_temp; + + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.get_layout (&layout_temp); + + *layout = (Ecore_IMF_Input_Panel_Layout)layout_temp; + return 0; +} + +EAPI int _isf_imf_context_input_panel_caps_mode_set (unsigned int mode) +{ + connect_panel (); + + _imcontrol_client.prepare (); + _imcontrol_client.set_caps_mode (mode); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_candidate_window_geometry_get (int *x, int *y, int *w, int *h) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.get_candidate_window_geometry (x, y, w, h); + return 0; +} + +EAPI int _isf_imf_context_control_focus_in (void) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.focus_in (); + _imcontrol_client.send (); + return 0; +} + +EAPI int _isf_imf_context_control_focus_out (void) +{ + connect_panel (); + _imcontrol_client.prepare (); + _imcontrol_client.focus_out (); + _imcontrol_client.send (); + return 0; +} + +/* +vi:ts=4:expandtab:nowrap +*/ diff --git a/ism/extras/efl_immodule/isf_imf_control.h b/ism/extras/efl_immodule/isf_imf_control.h new file mode 100644 index 0000000..e5e8fe5 --- /dev/null +++ b/ism/extras/efl_immodule/isf_imf_control.h @@ -0,0 +1,67 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_IMF_CONTROL_H +#define __ISF_IMF_CONTROL_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /* non UI related works */ + void _isf_imf_control_finalize (void); + + int _isf_imf_context_input_panel_show (int client_id, int context, void *data, int length, bool &input_panel_show); + int _isf_imf_context_input_panel_hide (int client_id, int context); + int _isf_imf_context_control_panel_show (void); + int _isf_imf_context_control_panel_hide (void); + + int _isf_imf_context_input_panel_language_set (Ecore_IMF_Input_Panel_Lang lang); + int _isf_imf_context_input_panel_language_locale_get (char **locale); + + int _isf_imf_context_input_panel_imdata_set (const void *data, int len); + int _isf_imf_context_input_panel_imdata_get (void *data, int *len); + int _isf_imf_context_input_panel_geometry_get (int *x, int *y, int *w, int *h); + int _isf_imf_context_input_panel_layout_set (Ecore_IMF_Input_Panel_Layout layout); + int _isf_imf_context_input_panel_layout_get (Ecore_IMF_Input_Panel_Layout *layout); + int _isf_imf_context_input_panel_return_key_type_set (Ecore_IMF_Input_Panel_Return_Key_Type type); + int _isf_imf_context_input_panel_return_key_type_get (Ecore_IMF_Input_Panel_Return_Key_Type &type); + int _isf_imf_context_input_panel_return_key_disabled_set (Eina_Bool disabled); + int _isf_imf_context_input_panel_return_key_disabled_get (Eina_Bool &disabled); + int _isf_imf_context_input_panel_caps_mode_set (unsigned int mode); + + int _isf_imf_context_candidate_window_geometry_get (int *x, int *y, int *w, int *h); + + int _isf_imf_context_control_focus_in (void); + int _isf_imf_context_control_focus_out (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __ISF_IMF_CONTROL_H */ + diff --git a/ism/extras/efl_immodule/isf_imf_control_ui.cpp b/ism/extras/efl_immodule/isf_imf_control_ui.cpp new file mode 100644 index 0000000..246083e --- /dev/null +++ b/ism/extras/efl_immodule/isf_imf_control_ui.cpp @@ -0,0 +1,882 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_TRANSACTION + + +/* IM control UI part */ +#include +#include +#include +#include +#include "scim.h" +#include "isf_imf_control_ui.h" +#include "isf_imf_context.h" +#include "isf_imf_control.h" +#include "ise_context.h" + +using namespace scim; + +typedef struct { + void (*func)(void *data, Ecore_IMF_Context *ctx, int value); + void *data; + Ecore_IMF_Input_Panel_Event type; + Ecore_IMF_Context *imf_context; +} EventCallbackNode; + +/* IM control related variables */ +static Ise_Context iseContext; +static bool IfInitContext = false; +static Eina_List *EventCallbackList = NULL; +static Ecore_IMF_Context *show_req_ic = NULL; +static Ecore_IMF_Context *hide_req_ic = NULL; +static Ecore_Event_Handler *_prop_change_handler = NULL; +static Ecore_X_Atom prop_x_ext_keyboard_exist = 0; +static Ecore_X_Window _rootwin; +static unsigned int hw_kbd_num = 0; +static Ecore_Timer *hide_timer = NULL; +static Ecore_IMF_Input_Panel_State input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE; +static int hide_context_id = -1; +Ecore_IMF_Context *input_panel_ctx = NULL; + +static Eina_Bool _clear_timer () +{ + if (hide_timer) { + ecore_timer_del (hide_timer); + hide_timer = NULL; + return EINA_TRUE; + } + + return EINA_FALSE; +} + +static Eina_Bool _prop_change (void *data, int ev_type, void *ev) +{ + Ecore_X_Event_Window_Property *event = (Ecore_X_Event_Window_Property *)ev; + unsigned int val = 0; + + if (event->win != _rootwin) return ECORE_CALLBACK_PASS_ON; + if (event->atom != prop_x_ext_keyboard_exist) return ECORE_CALLBACK_PASS_ON; + + if (!ecore_x_window_prop_card32_get (event->win, prop_x_ext_keyboard_exist, &val, 1) > 0) + return ECORE_CALLBACK_PASS_ON; + + if (val != 0) { + if (show_req_ic) + ecore_imf_context_input_panel_hide (show_req_ic); + } + + hw_kbd_num = val; + LOGD ("The number of connected H/W keyboard : %d\n", hw_kbd_num); + + return ECORE_CALLBACK_PASS_ON; +} + +static Ecore_X_Window _client_window_id_get (Ecore_IMF_Context *ctx) +{ + Ecore_X_Window xid = 0; + Evas *evas = NULL; + Ecore_Evas *ee = NULL; + + evas = (Evas *)ecore_imf_context_client_canvas_get (ctx); + + if (evas) { + ee = ecore_evas_ecore_evas_get (evas); + if (ee) + xid = (Ecore_X_Window)ecore_evas_window_get (ee); + } else { + xid = (Ecore_X_Window)ecore_imf_context_client_window_get (ctx); + } + + return xid; +} + +static void _save_current_xid (Ecore_IMF_Context *ctx) +{ + Ecore_X_Window xid = 0, rootwin_xid = 0; + + xid = _client_window_id_get (ctx); + + if (xid == 0) + rootwin_xid = ecore_x_window_root_first_get (); + else + rootwin_xid = ecore_x_window_root_get (xid); + Ecore_X_Atom isf_active_window_atom = ecore_x_atom_get ("_ISF_ACTIVE_WINDOW"); + ecore_x_window_prop_property_set (rootwin_xid, isf_active_window_atom, ((Ecore_X_Atom) 33), 32, &xid, 1); + ecore_x_flush (); + ecore_x_sync (); +} + +static void _event_callback_call (Ecore_IMF_Input_Panel_Event type, int value) +{ + void *list_data = NULL; + EventCallbackNode *fn = NULL; + Eina_List *l = NULL; + Ecore_IMF_Context *using_ic = NULL; + + if (show_req_ic) + using_ic = show_req_ic; + else if (get_focused_ic ()) + using_ic = get_focused_ic ()->ctx; + + if (type == ECORE_IMF_INPUT_PANEL_STATE_EVENT && + value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + if (hide_req_ic) { + using_ic = hide_req_ic; + } + } + + EINA_LIST_FOREACH(EventCallbackList, l, list_data) { + fn = (EventCallbackNode *)list_data; + + if ((fn) && (fn->imf_context == using_ic) && + (fn->type == type) && (fn->func)) { + fn->func (fn->data, fn->imf_context, value); + if (type == ECORE_IMF_INPUT_PANEL_STATE_EVENT) { + switch (value) + { + case ECORE_IMF_INPUT_PANEL_STATE_HIDE: + LOGD ("[input panel has been hidden] ctx : %p\n", fn->imf_context); + hide_req_ic = NULL; + break; + case ECORE_IMF_INPUT_PANEL_STATE_SHOW: + LOGD ("[input panel has been shown] ctx : %p\n", fn->imf_context); + break; + case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW: + LOGD ("[input panel will be shown] ctx : %p\n", fn->imf_context); + break; + } + } + } + } +} + +static void _isf_imf_context_init (void) +{ + iseContext.language = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC; + iseContext.return_key_type = ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT; + iseContext.return_key_disabled = FALSE; + iseContext.prediction_allow = TRUE; + + if (!IfInitContext) { + IfInitContext = true; + } +} + +static int _get_context_id (Ecore_IMF_Context *ctx) +{ + EcoreIMFContextISF *context_scim = NULL; + if (!ctx) return -1; + + context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + if (!context_scim) return -1; + + return context_scim->id; +} + +static void _send_input_panel_hide_request () +{ + if (hide_context_id < 0) return; + + _isf_imf_context_input_panel_hide (get_panel_client_id (), hide_context_id); + hide_context_id = -1; +} + +static Eina_Bool _hide_timer_handler (void *data) +{ + _send_input_panel_hide_request (); + + hide_timer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void _input_panel_hide_timer_start (void *data) +{ + Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)data; + hide_context_id = _get_context_id (ctx); + + if (!hide_timer) + hide_timer = ecore_timer_add (0.05, _hide_timer_handler, data); +} + +static void _input_panel_hide (Ecore_IMF_Context *ctx, Eina_Bool instant) +{ + if (IfInitContext == false) { + _isf_imf_context_init (); + } + + if (input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_SHOW) { + hide_req_ic = ctx; + } + + if (instant) { + _clear_timer (); + + hide_context_id = _get_context_id (ctx); + _send_input_panel_hide_request (); + } else { + _input_panel_hide_timer_start (ctx); + } +} + +static Eina_Bool _compare_context (Ecore_IMF_Context *ctx1, Ecore_IMF_Context *ctx2) +{ + if (!ctx1 || !ctx2) return EINA_FALSE; + + if ((ecore_imf_context_autocapital_type_get (ctx1) == ecore_imf_context_autocapital_type_get (ctx2)) && + (ecore_imf_context_input_panel_layout_get (ctx1) == ecore_imf_context_input_panel_layout_get (ctx2)) && + (ecore_imf_context_input_panel_language_get (ctx1) == ecore_imf_context_input_panel_language_get (ctx2)) && + (ecore_imf_context_input_panel_return_key_type_get (ctx1) == ecore_imf_context_input_panel_return_key_type_get (ctx2)) && + (ecore_imf_context_input_panel_return_key_disabled_get (ctx1) == ecore_imf_context_input_panel_return_key_disabled_get (ctx2)) && + (ecore_imf_context_input_panel_caps_lock_mode_get (ctx1) == ecore_imf_context_input_panel_caps_lock_mode_get (ctx2))) + return EINA_TRUE; + + return EINA_FALSE; +} + +EAPI void input_panel_event_callback_call (Ecore_IMF_Input_Panel_Event type, int value) +{ + _event_callback_call (type, value); +} + +EAPI void isf_imf_context_control_panel_show (Ecore_IMF_Context *ctx) +{ + if (IfInitContext == false) { + _isf_imf_context_init (); + } + _isf_imf_context_control_panel_show (); +} + +EAPI void isf_imf_context_control_panel_hide (Ecore_IMF_Context *ctx) +{ + if (IfInitContext == false) { + _isf_imf_context_init (); + } + _isf_imf_context_control_panel_hide (); +} + +EAPI void isf_imf_input_panel_init (void) +{ + if (_prop_change_handler) return; + + _rootwin = ecore_x_window_root_first_get (); + ecore_x_event_mask_set (_rootwin, ECORE_X_EVENT_MASK_WINDOW_PROPERTY); + + _prop_change_handler = ecore_event_handler_add (ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, NULL); + + if (!prop_x_ext_keyboard_exist) + prop_x_ext_keyboard_exist = ecore_x_atom_get (PROP_X_EXT_KEYBOARD_EXIST); + + if (!ecore_x_window_prop_card32_get (_rootwin, prop_x_ext_keyboard_exist, &hw_kbd_num, 1)) { + printf ("Error! cannot get hw_kbd_num\n"); + return; + } + + LOGD ("The number of connected H/W keyboard : %d\n", hw_kbd_num); +} + +EAPI void isf_imf_input_panel_shutdown (void) +{ + if (_prop_change_handler) { + ecore_event_handler_del (_prop_change_handler); + _prop_change_handler = NULL; + } + + if (hide_timer) { + if (input_panel_state != ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + Ecore_IMF_Context *using_ic = NULL; + + if (show_req_ic) + using_ic = show_req_ic; + else if (get_focused_ic ()) + using_ic = get_focused_ic ()->ctx; + + hide_context_id = _get_context_id (using_ic); + _send_input_panel_hide_request (); + } + } + + _clear_timer (); + + _isf_imf_control_finalize (); +} + +EAPI void isf_imf_context_input_panel_show (Ecore_IMF_Context* ctx) +{ + int length = -1; + void *packet = NULL; + char imdata[1024] = {0}; + bool input_panel_show = false; + input_panel_ctx = ctx; + + if (IfInitContext == false) { + _isf_imf_context_init (); + } + + /* set password mode */ + iseContext.password_mode = !!(ecore_imf_context_input_mode_get (ctx) & ECORE_IMF_INPUT_MODE_INVISIBLE); + + /* set language */ + iseContext.language = ecore_imf_context_input_panel_language_get (ctx); + + /* set layout in ise context info */ + iseContext.layout = ecore_imf_context_input_panel_layout_get (ctx); + + /* set prediction allow */ + iseContext.prediction_allow = ecore_imf_context_prediction_allow_get (ctx); + + if (iseContext.layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD) + iseContext.password_mode = EINA_TRUE; + + if (iseContext.password_mode) + iseContext.prediction_allow = EINA_FALSE; + + if (iseContext.layout == ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL || + iseContext.layout == ECORE_IMF_INPUT_PANEL_LAYOUT_URL || + iseContext.layout == ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL) + iseContext.prediction_allow = EINA_FALSE; + + isf_imf_context_prediction_allow_set (ctx, iseContext.prediction_allow); + /* Set the current XID of the active window into the root window property */ + _save_current_xid (ctx); + + if (get_desktop_mode ()) { + LOGD ("IME will not appear in case of desktop mode.\n"); + return; + } + + if (hw_kbd_num != 0) { + LOGD ("H/W keyboard is existed.\n"); + printf ("H/W keyboard is existed.\n"); + return; + } + + if (_clear_timer ()) { + hide_req_ic = NULL; + } + + if ((show_req_ic == ctx) && + (_compare_context (show_req_ic, ctx) == EINA_TRUE) && + (input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW || + input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_SHOW)) { + return; + } + + show_req_ic = ctx; + + LOGD ("===============================================================\n"); + LOGD ("[request to show input panel] ctx : %p\n", ctx); + LOGD (" - language : %d\n", iseContext.language); + LOGD (" - layout : %d\n", iseContext.layout); + + /* set return key type */ + iseContext.return_key_type = ecore_imf_context_input_panel_return_key_type_get (ctx); + LOGD (" - return_key_type : %d\n", iseContext.return_key_type); + + /* set return key disabled */ + iseContext.return_key_disabled = ecore_imf_context_input_panel_return_key_disabled_get (ctx); + LOGD (" - return_key_disabled : %d\n", iseContext.return_key_disabled); + + /* set caps mode */ + iseContext.caps_mode = caps_mode_check (ctx, EINA_TRUE, EINA_FALSE); + LOGD (" - caps mode : %d\n", iseContext.caps_mode); + + /* set X Client window ID */ + iseContext.client_window = _client_window_id_get (ctx); + LOGD (" - client_window : %#x\n", iseContext.client_window); + + /* set the size of imdata */ + context_scim_imdata_get (ctx, (void *)imdata, &iseContext.imdata_size); + + LOGD (" - password mode : %d\n", iseContext.password_mode); + LOGD (" - prediction_allow : %d\n", iseContext.prediction_allow); + + /* set the cursor position of the editable widget */ + ecore_imf_context_surrounding_get (ctx, NULL, &iseContext.cursor_pos); + LOGD (" - cursor position : %d\n", iseContext.cursor_pos); + + /* calculate packet size */ + length = sizeof (iseContext); + length += iseContext.imdata_size; + + /* create packet */ + packet = calloc (1, length); + if (!packet) + return; + + memcpy (packet, (void *)&iseContext, sizeof (iseContext)); + + memcpy ((void *)((unsigned int)packet + sizeof (iseContext)), (void *)imdata, iseContext.imdata_size); + + int context_id = _get_context_id (ctx); + + _isf_imf_context_input_panel_show (get_panel_client_id (), context_id, packet, length, input_panel_show); + + if (input_panel_show == true && input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) + input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW; + + free (packet); + + caps_mode_check (ctx, EINA_TRUE, EINA_TRUE); + LOGD ("===============================================================\n"); +} + +EAPI void isf_imf_context_input_panel_hide (Ecore_IMF_Context *ctx) +{ + LOGD ("ctx : %p\n", ctx); + + if (get_desktop_mode ()) + return; + + _input_panel_hide (ctx, EINA_FALSE); +} + +EAPI void isf_imf_context_input_panel_instant_hide (Ecore_IMF_Context *ctx) +{ + if (get_desktop_mode ()) + return; + + _input_panel_hide (ctx, EINA_TRUE); +} + +EAPI void isf_imf_context_input_panel_language_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang language) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!IfInitContext) + _isf_imf_context_init (); + iseContext.language = language; + + if (context_scim == get_focused_ic ()) + _isf_imf_context_input_panel_language_set (language); +} + +EAPI Ecore_IMF_Input_Panel_Lang isf_imf_context_input_panel_language_get (Ecore_IMF_Context *ctx) +{ + if (!IfInitContext) + _isf_imf_context_init (); + return iseContext.language; +} + +EAPI void isf_imf_context_input_panel_language_locale_get (Ecore_IMF_Context *ctx, char **locale) +{ + if (!IfInitContext) + _isf_imf_context_init (); + + if (locale) + _isf_imf_context_input_panel_language_locale_get (locale); +} + +EAPI void isf_imf_context_input_panel_caps_mode_set (Ecore_IMF_Context *ctx, unsigned int mode) +{ + if (!IfInitContext) + _isf_imf_context_init (); + _isf_imf_context_input_panel_caps_mode_set (mode); +} + +EAPI void isf_imf_context_input_panel_caps_lock_mode_set (Ecore_IMF_Context *ctx, Eina_Bool mode) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!IfInitContext) + _isf_imf_context_init (); + + if (context_scim == get_focused_ic ()) + caps_mode_check(ctx, EINA_TRUE, EINA_TRUE); +} + +/** + * Set up an ISE specific data + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[in] data pointer of data to sets up to ISE + * @param[in] length length of data + */ +EAPI void isf_imf_context_input_panel_imdata_set (Ecore_IMF_Context *ctx, const void* data, int length) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (context_scim == get_focused_ic ()) + _isf_imf_context_input_panel_imdata_set (data, length); +} + +/** + * Get the ISE specific data from ISE + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[out] data pointer of data to return + * @param[out] length length of data + */ +EAPI void isf_imf_context_input_panel_imdata_get (Ecore_IMF_Context *ctx, void* data, int* length) +{ + if (!IfInitContext) + _isf_imf_context_init (); + _isf_imf_context_input_panel_imdata_get (data, length); +} + +/** + * Get ISE's position and size, in screen coodinates of the ISE rectangle not the client area, + * the represents the size and location of the ISE + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[out] x the x position of ISE window + * @param[out] y the y position of ISE window + * @param[out] w the width of ISE window + * @param[out] h the height of ISE window + */ +EAPI void isf_imf_context_input_panel_geometry_get (Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) +{ + if (!IfInitContext) + _isf_imf_context_init (); + _isf_imf_context_input_panel_geometry_get (x, y, w, h); + + LOGD ("ctx : %p, x : %d, y : %d, w : %d, h : %d\n", ctx, *x, *y, *w, *h); +} + +/** + * Set type of return key. + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[in] type the type of return key + */ +EAPI void isf_imf_context_input_panel_return_key_type_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type type) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!IfInitContext) + _isf_imf_context_init (); + + if (context_scim == get_focused_ic ()) { + _isf_imf_context_input_panel_return_key_type_set (type); + } +} + +/** + * Get type of return key. + * + * @param[in] ctx a #Ecore_IMF_Context + * + * @return the type of return key. + */ +EAPI Ecore_IMF_Input_Panel_Return_Key_Type isf_imf_context_input_panel_return_key_type_get (Ecore_IMF_Context *ctx) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!IfInitContext) + _isf_imf_context_init (); + + Ecore_IMF_Input_Panel_Return_Key_Type type = ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT; + if (context_scim == get_focused_ic ()) + _isf_imf_context_input_panel_return_key_type_get (type); + + return type; +} + +/** + * Make return key to be disabled in active ISE keyboard layout for own's application. + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[in] disabled the state + */ +EAPI void isf_imf_context_input_panel_return_key_disabled_set (Ecore_IMF_Context *ctx, Eina_Bool disabled) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!IfInitContext) + _isf_imf_context_init (); + + if (context_scim == get_focused_ic ()) + _isf_imf_context_input_panel_return_key_disabled_set (disabled); +} + +/** + * Get the disabled status of return key. + * + * @param[in] ctx a #Ecore_IMF_Context + * + * @return the disable state of return key. + */ +EAPI Eina_Bool isf_imf_context_input_panel_return_key_disabled_get (Ecore_IMF_Context *ctx) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!IfInitContext) + _isf_imf_context_init (); + + Eina_Bool disabled = EINA_FALSE; + if (context_scim == get_focused_ic ()) + _isf_imf_context_input_panel_return_key_disabled_get (disabled); + + return disabled; +} + +/** + * Sets up the layout infomation of active ISE + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[in] layout sets a layout ID to be shown. The layout ID will define by the configuration of selected ISE. + */ +EAPI void +isf_imf_context_input_panel_layout_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx); + + if (!IfInitContext) + _isf_imf_context_init (); + + if (context_scim == get_focused_ic ()) + _isf_imf_context_input_panel_layout_set (layout); +} + +/** +* Get current ISE layout +* +* @param[in] ctx a #Ecore_IMF_Context +* +* @return the layout of current ISE. +*/ +EAPI Ecore_IMF_Input_Panel_Layout isf_imf_context_input_panel_layout_get (Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Input_Panel_Layout layout; + if (!IfInitContext) + _isf_imf_context_init (); + _isf_imf_context_input_panel_layout_get (&layout); + + return layout; +} + +/** + * Get current ISE state + * + * @param[in] ctx a #Ecore_IMF_Context + * + * @return the state of current ISE. + */ +EAPI Ecore_IMF_Input_Panel_State isf_imf_context_input_panel_state_get (Ecore_IMF_Context *ctx) +{ + if (!IfInitContext) + _isf_imf_context_init (); + return input_panel_state; +} + +EAPI void isf_imf_context_input_panel_event_callback_add (Ecore_IMF_Context *ctx, + Ecore_IMF_Input_Panel_Event type, + void (*func) (void *data, Ecore_IMF_Context *ctx, int value), + void *data) +{ + EventCallbackNode *fn = (EventCallbackNode *)calloc (1, sizeof (EventCallbackNode)); + if (!fn) + return; + + LOGD ("ctx : %p, type : %d, func : %p\n", ctx, type, func); + + fn->func = func; + fn->data = data; + fn->type = type; + fn->imf_context = ctx; + + EventCallbackList = eina_list_append (EventCallbackList, fn); +} + +EAPI void isf_imf_context_input_panel_event_callback_del (Ecore_IMF_Context *ctx, + Ecore_IMF_Input_Panel_Event type, + void (*func) (void *data, Ecore_IMF_Context *ctx, int value)) +{ + Eina_List *l = NULL; + EventCallbackNode *fn = NULL; + + LOGD ("ctx : %p, type : %d, func : %p\n", ctx, type, func); + + for (l = EventCallbackList; l;) { + fn = (EventCallbackNode *)l->data; + + if ((fn) && (fn->func == func) && (fn->type == type) && (fn->imf_context == ctx)) { + EventCallbackList = eina_list_remove (EventCallbackList, fn); + free (fn); + break; + } + l = l->next; + } +} + +EAPI void isf_imf_context_input_panel_event_callback_clear (Ecore_IMF_Context *ctx) +{ + Eina_List *l; + EventCallbackNode *fn; + + LOGD ("ctx : %p\n", ctx); + + for (l = EventCallbackList; l;) { + fn = (EventCallbackNode *)l->data; + + if ((fn) && (fn->imf_context == ctx)) { + EventCallbackList = eina_list_remove (EventCallbackList, fn); + free (fn); + } + l = l->next; + } +} + +/** + * Get candidate window position and size, in screen coodinates of the candidate rectangle not the client area, + * the represents the size and location of the candidate window + * + * @param[in] ctx a #Ecore_IMF_Context + * @param[out] x the x position of candidate window + * @param[out] y the y position of candidate window + * @param[out] w the width of candidate window + * @param[out] h the height of candidate window + */ +EAPI void isf_imf_context_candidate_window_geometry_get (Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) +{ + if (!IfInitContext) + _isf_imf_context_init (); + _isf_imf_context_candidate_window_geometry_get (x, y, w, h); + + LOGD ("ctx : %p, x : %d, y : %d, w : %d, h : %d\n", ctx, *x, *y, *w, *h); +} + +/** + * This method should be called when focus in + * + * @param[in] ctx a #Ecore_IMF_Context + */ +EAPI void isf_imf_context_control_focus_in (Ecore_IMF_Context *ctx) +{ + if (IfInitContext == false) { + _isf_imf_context_init (); + } + /* Set the current XID of the active window into the root window property */ + _save_current_xid (ctx); + _isf_imf_context_control_focus_in (); +} + +/** + * This method should be called when focus out + * + * @param[in] ctx a #Ecore_IMF_Context + */ +EAPI void isf_imf_context_control_focus_out (Ecore_IMF_Context *ctx) +{ + if (IfInitContext == false) { + _isf_imf_context_init (); + } + _isf_imf_context_control_focus_out (); +} + +/** + * process command message, ISM_TRANS_CMD_ISE_PANEL_SHOWED of ecore_ise_process_event() + */ +static bool _process_ise_panel_showed (void) +{ + /* When the size of ISE gets changed, STATE_SHOW is be delivered again to letting applications know the change. + Later, an event type for notifying the size change of ISE needs to be added instead. */ + input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_SHOW; + + /* Notify that ISE status has changed */ + _event_callback_call (ECORE_IMF_INPUT_PANEL_STATE_EVENT, ECORE_IMF_INPUT_PANEL_STATE_SHOW); + + return true; +} + +/** + * process command message, ISM_TRANS_CMD_ISE_PANEL_HIDED of ecore_ise_process_event() + */ +static bool _process_ise_panel_hided (void) +{ + if (input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + return false; + } + + input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE; + + /* Notify that ISE status has changed */ + _event_callback_call (ECORE_IMF_INPUT_PANEL_STATE_EVENT, ECORE_IMF_INPUT_PANEL_STATE_HIDE); + + return true; +} + +/** + * process command message, ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT of gtk_ise_process_event() + */ +static bool _process_update_input_context (Transaction &trans) +{ + uint32 type; + uint32 value; + + if (!(trans.get_data (type) && trans.get_data (value))) + return false; + + if (type == (uint32)ECORE_IMF_INPUT_PANEL_STATE_EVENT) { + switch(value) + { + case ECORE_IMF_INPUT_PANEL_STATE_HIDE: + _process_ise_panel_hided (); + return true; + case ECORE_IMF_INPUT_PANEL_STATE_SHOW: + _process_ise_panel_showed (); + return true; + case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW: + input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW; + break; + default: + break; + } + } + + _event_callback_call ((Ecore_IMF_Input_Panel_Event)type, (int)value); + + return true; +} + +/** + * process ISE data of command message with ISF + * + * @param[in] trans packet data to be processed + * @param[in] cmd command ID that defines with ISF + */ +void ecore_ise_process_data (Transaction &trans, int cmd) +{ + switch (cmd) { + case ISM_TRANS_CMD_ISE_PANEL_SHOWED : { + _process_ise_panel_showed (); + break; + } + case ISM_TRANS_CMD_ISE_PANEL_HIDED : { + _process_ise_panel_hided (); + break; + } + case ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT : { + _process_update_input_context (trans); + break; + } + case ISM_TRANS_CMD_UPDATE_ISF_CANDIDATE_PANEL : { + _process_update_input_context (trans); + break; + } + default : + break; + } +} + diff --git a/ism/extras/efl_immodule/isf_imf_control_ui.h b/ism/extras/efl_immodule/isf_imf_control_ui.h new file mode 100644 index 0000000..0163440 --- /dev/null +++ b/ism/extras/efl_immodule/isf_imf_control_ui.h @@ -0,0 +1,73 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_IMF_CONTROL_UI_H +#define __ISF_IMF_CONTROL_UI_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /* non UI related works */ + void isf_imf_input_panel_init (); + void isf_imf_input_panel_shutdown (); + void isf_imf_context_input_panel_show (Ecore_IMF_Context *ctx); + void isf_imf_context_input_panel_hide (Ecore_IMF_Context *ctx); + void isf_imf_context_input_panel_instant_hide (Ecore_IMF_Context *ctx); + void isf_imf_context_control_panel_show (Ecore_IMF_Context *ctx); + void isf_imf_context_control_panel_hide (Ecore_IMF_Context *ctx); + void isf_imf_context_input_panel_language_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); + Ecore_IMF_Input_Panel_Lang isf_imf_context_input_panel_language_get (Ecore_IMF_Context *ctx); + void isf_imf_context_input_panel_language_locale_get (Ecore_IMF_Context *ctx, char **locale); + void isf_imf_context_input_panel_imdata_set (Ecore_IMF_Context *ctx, const void* data, int len); + void isf_imf_context_input_panel_imdata_get (Ecore_IMF_Context *ctx, void* data, int* len); + void isf_imf_context_input_panel_geometry_get (Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); + void isf_imf_context_input_panel_layout_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); + Ecore_IMF_Input_Panel_Layout isf_imf_context_input_panel_layout_get (Ecore_IMF_Context *ctx); + Ecore_IMF_Input_Panel_State isf_imf_context_input_panel_state_get (Ecore_IMF_Context *ctx); + void isf_imf_context_input_panel_caps_mode_set (Ecore_IMF_Context *ctx, unsigned int mode); + void isf_imf_context_input_panel_event_callback_add (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), void *data); + void isf_imf_context_input_panel_event_callback_del (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); + void isf_imf_context_input_panel_event_callback_clear (Ecore_IMF_Context *ctx); + + void isf_imf_context_input_panel_return_key_type_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type type); + Ecore_IMF_Input_Panel_Return_Key_Type isf_imf_context_input_panel_return_key_type_get (Ecore_IMF_Context *ctx); + void isf_imf_context_input_panel_return_key_disabled_set (Ecore_IMF_Context *ctx, Eina_Bool disabled); + Eina_Bool isf_imf_context_input_panel_return_key_disabled_get (Ecore_IMF_Context *ctx); + void isf_imf_context_input_panel_caps_lock_mode_set (Ecore_IMF_Context *ctx, Eina_Bool mode); + void isf_imf_context_candidate_window_geometry_get (Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); + void input_panel_event_callback_call (Ecore_IMF_Input_Panel_Event type, int value); + + void isf_imf_context_control_focus_in (Ecore_IMF_Context *ctx); + void isf_imf_context_control_focus_out (Ecore_IMF_Context *ctx); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __ISF_IMF_CONTROL_UI_H */ + diff --git a/ism/extras/efl_immodule/isf_imf_module.cpp b/ism/extras/efl_immodule/isf_imf_module.cpp new file mode 100644 index 0000000..29149f6 --- /dev/null +++ b/ism/extras/efl_immodule/isf_imf_module.cpp @@ -0,0 +1,128 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include "isf_imf_context.h" +#include "isf_imf_control_ui.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + static const Ecore_IMF_Context_Info isf_imf_info = { + "isf", /* ID */ + "Input Service Framework for Ecore", /* Description */ + "*", /* Default locales */ + NULL, /* Canvas type */ + 0 /* Canvas required */ + }; + + static Ecore_IMF_Context_Class isf_imf_class = { + isf_imf_context_add, /* add */ + isf_imf_context_del, /* del */ + isf_imf_context_client_window_set, /* client_window_set */ + isf_imf_context_client_canvas_set, /* client_canvas_set */ + isf_imf_context_input_panel_show, /* show */ + isf_imf_context_input_panel_hide, /* hide */ + isf_imf_context_preedit_string_get, /* get_preedit_string */ + isf_imf_context_focus_in, /* focus_in */ + isf_imf_context_focus_out, /* focus_out */ + isf_imf_context_reset, /* reset */ + isf_imf_context_cursor_position_set, /* cursor_position_set */ + isf_imf_context_use_preedit_set, /* use_preedit_set */ + isf_imf_context_input_mode_set, /* input_mode_set */ + isf_imf_context_filter_event, /* filter_event */ + isf_imf_context_preedit_string_with_attributes_get, + isf_imf_context_prediction_allow_set, + isf_imf_context_autocapital_type_set, + isf_imf_context_control_panel_show, + isf_imf_context_control_panel_hide, + isf_imf_context_input_panel_layout_set, + isf_imf_context_input_panel_layout_get, + isf_imf_context_input_panel_language_set, + isf_imf_context_input_panel_language_get, + isf_imf_context_cursor_location_set, + isf_imf_context_imdata_set, + isf_imf_context_imdata_get, + isf_imf_context_input_panel_return_key_type_set, + isf_imf_context_input_panel_return_key_disabled_set, + isf_imf_context_input_panel_caps_lock_mode_set, + isf_imf_context_input_panel_geometry_get, + isf_imf_context_input_panel_state_get, + isf_imf_context_input_panel_event_callback_add, + isf_imf_context_input_panel_event_callback_del, + isf_imf_context_input_panel_language_locale_get, + isf_imf_context_candidate_window_geometry_get + }; + + static Ecore_IMF_Context *imf_module_create (void); + static Ecore_IMF_Context *imf_module_exit (void); + + static Eina_Bool imf_module_init (void) { + ecore_imf_module_register (&isf_imf_info, imf_module_create, imf_module_exit); + register_key_handler (); + return EINA_TRUE; + } + + static void imf_module_shutdown (void) { + unregister_key_handler (); + isf_imf_context_shutdown (); + } + + static Ecore_IMF_Context *imf_module_create (void) { + Ecore_IMF_Context *ctx = NULL; + EcoreIMFContextISF *ctxd = NULL; + + ctxd = isf_imf_context_new (); + if (!ctxd) { + printf ("isf_imf_context_new () failed!!!\n"); + return NULL; + } + + ctx = ecore_imf_context_new (&isf_imf_class); + if (!ctx) { + delete ctxd; + return NULL; + } + + ecore_imf_context_data_set (ctx, ctxd); + + return ctx; + } + + static Ecore_IMF_Context *imf_module_exit (void) { + return NULL; + } + + EINA_MODULE_INIT(imf_module_init); + EINA_MODULE_SHUTDOWN(imf_module_shutdown); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* +vi:ts=4:expandtab:nowrap +*/ diff --git a/ism/extras/efl_panel/Makefile.am b/ism/extras/efl_panel/Makefile.am new file mode 100644 index 0000000..89fbb51 --- /dev/null +++ b/ism/extras/efl_panel/Makefile.am @@ -0,0 +1,39 @@ +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak *.edj + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/data \ + -I$(top_srcdir)/ism/utils \ + -I$(includedir) \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" + +noinst_HEADERS = isf_panel_utility.h + +if ISF_BUILD_PANEL_EFL +CONFIG_SCIM_PANEL_EFL = isf-panel-efl +endif + +bin_PROGRAMS = $(CONFIG_SCIM_PANEL_EFL) + +isf_panel_efl_SOURCES = isf_panel_efl.cpp \ + isf_panel_utility.cpp + +isf_panel_efl_CXXFLAGS = @EFL_CFLAGS@ @VCONF_CFLAGS@ @PRIVILEGE_CONTROL_CFLAGS@ + +isf_panel_efl_LDFLAGS = @EFL_LIBS@ @LTLIBINTL@ -rpath $(libdir) \ + @VCONF_LIBS@ \ + @X11_LIBS@ \ + @PRIVILEGE_CONTROL_LIBS@ + +isf_panel_efl_LDADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la + diff --git a/ism/extras/efl_panel/isf_panel_efl.cpp b/ism/extras/efl_panel/isf_panel_efl.cpp new file mode 100644 index 0000000..5321062 --- /dev/null +++ b/ism/extras/efl_panel/isf_panel_efl.cpp @@ -0,0 +1,3448 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_PANEL_AGENT +#define Uses_SCIM_COMPOSE_KEY +#define Uses_SCIM_IMENGINE_MODULE +#define WAIT_WM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "scim_stl_map.h" +#if HAVE_VCONF +#include +#include +#endif +#include +#include "isf_panel_utility.h" + + +using namespace scim; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of macro. +///////////////////////////////////////////////////////////////////////////// +#define EFL_CANDIDATE_THEME1 (SCIM_DATADIR "/isf_candidate_theme1.edj") + +#define ISF_CANDIDATE_TABLE 0 + +#define ISF_EFL_AUX 1 +#define ISF_EFL_CANDIDATE_0 2 +#define ISF_EFL_CANDIDATE_ITEMS 3 + +#define ISE_DEFAULT_HEIGHT_PORTRAIT 444 +#define ISE_DEFAULT_HEIGHT_LANDSCAPE 316 + +#define ISF_READY_FILE "/tmp/hibernation/isf_ready" + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of external variables. +///////////////////////////////////////////////////////////////////////////// +extern MapStringVectorSizeT _groups; +extern std::vector _uuids; +extern std::vector _names; +extern std::vector _module_names; +extern std::vector _langs; +extern std::vector _icons; +extern std::vector _options; +extern std::vector _modes; + +extern std::vector _load_ise_list; + +extern CommonLookupTable g_isf_candidate_table; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal data types. +///////////////////////////////////////////////////////////////////////////// +typedef enum _VIRTUAL_KEYBOARD_STATE { + KEYBOARD_STATE_UNKNOWN = 0, + KEYBOARD_STATE_OFF, + KEYBOARD_STATE_ON, +} VIRTUAL_KEYBOARD_STATE; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal functions. +///////////////////////////////////////////////////////////////////////////// +static Evas_Object *efl_create_window (const char *strWinName, const char *strEffect); +static void efl_set_transient_for_app_window (Evas_Object *win_obj); +static int efl_get_angle_for_root_window (Evas_Object *win_obj); + +static int ui_candidate_get_valid_height (void); +static void ui_candidate_hide (bool bForce, bool bSetVirtualKbd = true); +static void ui_destroy_candidate_window (void); +static void ui_settle_candidate_window (void); +static void ui_candidate_show (bool bSetVirtualKbd = true); +static void ui_create_candidate_window (void); +static void update_table (int table_type, const LookupTable &table); + +/* PanelAgent related functions */ +static bool initialize_panel_agent (const String &config, const String &display, bool resident); + +static void slot_reload_config (void); +static void slot_focus_in (void); +static void slot_focus_out (void); +static void slot_expand_candidate (void); +static void slot_contract_candidate (void); +static void slot_set_candidate_style (int portrait_line, int mode); +static void slot_update_input_context (int type, int value); +static void slot_update_ise_geometry (int x, int y, int width, int height); +static void slot_update_spot_location (int x, int y, int top_y); +static void slot_update_factory_info (const PanelFactoryInfo &info); +static void slot_show_aux_string (void); +static void slot_show_candidate_table (void); +static void slot_hide_aux_string (void); +static void slot_hide_candidate_table (void); +static void slot_update_aux_string (const String &str, const AttributeList &attrs); +static void slot_update_candidate_table (const LookupTable &table); +static void slot_set_active_ise (const String &uuid, bool changeDefault); +static bool slot_get_ise_list (std::vector &list); +static bool slot_get_ise_information (String uuid, String &name, String &language, int &type, int &option); +static bool slot_get_keyboard_ise_list (std::vector &name_list); +static void slot_get_language_list (std::vector &name); +static void slot_get_all_language (std::vector &lang); +static void slot_get_ise_language (char *name, std::vector &list); +static bool slot_get_ise_info (const String &uuid, ISE_INFO &info); +static void slot_get_candidate_geometry (struct rectinfo &info); +static void slot_get_input_panel_geometry (struct rectinfo &info); +static void slot_set_keyboard_ise (const String &uuid); +static void slot_get_keyboard_ise (String &ise_name, String &ise_uuid); +static void slot_accept_connection (int fd); +static void slot_close_connection (int fd); +static void slot_exit (void); + +static Eina_Bool panel_agent_handler (void *data, Ecore_Fd_Handler *fd_handler); + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal variables. +///////////////////////////////////////////////////////////////////////////// +static Evas_Object *_candidate_window = 0; +static Evas_Object *_candidate_area_1 = 0; +static Evas_Object *_candidate_area_2 = 0; +static Evas_Object *_candidate_bg = 0; +static Evas_Object *_candidate_0_scroll = 0; +static Evas_Object *_candidate_scroll = 0; +static Evas_Object *_scroller_bg = 0; +static Evas_Object *_candidate_0_table = 0; +static Evas_Object *_candidate_table = 0; +static Evas_Object *_candidate_0 [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; +static Evas_Object *_candidate_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; +static Evas_Object *_seperate_0 [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; +static Evas_Object *_seperate_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; +static Evas_Object *_line_0 [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; +static Evas_Object *_line_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; +static Evas_Object *_more_btn = 0; +static Evas_Object *_close_btn = 0; +static bool _candidate_window_show = false; + +static int _candidate_x = 0; +static int _candidate_y = 0; +static int _candidate_width = 0; +static int _candidate_height = 0; +static int _candidate_valid_height = 0; + +static ISF_CANDIDATE_MODE_T _candidate_mode = FIXED_CANDIDATE_WINDOW; +static ISF_CANDIDATE_PORTRAIT_LINE_T _candidate_port_line = ONE_LINE_CANDIDATE; + +static int _candidate_port_width = 480; +static int _candidate_port_height_min = 76; +static int _candidate_port_height_min_2 = 150; +static int _candidate_port_height_max = 286; +static int _candidate_port_height_max_2 = 350; +static int _candidate_land_width = 784; +static int _candidate_land_height_min = 84; +static int _candidate_land_height_min_2 = 168; +static int _candidate_land_height_max = 150; +static int _candidate_land_height_max_2 = 214; +static int _candidate_area_1_pos [2] = {0, 2}; +static int _more_btn_pos [4] = {369, 11, 689, 11}; +static int _close_btn_pos [4] = {362, 211, 682, 75}; + +static int _v_padding = 2; +static int _item_min_width = 99; +static int _item_min_height = 82; + +static int _candidate_scroll_0_width_min = 350; +static int _candidate_scroll_0_width_max = 670; + +static int _candidate_scroll_width = 453; +static int _candidate_scroll_width_min = 453; +static int _candidate_scroll_width_max = 663; +static int _candidate_scroll_height_min = 124; +static int _candidate_scroll_height_max = 190; + +static Evas_Object *_aux_area = 0; +static Evas_Object *_aux_line = 0; +static Evas_Object *_aux_table = 0; +static int _aux_height = 0; +static int _aux_port_width = 444; +static int _aux_land_width = 764; +static std::vector _aux_items; + +static Evas_Object *_tmp_aux_text = 0; +static Evas_Object *_tmp_candidate_text = 0; + +static int _spot_location_x = -1; +static int _spot_location_y = -1; +static int _spot_location_top_y = -1; +static int _candidate_angle = 0; + +static int _ise_width = 0; +static int _ise_height = 0; +static bool _ise_show = false; + +static int _indicator_height = 0;//24; +static int _screen_width = 720; +static int _screen_height = 1280; +static float _width_rate = 1.0; +static float _height_rate = 1.0; +static int _blank_width = 30; + +static String _candidate_name = String ("candidate"); +static String _candidate_edje_file = String (EFL_CANDIDATE_THEME1); + +static String _candidate_font_name = String ("Tizen"); +static int _candidate_font_size = 38; +static int _aux_font_size = 38; +static int _click_object = 0; +static int _click_down_pos [2] = {0, 0}; +static int _click_up_pos [2] = {0, 0}; +static bool _is_click = true; + +static String _initial_ise_uuid = String (""); +static ConfigPointer _config; +static PanelAgent *_panel_agent = 0; +static std::vector _read_handler_list; + +static clock_t _clock_start; + +static Ecore_Timer *_check_size_timer = NULL; +static Ecore_Timer *_longpress_timer = NULL; +static Ecore_Timer *_destroy_timer = NULL; + + +///////////////////////////////////////////////////////////////////////////// +// Implementation of internal functions. +///////////////////////////////////////////////////////////////////////////// +/** + * @brief Print system time point for panel performance. + * + * @param strInfo The output information. + */ +static void check_time (const char *strInfo) +{ + gettime (_clock_start, strInfo); + ISF_LOG ("%s ppid=%d pid=%d\n", strInfo, getppid (), getpid ()); +} + +/** + * @brief Check the specific file. + * + * @param strFile The file path. + * + * @return true if the file is existed, otherwise false. + */ +static bool check_file (const char* strFile) +{ + struct stat st; + + /* Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor */ + if (stat (strFile, &st) < 0 && strcmp (strFile, "/")) + return false; + else + return true; +} + +/** + * @brief Flush memory for elm. + * + * @return void + */ +static void flush_memory (void) +{ + elm_cache_all_flush (); + malloc_trim (0); +} + +/** + * @brief Get ISE geometry information. + * + * @param info The data is used to store ISE position and size. + * @param kbd_state The keyboard state. + */ +static void get_ise_geometry (RECT_INFO &info, VIRTUAL_KEYBOARD_STATE kbd_state) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + info.width = _ise_width; + info.height = _ise_height; + + int win_w = _screen_width, win_h = _screen_height; + int angle = efl_get_angle_for_root_window (_candidate_window); + if (angle == 90 || angle == 270) { + win_w = _screen_height; + win_h = _screen_width; + } + + if (win_w != (int)info.width) + _panel_agent->get_current_ise_geometry (info); + + if ((int)info.width > win_w) { + win_w = _screen_height; + win_h = _screen_width; + } + + info.pos_x = (int)info.width > win_w ? 0 : (win_w - info.width) / 2; + if (kbd_state == KEYBOARD_STATE_OFF) + info.pos_y = win_h; + else + info.pos_y = win_h - info.height; +} + +/** + * @brief Set keyboard geometry for autoscroll. + * + * @param kbd_state The keyboard state. + */ +static void set_keyboard_geometry_atom_info (VIRTUAL_KEYBOARD_STATE kbd_state) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (kbd_state == KEYBOARD_STATE_UNKNOWN) + return; + + Ecore_X_Window* zone_lists; + if (ecore_x_window_prop_window_list_get (ecore_x_window_root_first_get (), + ECORE_X_ATOM_E_ILLUME_ZONE_LIST, &zone_lists) > 0) { + + struct rectinfo info = {0, 0, 0, 0}; + if (_ise_width == 0 && _ise_height == 0) { + info.pos_x = 0; + if (_candidate_window && evas_object_visible_get (_candidate_window)) { + info.width = _candidate_width; + info.height = _candidate_height; + } + int angle = efl_get_angle_for_root_window (_candidate_window); + if (angle == 90 || angle == 270) + info.pos_y = _screen_width - info.height; + else + info.pos_y = _screen_height - info.height; + } else { + get_ise_geometry (info, kbd_state); + if (_candidate_mode == FIXED_CANDIDATE_WINDOW) { + if (_candidate_window && evas_object_visible_get (_candidate_window)) { + _candidate_valid_height = ui_candidate_get_valid_height (); + if ((_candidate_height - _candidate_valid_height) > _ise_height) { + _candidate_valid_height = _candidate_height; + info.pos_y = info.pos_y + info.height - _candidate_height; + info.height = _candidate_height; + } else { + info.pos_y -= _candidate_valid_height; + info.height += _candidate_valid_height; + } + } + } + } + if (kbd_state == KEYBOARD_STATE_ON) { + ecore_x_e_virtual_keyboard_state_set (zone_lists[0], ECORE_X_VIRTUAL_KEYBOARD_STATE_ON); + ecore_x_e_illume_keyboard_geometry_set (zone_lists[0], info.pos_x, info.pos_y, info.width, info.height); + SCIM_DEBUG_MAIN (3) << " KEYBOARD_STATE_ON x=" << info.pos_x << " y=" << info.pos_y + << " width=" << info.width << " height=" << info.height << "\n"; + } else { + ecore_x_e_virtual_keyboard_state_set (zone_lists[0], ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF); + ecore_x_e_illume_keyboard_geometry_set (zone_lists[0], info.pos_x, info.pos_y, 0, 0); + SCIM_DEBUG_MAIN (3) << " KEYBOARD_STATE_OFF x=" << info.pos_x << " y=" << info.pos_y << "\n"; + } + } + + if (zone_lists) + free (zone_lists); +} + +/** + * @brief Get ISE name according to uuid. + * + * @param uuid The ISE uuid. + * + * @return The ISE name + */ +static String get_ise_name (const String uuid) +{ + String ise_name; + if (uuid.length () > 0) { + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (strcmp (uuid.c_str (), _uuids[i].c_str ()) == 0) { + ise_name = _names[i]; + break; + } + } + } + + return ise_name; +} + +/** + * @brief Get ISE type according to uuid. + * + * @param uuid The ISE uuid. + * + * @return The ISE type + */ +TOOLBAR_MODE_T get_ise_type (const String uuid) +{ + TOOLBAR_MODE_T ise_type = TOOLBAR_KEYBOARD_MODE; + if (uuid.length () > 0) { + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (strcmp (uuid.c_str (), _uuids[i].c_str ()) == 0) { + ise_type = _modes[i]; + break; + } + } + } + + return ise_type; +} + +/** + * @brief Get ISE language according to uuid. + * + * @param uuid The ISE uuid. + * + * @return The ISE language + */ +String get_ise_language (const String uuid) +{ + String ise_language; + if (uuid.length () > 0) { + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (strcmp (uuid.c_str (), _uuids[i].c_str ()) == 0) { + ise_language = _langs[i]; + break; + } + } + } + + return ise_language; +} + +/** + * @brief Set keyboard ISE. + * + * @param uuid The keyboard ISE's uuid. + * + * @return false if keyboard ISE change is failed, otherwise return true. + */ +static bool set_keyboard_ise (const String &uuid) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode (); + + if (TOOLBAR_HELPER_MODE == mode) { + String pre_uuid = _panel_agent->get_current_helper_uuid (); + _panel_agent->stop_helper (pre_uuid); + } else if (TOOLBAR_KEYBOARD_MODE == mode) { + uint32 kbd_option = 0; + String kbd_uuid, kbd_name; + isf_get_keyboard_ise (_config, kbd_uuid, kbd_name, kbd_option); + if (kbd_uuid == uuid) + return false; + } + + _panel_agent->change_factory (uuid); + + String language = String ("~other");/*scim_get_locale_language (scim_get_current_locale ());*/ + _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, uuid); + + return true; +} + +/** + * @brief Set helper ISE. + * + * @param uuid The helper ISE's uuid. + * + * @return false if helper ISE change is failed, otherwise return true. + */ +static bool set_helper_ise (const String &uuid) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode (); + + if (TOOLBAR_HELPER_MODE == mode) { + String pre_uuid = _panel_agent->get_current_helper_uuid (); + if (!pre_uuid.compare (uuid)) + return false; + _panel_agent->hide_helper (pre_uuid); + _panel_agent->stop_helper (pre_uuid); + } + + /* Set ComposeKey as keyboard ISE */ + uint32 kbd_option = 0; + String kbd_uuid, kbd_name; + isf_get_keyboard_ise (_config, kbd_uuid, kbd_name, kbd_option); + if (kbd_uuid != String (SCIM_COMPOSE_KEY_FACTORY_UUID)) { + kbd_uuid = String (SCIM_COMPOSE_KEY_FACTORY_UUID); + _panel_agent->change_factory (kbd_uuid); + + String language = String ("~other");/*scim_get_locale_language (scim_get_current_locale ());*/ + _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, kbd_uuid); + } + + _panel_agent->start_helper (uuid); + _config->write (String (SCIM_CONFIG_DEFAULT_HELPER_ISE), uuid); + + return true; +} + +/** + * @brief Set active ISE. + * + * @param uuid The ISE's uuid. + * + * @return false if ISE change is failed, otherwise return true. + */ +static bool set_active_ise (const String &uuid) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (uuid.length () <= 0) + return false; + + bool ise_changed = false; + + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (!uuid.compare (_uuids[i])) { + if (TOOLBAR_KEYBOARD_MODE == _modes[i]) + ise_changed = set_keyboard_ise (_uuids[i]); + else if (TOOLBAR_HELPER_MODE == _modes[i]) + ise_changed = set_helper_ise (_uuids[i]); + + if (ise_changed) { + _panel_agent->set_current_toolbar_mode (_modes[i]); + _panel_agent->set_current_ise_name (_names[i]); + + _ise_width = 0; + _ise_height = 0; + _ise_show = false; + _candidate_mode = FIXED_CANDIDATE_WINDOW; + _candidate_port_line = ONE_LINE_CANDIDATE; + if (_candidate_window) + ui_create_candidate_window (); + + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _uuids[i]); + scim_global_config_flush (); + + _config->flush (); + _config->reload (); + _panel_agent->reload_config (); + } + + return true; + } + } + + return false; +} + +/** + * @brief Load ISF configuration and ISEs information. + */ +static void load_config (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + /* Read configurations. */ + if (!_config.null ()) { + bool shared_ise = _config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), false); + _panel_agent->set_should_shared_ise (shared_ise); + } + + isf_load_ise_information (ALL_ISE, _config); +} + +/** + * @brief Reload config callback function for ISF panel. + * + * @param config The config pointer. + */ +static void config_reload_cb (const ConfigPointer &config) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + /* load_config (); */ +} + + +////////////////////////////////////////////////////////////////////// +// Start of Candidate Functions +////////////////////////////////////////////////////////////////////// +/** + * @brief Get candidate window valid height for autoscroll. + * + * @return The valid height. + */ +static int ui_candidate_get_valid_height (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "\n"; + + int height = 0; + if (_candidate_window) { + int angle = efl_get_angle_for_root_window (_candidate_window); + + if (evas_object_visible_get (_aux_area) && evas_object_visible_get (_candidate_area_1)) { + if (angle == 90 || angle == 270) + height = _candidate_land_height_min_2; + else + height = _candidate_port_height_min_2; + } else { + if (angle == 90 || angle == 270) + height = _candidate_land_height_min; + else + height = _candidate_port_height_min; + } + } + return height; +} + +/** + * @brief Resize candidate window size. + * + * @param new_width New width for candidate window. + * @param new_height New height for candidate window. + */ +static void ui_candidate_window_resize (int new_width, int new_height) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " width:" << new_width << " height:" << new_height << "\n"; + + if (!_candidate_window) + return; + + int x, y, width, height; + evas_object_geometry_get (_candidate_window, &x, &y, &width, &height); + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " old width:" << width << " old height:" << height << "\n"; + + if (width == new_width && height == new_height) + return; + + evas_object_resize (_candidate_window, new_width, new_height); + evas_object_resize (_aux_line, new_width, 2); + _candidate_width = new_width; + _candidate_height = new_height; + if (evas_object_visible_get (_candidate_window)) + _panel_agent->update_candidate_panel_event ((uint32)ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT, 0); + + if (evas_object_visible_get (_candidate_window) && _candidate_mode == FIXED_CANDIDATE_WINDOW) { + height = ui_candidate_get_valid_height (); + if ((_ise_width == 0 && _ise_height == 0) || + (_ise_height > 0 && _candidate_valid_height != height) || + (_ise_height > 0 && (_candidate_height - height) > _ise_height)) { + set_keyboard_geometry_atom_info (KEYBOARD_STATE_ON); + _panel_agent->update_input_panel_event (ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0); + } + } +} + +/** + * @brief This function will show/hide widgets of candidate window, + * and resize candidate window size according to aux_area/candidate_area. + */ +static void ui_candidate_window_adjust (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (!_candidate_window) + return; + + int x, y, width, height; + + /* Get candidate window size */ + evas_object_geometry_get (_candidate_window, &x, &y, &width, &height); + { + if (evas_object_visible_get (_aux_area) && evas_object_visible_get (_candidate_area_2)) { + evas_object_show (_aux_line); + evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min); + if (_candidate_angle == 90 || _candidate_angle == 270) { + ui_candidate_window_resize (width, _candidate_land_height_max_2); + evas_object_move (_close_btn, _close_btn_pos[2], _close_btn_pos[3] + _candidate_port_height_min_2 - _candidate_port_height_min); + evas_object_move (_candidate_area_2, 0, _candidate_land_height_min_2); + evas_object_move (_scroller_bg, 0, _candidate_land_height_min_2); + } else { + ui_candidate_window_resize (width, _candidate_port_height_max_2); + evas_object_move (_close_btn, _close_btn_pos[0], _close_btn_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min); + evas_object_move (_candidate_area_2, 0, _candidate_port_height_min_2); + evas_object_move (_scroller_bg, 0, _candidate_port_height_min_2); + } + } else if (evas_object_visible_get (_aux_area) && evas_object_visible_get (_candidate_area_1)) { + evas_object_show (_aux_line); + evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min); + if (_candidate_angle == 90 || _candidate_angle == 270) { + ui_candidate_window_resize (width, _candidate_land_height_min_2); + evas_object_move (_more_btn, _more_btn_pos[2], _more_btn_pos[3] + _candidate_port_height_min_2 - _candidate_port_height_min); + } else { + ui_candidate_window_resize (width, _candidate_port_height_min_2); + evas_object_move (_more_btn, _more_btn_pos[0], _more_btn_pos[1] + _candidate_port_height_min_2 - _candidate_port_height_min); + } + } else if (evas_object_visible_get (_aux_area)) { + evas_object_hide (_aux_line); + ui_candidate_window_resize (width, _aux_height + 2); + } else if (evas_object_visible_get (_candidate_area_2)) { + evas_object_hide (_aux_line); + evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1]); + if (_candidate_angle == 90 || _candidate_angle == 270) { + ui_candidate_window_resize (width, _candidate_land_height_max); + evas_object_move (_close_btn, _close_btn_pos[2], _close_btn_pos[3]); + evas_object_move (_candidate_area_2, 0, _candidate_land_height_min); + evas_object_move (_scroller_bg, 0, _candidate_land_height_min); + } else { + ui_candidate_window_resize (width, _candidate_port_height_max); + evas_object_move (_close_btn, _close_btn_pos[0], _close_btn_pos[1]); + evas_object_move (_candidate_area_2, 0, _candidate_port_height_min); + evas_object_move (_scroller_bg, 0, _candidate_port_height_min); + } + } else { + evas_object_hide (_aux_line); + evas_object_move (_candidate_area_1, _candidate_area_1_pos[0], _candidate_area_1_pos[1]); + if (_candidate_angle == 90 || _candidate_angle == 270) { + ui_candidate_window_resize (width, _candidate_land_height_min); + evas_object_move (_more_btn, _more_btn_pos[2], _more_btn_pos[3]); + } else { + ui_candidate_window_resize (width, _candidate_port_height_min); + evas_object_move (_more_btn, _more_btn_pos[0], _more_btn_pos[1]); + } + } + } +} + +/** + * @brief Rotate candidate window. + * + * @param angle The angle of candidate window. + */ +static void ui_candidate_window_rotate (int angle) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (!_candidate_window) + return; + + elm_win_rotation_set (_candidate_window, angle); + if (angle == 90 || angle == 270) { + _candidate_scroll_width = _candidate_scroll_width_max; + ui_candidate_window_resize (_candidate_land_width, _candidate_land_height_min); + evas_object_resize (_aux_area, _aux_land_width, _aux_height); + evas_object_resize (_candidate_area_1, _candidate_scroll_0_width_max, _item_min_height); + evas_object_resize (_candidate_area_2, _candidate_scroll_width, _candidate_scroll_height_min); + evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_min + 6); + } else { + _candidate_scroll_width = _candidate_scroll_width_min; + ui_candidate_window_resize (_candidate_port_width, _candidate_port_height_min); + evas_object_resize (_aux_area, _aux_port_width, _aux_height); + evas_object_resize (_candidate_area_1, _candidate_scroll_0_width_min, (_item_min_height+2)*_candidate_port_line-2); + evas_object_resize (_candidate_area_2, _candidate_scroll_width, _candidate_scroll_height_max); + evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_max + 6); + } + + ui_settle_candidate_window (); + ui_candidate_window_adjust (); + if (evas_object_visible_get (_candidate_area_1)) { + update_table (ISF_CANDIDATE_TABLE, g_isf_candidate_table); + } + flush_memory (); +} + +/** + * @brief This function is used to judge whether candidate window should be hidden. + * + * @return true if candidate window should be hidden, otherwise return false. + */ +static bool ui_candidate_can_be_hide (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (evas_object_visible_get (_aux_area) || + evas_object_visible_get (_candidate_area_1) || + evas_object_visible_get (_candidate_area_2)) + return false; + else + return true; +} + +/** + * @brief Delete check candidate window size timer. + * + * @return void + */ +static void ui_candidate_delete_check_size_timer (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (_check_size_timer != NULL) { + ecore_timer_del (_check_size_timer); + _check_size_timer = NULL; + } +} + +/** + * @brief Callback function for check candidate window size timer. + * + * @param data Data to pass when it is called. + * + * @return ECORE_CALLBACK_CANCEL + */ +static Eina_Bool ui_candidate_check_size_timeout (void *data) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + ui_candidate_delete_check_size_timer (); + ui_candidate_window_resize (_candidate_width, _candidate_height); + ui_settle_candidate_window (); + return ECORE_CALLBACK_CANCEL; +} + +/** + * @brief Delete longpress timer. + * + * @return void + */ +static void ui_candidate_delete_longpress_timer (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (_longpress_timer != NULL) { + ecore_timer_del (_longpress_timer); + _longpress_timer = NULL; + } +} + +/** + * @brief Callback function for candidate longpress timer. + * + * @param data Data to pass when it is called. + * + * @return ECORE_CALLBACK_CANCEL + */ +static Eina_Bool ui_candidate_longpress_timeout (void *data) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + int index = (int)GPOINTER_TO_INT(data); + ui_candidate_delete_longpress_timer (); + _is_click = false; + _panel_agent->send_longpress_event (_click_object, index); + return ECORE_CALLBACK_CANCEL; +} + +/** + * @brief Delete destroy timer. + * + * @return void + */ +static void ui_candidate_delete_destroy_timer (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (_destroy_timer != NULL) { + ecore_timer_del (_destroy_timer); + _destroy_timer = NULL; + } +} + +/** + * @brief Callback function for destroy timer. + * + * @param data Data to pass when it is called. + * + * @return ECORE_CALLBACK_CANCEL + */ +static Eina_Bool ui_candidate_destroy_timeout (void *data) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + ui_candidate_delete_destroy_timer (); + ui_destroy_candidate_window (); + return ECORE_CALLBACK_CANCEL; +} + +/** + * @brief Show candidate window. + * + * @param bSetVirtualKbd The flag for set_keyboard_geometry_atom_info () calling. + */ +static void ui_candidate_show (bool bSetVirtualKbd) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0); + if (!_candidate_window || (hw_kbd_detect == 0 && !_ise_show)) + return; + + int angle = efl_get_angle_for_root_window (_candidate_window); + if (_candidate_angle != angle) { + _candidate_angle = angle; + ui_candidate_window_rotate (angle); + } + + if (!evas_object_visible_get (_candidate_window)) { + evas_object_show (_candidate_window); + _panel_agent->update_candidate_panel_event ((uint32)ECORE_IMF_CANDIDATE_PANEL_STATE_EVENT, (uint32)ECORE_IMF_CANDIDATE_PANEL_SHOW); + + if (_candidate_mode == FIXED_CANDIDATE_WINDOW) { + if (!_ise_show) + _panel_agent->update_input_panel_event ((uint32)ECORE_IMF_INPUT_PANEL_STATE_EVENT, (uint32)ECORE_IMF_INPUT_PANEL_STATE_SHOW); + + if (bSetVirtualKbd) + set_keyboard_geometry_atom_info (KEYBOARD_STATE_ON); + _panel_agent->update_input_panel_event (ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0); + } + + ui_candidate_delete_check_size_timer (); + _check_size_timer = ecore_timer_add (0.02, ui_candidate_check_size_timeout, NULL); + } + + SCIM_DEBUG_MAIN (3) << " Show candidate window\n"; + _candidate_window_show = true; + evas_object_show (_candidate_window); + efl_set_transient_for_app_window (_candidate_window); +} + +/** + * @brief Hide candidate window. + * + * @param bForce The flag to hide candidate window by force. + * @param bSetVirtualKbd The flag for set_keyboard_geometry_atom_info () calling. + */ +static void ui_candidate_hide (bool bForce, bool bSetVirtualKbd) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (!_candidate_window) + return; + + if (bForce) { + if (_candidate_area_2 && evas_object_visible_get (_candidate_area_2)) { + evas_object_hide (_candidate_area_2); + evas_object_hide (_scroller_bg); + evas_object_hide (_close_btn); + _panel_agent->candidate_more_window_hide (); + ui_candidate_window_adjust (); + } + } + + if (bForce || ui_candidate_can_be_hide ()) { + if (evas_object_visible_get (_candidate_window)) { + evas_object_hide (_candidate_window); + _panel_agent->update_candidate_panel_event ((uint32)ECORE_IMF_CANDIDATE_PANEL_STATE_EVENT, (uint32)ECORE_IMF_CANDIDATE_PANEL_HIDE); + + if (_candidate_mode == FIXED_CANDIDATE_WINDOW) { + _panel_agent->update_input_panel_event (ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0); + if (_ise_show) { + set_keyboard_geometry_atom_info (KEYBOARD_STATE_ON); + } else { + if (bSetVirtualKbd) + set_keyboard_geometry_atom_info (KEYBOARD_STATE_OFF); + _panel_agent->update_input_panel_event ((uint32)ECORE_IMF_INPUT_PANEL_STATE_EVENT, (uint32)ECORE_IMF_INPUT_PANEL_STATE_HIDE); + } + } + } + + SCIM_DEBUG_MAIN (3) << " Hide candidate window\n"; + _candidate_window_show = false; + evas_object_hide (_candidate_window); + } +} + +static Eina_Bool _move_candidate_window_timer_cb (void *data) +{ + evas_object_hide (_more_btn); + evas_object_show (_close_btn); + + ui_settle_candidate_window (); + flush_memory (); + + return ECORE_CALLBACK_CANCEL; +} + +/** + * @brief Callback function for more button. + * + * @param data Data to pass when it is called. + * @param e The evas for current event. + * @param button The evas object for current event. + * @param event_info The information for current event. + */ +static void ui_candidate_window_more_button_cb (void *data, Evas *e, Evas_Object *button, void *event_info) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + _panel_agent->candidate_more_window_show (); + + evas_object_show (_candidate_area_2); + evas_object_show (_scroller_bg); + elm_win_raise (_candidate_window); + ui_candidate_window_adjust (); + + /* FIXME : use timer to move candidate window after rendering candidate window which is resized. + This code is added for avoiding a flickering problem changing the window size by the EVAS graphic rendering restriction(Retained mode) + */ + ecore_timer_add (0.02, _move_candidate_window_timer_cb, NULL); +} + +/** + * @brief Callback function for close button. + * + * @param data Data to pass when it is called. + * @param e The evas for current event. + * @param button The evas object for current event. + * @param event_info The information for current event. + */ +static void ui_candidate_window_close_button_cb (void *data, Evas *e, Evas_Object *button, void *event_info) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (_candidate_area_2 == NULL || !evas_object_visible_get (_candidate_area_2)) + return; + + evas_object_hide (_candidate_area_2); + evas_object_hide (_scroller_bg); + evas_object_hide (_close_btn); + _panel_agent->candidate_more_window_hide (); + + evas_object_show (_candidate_area_1); + evas_object_show (_more_btn); + ui_candidate_window_adjust (); + ui_settle_candidate_window (); + elm_scroller_region_show (_candidate_area_2, 0, 0, _candidate_scroll_width, 100); + flush_memory (); +} + +/** + * @brief Callback function for mouse button press. + * + * @param data Data to pass when it is called. + * @param e The evas for current event. + * @param button The evas object for current event. + * @param event_info The information for current event. + */ +static void ui_mouse_button_pressed_cb (void *data, Evas *e, Evas_Object *button, void *event_info) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + _click_object = GPOINTER_TO_INT (data) & 0xFF; + _is_click = true; + + Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info; + _click_down_pos [0] = ev->canvas.x; + _click_down_pos [1] = ev->canvas.y; + + if (_click_object == ISF_EFL_CANDIDATE_0 || _click_object == ISF_EFL_CANDIDATE_ITEMS) { + int index = GPOINTER_TO_INT (data) >> 8; + ui_candidate_delete_longpress_timer (); + _longpress_timer = ecore_timer_add (1.0, ui_candidate_longpress_timeout, (void *)index); + } +} + +/** + * @brief Callback function for mouse button release. + * + * @param data Data to pass when it is called. + * @param e The evas for current event. + * @param button The evas object for current event. + * @param event_info The information for current event. + */ +static void ui_mouse_button_released_cb (void *data, Evas *e, Evas_Object *button, void *event_info) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " index:" << GPOINTER_TO_INT (data) << "...\n"; + + ui_candidate_delete_longpress_timer (); + + int index = GPOINTER_TO_INT (data); + if (_click_object == ISF_EFL_AUX && _is_click) { +/* double ret = 0; + const char *buf = edje_object_part_state_get (button, "aux", &ret); + if (strcmp ("selected", buf)) { + for (unsigned int i = 0; i < _aux_items.size (); i++) { + buf = edje_object_part_state_get (_aux_items [i], "aux", &ret); + if (!strcmp ("selected", buf)) + edje_object_signal_emit (_aux_items [i], "aux,state,unselected", "aux"); + } + edje_object_signal_emit (button, "aux,state,selected", "aux"); + _panel_agent->select_aux (index); + }*/ + int r, g, b, a, r2, g2, b2, a2, r3, g3, b3, a3; + edje_object_color_class_get (_aux_items [index], "text_color", &r, &g, &b, &a, &r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3); + // Normal item is clicked + if (!(r == 62 && g == 207 && b == 255)) { + for (unsigned int i = 0; i < _aux_items.size (); i++) { + edje_object_color_class_set (_aux_items [i], "text_color", 249, 249, 249, 255, r2, g2, b2, a2, r3, g3, b3, a3); + } + edje_object_color_class_set (_aux_items [index], "text_color", 62, 207, 255, 255, r2, g2, b2, a2, r3, g3, b3, a3); + _panel_agent->select_aux (index); + } + } else if (_click_object == ISF_EFL_CANDIDATE_0 && _is_click) { + ui_candidate_window_close_button_cb (NULL, NULL, _close_btn, NULL); + _panel_agent->select_candidate (index); + } else if (_click_object == ISF_EFL_CANDIDATE_ITEMS && _is_click) { + ui_candidate_window_close_button_cb (NULL, NULL, _close_btn, NULL); + _panel_agent->select_candidate (index); + } +} + +/** + * @brief Callback function for mouse move. + * + * @param data Data to pass when it is called. + * @param e The evas for current event. + * @param button The evas object for current event. + * @param event_info The information for current event. + */ +static void ui_mouse_moved_cb (void *data, Evas *e, Evas_Object *button, void *event_info) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info; + _click_up_pos [0] = ev->canvas.x; + _click_up_pos [1] = ev->canvas.y; + + if (abs (_click_up_pos [0] - _click_down_pos [0]) >= (int)(15 * _height_rate) || + abs (_click_up_pos [1] - _click_down_pos [1]) >= (int)(15 * _height_rate)) { + _is_click = false; + ui_candidate_delete_longpress_timer (); + } +} + +/** + * @brief Create native style candidate window. + */ +static void ui_create_native_candidate_window (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + _candidate_port_width = _screen_width; + _candidate_port_height_min = 84 * _height_rate * _candidate_port_line; + _candidate_port_height_min_2 = 84 * _height_rate + _candidate_port_height_min; + _candidate_port_height_max = 426 * _height_rate + _candidate_port_height_min; + _candidate_port_height_max_2 = 84 * _height_rate + _candidate_port_height_max; + _candidate_land_width = _screen_height; + _candidate_land_height_min = 84 * _width_rate; + _candidate_land_height_min_2 = 168 * _width_rate; + _candidate_land_height_max = 342 * _width_rate; + _candidate_land_height_max_2 = 426 * _width_rate; + + _candidate_scroll_0_width_min= _screen_width; + _candidate_scroll_0_width_max= _screen_height; + _candidate_scroll_width_min = _screen_width; + _candidate_scroll_width_max = _screen_height; + _candidate_scroll_height_min = 252 * _width_rate; + _candidate_scroll_height_max = 420 * _height_rate; + + _candidate_area_1_pos [0] = 0 * _width_rate; + _candidate_area_1_pos [1] = 2 * _height_rate; + _more_btn_pos [0] = 628 * _width_rate; + _more_btn_pos [1] = 12 * _height_rate; + _more_btn_pos [2] = 1188 * _height_rate; + _more_btn_pos [3] = 12 * _width_rate; + _close_btn_pos [0] = 628 * _width_rate; + _close_btn_pos [1] = 12 * _height_rate; + _close_btn_pos [2] = 1188 * _height_rate; + _close_btn_pos [3] = 12 * _width_rate; + + _aux_height = 84 * _height_rate - 2; + _aux_port_width = _screen_width; + _aux_land_width = _screen_height; + + _item_min_height = 84 * _height_rate - 2; + + /* Create candidate window */ + if (_candidate_window == NULL) { + _candidate_window = efl_create_window ("candidate", "Prediction Window"); + evas_object_resize (_candidate_window, _candidate_port_width, _candidate_port_height_min); + _candidate_width = _candidate_port_width; + _candidate_height = _candidate_port_height_min; + + /* Add background */ + _candidate_bg = edje_object_add (evas_object_evas_get (_candidate_window)); + edje_object_file_set (_candidate_bg, _candidate_edje_file.c_str (), "candidate_bg"); + evas_object_size_hint_weight_set (_candidate_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add (_candidate_window, _candidate_bg); + evas_object_show (_candidate_bg); + + /* Create _candidate_0 scroller */ + _candidate_0_scroll = elm_scroller_add (_candidate_window); + elm_scroller_bounce_set (_candidate_0_scroll, EINA_TRUE, EINA_FALSE); + elm_scroller_policy_set (_candidate_0_scroll, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF); + evas_object_resize (_candidate_0_scroll, _candidate_scroll_0_width_min, (_item_min_height+2)*_candidate_port_line-2); + evas_object_move (_candidate_0_scroll, _candidate_area_1_pos[0], _candidate_area_1_pos[1]); + _candidate_0_table = elm_table_add (_candidate_window); + evas_object_size_hint_weight_set (_candidate_0_table, 0.0, 0.0); + evas_object_size_hint_align_set (_candidate_0_table, 0.0, 0.0); + elm_table_padding_set (_candidate_0_table, 0, 0); + elm_object_content_set (_candidate_0_scroll, _candidate_0_table); + evas_object_show (_candidate_0_table); + _candidate_area_1 = _candidate_0_scroll; + + /* Create more button */ + _more_btn = edje_object_add (evas_object_evas_get (_candidate_window)); + if (_ise_width == 0 && _ise_height == 0) + edje_object_file_set (_more_btn, _candidate_edje_file.c_str (), "close_button"); + else + edje_object_file_set (_more_btn, _candidate_edje_file.c_str (), "more_button"); + evas_object_move (_more_btn, _more_btn_pos[0], _more_btn_pos[1]); + evas_object_resize (_more_btn, 80 * _width_rate, 64 * _height_rate); + evas_object_event_callback_add (_more_btn, EVAS_CALLBACK_MOUSE_UP, ui_candidate_window_more_button_cb, NULL); + + /* Add scroller background */ + _candidate_scroll_width = _candidate_scroll_width_min; + _scroller_bg = edje_object_add (evas_object_evas_get (_candidate_window)); + edje_object_file_set (_scroller_bg, _candidate_edje_file.c_str (), "scroller_bg"); + evas_object_size_hint_weight_set (_scroller_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_max + 6); + evas_object_move (_scroller_bg, 0, _candidate_port_height_min); + + /* Create vertical scroller */ + _candidate_scroll = elm_scroller_add (_candidate_window); + elm_scroller_bounce_set (_candidate_scroll, 0, 1); + elm_scroller_policy_set (_candidate_scroll, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); + evas_object_resize (_candidate_scroll, _candidate_scroll_width, _candidate_scroll_height_max); + evas_object_resize (_scroller_bg, _candidate_scroll_width, _candidate_scroll_height_max + 6); + elm_scroller_page_size_set (_candidate_scroll, 0, _item_min_height+_v_padding); + evas_object_move (_candidate_scroll, 0, _candidate_port_height_min); + _candidate_table = elm_table_add (_candidate_window); + evas_object_size_hint_weight_set (_candidate_table, 0.0, 0.0); + evas_object_size_hint_align_set (_candidate_table, 0.0, 0.0); + elm_table_padding_set (_candidate_table, 0, 0); + elm_object_content_set (_candidate_scroll, _candidate_table); + evas_object_show (_candidate_table); + _candidate_area_2 = _candidate_scroll; + + /* Create close button */ + _close_btn = edje_object_add (evas_object_evas_get (_candidate_window)); + if (_ise_width == 0 && _ise_height == 0) + edje_object_file_set (_close_btn, _candidate_edje_file.c_str (), "more_button"); + else + edje_object_file_set (_close_btn, _candidate_edje_file.c_str (), "close_button"); + evas_object_move (_close_btn, _close_btn_pos[0], _close_btn_pos[1]); + evas_object_resize (_close_btn, 80 * _width_rate, 64 * _height_rate); + evas_object_event_callback_add (_close_btn, EVAS_CALLBACK_MOUSE_UP, ui_candidate_window_close_button_cb, NULL); + + _tmp_candidate_text = evas_object_text_add (evas_object_evas_get (_candidate_window)); + evas_object_text_font_set (_tmp_candidate_text, _candidate_font_name.c_str (), _candidate_font_size); + + /* Create aux */ + _aux_area = elm_scroller_add (_candidate_window); + elm_scroller_bounce_set (_aux_area, 1, 0); + elm_scroller_policy_set (_aux_area, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF); + evas_object_resize (_aux_area, _aux_port_width, _aux_height); + evas_object_move (_aux_area, 0, 2); + + _aux_table = elm_table_add (_candidate_window); + elm_object_content_set (_aux_area, _aux_table); + elm_table_padding_set (_aux_table, 4, 0); + evas_object_size_hint_weight_set (_aux_table, 0.0, 0.0); + evas_object_size_hint_align_set (_aux_table, 0.0, 0.0); + evas_object_show (_aux_table); + + _aux_line = edje_object_add (evas_object_evas_get (_candidate_window)); + edje_object_file_set (_aux_line, _candidate_edje_file.c_str (), "popup_line"); + evas_object_resize (_aux_line, _candidate_port_width, 2); + evas_object_move (_aux_line, 0, _aux_height + 2); + + _tmp_aux_text = evas_object_text_add (evas_object_evas_get (_candidate_window)); + evas_object_text_font_set (_tmp_aux_text, _candidate_font_name.c_str (), _aux_font_size); + } + + flush_memory (); +} + +/** + * @brief Create candidate window. + * + * @return void + */ +static void ui_create_candidate_window (void) +{ + check_time ("\nEnter ui_create_candidate_window"); + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + ui_destroy_candidate_window (); + + _candidate_x = 0; + _candidate_y = 0; + _candidate_angle = 0; + + ui_create_native_candidate_window (); + + int angle = efl_get_angle_for_root_window (_candidate_window); + if (_candidate_angle != angle) { + _candidate_angle = angle; + ui_candidate_window_rotate (angle); + } else { + ui_settle_candidate_window (); + } + + check_time ("Exit ui_create_candidate_window"); +} + +/** + * @brief Destroy candidate window. + * + * @return void + */ +static void ui_destroy_candidate_window (void) +{ + check_time ("Enter ui_destroy_candidate_window"); + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + /* Delete candidate items, popup lines and seperator items */ + for (int i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) { + if (_candidate_0 [i]) { + evas_object_del (_candidate_0 [i]); + _candidate_0 [i] = NULL; + } + if (_candidate_items [i]) { + evas_object_del (_candidate_items [i]); + _candidate_items [i] = NULL; + } + + if (_seperate_0 [i]) { + evas_object_del (_seperate_0 [i]); + _seperate_0 [i] = NULL; + } + if (_seperate_items [i]) { + evas_object_del (_seperate_items [i]); + _seperate_items [i] = NULL; + } + + if (_line_0 [i]) { + evas_object_del (_line_0 [i]); + _line_0 [i] = NULL; + } + if (_line_items [i]) { + evas_object_del (_line_items [i]); + _line_items [i] = NULL; + } + } + + _aux_items.clear (); + /* Delete candidate window */ + if (_candidate_window) { + ui_candidate_hide (true); + + evas_object_del (_candidate_window); + _candidate_window = NULL; + _aux_area = NULL; + _candidate_area_1 = NULL; + _candidate_area_2 = NULL; + _scroller_bg = NULL; + } + + flush_memory (); + check_time ("Exit ui_destroy_candidate_window"); +} + +/** + * @brief Settle candidate window position. + */ +static void ui_settle_candidate_window (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (!_candidate_window) + return; + + int spot_x, spot_y; + int x, y, width, height; + bool reverse = false; + + /* Get candidate window position */ + ecore_evas_geometry_get (ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window)), &x, &y, &width, &height); + + int height2 = ui_candidate_get_valid_height (); + + if (_candidate_mode == FIXED_CANDIDATE_WINDOW) { + if (_candidate_angle == 90) { + spot_x = _screen_width - _ise_height - height2; + spot_y = 0; + } else if (_candidate_angle == 270) { + spot_x = _ise_height - (_candidate_height - height2); + spot_y = 0; + } else if (_candidate_angle == 180) { + spot_x = 0; + spot_y = _ise_height - (_candidate_height - height2); + } else { + spot_x = 0; + spot_y = _screen_height - _ise_height - height2; + } + } else { + spot_x = _spot_location_x; + spot_y = _spot_location_y; + + rectinfo ise_rect; + _panel_agent->get_current_ise_geometry (ise_rect); + if (_candidate_angle == 90 || _candidate_angle == 270) { + if (ise_rect.height <= (uint32)0 || ise_rect.height >= (uint32)_screen_width) + ise_rect.height = ISE_DEFAULT_HEIGHT_LANDSCAPE * _width_rate; + } else { + if (ise_rect.height <= (uint32)0 || ise_rect.height >= (uint32) _screen_height) + ise_rect.height = ISE_DEFAULT_HEIGHT_PORTRAIT * _height_rate; + } + + int nOffset = _candidate_port_height_min / 3; + if (_candidate_angle == 270) { + if (ise_rect.height > 0 && spot_y + height2 > _screen_width - (int)ise_rect.height + nOffset) { + reverse = true; + spot_x = _screen_width - _spot_location_top_y - (_candidate_height - height2); + } else { + spot_x = _screen_width - _spot_location_y - _candidate_height; + } + } else if (_candidate_angle == 90) { + if (ise_rect.height > 0 && spot_y + height2 > _screen_width - (int)ise_rect.height + nOffset) { + reverse = true; + spot_x = _spot_location_top_y - height2; + } else { + spot_x = spot_y; + } + } else if (_candidate_angle == 180) { + if (ise_rect.height > 0 && spot_y + height2 > _screen_height - (int)ise_rect.height + nOffset) { + reverse = true; + spot_y = _screen_height - _spot_location_top_y - (_candidate_height - height2); + } else { + spot_y = _screen_height - _spot_location_y - _candidate_height; + } + } else { + if (ise_rect.height > 0 && spot_y + height2 > _screen_height - (int)ise_rect.height + nOffset) { + reverse = true; + spot_y = _spot_location_top_y - height2; + } else { + spot_y = spot_y; + } + } + } + + if (_candidate_angle == 90) { + spot_y = (_screen_height - _candidate_width) / 2; + spot_x = spot_x < _indicator_height ? _indicator_height : spot_x; + if (spot_x > _screen_width - _candidate_height) + spot_x = _screen_width - _candidate_height; + } else if (_candidate_angle == 270) { + spot_y = (_screen_height - _candidate_width) / 2; + spot_x = spot_x < 0 ? 0 : spot_x; + if (spot_x > _screen_width - (_indicator_height+_candidate_height)) + spot_x = _screen_width - (_indicator_height+_candidate_height); + } else if (_candidate_angle == 180) { + spot_x = (_screen_width - _candidate_width) / 2; + spot_y = spot_y < 0 ? 0 : spot_y; + if (spot_y > _screen_height - (_indicator_height+_candidate_height)) + spot_y = _screen_height - (_indicator_height+_candidate_height); + } else { + spot_x = (_screen_width - _candidate_width) / 2; + spot_y = spot_y < _indicator_height ? _indicator_height : spot_y; + if (spot_y > _screen_height - _candidate_height) + spot_y = _screen_height - _candidate_height; + } + + if (spot_x != x || spot_y != y) { + _candidate_x = spot_x; + _candidate_y = spot_y; + evas_object_move (_candidate_window, spot_x, spot_y); + if (evas_object_visible_get (_candidate_window)) { + _panel_agent->update_candidate_panel_event ((uint32)ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT, 0); + } + } + + if (!_candidate_window_show) + ui_candidate_hide (false); +} + +////////////////////////////////////////////////////////////////////// +// End of Candidate Functions +////////////////////////////////////////////////////////////////////// + +/** + * @brief Get screen width and height. + * + * @param width The screen width. + * @param height The screen height. + */ +static void efl_get_screen_size (int &width, int &height) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + Display *d = (Display *)ecore_x_display_get (); + if (d) { + int screen_num = DefaultScreen (d); + width = DisplayWidth (d, screen_num); + height = DisplayHeight (d, screen_num); + } else { + std::cerr << "ecore_x_display_get () is failed!!!\n"; + } +} + +/** + * @brief Set transient for app window. + * + * @param win_obj The Evas_Object handler of app window. + */ +static void efl_set_transient_for_app_window (Evas_Object *win_obj) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + /* Set a transient window for window stack */ + /* Gets the current XID of the active window into the root window property */ + int ret = 0; + Atom type_return; + int format_return; + unsigned long nitems_return; + unsigned long bytes_after_return; + unsigned char *data = NULL; + Ecore_X_Window xAppWindow; + Ecore_X_Window xKeypadWin = elm_win_xwindow_get (win_obj); + + ret = XGetWindowProperty ((Display *)ecore_x_display_get (), ecore_x_window_root_get (xKeypadWin), + ecore_x_atom_get ("_ISF_ACTIVE_WINDOW"), + 0, G_MAXLONG, False, ((Atom) 33), &type_return, + &format_return, &nitems_return, &bytes_after_return, + &data); + + if (ret == Success) { + if ((type_return == ((Atom) 33)) && (format_return == 32) && (data)) { + xAppWindow = *(Window *)data; + ecore_x_icccm_transient_for_set (xKeypadWin, xAppWindow); + if (data) + XFree (data); + } + } else { + std::cerr << "XGetWindowProperty () is failed!!!\n"; + } +} + +/** + * @brief Get angle for root window. + * + * @param win_obj The Evas_Object handler of application window. + * + * @return The angle of root window. + */ +static int efl_get_angle_for_root_window (Evas_Object *win_obj) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + int ret; + int count; + int angle = 0; + unsigned char *prop_data = NULL; + Ecore_X_Window root_win = ecore_x_window_root_first_get (); + if (win_obj) + root_win = ecore_x_window_root_get (elm_win_xwindow_get (win_obj)); + + ret = ecore_x_window_prop_property_get (root_win, ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE, ECORE_X_ATOM_CARDINAL, 32, &prop_data, &count); + if (ret && prop_data) { + memcpy (&angle, prop_data, sizeof (int)); + } else { + std::cerr << "ecore_x_window_prop_property_get () is failed!!!\n"; + } + if (prop_data) + XFree (prop_data); + + return angle; +} + +/** + * @brief Set showing effect for application window. + * + * @param win The Evas_Object handler of application window. + * @param strEffect The pointer of effect string. + */ +static void efl_set_showing_effect_for_app_window (Evas_Object *win, const char* strEffect) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + ecore_x_icccm_name_class_set (elm_win_xwindow_get (static_cast(win)), strEffect, "ISF"); +} + +/** + * @brief Create elementary window. + * + * @param strWinName The window name. + * @param strEffect The window effect string. + * + * @return The window pointer + */ +static Evas_Object *efl_create_window (const char *strWinName, const char *strEffect) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + Evas_Object *win = elm_win_add (NULL, strWinName, ELM_WIN_UTILITY); + elm_win_title_set (win, strWinName); + + /* set window properties */ + elm_win_autodel_set (win, EINA_TRUE); + elm_object_focus_allow_set (win, EINA_FALSE); + elm_win_borderless_set (win, EINA_TRUE); + elm_win_alpha_set (win, EINA_TRUE); + elm_win_prop_focus_skip_set (win, EINA_TRUE); + efl_set_showing_effect_for_app_window (win, strEffect); + + const char *szProfile[] = {"mobile", ""}; + elm_win_profiles_set (win, szProfile, 1); + + return win; +} + +/** + * @brief Get default zone geometry. + * + * @param x The zone x position. + * @param y The zone y position. + * @param w The zone width. + * @param h The zone height. + * + * @return EINA_TRUE if successful, otherwise return EINA_FALSE + */ +static Eina_Bool efl_get_default_zone_geometry_info (Ecore_X_Window root, uint *x, uint *y, uint *w, uint *h) +{ + Ecore_X_Atom zone_geometry_atom; + Ecore_X_Window *zone_lists; + int num_zone_lists; + int num_ret; + Eina_Bool ret; + + zone_geometry_atom = ecore_x_atom_get ("_E_ILLUME_ZONE_GEOMETRY"); + if (!zone_geometry_atom) { + /* Error... */ + return EINA_FALSE; + } + + uint geom[4]; + num_zone_lists = ecore_x_window_prop_window_list_get (root, ECORE_X_ATOM_E_ILLUME_ZONE_LIST, &zone_lists); + if (num_zone_lists > 0) { + num_ret = ecore_x_window_prop_card32_get (zone_lists[0], zone_geometry_atom, geom, 4); + if (num_ret == 4) { + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + ret = EINA_TRUE; + } else { + ret = EINA_FALSE; + } + } else { + /* if there is no zone available */ + ret = EINA_FALSE; + } + + if (zone_lists) { + /* We must free zone_lists */ + free (zone_lists); + } + + return ret; +} + +/** + * @brief Get screen resolution. + * + * @param width The screen width. + * @param height The screen height. + */ +static void efl_get_screen_resolution (int &width, int &height) +{ + static Evas_Coord scr_w = 0, scr_h = 0; + + if (scr_w == 0 || scr_h == 0) { + uint w, h; + if (efl_get_default_zone_geometry_info (ecore_x_window_root_first_get (), NULL, NULL, &w, &h)) { + scr_w = w; + scr_h = h; + } else { + ecore_x_window_size_get (ecore_x_window_root_first_get (), &scr_w, &scr_h); + } + } + + width = scr_w; + height = scr_h; +} + + +////////////////////////////////////////////////////////////////////// +// Start of PanelAgent Functions +////////////////////////////////////////////////////////////////////// + +/** + * @brief Initialize panel agent. + * + * @param config The config string for PanelAgent. + * @param display The current display. + * @param resident The variable indicates whether panel will be resident. + * + * @return true if initialize is successful, otherwise return false. + */ +static bool initialize_panel_agent (const String &config, const String &display, bool resident) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + _panel_agent = new PanelAgent (); + + if (!_panel_agent || !_panel_agent->initialize (config, display, resident)) + return false; + + _panel_agent->signal_connect_reload_config (slot (slot_reload_config)); + _panel_agent->signal_connect_focus_in (slot (slot_focus_in)); + _panel_agent->signal_connect_focus_out (slot (slot_focus_out)); + _panel_agent->signal_connect_expand_candidate (slot (slot_expand_candidate)); + _panel_agent->signal_connect_contract_candidate (slot (slot_contract_candidate)); + _panel_agent->signal_connect_set_candidate_ui (slot (slot_set_candidate_style)); + _panel_agent->signal_connect_update_factory_info (slot (slot_update_factory_info)); + _panel_agent->signal_connect_update_spot_location (slot (slot_update_spot_location)); + _panel_agent->signal_connect_update_input_context (slot (slot_update_input_context)); + _panel_agent->signal_connect_update_ise_geometry (slot (slot_update_ise_geometry)); + _panel_agent->signal_connect_show_aux_string (slot (slot_show_aux_string)); + _panel_agent->signal_connect_show_lookup_table (slot (slot_show_candidate_table)); + _panel_agent->signal_connect_hide_aux_string (slot (slot_hide_aux_string)); + _panel_agent->signal_connect_hide_lookup_table (slot (slot_hide_candidate_table)); + _panel_agent->signal_connect_update_aux_string (slot (slot_update_aux_string)); + _panel_agent->signal_connect_update_lookup_table (slot (slot_update_candidate_table)); + _panel_agent->signal_connect_get_candidate_geometry (slot (slot_get_candidate_geometry)); + _panel_agent->signal_connect_get_input_panel_geometry (slot (slot_get_input_panel_geometry)); + _panel_agent->signal_connect_set_active_ise_by_uuid (slot (slot_set_active_ise)); + _panel_agent->signal_connect_get_ise_list (slot (slot_get_ise_list)); + _panel_agent->signal_connect_get_ise_information (slot (slot_get_ise_information)); + _panel_agent->signal_connect_get_keyboard_ise_list (slot (slot_get_keyboard_ise_list)); + _panel_agent->signal_connect_get_language_list (slot (slot_get_language_list)); + _panel_agent->signal_connect_get_all_language (slot (slot_get_all_language)); + _panel_agent->signal_connect_get_ise_language (slot (slot_get_ise_language)); + _panel_agent->signal_connect_get_ise_info_by_uuid (slot (slot_get_ise_info)); + _panel_agent->signal_connect_set_keyboard_ise (slot (slot_set_keyboard_ise)); + _panel_agent->signal_connect_get_keyboard_ise (slot (slot_get_keyboard_ise)); + _panel_agent->signal_connect_accept_connection (slot (slot_accept_connection)); + _panel_agent->signal_connect_close_connection (slot (slot_close_connection)); + _panel_agent->signal_connect_exit (slot (slot_exit)); + _panel_agent->get_active_ise_list (_load_ise_list); + + return true; +} + +/** + * @brief Reload config slot function for PanelAgent. + */ +static void slot_reload_config (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + //if (!_config.null ()) + // _config->reload (); +} + +/** + * @brief Focus in slot function for PanelAgent. + */ +static void slot_focus_in (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + ui_candidate_delete_destroy_timer (); +} + +/** + * @brief Focus out slot function for PanelAgent. + */ +static void slot_focus_out (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + ui_candidate_delete_destroy_timer (); + _destroy_timer = ecore_timer_add (1.0, ui_candidate_destroy_timeout, NULL); +} + +/** + * @brief Expand candidate slot function for PanelAgent. + */ +static void slot_expand_candidate (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (_candidate_area_2 && !evas_object_visible_get (_candidate_area_2)) + ui_candidate_window_more_button_cb (NULL, NULL, NULL, NULL); +} + +/** + * @brief Contract candidate slot function for PanelAgent. + */ +static void slot_contract_candidate (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + ui_candidate_window_close_button_cb (NULL, NULL, NULL, NULL); +} + +/** + * @brief Set candidate style slot function for PanelAgent. + * + * @param portrait_line The displayed line number for portrait. + * @param mode The candidate mode. + */ +static void slot_set_candidate_style (int portrait_line, int mode) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " display_line:" << portrait_line << " mode:" << mode << "\n"; + if ((portrait_line != _candidate_port_line) || (mode != _candidate_mode)) { + _candidate_mode = (ISF_CANDIDATE_MODE_T)mode; + _candidate_port_line = (ISF_CANDIDATE_PORTRAIT_LINE_T)portrait_line; + if (_candidate_window) + ui_create_candidate_window (); + } +} + +/** + * @brief Update keyboard ISE information slot function for PanelAgent. + * + * @param info The information of current Keyboard ISE. + */ +static void slot_update_factory_info (const PanelFactoryInfo &info) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + String ise_name = info.name; + String ise_icon = info.icon; + + String old_ise = _panel_agent->get_current_ise_name (); + if (old_ise != ise_name) { + int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0); + if (hw_kbd_detect && _candidate_window) { + ui_destroy_candidate_window (); + } + } + + TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode (); + + if (TOOLBAR_HELPER_MODE == mode) + ise_name = get_ise_name (_panel_agent->get_current_helper_uuid ()); + + if (ise_name.length () > 0) + _panel_agent->set_current_ise_name (ise_name); +} + +/** + * @brief Update cursor position slot function for PanelAgent. + * + * @param x The x position of current cursor. + * @param y The bottom y position of current cursor. + * @param top_y The top y position of current cursor. + */ +static void slot_update_spot_location (int x, int y, int top_y) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (x >= 0 && x < _screen_height && y >= 0 && y < _screen_height) { + _spot_location_x = x; + _spot_location_y = y; + _spot_location_top_y = top_y; + + ui_settle_candidate_window (); + } +} + +/** + * @brief The input context of ISE is changed. + * + * @param type The event type. + * @param value The event value. + */ +static void slot_update_input_context (int type, int value) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " type=" << type << " value=" << value << "\n"; + + if (type == ECORE_IMF_INPUT_PANEL_STATE_EVENT) { + if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + _ise_show = false; + ui_candidate_hide (true, false); + set_keyboard_geometry_atom_info (KEYBOARD_STATE_OFF); + } else if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) { + _ise_show = true; + if (evas_object_visible_get (_candidate_area_1)) + ui_candidate_show (false); + set_keyboard_geometry_atom_info (KEYBOARD_STATE_ON); + } + } +} + +/** + * @brief Update ise geometry. + * + * @param x The x position in screen. + * @param y The y position in screen. + * @param width The ISE window width. + * @param height The ISE window height. + */ +static void slot_update_ise_geometry (int x, int y, int width, int height) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " x:" << x << " y:" << y << " width:" << width << " height:" << height << "...\n"; + + int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0); + if (hw_kbd_detect) + return; + + int old_height = _ise_height; + + _ise_width = width; + _ise_height = height; + + if (_candidate_window) { + int angle = efl_get_angle_for_root_window (_candidate_window); + if (_candidate_angle != angle) { + _candidate_angle = angle; + ui_candidate_window_rotate (angle); + } else if (old_height != height) { + ui_settle_candidate_window (); + } + } + + if (old_height != height && _ise_show) + set_keyboard_geometry_atom_info (KEYBOARD_STATE_ON); +} + +/** + * @brief Show aux slot function for PanelAgent. + */ +static void slot_show_aux_string (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (_candidate_window == NULL) + ui_create_candidate_window (); + + if (_aux_area == NULL || evas_object_visible_get (_aux_area)) + return; + + evas_object_show (_aux_area); + ui_candidate_window_adjust (); + + ui_candidate_show (); + ui_settle_candidate_window (); +} + +/** + * @brief Show candidate table slot function for PanelAgent. + */ +static void slot_show_candidate_table (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (_candidate_window == NULL) + ui_create_candidate_window (); + + if (evas_object_visible_get (_candidate_window) && + (evas_object_visible_get (_candidate_area_1) || evas_object_visible_get (_candidate_area_2))) + return; + + evas_object_show (_candidate_area_1); + ui_candidate_window_adjust (); + + ui_candidate_show (); + ui_settle_candidate_window (); +} + +/** + * @brief Hide aux slot function for PanelAgent. + */ +static void slot_hide_aux_string (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (!_aux_area || !evas_object_visible_get (_aux_area)) + return; + + evas_object_hide (_aux_area); + elm_scroller_region_show (_aux_area, 0, 0, 10, 10); + ui_candidate_window_adjust (); + + ui_candidate_hide (false); + ui_settle_candidate_window (); +} + +/** + * @brief Hide candidate table slot function for PanelAgent. + */ +static void slot_hide_candidate_table (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (!_candidate_area_1) + return; + + if (evas_object_visible_get (_candidate_area_1) || evas_object_visible_get (_candidate_area_2)) { + if (evas_object_visible_get (_candidate_area_1)) { + evas_object_hide (_candidate_area_1); + evas_object_hide (_more_btn); + } + if (evas_object_visible_get (_candidate_area_2)) { + evas_object_hide (_candidate_area_2); + evas_object_hide (_scroller_bg); + evas_object_hide (_close_btn); + _panel_agent->candidate_more_window_hide (); + } + ui_candidate_window_adjust (); + + ui_candidate_hide (false); + ui_settle_candidate_window (); + } +} + +/** + * @brief Set hightlight text color and background color for edje object. + * + * @param item The edje object pointer. + * @param nForeGround The text color. + * @param nBackGround The background color. + * @param bSetBack The flag for background color. + */ +static void set_highlight_color (Evas_Object *item, uint32 nForeGround, uint32 nBackGround, bool bSetBack) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + int r, g, b, a, r2, g2, b2, a2, r3, g3, b3, a3; + if (edje_object_color_class_get (item, "text_color", &r, &g, &b, &a, &r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3)) { + r = SCIM_RGB_COLOR_RED(nForeGround); + g = SCIM_RGB_COLOR_GREEN(nForeGround); + b = SCIM_RGB_COLOR_BLUE(nForeGround); + edje_object_color_class_set (item, "text_color", r, g, b, a, r2, g2, b2, a2, r3, g3, b3, a3); + } + if (bSetBack && edje_object_color_class_get (item, "rect_color", &r, &g, &b, &a, &r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3)) { + r = SCIM_RGB_COLOR_RED(nBackGround); + g = SCIM_RGB_COLOR_GREEN(nBackGround); + b = SCIM_RGB_COLOR_BLUE(nBackGround); + edje_object_color_class_set (item, "rect_color", r, g, b, 255, r2, g2, b2, a2, r3, g3, b3, a3); + } +} + +/** + * @brief Update aux slot function for PanelAgent. + * + * @param str The new aux string. + * @param attrs The attribute list of new aux string. + */ +static void slot_update_aux_string (const String &str, const AttributeList &attrs) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (_candidate_window == NULL) + ui_create_candidate_window (); + + if (!_aux_area || (str.length () <= 0)) + return; + + if (!evas_object_visible_get (_aux_area)) { + ui_candidate_show (); + slot_show_aux_string (); + } + + int x, y, width, height, item_width = 0; + unsigned int window_width = 0, count = 0, i; + + Evas_Object *aux_edje = NULL; + + /* Get highlight item index */ + int aux_index = -1, aux_start = 0, aux_end = 0; + String strAux = str; + bool bSetBack = false; + uint32 nForeGround = SCIM_RGB_COLOR(62, 207, 255); + uint32 nBackGround = SCIM_RGB_COLOR(0, 0, 0); + for (AttributeList::const_iterator ait = attrs.begin (); ait != attrs.end (); ++ait) { + if (aux_index == -1 && ait->get_type () == SCIM_ATTR_DECORATE) { + aux_index = ait->get_value (); + } else if (ait->get_type () == SCIM_ATTR_FOREGROUND) { + nForeGround = ait->get_value (); + } else if (ait->get_type () == SCIM_ATTR_BACKGROUND) { + nBackGround = ait->get_value (); + bSetBack = true; + } + } + + std::vector aux_list; + scim_split_string_list (aux_list, strAux, '|'); + + if (_aux_items.size () > 0) { + for (i = 0; i < _aux_items.size (); i++) + evas_object_del (_aux_items [i]); + _aux_items.clear (); + } + + for (i = 0; i < aux_list.size (); i++) { + count++; + aux_edje = edje_object_add (evas_object_evas_get (_candidate_window)); + edje_object_file_set (aux_edje, _candidate_edje_file.c_str (), "aux"); + edje_object_text_class_set (aux_edje, "aux_text_class", _candidate_font_name.c_str (), _aux_font_size); + edje_object_part_text_set (aux_edje, "aux", aux_list [i].c_str ()); + elm_table_pack (_aux_table, aux_edje, i, 0, 1, 1); + evas_object_event_callback_add (aux_edje, EVAS_CALLBACK_MOUSE_DOWN, ui_mouse_button_pressed_cb, GINT_TO_POINTER ((i << 8) + ISF_EFL_AUX)); + evas_object_event_callback_add (aux_edje, EVAS_CALLBACK_MOUSE_UP, ui_mouse_button_released_cb, GINT_TO_POINTER (i)); + evas_object_event_callback_add (aux_edje, EVAS_CALLBACK_MOUSE_MOVE, ui_mouse_moved_cb, GINT_TO_POINTER (ISF_EFL_AUX)); + evas_object_show (aux_edje); + _aux_items.push_back (aux_edje); +/* if (i == (unsigned int)aux_index) + edje_object_signal_emit (aux_edje, "aux,state,selected", "aux"); + else + edje_object_signal_emit (aux_edje, "aux,state,unselected", "aux"); +*/ + evas_object_text_text_set (_tmp_aux_text, aux_list [i].c_str ()); + evas_object_geometry_get (_tmp_aux_text, &x, &y, &width, &height); + item_width = width + 2*_blank_width; + item_width = item_width > _item_min_width ? item_width : _item_min_width; + evas_object_size_hint_min_set (aux_edje, item_width, _aux_height); + if (aux_index == (int)i || (aux_index == -1 && i == 0)) { + aux_start = window_width; + aux_end = window_width + item_width; + } + window_width = window_width + item_width + 4; + } + + // Set highlight item + for (AttributeList::const_iterator ait = attrs.begin (); ait != attrs.end (); ++ait) { + if (ait->get_type () == SCIM_ATTR_DECORATE) { + unsigned int index = ait->get_value (); + if (index < _aux_items.size ()) + set_highlight_color (_aux_items [index], nForeGround, nBackGround, bSetBack); + } + } + + int w, h; + elm_scroller_region_get (_aux_area, &x, &y, &w, &h); + item_width = aux_end - aux_start; + if (item_width > 0) { + if (item_width >= w) + elm_scroller_region_show (_aux_area, aux_end - w, y, w, h); + else if (aux_end > x + w) + elm_scroller_region_show (_aux_area, aux_end - w, y, w, h); + else if (aux_start < x) + elm_scroller_region_show (_aux_area, aux_start, y, w, h); + } + flush_memory (); +} + +/** + * @brief Update candidate/associate table. + * + * @param table_type The table type. + * @param table The lookup table for candidate or associate. + */ +static void update_table (int table_type, const LookupTable &table) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " (" << table.get_current_page_size () << ")\n"; + + int item_num = table.get_current_page_size (); + if (item_num < 0) + return; + + String mbs; + WideString wcs; + + AttributeList attrs; + int i, x, y, width, height, item_0_width; + + int nLast = 0; + std::vector row_items; + + int seperate_width = 4; + int seperate_height = 52 * _height_rate; + int line_width = _candidate_scroll_width; + int line_height = _v_padding; + int total_width = 0; + int current_width = 0; + int line_0 = 0; + int line_count = 0; + int more_item_count = 0; + int scroll_0_width = _candidate_scroll_0_width_min; + int cursor_pos = table.get_cursor_pos (); + int cursor_line = 0; + + if (_candidate_angle == 90 || _candidate_angle == 270) + scroll_0_width = 1176 * _height_rate; + else + scroll_0_width = 618 * _width_rate; + + Evas *evas = evas_object_evas_get (_candidate_window); + for (i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) { + if (_candidate_0 [i]) { + evas_object_del (_candidate_0 [i]); + _candidate_0 [i] = NULL; + } + if (_seperate_0 [i]) { + evas_object_del (_seperate_0 [i]); + _seperate_0 [i] = NULL; + } + if (_candidate_items [i]) { + evas_object_del (_candidate_items [i]); + _candidate_items [i] = NULL; + } + if (_seperate_items [i]) { + evas_object_del (_seperate_items [i]); + _seperate_items [i] = NULL; + } + if (_line_items [i]) { + evas_object_del (_line_items [i]); + _line_items [i] = NULL; + } + + if (i < item_num) { + bool bHighLight = false; + bool bSetBack = false; + uint32 nForeGround = SCIM_RGB_COLOR(249, 249, 249); + uint32 nBackGround = SCIM_RGB_COLOR(0, 0, 0); + attrs = table.get_attributes_in_current_page (i); + for (AttributeList::const_iterator ait = attrs.begin (); ait != attrs.end (); ++ait) { + if (ait->get_type () == SCIM_ATTR_DECORATE && ait->get_value () == SCIM_ATTR_DECORATE_HIGHLIGHT) { + bHighLight = true; + nForeGround = SCIM_RGB_COLOR(62, 207, 255); + } else if (ait->get_type () == SCIM_ATTR_FOREGROUND) { + bHighLight = true; + nForeGround = ait->get_value (); + } else if (ait->get_type () == SCIM_ATTR_BACKGROUND) { + bSetBack = true; + nBackGround = ait->get_value (); + } + } + + wcs = table.get_candidate_in_current_page (i); + mbs = utf8_wcstombs (wcs); + + if (!_candidate_0 [i] && total_width <= scroll_0_width) { + _candidate_0 [i] = edje_object_add (evas); + edje_object_file_set (_candidate_0 [i], _candidate_edje_file.c_str (), _candidate_name.c_str ()); + edje_object_text_class_set (_candidate_0 [i], "candidate_text_class", _candidate_font_name.c_str (), _candidate_font_size); + evas_object_event_callback_add (_candidate_0 [i], EVAS_CALLBACK_MOUSE_DOWN, ui_mouse_button_pressed_cb, GINT_TO_POINTER ((i << 8) + ISF_EFL_CANDIDATE_0)); + evas_object_event_callback_add (_candidate_0 [i], EVAS_CALLBACK_MOUSE_UP, ui_mouse_button_released_cb, GINT_TO_POINTER (i)); + evas_object_event_callback_add (_candidate_0 [i], EVAS_CALLBACK_MOUSE_MOVE, ui_mouse_moved_cb, GINT_TO_POINTER (ISF_EFL_CANDIDATE_0)); + evas_object_show (_candidate_0 [i]); + + edje_object_part_text_set (_candidate_0 [i], "candidate", mbs.c_str ()); + /* Resize _candidate_0 [i] display width */ + evas_object_text_text_set (_tmp_candidate_text, mbs.c_str ()); + evas_object_geometry_get (_tmp_candidate_text, &x, &y, &width, &height); + item_0_width = width + 2*_blank_width; + item_0_width = item_0_width > _item_min_width ? item_0_width : _item_min_width; + evas_object_size_hint_min_set (_candidate_0 [i], item_0_width, _item_min_height); + if (bHighLight || bSetBack) { + set_highlight_color (_candidate_0 [i], nForeGround, nBackGround, bSetBack); + } + + /* Check whether this item is the last one */ + if (i == item_num - 1) { + if (_candidate_angle == 90 || _candidate_angle == 270) + scroll_0_width = _candidate_land_width; + else + scroll_0_width = _candidate_port_width; + } + + /* Add first item */ + if (i == 0) { + item_0_width = item_0_width > scroll_0_width ? scroll_0_width : item_0_width; + evas_object_size_hint_min_set (_candidate_0 [i], item_0_width, _item_min_height); + elm_table_pack (_candidate_0_table, _candidate_0 [i], 0, 0, item_0_width, _item_min_height); + total_width += item_0_width; + continue; + } else { + total_width += (item_0_width + seperate_width); + if (total_width <= scroll_0_width) { + _seperate_0 [i] = edje_object_add (evas); + edje_object_file_set (_seperate_0 [i], _candidate_edje_file.c_str (), "seperate_line"); + evas_object_size_hint_min_set (_seperate_0 [i], seperate_width, seperate_height); + elm_table_pack (_candidate_0_table, _seperate_0 [i], + total_width - item_0_width - seperate_width, + line_0*(_item_min_height+line_height) + (_item_min_height - seperate_height)/2, + seperate_width, seperate_height); + evas_object_show (_seperate_0 [i]); + + elm_table_pack (_candidate_0_table, _candidate_0 [i], total_width - item_0_width, line_0*(_item_min_height+line_height), item_0_width, _item_min_height); + continue; + } else if ((_candidate_angle == 0 || _candidate_angle == 180) && + (_candidate_port_line > 1 && (line_0 + 1) < _candidate_port_line)) { + line_0++; + scroll_0_width = _candidate_scroll_0_width_min; + item_0_width = item_0_width > scroll_0_width ? scroll_0_width : item_0_width; + evas_object_size_hint_min_set (_candidate_0 [i], item_0_width, _item_min_height); + elm_table_pack (_candidate_0_table, _candidate_0 [i], 0, line_0*(_item_min_height+line_height), item_0_width, _item_min_height); + total_width = item_0_width; + + row_items.push_back (i - nLast); + nLast = i; + continue; + } else { + row_items.push_back (i - nLast); + nLast = i; + } + } + } + + if (!_candidate_items [i]) { + _candidate_items [i] = edje_object_add (evas); + edje_object_file_set (_candidate_items [i], _candidate_edje_file.c_str (), _candidate_name.c_str ()); + edje_object_text_class_set (_candidate_items [i], "candidate_text_class", _candidate_font_name.c_str (), _candidate_font_size); + evas_object_event_callback_add (_candidate_items [i], EVAS_CALLBACK_MOUSE_DOWN, ui_mouse_button_pressed_cb, GINT_TO_POINTER ((i << 8) + ISF_EFL_CANDIDATE_ITEMS)); + evas_object_event_callback_add (_candidate_items [i], EVAS_CALLBACK_MOUSE_UP, ui_mouse_button_released_cb, GINT_TO_POINTER (i)); + evas_object_event_callback_add (_candidate_items [i], EVAS_CALLBACK_MOUSE_MOVE, ui_mouse_moved_cb, GINT_TO_POINTER (ISF_EFL_CANDIDATE_ITEMS)); + evas_object_show (_candidate_items [i]); + } + if (bHighLight || bSetBack) { + set_highlight_color (_candidate_items [i], nForeGround, nBackGround, bSetBack); + } + edje_object_part_text_set (_candidate_items [i], "candidate", mbs.c_str ()); + /* Resize _candidate_items [i] display width */ + evas_object_text_text_set (_tmp_candidate_text, mbs.c_str ()); + evas_object_geometry_get (_tmp_candidate_text, &x, &y, &width, &height); + item_0_width = width + 2*_blank_width; + item_0_width = item_0_width > _item_min_width ? item_0_width : _item_min_width; + evas_object_size_hint_min_set (_candidate_items [i], item_0_width, _item_min_height); + if (current_width > 0 && current_width + item_0_width > _candidate_scroll_width) { + current_width = 0; + line_count++; + + row_items.push_back (i - nLast); + nLast = i; + if (cursor_pos >= i) + cursor_line++; + } + if (current_width == 0 && !_line_items [i]) { + _line_items [i] = edje_object_add (evas); + edje_object_file_set (_line_items [i], _candidate_edje_file.c_str (), "popup_line"); + evas_object_size_hint_min_set (_line_items [i], line_width, line_height); + x = 0; + y = line_count*(_item_min_height+line_height); + elm_table_pack (_candidate_table, _line_items [i], x, y, line_width, line_height); + evas_object_show (_line_items [i]); + } + if (current_width != 0 && !_seperate_items [i]) { + _seperate_items [i] = edje_object_add (evas); + edje_object_file_set (_seperate_items [i], _candidate_edje_file.c_str (), "seperate_line"); + evas_object_size_hint_min_set (_seperate_items [i], seperate_width, seperate_height); + x = current_width; + y = line_count*(_item_min_height+line_height) + line_height + (_item_min_height - seperate_height)/2; + elm_table_pack (_candidate_table, _seperate_items [i], x, y, seperate_width, seperate_height); + evas_object_show (_seperate_items [i]); + current_width += seperate_width; + } + x = current_width; + y = line_count*(_item_min_height+line_height) + line_height; + elm_table_pack (_candidate_table, _candidate_items [i], x, y, item_0_width, _item_min_height); + current_width += item_0_width; + more_item_count++; + } + } + + for (i = 1; i < _candidate_port_line; i++) { + if ((_candidate_angle == 0 || _candidate_angle == 180)) { + if (_line_0 [i] == NULL) { + _line_0 [i] = edje_object_add (evas); + edje_object_file_set (_line_0 [i], _candidate_edje_file.c_str (), "popup_line"); + evas_object_size_hint_min_set (_line_0 [i], line_width, line_height); + x = 0; + y = i * (_item_min_height + line_height) - line_height; + elm_table_pack (_candidate_0_table, _line_0 [i], x, y, line_width, line_height); + evas_object_show (_line_0 [i]); + } + + // Create blank line + if (line_0 + 1 < _candidate_port_line && i > line_0) { + int nIndex = item_num + i; + nIndex = nIndex < SCIM_LOOKUP_TABLE_MAX_PAGESIZE ? nIndex : SCIM_LOOKUP_TABLE_MAX_PAGESIZE - 1; + _seperate_0 [nIndex] = edje_object_add (evas); + edje_object_file_set (_seperate_0 [nIndex], _candidate_edje_file.c_str (), "seperate_line"); + evas_object_size_hint_min_set (_seperate_0 [nIndex], seperate_width, _item_min_height); + elm_table_pack (_candidate_0_table, _seperate_0 [nIndex], + 0, i*(_item_min_height+line_height), seperate_width, _item_min_height); + } + } else if (_line_0 [i]) { + evas_object_del (_line_0 [i]); + _line_0 [i] = NULL; + } + } + + row_items.push_back (item_num - nLast); /* Add the number of last row */ + _panel_agent->update_candidate_item_layout (row_items); + _panel_agent->update_displayed_candidate_number (item_num - more_item_count); + if (more_item_count == 0) { + ui_candidate_window_close_button_cb (NULL, NULL, NULL, NULL); + evas_object_hide (_more_btn); + } else if (!evas_object_visible_get (_candidate_area_2)) { + evas_object_show (_more_btn); + evas_object_hide (_close_btn); + } else { + evas_object_hide (_more_btn); + evas_object_show (_close_btn); + } + + int w, h; + elm_scroller_region_get (_candidate_area_2, &x, &y, &w, &h); + + int line_h = _item_min_height + _v_padding; + int cursor_y = cursor_line * line_h; + if (cursor_y < y) { + elm_scroller_region_show (_candidate_area_2, 0, cursor_y, w, h); + } else if (cursor_y >= y + h) { + elm_scroller_region_show (_candidate_area_2, 0, cursor_y + line_h - h, w, h); + } + + flush_memory (); +} + +/** + * @brief Update candidate table slot function for PanelAgent. + * + * @param table The lookup table for candidate. + */ +static void slot_update_candidate_table (const LookupTable &table) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (_candidate_window == NULL) + ui_create_candidate_window (); + + if (!_candidate_window || table.get_current_page_size () < 0) + return; + + update_table (ISF_CANDIDATE_TABLE, table); +} + +/** + * @brief Get candidate geometry slot function for PanelAgent. + * + * @param info The data is used to store candidate position and size. + */ +static void slot_get_candidate_geometry (struct rectinfo &info) +{ + int x = 0; + int y = 0; + int width = 0; + int height = 0; + if (_candidate_window && evas_object_visible_get (_candidate_window)) { + /* Get candidate window position */ + /*ecore_evas_geometry_get (ecore_evas_ecore_evas_get (evas_object_evas_get (_candidate_window)), &x, &y, &width, &height);*/ + /* Get exact candidate window size */ + /*int x2, y2; + evas_object_geometry_get (_candidate_window, &x2, &y2, &width, &height);*/ + + x = _candidate_x; + y = _candidate_y; + width = _candidate_width; + height = _candidate_height; + } + info.pos_x = x; + info.pos_y = y; + info.width = width; + info.height = height; + + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " x:" << info.pos_x << " y:" << info.pos_y + << " width:" << info.width << " height:" << info.height << "\n"; +} + +/** + * @brief Get input panel geometry slot function for PanelAgent. + * + * @param info The data is used to store input panel position and size. + */ +static void slot_get_input_panel_geometry (struct rectinfo &info) +{ + VIRTUAL_KEYBOARD_STATE kbd_state = _ise_show ? KEYBOARD_STATE_ON : KEYBOARD_STATE_OFF; + + if (_ise_width == 0 && _ise_height == 0) { + info.pos_x = 0; + if (_candidate_window && evas_object_visible_get (_candidate_window)) { + info.width = _candidate_width; + info.height = _candidate_height; + } + int angle = efl_get_angle_for_root_window (_candidate_window); + if (angle == 90 || angle == 270) + info.pos_y = _screen_width - info.height; + else + info.pos_y = _screen_height - info.height; + } else { + get_ise_geometry (info, kbd_state); + if (_candidate_mode == FIXED_CANDIDATE_WINDOW) { + if (_candidate_window && evas_object_visible_get (_candidate_window)) { + int height = ui_candidate_get_valid_height (); + if ((_candidate_height - height) > _ise_height) { + info.pos_y = info.pos_y + info.height - _candidate_height; + info.height = _candidate_height; + } else { + info.pos_y -= height; + info.height += height; + } + } + } + } + + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " x:" << info.pos_x << " y:" << info.pos_y + << " width:" << info.width << " height:" << info.height << "\n"; +} + +/** + * @brief Set active ISE slot function for PanelAgent. + * + * @param uuid The active ISE's uuid. + * @param changeDefault The flag for changeing default ISE. + */ +static void slot_set_active_ise (const String &uuid, bool changeDefault) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " (" << uuid << ")\n"; + + set_active_ise (uuid); +} + +/** + * @brief Get all ISEs list slot function for PanelAgent. + * + * @param list The list is used to store all ISEs. + * + * @return true if this operation is successful, otherwise return false. + */ +static bool slot_get_ise_list (std::vector &list) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + /* update ise list */ + bool ret = isf_update_ise_list (ALL_ISE, _config); + + std::vector langs, name_list; + isf_get_all_languages (langs); + isf_get_all_ises_in_languages (langs, list, name_list); + + _panel_agent->update_ise_list (list); + return ret; +} + +/** + * @brief Get the ISE's information. + * + * @param uuid The ISE's uuid. + * @param name The ISE's name. + * @param language The ISE's language. + * @param type The ISE's type. + * @param option The ISE's option. + * + * @return true if this operation is successful, otherwise return false. + */ +static bool slot_get_ise_information (String uuid, String &name, String &language, int &type, int &option) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (uuid.length () > 0) { + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (uuid == _uuids[i]) { + name = _names[i]; + language = _langs[i]; + type = _modes[i]; + option = _options[i]; + return true; + } + } + } + + std::cerr << __func__ << " is failed!!!\n"; + return false; +} + +/** + * @brief Get keyboard ISEs list slot function for PanelAgent. + * + * @param name_list The list is used to store keyboard ISEs. + * + * @return true if this operation is successful, otherwise return false. + */ +static bool slot_get_keyboard_ise_list (std::vector &name_list) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + /* update ise list */ + bool ret = isf_update_ise_list (ALL_ISE, _config); + + std::vector lang_list, uuid_list; + isf_get_all_languages (lang_list); + isf_get_keyboard_ises_in_languages (lang_list, uuid_list, name_list, false); + + if (ret) + _panel_agent->update_ise_list (uuid_list); + return ret; +} + +/** + * @brief Get enable languages list slot function for PanelAgent. + * + * @param list The list is used to store languages. + */ +static void slot_get_language_list (std::vector &list) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + String lang_name; + MapStringVectorSizeT::iterator iter = _groups.begin (); + + for (; iter != _groups.end (); iter++) { + lang_name = scim_get_language_name (iter->first); + list.push_back (lang_name); + } +} + +/** + * @brief Get all languages list slot function for PanelAgent. + * + * @param lang The list is used to store languages. + */ +static void slot_get_all_language (std::vector &lang) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + isf_get_all_languages (lang); +} + +/** + * @brief Get specific ISE language list slot function for PanelAgent. + * + * @param name The ISE name. + * @param list The list is used to store ISE languages. + */ +static void slot_get_ise_language (char *name, std::vector &list) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (name == NULL) + return; + + unsigned int num = _names.size (); + std::vector list_tmp; + list_tmp.clear (); + for (unsigned int i = 0; i < num; i++) { + if (!strcmp (_names[i].c_str (), name)) { + scim_split_string_list (list_tmp, _langs[i], ','); + for (i = 0; i < list_tmp.size (); i++) + list.push_back (scim_get_language_name (list_tmp[i])); + return; + } + } +} + +/** + * @brief Get ISE information slot function for PanelAgent. + * + * @param uuid The ISE uuid. + * @param info The variable is used to store ISE information. + * + * @return true if this operation is successful, otherwise return false. + */ +static bool slot_get_ise_info (const String &uuid, ISE_INFO &info) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (!uuid.compare (_uuids[i])) { + info.uuid = _uuids[i]; + info.name = _names[i]; + info.icon = _icons[i]; + info.lang = _langs[i]; + info.option = _options[i]; + info.type = _modes[i]; + return true; + } + } + + return false; +} + +/** + * @brief Set keyboard ISE slot function for PanelAgent. + * + * @param uuid The variable is ISE uuid. + */ +static void slot_set_keyboard_ise (const String &uuid) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + if (uuid.length () <= 0) + return; + + String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), String ("")); + if (get_ise_type (default_uuid) == TOOLBAR_KEYBOARD_MODE) + return; + + uint32 ise_option = 0; + String ise_uuid, ise_name; + isf_get_keyboard_ise (_config, ise_uuid, ise_name, ise_option); + if (ise_uuid == uuid) + return; + + String language = String ("~other");/*scim_get_locale_language (scim_get_current_locale ());*/ + _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, uuid); + _config->flush (); + _config->reload (); + + _panel_agent->change_factory (uuid); + _panel_agent->reload_config (); + + if (_candidate_window) + ui_create_candidate_window (); +} + +/** + * @brief Get current keyboard ISE name and uuid slot function for PanelAgent. + * + * @param ise_name The variable is used to store ISE name. + * @param ise_uuid The variable is used to store ISE uuid. + */ +static void slot_get_keyboard_ise (String &ise_name, String &ise_uuid) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + uint32 ise_option = 0; + isf_get_keyboard_ise (_config, ise_uuid, ise_name, ise_option); +} + +/** + * @brief Accept connection slot function for PanelAgent. + * + * @param fd The file descriptor to connect. + */ +static void slot_accept_connection (int fd) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + Ecore_Fd_Handler *panel_agent_read_handler = ecore_main_fd_handler_add (fd, ECORE_FD_READ, panel_agent_handler, NULL, NULL, NULL); + _read_handler_list.push_back (panel_agent_read_handler); +} + +/** + * @brief Close connection slot function for PanelAgent. + * + * @param fd The file descriptor to connect. + */ +static void slot_close_connection (int fd) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + int i = 0; + std::vector::iterator IterPos; + + for (IterPos = _read_handler_list.begin (); IterPos != _read_handler_list.end (); ++IterPos,++i) { + if (ecore_main_fd_handler_fd_get (_read_handler_list[i]) == fd) { + ecore_main_fd_handler_del (_read_handler_list[i]); + _read_handler_list.erase (IterPos); + break; + } + } +} + +/** + * @brief Exit panel process slot function for PanelAgent. + */ +static void slot_exit (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + elm_exit (); +} + +////////////////////////////////////////////////////////////////////// +// End of PanelAgent-Functions +////////////////////////////////////////////////////////////////////// + + +/** + * @brief Callback function for ecore fd handler. + * + * @param data The data to pass to this callback. + * @param fd_handler The ecore fd handler. + * + * @return ECORE_CALLBACK_RENEW + */ +static Eina_Bool panel_agent_handler (void *data, Ecore_Fd_Handler *fd_handler) +{ + if (fd_handler == NULL) + return ECORE_CALLBACK_RENEW; + + int fd = ecore_main_fd_handler_fd_get (fd_handler); + for (unsigned int i = 0; i < _read_handler_list.size (); i++) { + if (fd_handler == _read_handler_list [i]) { + if (!_panel_agent->filter_event (fd)) { + std::cerr << "_panel_agent->filter_event () is failed!!!\n"; + ecore_main_fd_handler_del (fd_handler); + } + return ECORE_CALLBACK_RENEW; + } + } + std::cerr << "panel_agent_handler () has received exception event!!!\n"; + _panel_agent->filter_exception_event (fd); + ecore_main_fd_handler_del (fd_handler); + return ECORE_CALLBACK_RENEW; +} + +/** + * @brief Handler function for HelperManager input. + * + * @param data The data to pass to this callback. + * @param fd_handler The Ecore Fd handler. + * + * @return ECORE_CALLBACK_RENEW + */ +static Eina_Bool helper_manager_input_handler (void *data, Ecore_Fd_Handler *fd_handler) +{ + if (_panel_agent->has_helper_manager_pending_event ()) { + if (!_panel_agent->filter_helper_manager_event ()) { + std::cerr << "_panel_agent->filter_helper_manager_event () is failed!!!\n"; + elm_exit (); + } + } else { + std::cerr << "_panel_agent->has_helper_manager_pending_event () is failed!!!\n"; + elm_exit (); + } + + return ECORE_CALLBACK_RENEW; +} + +/** + * @brief Callback function for abnormal signal. + * + * @param sig The signal. + */ +static void signalhandler (int sig) +{ + SCIM_DEBUG_MAIN (1) << __FUNCTION__ << " Signal=" << sig << "\n"; + + elm_exit (); +} + +#if HAVE_VCONF +/** + * @brief Update keyboard ISE name when display language is changed. + * + * @param module_name The keyboard ISE module name. + * @param index The index of _module_names. + * + * @return true if suceessful, otherwise return false. + */ +static bool update_keyboard_ise_locale (const String module_name, int index) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (module_name.length () <= 0 || module_name == "socket") + return false; + + IMEngineFactoryPointer factory; + IMEngineModule ime_module; + ime_module.load (module_name, _config); + + if (ime_module.valid ()) { + for (size_t j = 0; j < ime_module.number_of_factories (); ++j) { + try { + factory = ime_module.create_factory (j); + } catch (...) { + factory.reset (); + } + if (!factory.null ()) { + _names[index+j] = utf8_wcstombs (factory->get_name ()); + factory.reset (); + } + } + ime_module.unload (); + } else { + std::cerr << module_name << " can not be loaded!!!\n"; + } + + return true; +} + +/** + * @brief Update helper ISE name when display language is changed. + * + * @param module_name The helper ISE module name. + * @param index The index of _module_names. + * + * @return true if suceessful, otherwise return false. + */ +static bool update_helper_ise_locale (const String module_name, int index) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + if (module_name.length () <= 0) + return false; + + HelperModule helper_module; + HelperInfo helper_info; + helper_module.load (module_name); + if (helper_module.valid ()) { + for (size_t j = 0; j < helper_module.number_of_helpers (); ++j) { + helper_module.get_helper_info (j, helper_info); + _names[index+j] = helper_info.name; + } + helper_module.unload (); + } else { + std::cerr << module_name << " can not be loaded!!!\n"; + } + + return true; +} + +/** + * @brief Set language and locale. + * + * @return void + */ +static void set_language_and_locale (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + char *lang_str = vconf_get_str (VCONFKEY_LANGSET); + + if (lang_str) { + setenv ("LANG", lang_str, 1); + setlocale (LC_MESSAGES, lang_str); + free (lang_str); + } else { + setenv ("LANG", "en_US.utf8", 1); + setlocale (LC_MESSAGES, "en_US.utf8"); + } +} + +/** + * @brief Callback function for display language change. + * + * @param key The key node. + * @param data The data to pass to this callback. + * + * @return void + */ +static void display_language_changed_cb (keynode_t *key, void* data) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + set_language_and_locale (); + + /* Update all ISE names according to display language */ + std::vector module_list; + for (unsigned int i = 0; i < _module_names.size (); i++) { + if (std::find (module_list.begin (), module_list.end (), _module_names[i]) != module_list.end ()) + continue; + module_list.push_back (_module_names[i]); + if (_module_names[i] == String (COMPOSE_KEY_MODULE)) { + IMEngineFactoryPointer factory; + factory = new ComposeKeyFactory (); + _names[i] = utf8_wcstombs (factory->get_name ()); + factory.reset (); + } else if (_modes[i] == TOOLBAR_KEYBOARD_MODE) { + update_keyboard_ise_locale (_module_names[i], i); + } else if (_modes[i] == TOOLBAR_HELPER_MODE) { + update_helper_ise_locale (_module_names[i], i); + } + } + isf_save_ise_information (); + + String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _initial_ise_uuid); + String default_name = get_ise_name (default_uuid); + _panel_agent->set_current_ise_name (default_name); + _config->reload (); +} +#endif + +/** + * @brief Start default ISE. + * + * @return void + */ +static void start_default_ise (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _initial_ise_uuid); + String default_name = get_ise_name (default_uuid); + if (!set_active_ise (default_uuid)) { + std::cerr << __FUNCTION__ << " Failed to launch default ISE(" << default_uuid << ")\n"; + + if (default_uuid != _initial_ise_uuid) { + std::cerr << __FUNCTION__ << " Launch initial ISE(" << _initial_ise_uuid << ")\n"; + set_active_ise (_initial_ise_uuid); + } + } +} + +/** + * @brief Check hardware keyboard. + * + * @return void + */ +static void check_hardware_keyboard (void) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + unsigned int val = 0; + + _config->write (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0); + if (ecore_x_window_prop_card32_get (ecore_x_window_root_first_get (), ecore_x_atom_get (PROP_X_EXT_KEYBOARD_EXIST), &val, 1)) { + uint32 option = 0; + String uuid, name; + String helper_uuid = _config->read (SCIM_CONFIG_DEFAULT_HELPER_ISE, String ("")); + String default_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), String ("")); + + if (val != 0) { + _config->write (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 1); + + if (get_ise_type (default_uuid) == TOOLBAR_HELPER_MODE) { + /* Get the keyboard ISE */ + isf_get_keyboard_ise (_config, uuid, name, option); + if (option & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD) { + uuid = String (SCIM_COMPOSE_KEY_FACTORY_UUID); + std::cerr << __FUNCTION__ << ": Keyboard ISE (" << name << ") can not support hardware keyboard!!!\n"; + } + /* Try to find reasonable keyboard ISE according to helper ISE language */ + if (uuid == String (SCIM_COMPOSE_KEY_FACTORY_UUID)) { + String helper_language = get_ise_language (default_uuid); + if (helper_language.length () > 0) { + std::vector ise_langs; + scim_split_string_list (ise_langs, helper_language); + for (size_t i = 0; i < _groups[ise_langs[0]].size (); ++i) { + int j = _groups[ise_langs[0]][i]; + if (_uuids[j] != uuid && _modes[j] == TOOLBAR_KEYBOARD_MODE) { + uuid = _uuids[j]; + break; + } + } + } + } + } else { + uuid = default_uuid; + } + } else { + uuid = helper_uuid.length () > 0 ? helper_uuid : _initial_ise_uuid; + } + + set_active_ise (uuid); + } +} + +/** + * @brief Callback function for ECORE_X_EVENT_WINDOW_PROPERTY. + * + * @param data Data to pass when it is called. + * @param ev_type The event type. + * @param ev The information for current message. + * + * @return ECORE_CALLBACK_PASS_ON + */ +static Eina_Bool x_event_window_property_cb (void *data, int ev_type, void *ev) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + Ecore_X_Event_Window_Property *event = (Ecore_X_Event_Window_Property *)ev; + + Ecore_X_Window rootwin = ecore_x_window_root_first_get (); + if (event->win == rootwin && event->atom == ecore_x_atom_get (PROP_X_EXT_KEYBOARD_EXIST)) { + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + check_hardware_keyboard (); + } + + return ECORE_CALLBACK_PASS_ON; +} + +/** + * @brief Callback function for X event client message. + * + * @param data Data to pass when it is called. + * @param type The event type. + * @param event The information for current message. + * + * @return ECORE_CALLBACK_RENEW + */ +static Eina_Bool x_event_client_message_cb (void *data, int type, void *event) +{ + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; + + Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event; + if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE) { + int angle = ev->data.l[0]; + SCIM_DEBUG_MAIN (3) << __FUNCTION__ << " : ANGLE (" << angle << ")\n"; + ui_candidate_hide (true); + if (_candidate_window && _candidate_angle != angle) { + _candidate_angle = angle; + ui_candidate_window_rotate (angle); + int hw_kbd_detect = _config->read (ISF_CONFIG_HARDWARE_KEYBOARD_DETECT, 0); + if (hw_kbd_detect && evas_object_visible_get (_candidate_area_1)) + ui_candidate_show (); + } + } + + return ECORE_CALLBACK_RENEW; +} + +int main (int argc, char *argv []) +{ + struct tms tiks_buf; + _clock_start = times (&tiks_buf); + + int i; +#ifdef WAIT_WM + int try_count = 0; +#endif + int ret = 0; + + bool daemon = false; + bool should_resident = true; + + int new_argc = 0; + char **new_argv = new char * [40]; + ConfigModule *config_module = NULL; + String config_name = String ("socket"); + String display_name = String (); + + Ecore_Fd_Handler *panel_agent_read_handler = NULL; + Ecore_Fd_Handler *helper_manager_handler = NULL; + Ecore_Event_Handler *xclient_message_handler = NULL; + Ecore_Event_Handler *xwindow_property_handler = NULL; + + set_app_privilege ("isf", NULL, NULL); + + check_time ("\nStarting ISF Panel EFL...... "); + + DebugOutput::disable_debug (SCIM_DEBUG_AllMask); + DebugOutput::enable_debug (SCIM_DEBUG_MainMask); + + /* Parse command options */ + i = 0; + while (i < argc) { + if (++i >= argc) + break; + + if (String ("-c") == argv [i] || String ("--config") == argv [i]) { + if (++i >= argc) { + std::cerr << "no argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + config_name = argv [i]; + continue; + } + + if (String ("-h") == argv [i] || String ("--help") == argv [i]) { + std::cout << "Usage: " << argv [0] << " [option]...\n\n" + << "The options are: \n" + << " --display DISPLAY Run on display DISPLAY.\n" + << " -c, --config NAME Uses specified Config module.\n" + << " -d, --daemon Run " << argv [0] << " as a daemon.\n" + << " -ns, --no-stay Quit if no connected client.\n" +#if ENABLE_DEBUG + << " -v, --verbose LEVEL Enable debug info, to specific LEVEL.\n" + << " -o, --output FILE Output debug information into FILE.\n" +#endif + << " -h, --help Show this help message.\n"; + delete []new_argv; + return 0; + } + + if (String ("-d") == argv [i] || String ("--daemon") == argv [i]) { + daemon = true; + continue; + } + + if (String ("-ns") == argv [i] || String ("--no-stay") == argv [i]) { + should_resident = false; + continue; + } + + if (String ("-v") == argv [i] || String ("--verbose") == argv [i]) { + if (++i >= argc) { + std::cerr << "no argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + DebugOutput::set_verbose_level (atoi (argv [i])); + continue; + } + + if (String ("-o") == argv [i] || String ("--output") == argv [i]) { + if (++i >= argc) { + std::cerr << "No argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + DebugOutput::set_output (argv [i]); + continue; + } + + if (String ("--display") == argv [i]) { + if (++i >= argc) { + std::cerr << "No argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + display_name = argv [i]; + continue; + } + + if (String ("--") == argv [i]) + break; + + std::cerr << "Invalid command line option: " << argv [i] << "\n"; + delete []new_argv; + return 0; + } /* End of command line parsing. */ + + new_argv [new_argc ++] = argv [0]; + + /* Store the rest argvs into new_argv. */ + for (++i; i < argc && new_argc < 37; ++i) { + new_argv [new_argc ++] = argv [i]; + } + + /* Make up DISPLAY env. */ + if (display_name.length ()) { + new_argv [new_argc ++] = const_cast ("--display"); + new_argv [new_argc ++] = const_cast (display_name.c_str ()); + + setenv ("DISPLAY", display_name.c_str (), 1); + } + + new_argv [new_argc] = 0; + + if (!config_name.length ()) { + std::cerr << "No Config module is available!\n"; + ret = -1; + goto cleanup; + } + + if (config_name != "dummy") { + /* Load config module */ + config_module = new ConfigModule (config_name); + + if (!config_module || !config_module->valid ()) { + std::cerr << "Can not load " << config_name << " Config module.\n"; + ret = -1; + goto cleanup; + } + } else { + _config = new DummyConfig (); + } + + setenv ("ELM_FPS", "6000", 1); + setenv ("ELM_ENGINE", "software_x11", 1); /* Avoid the inheritance of ELM_ENGINE */ + set_language_and_locale (); + +#ifdef WAIT_WM + while (1) { + if (check_file ("/tmp/.wm_ready")) + break; + + if (try_count == 6000) { + std::cerr << "[ISF-PANEL-EFL] Timeout. cannot check the state of window manager....\n"; + break; + } + + try_count++; + usleep (50000); + } +#endif + + elm_init (argc, argv); + check_time ("elm_init"); + + /* Get current display. */ + { + const char *p = getenv ("DISPLAY"); + if (p) + display_name = String (p); + } + + char buf [256]; + snprintf (buf, sizeof (buf), "config_name=%s display_name=%s", config_name.c_str (), display_name.c_str ()); + check_time (buf); + try { + if (!initialize_panel_agent (config_name, display_name, should_resident)) { + check_time ("Failed to initialize Panel Agent!"); + std::cerr << "Failed to initialize Panel Agent!\n"; + ret = -1; + goto cleanup; + } + } catch (scim::Exception & e) { + std::cerr << e.what() << "\n"; + ret = -1; + goto cleanup; + } + check_time ("initialize_panel_agent"); + + /* Create config instance */ + if (_config.null () && config_module && config_module->valid ()) + _config = config_module->create_config (); + if (_config.null ()) { + std::cerr << "Failed to create Config instance from " << config_name << " Config module.\n"; + ret = -1; + goto cleanup; + } + check_time ("create config instance"); + + /* Initialize global variables and pointers for candidate items and etc. */ + for (i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; i++) { + _candidate_0 [i] = NULL; + _candidate_items [i] = NULL; + _seperate_0 [i] = NULL; + _seperate_items [i] = NULL; + _line_0 [i] = NULL; + _line_items [i] = NULL; + } + + efl_get_screen_resolution (_screen_width, _screen_height); + + _width_rate = (float)(_screen_width / 720.0); + _height_rate = (float)(_screen_height / 1280.0); + _blank_width = (int)(_blank_width * _width_rate); + _item_min_width = (int)(_item_min_width * _width_rate); + _item_min_height = (int)(_item_min_height * _height_rate); + _candidate_width = (int)(_candidate_port_width * _width_rate); + _candidate_height = (int)(_candidate_port_height_min * _height_rate); + _indicator_height = (int)(_indicator_height * _height_rate); + + _aux_font_size = (int)(_aux_font_size * _width_rate); + _candidate_font_size = (int)(_candidate_font_size * _width_rate); + + /* Load ISF configuration */ + load_config (); + check_time ("load_config"); + + try { + _panel_agent->send_display_name (display_name); + } catch (scim::Exception & e) { + std::cerr << e.what() << "\n"; + ret = -1; + goto cleanup; + } + + if (daemon) { + check_time ("ISF Panel EFL run as daemon"); + scim_daemon (); + } + + /* Connect the configuration reload signal. */ + _config->signal_connect_reload (slot (config_reload_cb)); + + helper_manager_handler = ecore_main_fd_handler_add (_panel_agent->get_helper_manager_id (), ECORE_FD_READ, helper_manager_input_handler, NULL, NULL, NULL); + panel_agent_read_handler = ecore_main_fd_handler_add (_panel_agent->get_server_id (), ECORE_FD_READ, panel_agent_handler, NULL, NULL, NULL); + _read_handler_list.push_back (panel_agent_read_handler); + check_time ("run_panel_agent"); + +#if HAVE_VCONF + /* Add callback function for input language and display language */ + vconf_notify_key_changed (VCONFKEY_LANGSET, display_language_changed_cb, NULL); + + set_language_and_locale (); +#endif + + try { + /* Update ISE list */ + std::vector list; + slot_get_ise_list (list); + + /* Load initial ISE information */ + _initial_ise_uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_INITIAL_ISE_UUID), String (SCIM_COMPOSE_KEY_FACTORY_UUID)); + + /* Start default ISE */ + start_default_ise (); + check_hardware_keyboard (); + } catch (scim::Exception & e) { + std::cerr << e.what () << "\n"; + } + + /* Create hibernation ready file */ + FILE *rfd; + rfd = fopen (ISF_READY_FILE, "w+"); + if (rfd) + fclose (rfd); + + xclient_message_handler = ecore_event_handler_add (ECORE_X_EVENT_CLIENT_MESSAGE, x_event_client_message_cb, NULL); + ecore_x_event_mask_set (ecore_x_window_root_first_get (), ECORE_X_EVENT_MASK_WINDOW_PROPERTY); + xwindow_property_handler = ecore_event_handler_add (ECORE_X_EVENT_WINDOW_PROPERTY, x_event_window_property_cb, NULL); + + /* Set elementary scale */ + if (_screen_width) + elm_config_scale_set (_screen_width / 720.0f); + + signal (SIGQUIT, signalhandler); + signal (SIGTERM, signalhandler); + signal (SIGINT, signalhandler); + signal (SIGHUP, signalhandler); + + check_time ("EFL Panel launch time"); + + elm_run (); + + _config->flush (); + ret = 0; + + ecore_event_handler_del (xclient_message_handler); + ecore_event_handler_del (xwindow_property_handler); + if (helper_manager_handler) + ecore_main_fd_handler_del (helper_manager_handler); + for (unsigned int ii = 0; ii < _read_handler_list.size (); ++ii) { + ecore_main_fd_handler_del (_read_handler_list[ii]); + } + _read_handler_list.clear (); + +#if HAVE_VCONF + /* Remove callback function for input language and display language */ + vconf_ignore_key_changed (VCONFKEY_LANGSET, display_language_changed_cb); +#endif + +cleanup: + ui_candidate_delete_check_size_timer (); + ui_candidate_delete_longpress_timer (); + ui_candidate_delete_destroy_timer (); + + if (!_config.null ()) + _config.reset (); + if (config_module) + delete config_module; + if (_panel_agent) { + try { + _panel_agent->stop (); + } catch (scim::Exception & e) { + std::cerr << "Exception is thrown from _panel_agent->stop (), error is " << e.what () << "\n"; + } + delete _panel_agent; + } + + delete []new_argv; + + if (ret == 0) { + std::cerr << "Successfully exited.\n"; + return 0; + } else { + std::cerr << "Abnormally exited.\n"; + return -1; + } +} + +/* +vi:ts=4:nowrap:expandtab +*/ diff --git a/ism/extras/efl_panel/isf_panel_utility.cpp b/ism/extras/efl_panel/isf_panel_utility.cpp new file mode 100644 index 0000000..fc0ac48 --- /dev/null +++ b/ism/extras/efl_panel/isf_panel_utility.cpp @@ -0,0 +1,522 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_PANEL_AGENT +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_COMPOSE_KEY + + +#include +#include "scim.h" +#include "scim_stl_map.h" +#include "isf_panel_utility.h" +#include "isf_query_utility.h" + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of global variables. +///////////////////////////////////////////////////////////////////////////// +MapStringVectorSizeT _groups; +std::vector _uuids; +std::vector _names; +std::vector _module_names; +std::vector _langs; +std::vector _icons; +std::vector _options; +std::vector _modes; + +std::vector _load_ise_list; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal variables. +///////////////////////////////////////////////////////////////////////////// +static std::vector _current_modules_list; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal functions. +///////////////////////////////////////////////////////////////////////////// +static bool add_keyboard_ise_module (const String ise_name, const ConfigPointer &config); +static bool add_helper_ise_module (const String ise_name); + + +/** + * @brief Get all ISEs support languages. + * + * @param all_langs The list to store all languages. + */ +void isf_get_all_languages (std::vector &all_langs) +{ + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + all_langs.push_back (lang_name); + } +} + +/** + * @brief Get all ISEs for the specific languages. + * + * @param lang_list The specific languages list. + * @param uuid_list The list to store ISEs' UUID. + * @param name_list The list to store ISEs' name. + */ +void isf_get_all_ises_in_languages (std::vector lang_list, std::vector &uuid_list, std::vector &name_list) +{ + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + if (std::find (lang_list.begin (), lang_list.end (), lang_name) != lang_list.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + if (_current_modules_list.size () > 0 && + std::find (_current_modules_list.begin (), _current_modules_list.end (), _module_names[it->second[i]]) == _current_modules_list.end ()) + continue; + // Avoid to add the same ISE + if (std::find (uuid_list.begin (), uuid_list.end (), _uuids[it->second[i]]) == uuid_list.end ()) { + uuid_list.push_back (_uuids[it->second[i]]); + name_list.push_back (_names[it->second[i]]); + } + } + } + } +} + +/** + * @brief Get keyboard ISE + * + * @param config The config pointer for loading keyboard ISE. + * @param ise_uuid The keyboard ISE uuid. + * @param ise_name The keyboard ISE name. + * @param ise_option The keyboard ISE option. + */ +void isf_get_keyboard_ise (const ConfigPointer &config, String &ise_uuid, String &ise_name, uint32 &ise_option) +{ + String uuid = config->read (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + String ("~other"), String ("")); + if (ise_uuid.length () > 0) + uuid = ise_uuid; + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (uuid == _uuids[i]) { + ise_uuid = _uuids[i]; + ise_name = _names[i]; + ise_option = _options[i]; + return; + } + } + ise_name = String (""); + ise_uuid = String (""); +} + +/** + * @brief Get all keyboard ISEs for the specific languages. + * + * @param lang_list The specific languages list. + * @param uuid_list The list to store keyboard ISEs' UUID. + * @param name_list The list to store keyboard ISEs' name. + * @param bCheckOption The flag to check whether support hardware keyboard. + */ +void isf_get_keyboard_ises_in_languages (const std::vector &lang_list, + std::vector &uuid_list, + std::vector &name_list, + bool bCheckOption) +{ + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + + if (std::find (lang_list.begin (), lang_list.end (), lang_name) != lang_list.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + if (_modes[it->second[i]] != TOOLBAR_KEYBOARD_MODE) + continue; + if (bCheckOption && (_options[it->second[i]] & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD)) + continue; + if (_current_modules_list.size () > 0 && + std::find (_current_modules_list.begin (), _current_modules_list.end (), _module_names[it->second[i]]) == _current_modules_list.end ()) + continue; + if (std::find (uuid_list.begin (), uuid_list.end (), _uuids[it->second[i]]) == uuid_list.end ()) { + uuid_list.push_back (_uuids[it->second[i]]); + name_list.push_back (_names[it->second[i]]); + } + } + } + } +} + +/** + * @brief Get all helper ISEs for the specific languages. + * + * @param lang_list The specific languages list. + * @param uuid_list The list to store helper ISEs' UUID. + * @param name_list The list to store helper ISEs' name. + */ +void isf_get_helper_ises_in_languages (const std::vector &lang_list, std::vector &uuid_list, std::vector &name_list) +{ + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + if (std::find (lang_list.begin (), lang_list.end (), lang_name) != lang_list.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + + if (_modes[it->second[i]]!= TOOLBAR_HELPER_MODE) + continue; + if (_current_modules_list.size () > 0 && + std::find (_current_modules_list.begin (), _current_modules_list.end (), _module_names[it->second[i]]) == _current_modules_list.end ()) + continue; + // Avoid to add the same ISE + if (std::find (uuid_list.begin (), uuid_list.end (), _uuids[it->second[i]]) == uuid_list.end ()) { + uuid_list.push_back (_uuids[it->second[i]]); + name_list.push_back (_names[it->second[i]]); + } + } + } + } +} + +/** + * @brief Save all ISEs information into cache file. + * + * @return void + */ +void isf_save_ise_information (void) +{ + if (_module_names.size () <= 0) + return; + + std::vector info_list; + for (size_t i = 0; i < _module_names.size (); ++i) { + if (_module_names[i] == COMPOSE_KEY_MODULE) + continue; + ISEINFO info; + info.name = _names[i]; + info.uuid = _uuids[i]; + info.module = _module_names[i]; + info.language = _langs[i]; + info.icon = _icons[i]; + info.mode = _modes[i]; + info.option = _options[i]; + info.locales = ""; + info_list.push_back (info); + } + + String user_file_name = String (USER_ENGINE_FILE_NAME); + isf_write_ise_info_list (user_file_name.c_str (), info_list); +} + +/** + * @brief Load all ISEs to initialize. + * + * @param type The loading ISE type. + * @param config The config pointer for loading keyboard ISE. + * @param uuids The ISE uuid list. + * @param names The ISE name list. + * @param module_names The ISE module name list. + * @param langs The ISE language list. + * @param icons The ISE icon list. + * @param modes The ISE type list. + * @param options The ISE option list. + * @param ise_list The already loaded ISE list. + */ +void isf_get_factory_list (LOAD_ISE_TYPE type, + const ConfigPointer &config, + std::vector &uuids, + std::vector &names, + std::vector &module_names, + std::vector &langs, + std::vector &icons, + std::vector &modes, + std::vector &options, + const std::vector &ise_list) +{ + uuids.clear (); + names.clear (); + module_names.clear (); + langs.clear (); + icons.clear (); + modes.clear (); + options.clear (); + _groups.clear (); + + if (type != HELPER_ONLY) { + /* Add ComposeKeyFactory first. */ + IMEngineFactoryPointer factory = new ComposeKeyFactory (); + uuids.push_back (factory->get_uuid ()); + names.push_back (utf8_wcstombs (factory->get_name ())); + module_names.push_back (COMPOSE_KEY_MODULE); + langs.push_back (isf_get_normalized_language (factory->get_language ())); + icons.push_back (factory->get_icon_file ()); + modes.push_back (TOOLBAR_KEYBOARD_MODE); + options.push_back (factory->get_option ()); + factory.reset (); + } + + String user_file_name = String (USER_ENGINE_FILE_NAME); + FILE *engine_list_file = fopen (user_file_name.c_str (), "r"); + if (engine_list_file == NULL) { + std::cerr << __func__ << " Failed to open(" << user_file_name << ")\n"; + return; + } + + char buf[MAXLINE]; + while (fgets (buf, MAXLINE, engine_list_file) != NULL) { + ISEINFO info; + isf_get_ise_info_from_string (buf, info); + if (info.mode == TOOLBAR_HELPER_MODE || type != HELPER_ONLY) { + names.push_back (info.name); + uuids.push_back (info.uuid); + module_names.push_back (info.module); + langs.push_back (info.language); + icons.push_back (info.icon); + modes.push_back (info.mode); + options.push_back (info.option); + } + } + + fclose (engine_list_file); +} + +/** + * @brief Load all ISEs information and ISF default languages. + * + * @param type The load ISE type. + * @param config The config pointer for loading keyboard ISE. + */ +void isf_load_ise_information (LOAD_ISE_TYPE type, const ConfigPointer &config) +{ + /* Load ISE engine info */ + isf_get_factory_list (type, config, _uuids, _names, _module_names, _langs, _icons, _modes, _options, _load_ise_list); + + _current_modules_list.clear (); + scim_get_helper_module_list (_current_modules_list); + /* Check keyboard ISEs */ + if (type != HELPER_ONLY) { + _current_modules_list.push_back (COMPOSE_KEY_MODULE); + std::vector imengine_list; + scim_get_imengine_module_list (imengine_list); + for (size_t i = 0; i < imengine_list.size (); ++i) + _current_modules_list.push_back (imengine_list [i]); + } + + /* Update _groups */ + std::vector ise_langs; + for (size_t i = 0; i < _uuids.size (); ++i) { + scim_split_string_list (ise_langs, _langs[i]); + for (size_t j = 0; j < ise_langs.size (); j++) { + if (std::find (_groups[ise_langs[j]].begin (), _groups[ise_langs[j]].end (), i) == _groups[ise_langs[j]].end ()) + _groups[ise_langs[j]].push_back (i); + } + ise_langs.clear (); + } +} + +/** + * @brief Load one keyboard ISE module. + * + * @param module_name The keboard ISE module name. + * @param config The config pointer for loading keyboard ISE. + * + * @return true if load module is successful, otherwise return false. + */ +static bool add_keyboard_ise_module (const String module_name, const ConfigPointer &config) +{ + if (module_name.length () <= 0 || module_name == "socket") + return false; + + IMEngineFactoryPointer factory; + IMEngineModule ime_module; + + String filename = String (USER_ENGINE_FILE_NAME); + FILE *engine_list_file = fopen (filename.c_str (), "a"); + if (engine_list_file == NULL) { + std::cerr << __func__ << " Failed to open(" << filename << ")\n"; + return false; + } + + ime_module.load (module_name, config); + if (ime_module.valid ()) { + for (size_t j = 0; j < ime_module.number_of_factories (); ++j) { + try { + factory = ime_module.create_factory (j); + } catch (...) { + factory.reset (); + } + + if (!factory.null ()) { + if (std::find (_uuids.begin (), _uuids.end (), factory->get_uuid ()) == _uuids.end ()) { + String uuid = factory->get_uuid (); + String name = utf8_wcstombs (factory->get_name ()); + String language = isf_get_normalized_language (factory->get_language ()); + String icon = factory->get_icon_file (); + char mode[12]; + char option[12]; + + _uuids.push_back (uuid); + _names.push_back (name); + _module_names.push_back (module_name); + _langs.push_back (language); + _icons.push_back (icon); + _modes.push_back (TOOLBAR_KEYBOARD_MODE); + _options.push_back (factory->get_option ()); + + snprintf (mode, sizeof (mode), "%d", (int)TOOLBAR_KEYBOARD_MODE); + snprintf (option, sizeof (option), "%d", factory->get_option ()); + + String line = isf_combine_ise_info_string (name, uuid, module_name, language, + icon, String (mode), String (option), factory->get_locales ()); + if (fputs (line.c_str (), engine_list_file) < 0) { + std::cerr << "write to ise cache file failed:" << line << "\n"; + break; + } + } + factory.reset (); + } + } + ime_module.unload (); + } + + fclose (engine_list_file); + + return true; +} + +/** + * @brief Load one helper ISE module. + * + * @param module_name The helper ISE module name. + * + * @return true if load module is successful, otherwise return false. + */ +static bool add_helper_ise_module (const String module_name) +{ + if (module_name.length () <= 0) + return false; + + HelperModule helper_module; + HelperInfo helper_info; + + String filename = String (USER_ENGINE_FILE_NAME); + FILE *engine_list_file = fopen (filename.c_str (), "a"); + if (engine_list_file == NULL) { + std::cerr << __func__ << " Failed to open(" << filename << ")\n"; + return false; + } + + helper_module.load (module_name); + if (helper_module.valid ()) { + for (size_t j = 0; j < helper_module.number_of_helpers (); ++j) { + helper_module.get_helper_info (j, helper_info); + _uuids.push_back (helper_info.uuid); + _names.push_back (helper_info.name); + _langs.push_back (isf_get_normalized_language (helper_module.get_helper_lang (j))); + _module_names.push_back (module_name); + _icons.push_back (helper_info.icon); + _modes.push_back (TOOLBAR_HELPER_MODE); + _options.push_back (helper_info.option); + + char mode[12]; + char option[12]; + snprintf (mode, sizeof (mode), "%d", (int)TOOLBAR_HELPER_MODE); + snprintf (option, sizeof (option), "%d", helper_info.option); + + String line = isf_combine_ise_info_string (helper_info.name, helper_info.uuid, module_name, isf_get_normalized_language (helper_module.get_helper_lang (j)), + helper_info.icon, String (mode), String (option), String ("")); + if (fputs (line.c_str (), engine_list_file) < 0) { + std::cerr << "write to ise cache file failed:" << line << "\n"; + break; + } + } + helper_module.unload (); + } + + fclose (engine_list_file); + + return true; +} + +/** + * @brief Update ISEs information for ISE is added or removed. + * + * @param type The load ISE type. + * @param config The config pointer for loading keyboard ISE. + * + * @return true if ISEs list is changed, otherwise return false. + */ +bool isf_update_ise_list (LOAD_ISE_TYPE type, const ConfigPointer &config) +{ + bool ret = false; + + std::vector helper_list; + scim_get_helper_module_list (helper_list); + + _current_modules_list.clear (); + + /* Check keyboard ISEs */ + if (type != HELPER_ONLY) { + _current_modules_list.push_back (COMPOSE_KEY_MODULE); + std::vector imengine_list; + scim_get_imengine_module_list (imengine_list); + for (size_t i = 0; i < imengine_list.size (); ++i) { + _current_modules_list.push_back (imengine_list [i]); + if (std::find (_module_names.begin (), _module_names.end (), imengine_list [i]) == _module_names.end ()) { + if (add_keyboard_ise_module (imengine_list [i], config)) + ret = true; + } + } + } + + /* Check helper ISEs */ + for (size_t i = 0; i < helper_list.size (); ++i) { + _current_modules_list.push_back (helper_list [i]); + if (std::find (_module_names.begin (), _module_names.end (), helper_list [i]) == _module_names.end ()) { + if (add_helper_ise_module (helper_list [i])) + ret = true; + } + } + + /* Update _groups */ + if (ret) { + std::vector ise_langs; + for (size_t i = 0; i < _uuids.size (); ++i) { + scim_split_string_list (ise_langs, _langs[i]); + for (size_t j = 0; j < ise_langs.size (); j++) { + if (std::find (_groups[ise_langs[j]].begin (), _groups[ise_langs[j]].end (), i) == _groups[ise_langs[j]].end ()) + _groups[ise_langs[j]].push_back (i); + } + ise_langs.clear (); + } + } + + /* When load ise list is empty, all ISEs can be loaded. */ + _load_ise_list.clear (); + return ret; +} + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/efl_panel/isf_panel_utility.h b/ism/extras/efl_panel/isf_panel_utility.h new file mode 100644 index 0000000..ce25c71 --- /dev/null +++ b/ism/extras/efl_panel/isf_panel_utility.h @@ -0,0 +1,72 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_PANEL_UTILITY_H +#define __ISF_PANEL_UTILITY_H + +using namespace scim; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of macro. +///////////////////////////////////////////////////////////////////////////// +#define COMPOSE_KEY_MODULE "COMPOSE_KEY_MODULE" + + +#if SCIM_USE_STL_EXT_HASH_MAP +typedef __gnu_cxx::hash_map , scim_hash_string> MapStringVectorSizeT; +typedef std::map > MapStringVectorString; +typedef std::map MapStringString; +#elif SCIM_USE_STL_HASH_MAP +typedef std::hash_map , scim_hash_string> MapStringVectorSizeT; +typedef std::map > MapStringVectorString; +typedef std::map MapStringString; +#else +typedef std::map > MapStringVectorSizeT; +typedef std::map > MapStringVectorString; +typedef std::map MapStringString; +#endif + +typedef enum { + ALL_ISE = 0, + HELPER_ONLY, + TYPE_END +} LOAD_ISE_TYPE; + +void isf_get_all_languages (std::vector &all_langs); +void isf_get_all_ises_in_languages (std::vector lang_list, std::vector &uuid_list, std::vector &name_list); + +void isf_get_keyboard_ise (const ConfigPointer &config, String &ise_uuid, String &ise_name, uint32 &ise_option); +void isf_get_keyboard_ises_in_languages (const std::vector &lang_list, std::vector &uuid_list, std::vector &name_list, bool bCheckOption = true); +void isf_get_helper_ises_in_languages (const std::vector &lang_list, std::vector &uuid_list, std::vector &name_list); + +void isf_save_ise_information (void); +void isf_load_ise_information (LOAD_ISE_TYPE type, const ConfigPointer &config); +bool isf_update_ise_list (LOAD_ISE_TYPE type, const ConfigPointer &config); + +#endif /* __ISF_PANEL_UTILITY_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/efl_setting/Makefile.am b/ism/extras/efl_setting/Makefile.am new file mode 100644 index 0000000..dc6b816 --- /dev/null +++ b/ism/extras/efl_setting/Makefile.am @@ -0,0 +1,66 @@ +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/data \ + -I$(top_srcdir)/ism/utils \ + -I$(top_srcdir)/ism/extras/efl_setting/include \ + -I$(includedir) \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" + + +noinst_HEADERS = + +moduledir = /usr/ug/lib +module_LTLIBRARIES = libug-isfsetting-efl.la libug-keyboard-setting-wizard-efl.la +libug_isfsetting_efl_la_SOURCES = isf_setting_efl.cpp \ + scim_setup_module_efl.cpp \ + ../efl_panel/isf_panel_utility.cpp + +libug_isfsetting_efl_la_CXXFLAGS = @EFL_CFLAGS@ \ + @VCONF_CFLAGS@ \ + @UIGADGET_CFLAGS@ + +libug_isfsetting_efl_la_LDFLAGS = -avoid-version \ + -export-dynamic \ + -rpath $(moduledir) + +libug_isfsetting_efl_la_LIBADD = @LIBTOOL_EXPORT_OPTIONS@ \ + @LTLIBINTL@ \ + @EFL_LIBS@ \ + @VCONF_LIBS@ \ + @UIGADGET_LIBS@ \ + $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la \ + $(top_builddir)/ism/extras/efl_immodule/libisf-imf-module.la + +libug_keyboard_setting_wizard_efl_la_SOURCES = isf_setting_wizard.cpp \ + ../efl_panel/isf_panel_utility.cpp + +libug_keyboard_setting_wizard_efl_la_CXXFLAGS = @EFL_CFLAGS@ \ + @VCONF_CFLAGS@ \ + @DLOG_CFLAGS@ \ + @UIGADGET_CFLAGS@ + +libug_keyboard_setting_wizard_efl_la_LDFLAGS = -avoid-version \ + -export-dynamic \ + -rpath $(moduledir) + +libug_keyboard_setting_wizard_efl_la_LIBADD = @LIBTOOL_EXPORT_OPTIONS@ \ + @LTLIBINTL@ \ + @EFL_LIBS@ \ + @VCONF_LIBS@ \ + @DLOG_LIBS@ \ + @UIGADGET_LIBS@ \ + $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la \ + $(top_builddir)/ism/extras/efl_immodule/libisf-imf-module.la + diff --git a/ism/extras/efl_setting/include/isf_setting_efl.h b/ism/extras/efl_setting/include/isf_setting_efl.h new file mode 100644 index 0000000..cf9abbc --- /dev/null +++ b/ism/extras/efl_setting/include/isf_setting_efl.h @@ -0,0 +1,51 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_SETTING_EFL_H +#define __ISF_SETTING_EFL_H + +enum +{ + TYPE_KEY_END = 0, + // Add more here +}; + +struct ug_data { + Evas_Object *layout_main; + Evas_Object *naviframe; + Evas_Object *opt_eo; + Elm_Object_Item *autocapital_item; // Autocapital option + Elm_Object_Item *sw_ise_item_tizen; // SW + Elm_Object_Item *hw_ise_item_tizen; // HW + Elm_Object_Item *sw_ise_opt_item_tizen; // SW option + Elm_Object_Item *hw_ise_opt_item_tizen; // HW option + void (*key_end_cb)(void *, Evas_Object *, void *); + ui_gadget_h ug; +}; + +#endif /* __ISF_SETTING_EFL_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/efl_setting/include/isf_setting_wizard.h b/ism/extras/efl_setting/include/isf_setting_wizard.h new file mode 100644 index 0000000..e251caa --- /dev/null +++ b/ism/extras/efl_setting/include/isf_setting_wizard.h @@ -0,0 +1,43 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_SETTING_WIZARD_H +#define __ISF_SETTING_WIZARD_H + +#define ISF_HEADER_CANCEL_ICON (SCIM_ICONDIR "/01_header_icon_cancel.png") +#define ISF_HEADER_DONE_ICON (SCIM_ICONDIR "/01_header_icon_done.png") + +struct ug_data { + Evas_Object *layout_main; + Evas_Object *naviframe; + service_h data; + ui_gadget_h ug; +}; + +#endif /* __ISF_SETTING_WIZARD_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ + diff --git a/ism/extras/efl_setting/include/scim_setup_module_efl.h b/ism/extras/efl_setting/include/scim_setup_module_efl.h new file mode 100644 index 0000000..5967911 --- /dev/null +++ b/ism/extras/efl_setting/include/scim_setup_module_efl.h @@ -0,0 +1,90 @@ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_setup_module_efl.h,v 1.9 2005/01/10 08:30:45 suzhe Exp $ + */ + +#if !defined (__SCIM_SETUP_MODULE_EFL_H) +#define __SCIM_SETUP_MODULE_EFL_H + + +#include +#include + +using namespace scim; +typedef Evas_Object * (*SetupModuleCreateUIFunc) (Evas_Object *parent, Evas_Object *layout); +typedef String (*SetupModuleGetCategoryFunc) (void); +typedef String (*SetupModuleGetNameFunc) (void); +typedef String (*SetupModuleGetDescriptionFunc) (void); +typedef void (*SetupModuleLoadConfigFunc) (const ConfigPointer &config); +typedef void (*SetupModuleSaveConfigFunc) (const ConfigPointer &config); +typedef bool (*SetupModuleQueryChangedFunc) (void); +typedef bool (*SetupModuleKeyProceedingFunc) (int); +typedef bool (*SetupModuleOptionResetFunc) (const ConfigPointer &config); + +class SetupModule +{ + Module m_module; + + SetupModuleCreateUIFunc m_create_ui; + SetupModuleGetCategoryFunc m_get_category; + SetupModuleGetNameFunc m_get_name; + SetupModuleGetDescriptionFunc m_get_description; + SetupModuleLoadConfigFunc m_load_config; + SetupModuleSaveConfigFunc m_save_config; + SetupModuleQueryChangedFunc m_query_changed; + SetupModuleKeyProceedingFunc m_key_proceeding; + SetupModuleOptionResetFunc m_option_reset; + + SetupModule (const SetupModule &); + SetupModule & operator= (const SetupModule &); + +public: + SetupModule (); + SetupModule (const String &name); + + bool load (const String &name); + bool unload(); + bool valid () const; + + Evas_Object * create_ui (Evas_Object *,Evas_Object *) const; + + String get_category () const; + String get_name () const; + String get_description () const; + + void load_config (const ConfigPointer &config) const; + void save_config (const ConfigPointer &config) const; + + bool query_changed () const; + bool key_proceeding (int)const; + bool option_reset (const ConfigPointer &config) const; +}; + +int scim_get_setup_module_list (std::vector & mod_list); + +#endif // __SCIM_SETUP_MODULE_EFL_H + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/efl_setting/isf_setting_efl.cpp b/ism/extras/efl_setting/isf_setting_efl.cpp new file mode 100644 index 0000000..892dae1 --- /dev/null +++ b/ism/extras/efl_setting/isf_setting_efl.cpp @@ -0,0 +1,1485 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef UG_MODULE_API +#define UG_MODULE_API __attribute__ ((visibility("default"))) +#endif + +#define Uses_SCIM_PANEL_AGENT +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_COMPOSE_KEY + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scim.h" +#include "scim_stl_map.h" +#include "isf_setting_efl.h" +#include "../efl_panel/isf_panel_utility.h" +#include "scim_setup_module_efl.h" +#include "isf_control.h" + + +using namespace scim; + +#define _EDJ(x) elm_layout_edje_get(x) +#define ISF_SETTING_EDJ (SCIM_DATADIR "/isfsetting.edj") +#define PADDING_X 25 + +#define SETTING_PACKAGE "isfsetting-efl" +#define SETTING_LOCALEDIR "/usr/ug/res/locale" +#define _T(s) dgettext(SETTING_PACKAGE, s) + + +enum { + F_CONNECTION_AUTO = 0, + F_CONNECTION_ALWAYS_USED, + F_CONNECTION_END, +}; + +enum { + TYPE_PHONEPAD = 0, + TYPE_QWERTY, + TYPE_KEYBOARD_END, +}; + +enum { + AUTO_CAPITALIZATION_ITEM = 0, + AUTO_CAPITALIZATION_TXT_ITEM, + AUTO_FULL_STOP_ITEM, + AUTO_FULL_STOP_TXT_ITEM, + SW_KEYBOARD_GROUP_TITLE_ITEM, + SW_KEYBOARD_SEL_ITEM, + SW_ISE_OPTION_ITEM, + HW_KEYBOARD_GROUP_TITLE_ITEM, + HW_KEYBOARD_SEL_ITEM, + HW_ISE_OPTION_ITEM, + ITEM_TOTAL_COUNT +}; + +struct ItemData +{ + char *text; + char *sub_text; + int mode; +}; + + +static struct ug_data *_common_ugd = NULL; +static ItemData *_p_items[ITEM_TOTAL_COUNT]; + +static Ecore_X_Window _root_win; +static Ecore_X_Atom _prop_x_ext_keyboard_exist= 0; +static Ecore_Event_Handler *_prop_change_handler = NULL; + +static bool _hw_kbd_connected = false; +static unsigned int _hw_kbd_num = 0; + +static int _sw_ise_index = 0; +static int _hw_ise_index = 0; +static Evas_Object *_sw_radio_grp = NULL; +static Evas_Object *_hw_radio_grp = NULL; +static std::vector _sw_ise_list; +static std::vector _hw_ise_list; +static std::vector _setup_modules; +static String _mdl_name; + +static char _sw_ise_bak[256] = {'\0'}; +static char _hw_ise_bak[256] = {'\0'}; +static char _sw_ise_name[256] = {'\0'}; +static char _hw_ise_name[256] = {'\0'}; + +static SetupModule *_mdl = NULL; +static Ecore_IMF_Context *_imf_context = NULL; + +static Eina_Bool _auto_capitalisation = EINA_FALSE; +static Eina_Bool _auto_full_stop = EINA_FALSE; + +static ConfigPointer _config; +static Connection _reload_signal_connection; + +static Elm_Genlist_Item_Class itc1, itc2, itc3, itc4, itc5, itcText, itcTitle, itcSeparator; + + +extern std::vector _names; +extern std::vector _uuids; +extern std::vector _module_names; +extern std::vector _langs; +extern std::vector _modes; + + +static Evas_Object *_gl_icon_get (void *data, Evas_Object *obj, const char *part); +static char *_gl_label_get (void *data, Evas_Object *obj, const char *part); +static Eina_Bool _gl_state_get (void *data, Evas_Object *obj, const char *part); +static void _gl_del (void *data, Evas_Object *obj); +static void _gl_sel (void *data, Evas_Object *obj, void *event_info); +static void _gl_sw_ise_sel (void *data, Evas_Object *obj, void *event_info); +static void _gl_hw_ise_sel (void *data, Evas_Object *obj, void *event_info); +static void _gl_keyboard_sel (void *data, Evas_Object *obj, void *event_info); +static char *_gl_exp_sw_label_get (void *data, Evas_Object *obj, const char *part); +static Evas_Object *_gl_exp_sw_icon_get (void *data, Evas_Object *obj, const char *part); + +static void create_sw_keyboard_selection_view (ug_data *ugd); +static void create_hw_keyboard_selection_view (ug_data *ugd); + + +static Evas_Object *create_bg (Evas_Object *win) +{ + Evas_Object *bg = elm_bg_add (win); + evas_object_size_hint_weight_set (bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show (bg); + return bg; +} + +static Evas_Object *create_fullview (Evas_Object *parent, struct ug_data *ugd) +{ + Evas_Object *bg = create_bg (parent); + Evas_Object *layout_main = elm_layout_add (parent); + + if (layout_main == NULL) + return NULL; + + elm_layout_theme_set (layout_main, "layout", "application", "default"); + elm_object_style_set (bg, "group_list"); + elm_object_part_content_set (layout_main, "elm.swallow.bg", bg); + + return layout_main; +} + +static Evas_Object *create_frameview (Evas_Object *parent, struct ug_data *ugd) +{ + Evas_Object *bg = create_bg (parent); + Evas_Object *layout_main = elm_layout_add (parent); + if (layout_main == NULL) + return NULL; + + elm_layout_theme_set (layout_main, "layout", "application", "default"); + elm_object_style_set (bg, "group_list"); + elm_object_part_content_set (layout_main, "elm.swallow.bg", bg); + return layout_main; +} + +static Evas_Object *create_naviframe_layout (Evas_Object* parent) +{ + Evas_Object *naviframe = elm_naviframe_add (parent); + elm_object_part_content_set (parent, "elm.swallow.content", naviframe); + evas_object_show (naviframe); + + return naviframe; +} + +static void back_cb (void *data, Evas_Object *obj, void *event_info) +{ + static bool in_exit = false; + + if (in_exit) + return; + in_exit = true; + + if (data == NULL) + return; + struct ug_data *ugd = (struct ug_data *)data; + ug_destroy_me (ugd->ug); +} + +static bool find_ise_option_module (const char *ise_name) +{ + String mdl_name; + for (unsigned int i = 0; i < _names.size (); i++) { + if (_names[i] == String (ise_name)) { + if (_modes[i] == TOOLBAR_KEYBOARD_MODE) + mdl_name = _module_names[i] + String ("-imengine-setup"); + else + mdl_name = _module_names[i] + String ("-setup"); + } + } + _mdl_name = mdl_name; + for (unsigned int i = 0; i < _setup_modules.size (); i++) { + if (mdl_name == _setup_modules[i]) + return true; + } + return false; +} + +static void set_autocap_mode (void) +{ + if (vconf_set_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, _auto_capitalisation) == -1) + std::cerr << "Failed to set vconf autocapital\n"; +} + +static void set_auto_full_stop_mode (void) +{ + if (vconf_set_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, _auto_full_stop) == -1) + std::cerr << "Failed to set vconf autoperiod\n"; +} + +static String uuid_to_name (String uuid) +{ + String strName (""); + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (strcmp (uuid.c_str (), _uuids[i].c_str ()) == 0) { + strName = _names[i]; + break; + } + } + return strName; +} + +static void update_setting_main_view (ug_data *ugd) +{ + _p_items[SW_KEYBOARD_SEL_ITEM]->sub_text = strdup (_sw_ise_name); + elm_object_item_data_set (ugd->sw_ise_item_tizen, _p_items[SW_KEYBOARD_SEL_ITEM]); + if (_hw_kbd_connected || !find_ise_option_module ((const char *)_sw_ise_name)) + elm_object_item_disabled_set (ugd->sw_ise_opt_item_tizen, EINA_TRUE); + else + elm_object_item_disabled_set (ugd->sw_ise_opt_item_tizen, EINA_FALSE); + _p_items[HW_KEYBOARD_SEL_ITEM]->sub_text = strdup (_hw_ise_name); + elm_object_item_data_set (ugd->hw_ise_item_tizen, _p_items[HW_KEYBOARD_SEL_ITEM]); + if (!_hw_kbd_connected || !find_ise_option_module ((const char *)_hw_ise_name)) + elm_object_item_disabled_set (ugd->hw_ise_opt_item_tizen, EINA_TRUE); + else + elm_object_item_disabled_set (ugd->hw_ise_opt_item_tizen, EINA_FALSE); + + elm_genlist_item_update (ugd->sw_ise_item_tizen); + elm_genlist_item_update (ugd->hw_ise_item_tizen); +} + +static void set_active_sw_ise() +{ + if (strcmp (_sw_ise_bak, _sw_ise_name) != 0) { + // If ISE is changed, active it. + String uuid; + for (unsigned int i = 0; i < _names.size (); i++) { + if (strcmp (_names[i].c_str (), _sw_ise_name) == 0) + uuid = _uuids[i]; + } + isf_control_set_active_ise_by_uuid (uuid.c_str ()); + + snprintf (_sw_ise_bak, sizeof (_sw_ise_bak), "%s", _sw_ise_name); + } +} +static void sw_keyboard_selection_view_set_cb (void *data, Evas_Object *obj, void *event_info) +{ + if (data == NULL) + return; + + struct ug_data *ugd = (struct ug_data *)data; + + set_active_sw_ise(); + + update_setting_main_view (ugd); + + ugd->key_end_cb = back_cb; +} + +static void sw_keyboard_radio_cb (void *data, Evas_Object *obj, void *event_info) +{ + int index = GPOINTER_TO_INT(data); + elm_radio_value_set (_sw_radio_grp, index); + snprintf (_sw_ise_name, sizeof (_sw_ise_name), "%s", _sw_ise_list[index].c_str ()); +} + +static void hw_keyboard_radio_cb (void *data, Evas_Object *obj, void *event_info) +{ + int index = GPOINTER_TO_INT(data); + elm_radio_value_set (_hw_radio_grp, index); + snprintf (_hw_ise_name, sizeof (_hw_ise_name), "%s", _hw_ise_list[index].c_str ()); +} + +static void language_view_back_cb (void *data, Evas_Object *obj, void *event_info) +{ + _common_ugd->key_end_cb = sw_keyboard_selection_view_set_cb; +} + +static void show_language_cb (void *data, Evas_Object *obj, void *event_info) +{ + int index = GPOINTER_TO_INT(data); + String langlist_str, normal_langlist_str; + + for (unsigned int i = 0; i < _names.size (); i++) { + if (strcmp (_names[i].c_str (), _sw_ise_list[index].c_str()) == 0) + langlist_str = _langs[i]; + } + std::vector langlist_vec,normal_langlist_vec; + scim_split_string_list (langlist_vec, langlist_str); + normal_langlist_str = ((scim_get_language_name (langlist_vec[0].c_str ())).c_str ()); + for (unsigned int i = 1; i < langlist_vec.size (); i++) { + normal_langlist_str += String (", "); + normal_langlist_str += ((scim_get_language_name (langlist_vec[i].c_str ())).c_str ()); + } + + Evas_Object* layout = elm_layout_add (_common_ugd->naviframe); + elm_layout_file_set (layout, ISF_SETTING_EDJ, "isfsetting/languageview"); + + Evas_Object *scroller = elm_scroller_add (layout); + elm_scroller_bounce_set (scroller, EINA_FALSE, EINA_FALSE); + evas_object_size_hint_weight_set (scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + Evas_Object *label = elm_label_add (layout); + elm_label_line_wrap_set (label, ELM_WRAP_WORD); + + Evas_Coord win_w = 0, win_h = 0; + ecore_x_window_size_get (ecore_x_window_root_first_get (), &win_w, &win_h); + elm_label_wrap_width_set (label, win_w - PADDING_X * 2); + elm_object_text_set (label, normal_langlist_str.c_str ()); + elm_object_content_set (scroller, label); + elm_object_part_content_set (layout, "content", scroller); + + // Push the layout along with function buttons and title + Elm_Object_Item *it = elm_naviframe_item_push (_common_ugd->naviframe, _sw_ise_list[index].c_str (), NULL, NULL, layout, NULL); + + Evas_Object *back_btn = elm_object_item_part_content_get (it, "prev_btn"); + evas_object_smart_callback_add (back_btn, "clicked", language_view_back_cb, NULL); + + _common_ugd->key_end_cb = language_view_back_cb; +} + +static void helper_ise_reload_config (void) +{ + String display_name = String (":13"); + const char *p = getenv ("DISPLAY"); + if (p != NULL) + display_name = String (p); + HelperAgent helper_agent; + HelperInfo helper_info ("fd491a70-22f5-11e2-89f3-eb5999be869e", "ISF Setting", "", "", SCIM_HELPER_STAND_ALONE); + int id = helper_agent.open_connection (helper_info, display_name); + if (id == -1) { + std::cerr << " open_connection failed!!!!!!\n"; + } else { + helper_agent.reload_config (); + helper_agent.close_connection (); + } +} + +static void ise_option_view_set_cb (void *data, Evas_Object *obj, void *event_info) +{ + if (!data) + return; + + struct ug_data *ugd = (struct ug_data *)data; + ugd->key_end_cb = back_cb; + _mdl->save_config (_config); + _config->reload (); + + helper_ise_reload_config (); +} + +static void ise_option_show (ug_data *ugd, const char *ise_name) +{ + if (find_ise_option_module (ise_name)) { + char title[256]; + snprintf (title, sizeof (title), _T("Keyboard settings")); + + if (_mdl) { + delete _mdl; + _mdl = NULL; + } + + if (_mdl_name.length () > 0) + _mdl = new SetupModule (String (_mdl_name)); + + if (_mdl == NULL || !_mdl->valid ()) { + return; + } else { + _mdl->load_config (_config); + ugd->opt_eo = _mdl->create_ui (ugd->layout_main, ugd->naviframe); + + Elm_Object_Item *it = elm_naviframe_item_push (ugd->naviframe, title, NULL, NULL, ugd->opt_eo, NULL); + + Evas_Object *back_btn = elm_object_item_part_content_get (it, "prev_btn"); + evas_object_smart_callback_add (back_btn, "clicked", ise_option_view_set_cb, ugd); + ugd->key_end_cb = ise_option_view_set_cb; + } + } +} + +static char *_gl_text_get (void *data, Evas_Object *obj, const char *part) +{ + int index = (int)data; + return strdup (_p_items[index]->text); +} + +static char *_gl_label_get (void *data, Evas_Object *obj, const char *part) +{ + ItemData *item_data = (ItemData *)data; + if (!strcmp (part, "elm.text")) { + return strdup (item_data->text); + } + if (!strcmp (part, "elm.text.1")) { + return strdup (item_data->text); + } + if (!strcmp (part, "elm.text.2")) { + return strdup (item_data->sub_text); + } + return NULL; +} + +static Evas_Object *_gl_icon_get (void *data, Evas_Object *obj, const char *part) +{ + ItemData *item_data = (ItemData *)data; + + if (!strcmp (part, "elm.icon")) { + Evas_Object *onoff_ck = elm_check_add (obj); + elm_object_style_set (onoff_ck, "on&off"); + if (item_data->mode == AUTO_CAPITALIZATION_ITEM) { + elm_check_state_set (onoff_ck, _auto_capitalisation); + } else if (item_data->mode == AUTO_FULL_STOP_ITEM) { + elm_check_state_set (onoff_ck, _auto_full_stop); + } + return onoff_ck; + } + + return NULL; +} + +static Eina_Bool _gl_state_get (void *data, Evas_Object *obj, const char *part) +{ + return EINA_FALSE; +} + +static void _gl_del (void *data, Evas_Object *obj) +{ +} + +static void _gl_sw_ise_sel (void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + elm_genlist_item_selected_set (item, EINA_FALSE); + + _sw_ise_index = (int)(data); + snprintf (_sw_ise_name, sizeof (_sw_ise_name), "%s", _sw_ise_list[_sw_ise_index].c_str ()); + + elm_genlist_item_update (item); +} + +static void _gl_hw_ise_sel (void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + elm_genlist_item_selected_set (item, EINA_FALSE); + + _hw_ise_index = (int)(data); + snprintf (_hw_ise_name, sizeof (_hw_ise_name), "%s", _hw_ise_list[_hw_ise_index].c_str ()); + + elm_genlist_item_update (item); +} + +static void _gl_sel (void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + elm_genlist_item_selected_set (item, EINA_FALSE); + + int id = (int)(data); + + if (id == AUTO_CAPITALIZATION_ITEM) { + _auto_capitalisation = (_auto_capitalisation == EINA_TRUE ? EINA_FALSE : EINA_TRUE); + set_autocap_mode (); + } else if (id == AUTO_FULL_STOP_ITEM) { + _auto_full_stop = (_auto_full_stop == EINA_TRUE ? EINA_FALSE : EINA_TRUE); + set_auto_full_stop_mode (); + } + + elm_genlist_item_update (item); +} + +static void _gl_keyboard_sel (void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + ug_data *ugd = (ug_data *)data; + if (item == ugd->sw_ise_item_tizen) + create_sw_keyboard_selection_view (ugd); + if (item == ugd->hw_ise_item_tizen) + create_hw_keyboard_selection_view (ugd); + elm_genlist_item_selected_set (item, EINA_FALSE); +} + +static void _gl_ise_option_sel (void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + ug_data *ugd = (ug_data *)data; + const char *ise_name = NULL; + if (item == ugd->sw_ise_opt_item_tizen) + ise_name = _sw_ise_name; + else + ise_name = _hw_ise_name; + ise_option_show (ugd, ise_name); + elm_genlist_item_selected_set (item, EINA_FALSE); +} + +static char *_gl_exp_sw_label_get (void *data, Evas_Object *obj, const char *part) +{ + int index = (int)(data); + if (!strcmp (part, "elm.text")) { + return strdup (_sw_ise_list[index].c_str ()); + } + return NULL; +} + +static Evas_Object *_gl_exp_sw_icon_get (void *data, Evas_Object *obj, const char *part) +{ + int index = (int)(data); + if (!strcmp (part, "elm.icon.1")) { + Evas_Object *radio = elm_radio_add (obj); + elm_radio_state_value_set (radio, index); + if (_sw_radio_grp == NULL) + _sw_radio_grp = elm_radio_add (obj); + elm_radio_group_add (radio, _sw_radio_grp); + evas_object_show (radio); + evas_object_smart_callback_add (radio, "changed", sw_keyboard_radio_cb, (void *) (index)); + if (_sw_ise_index == index) { + elm_radio_value_set (_sw_radio_grp, _sw_ise_index); + } + return radio; + } + if (!strcmp (part, "elm.icon.2")) { + Evas_Object *icon = elm_button_add (obj); + elm_object_style_set (icon, "reveal"); + evas_object_smart_callback_add (icon, "clicked", show_language_cb, (void *)(index)); + evas_object_propagate_events_set (icon, EINA_FALSE); // Not propagate to genlist item. + return icon; + } + return NULL; +} + +static char *_gl_exp_hw_label_get (void *data, Evas_Object *obj, const char *part) +{ + int index = (int)(data); + if (!strcmp (part, "elm.text")) { + return strdup (_hw_ise_list[index].c_str ()); + } + return NULL; +} + +static Evas_Object *_gl_exp_hw_icon_get (void *data, Evas_Object *obj, const char *part) +{ + if (!strcmp (part, "elm.icon")) { + int index = (int)(data); + Evas_Object *radio = elm_radio_add (obj); + elm_radio_state_value_set (radio, index); + if (_hw_radio_grp == NULL) + _hw_radio_grp = elm_radio_add (obj); + elm_radio_group_add (radio, _hw_radio_grp); + evas_object_show (radio); + evas_object_smart_callback_add (radio, "changed", hw_keyboard_radio_cb, (void *) (index)); + if (_hw_ise_index == index) { + elm_radio_value_set (_hw_radio_grp, _hw_ise_index); + } + return radio; + } + return NULL; +} + +static void create_sw_keyboard_selection_view (ug_data *ugd) +{ + ugd->key_end_cb = sw_keyboard_selection_view_set_cb; + + if (_sw_radio_grp != NULL) { + evas_object_del (_sw_radio_grp); + _sw_radio_grp = NULL; + } + + Evas_Object *genlist = elm_genlist_add (ugd->naviframe); + elm_object_style_set (genlist, "dialogue"); + evas_object_show (genlist); + + // Push the layout along with function buttons and title + Elm_Object_Item *it = elm_naviframe_item_push (ugd->naviframe, _T("Keyboard selection"), NULL, NULL, genlist, NULL); + + Evas_Object *back_btn = elm_object_item_part_content_get (it, "prev_btn"); + evas_object_smart_callback_add (back_btn, "clicked", sw_keyboard_selection_view_set_cb, ugd); + + unsigned int i = 0; + + _sw_ise_list.clear (); + std::vector all_langs, uuid_list; + isf_get_all_languages (all_langs); + isf_get_helper_ises_in_languages (all_langs, uuid_list, _sw_ise_list); + std::sort (_sw_ise_list.begin (), _sw_ise_list.end ()); + + if (_sw_ise_list.size () > 0) { + // Set item class for dialogue group seperator + itcSeparator.item_style = "dialogue/separator/21/with_line"; + itcSeparator.func.text_get = NULL; + itcSeparator.func.content_get = NULL; + itcSeparator.func.state_get = NULL; + itcSeparator.func.del = NULL; + + // Separator + Elm_Object_Item *item; + item = elm_genlist_item_append ( + genlist, // genlist object + &itcSeparator, // item class + NULL, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + + for (i = 0; i < _sw_ise_list.size (); i++) { + if (strcmp (_sw_ise_name, _sw_ise_list[i].c_str ()) == 0) { + _sw_ise_index = i; + break; + } + } + + // Set item class for text + radio button + itc4.item_style = "dialogue/1text.2icon.2"; + itc4.func.text_get = _gl_exp_sw_label_get; + itc4.func.content_get = _gl_exp_sw_icon_get; + itc4.func.state_get = _gl_state_get; + itc4.func.del = _gl_del; + for (i = 0; i < _sw_ise_list.size (); i++) { + elm_genlist_item_append (genlist, &itc4, (void *)(i), NULL, ELM_GENLIST_ITEM_NONE, _gl_sw_ise_sel, (void *)(i)); + } +} + +static void set_active_hw_ise() +{ + if (strcmp (_hw_ise_bak, _hw_ise_name) != 0) { + // If ISE is changed, active it. + String uuid; + for (unsigned int i = 0; i < _names.size (); i++) { + if (strcmp (_names[i].c_str (), _hw_ise_name) == 0) + uuid = _uuids[i]; + } + isf_control_set_active_ise_by_uuid (uuid.c_str ()); + //printf (" Set keyboard ISE: %s\n", _hw_ise_name); + snprintf (_hw_ise_bak, sizeof (_hw_ise_bak), "%s", _hw_ise_name); + } +} + +static void hw_keyboard_selection_view_set_cb (void *data, Evas_Object *obj, void *event_info) +{ + if (!data) + return; + + struct ug_data *ugd = (struct ug_data *)data; + + set_active_hw_ise(); + + update_setting_main_view (ugd); + + ugd->key_end_cb = back_cb; +} + +static void create_hw_keyboard_selection_view (ug_data * ugd) +{ + ugd->key_end_cb = hw_keyboard_selection_view_set_cb; + + if (_hw_radio_grp != NULL) { + evas_object_del (_hw_radio_grp); + _hw_radio_grp = NULL; + } + + Evas_Object *genlist = elm_genlist_add (ugd->naviframe); + elm_object_style_set (genlist, "dialogue"); + evas_object_show (genlist); + + // Push the layout along with function buttons and title + Elm_Object_Item *nf_it = elm_naviframe_item_push (ugd->naviframe, _T("Keyboard selection"), NULL, NULL, genlist, NULL); + + Evas_Object *back_btn = elm_object_item_part_content_get (nf_it, "prev_btn"); + evas_object_smart_callback_add (back_btn, "clicked", hw_keyboard_selection_view_set_cb, ugd); + + unsigned int i = 0; + + _hw_ise_list.clear (); + std::vector all_langs, uuid_list; + isf_get_all_languages (all_langs); + isf_get_keyboard_ises_in_languages (all_langs, uuid_list, _hw_ise_list); + + if (_hw_ise_list.size () > 0) { + // Set item class for dialogue group seperator + itcSeparator.item_style = "dialogue/separator/21/with_line"; + itcSeparator.func.text_get = NULL; + itcSeparator.func.content_get = NULL; + itcSeparator.func.state_get = NULL; + itcSeparator.func.del = NULL; + + // Separator + Elm_Object_Item *item; + item = elm_genlist_item_append ( + genlist, // genlist object + &itcSeparator, // item class + NULL, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + + std::sort (_hw_ise_list.begin (), _hw_ise_list.end ()); + + for (i = 0; i < _hw_ise_list.size (); i++) { + if (strcmp (_hw_ise_name, _hw_ise_list[i].c_str ()) == 0) { + _hw_ise_index = i; + break; + } + } + + // Set item class for text + radio button) + itc5.item_style = "dialogue/1text.1icon.2"; + itc5.func.text_get = _gl_exp_hw_label_get; + itc5.func.content_get = _gl_exp_hw_icon_get; + itc5.func.state_get = _gl_state_get; + itc5.func.del = _gl_del; + for (i = 0; i < _hw_ise_list.size (); i++) { + elm_genlist_item_append (genlist, &itc5, (void *)(i), NULL, ELM_GENLIST_ITEM_NONE, _gl_hw_ise_sel, (void *)(i)); + } +} + +static Elm_Object_Item *nf_main_it = NULL; +static Evas_Object *create_setting_main_view (ug_data *ugd) +{ + Elm_Object_Item *item = NULL; + Eina_Bool fullstop = EINA_FALSE; + + if (ugd->naviframe == NULL) { + ugd->naviframe = create_naviframe_layout (ugd->layout_main); + ugd->key_end_cb = back_cb; + + Evas_Object *genlist = elm_genlist_add (ugd->naviframe); + elm_object_style_set (genlist, "dialogue"); + elm_genlist_mode_set (genlist, ELM_LIST_COMPRESS); + // Set item class for 1text.1icon(text+radiobutton) + itc1.item_style = "dialogue/1text.1icon"; + itc1.func.text_get = _gl_label_get; + itc1.func.content_get = _gl_icon_get; + itc1.func.state_get = _gl_state_get; + itc1.func.del = _gl_del; + + // Set item class for 2text(text+subtext) + itc2.item_style = "dialogue/2text.3"; + itc2.func.text_get = _gl_label_get; + itc2.func.content_get = NULL; + itc2.func.state_get = _gl_state_get; + itc2.func.del = _gl_del; + + // Set item class for normal text(text) + itc3.item_style = "dialogue/1text"; + itc3.func.text_get = _gl_label_get; + itc3.func.content_get = NULL; + itc3.func.state_get = _gl_state_get; + itc3.func.del = _gl_del; + + // Set item class for dialogue group seperator + itcSeparator.item_style = "dialogue/separator/21/with_line"; + itcSeparator.func.text_get = NULL; + itcSeparator.func.content_get = NULL; + itcSeparator.func.state_get = NULL; + itcSeparator.func.del = NULL; + + // Set item class for dialogue group title + itcTitle.item_style = "dialogue/title"; + itcTitle.func.text_get = _gl_label_get; + itcTitle.func.content_get = NULL; + itcTitle.func.state_get = _gl_state_get; + itcTitle.func.del = _gl_del; + + itcText.item_style = "multiline/1text"; + itcText.func.text_get = _gl_text_get; + itcText.func.content_get = NULL; + itcText.func.state_get = _gl_state_get; + itcText.func.del = _gl_del; + + //==================================group begin ======================= + ItemData *item_data = NULL; + + // Separator + item = elm_genlist_item_append( + genlist, // genlist object + &itcSeparator, // item class + NULL, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + // Group1 item1 + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[AUTO_CAPITALIZATION_ITEM] = item_data; + item_data->text = strdup(_T("Auto capitalization")); + item_data->mode = AUTO_CAPITALIZATION_ITEM; + ugd->autocapital_item = elm_genlist_item_append ( + genlist, // genlist object + &itc1, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + _gl_sel, + (void *)(item_data->mode)); + + if (_hw_kbd_connected) + elm_object_item_disabled_set (ugd->autocapital_item, EINA_TRUE); + } + + // Text + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[AUTO_CAPITALIZATION_TXT_ITEM] = item_data; + item_data->text = strdup (_T("Automatically capitalize first letter of sentence")); + item = elm_genlist_item_append ( + genlist, // genlist object + &itcText, // item class + (void *)(AUTO_CAPITALIZATION_TXT_ITEM), // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + + char *env = getenv ("ISF_AUTOFULLSTOP"); + if (env) + fullstop = !!atoi (env); + + if (fullstop) { + // Separator + item = elm_genlist_item_append ( + genlist, // genlist object + &itcSeparator, // item class + NULL, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + // Group1 item2 + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[AUTO_FULL_STOP_ITEM] = item_data; + item_data->text = strdup (_T("Automatic full stop")); + item_data->mode = AUTO_FULL_STOP_ITEM; + elm_genlist_item_append ( + genlist, // genlist object + &itc1, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + _gl_sel, + (void *)(item_data->mode)); + } + + // Text + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[AUTO_FULL_STOP_TXT_ITEM] = item_data; + item_data->text = strdup (_T("Automatically insert a full stop by tapping the space bar twice")); + item = elm_genlist_item_append ( + genlist, // genlist object + &itcText, // item class + (void *)(AUTO_FULL_STOP_TXT_ITEM), // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + } + + // Group2 title + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[SW_KEYBOARD_GROUP_TITLE_ITEM] = item_data; + item_data->text = strdup (_T("Software keyboard")); + item = elm_genlist_item_append ( + genlist, // genlist object + &itcTitle, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + + // Group2 item1 + std::vector ise_names; + + String ise_uuid = _config->read (SCIM_CONFIG_DEFAULT_HELPER_ISE, String ("")); + snprintf (_sw_ise_name, sizeof (_sw_ise_name), "%s", (uuid_to_name (ise_uuid)).c_str ()); + snprintf (_sw_ise_bak, sizeof (_sw_ise_bak), "%s", _sw_ise_name); + + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[SW_KEYBOARD_SEL_ITEM] = item_data; + item_data->text = strdup (_T("Keyboard selection")); + item_data->sub_text = strdup (_sw_ise_name); + + ugd->sw_ise_item_tizen = elm_genlist_item_append ( + genlist, // genlist object + &itc2, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + _gl_keyboard_sel, + (void *)ugd); + + if (_hw_kbd_connected) + elm_object_item_disabled_set (ugd->sw_ise_item_tizen, EINA_TRUE); + } + + // Group2 item2 + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[SW_ISE_OPTION_ITEM] = item_data; + item_data->text = strdup (_T("Keyboard settings")); + item_data->mode = SW_ISE_OPTION_ITEM; + ugd->sw_ise_opt_item_tizen = elm_genlist_item_append ( + genlist, // genlist object + &itc3, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + _gl_ise_option_sel, + (void *)ugd); + + if (_hw_kbd_connected || !find_ise_option_module ((const char *)_sw_ise_name)) + elm_object_item_disabled_set (ugd->sw_ise_opt_item_tizen, EINA_TRUE); + } + + // Group3 title + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[HW_KEYBOARD_GROUP_TITLE_ITEM] = item_data; + item_data->text = strdup (_T("Hardware keyboard")); + item = elm_genlist_item_append ( + genlist, // genlist object + &itcTitle, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + + // Group3 item1 + uint32 option = 0; + String uuid, name; + isf_get_keyboard_ise (_config, uuid, name, option); + snprintf (_hw_ise_name, sizeof (_hw_ise_name), "%s", name.c_str ()); + snprintf (_hw_ise_bak, sizeof (_hw_ise_bak), "%s", _hw_ise_name); + + if (option & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD) { + std::cerr << " Keyboard ISE (" << _hw_ise_name << ") can not support hardware keyboard!!!\n"; + + uuid = String (SCIM_COMPOSE_KEY_FACTORY_UUID); + isf_get_keyboard_ise (_config, uuid, name, option); + snprintf (_hw_ise_name, sizeof (_hw_ise_name), "%s", name.c_str ()); + } + + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[HW_KEYBOARD_SEL_ITEM] = item_data; + item_data->text = strdup (_T("Keyboard selection")); + item_data->sub_text = strdup (_hw_ise_name); + ugd->hw_ise_item_tizen = elm_genlist_item_append ( + genlist, // genlist object + &itc2, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + _gl_keyboard_sel, + (void *)ugd); + + if (!_hw_kbd_connected) + elm_object_item_disabled_set (ugd->hw_ise_item_tizen,EINA_TRUE); + } + // Group3 item2 + item_data = (ItemData *)malloc (sizeof (ItemData)); + if (item_data != NULL) { + memset (item_data, 0, sizeof (ItemData)); + _p_items[HW_ISE_OPTION_ITEM] = item_data; + item_data->text = strdup (_T("Keyboard settings")); + item_data->mode = HW_ISE_OPTION_ITEM; + ugd->hw_ise_opt_item_tizen = elm_genlist_item_append ( + genlist, // genlist object + &itc3, // item class + item_data, // data + NULL, + ELM_GENLIST_ITEM_NONE, + _gl_ise_option_sel, + (void *)ugd); + + if (!_hw_kbd_connected || !find_ise_option_module ((const char *)_hw_ise_name)) + elm_object_item_disabled_set (ugd->hw_ise_opt_item_tizen, EINA_TRUE); + } + + // Separator + item = elm_genlist_item_append ( + genlist, // genlist object + &itcSeparator, // item class + NULL, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set (item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + //==================================group end ========================= + Evas_Object *back_btn = elm_button_add (ugd->naviframe); + elm_object_style_set (back_btn, "naviframe/back_btn/default"); + evas_object_smart_callback_add (back_btn, "clicked", back_cb, ugd); + + nf_main_it = elm_naviframe_item_push (ugd->naviframe, _T("Keyboard"), back_btn, NULL, genlist, NULL); + } + return ugd->naviframe; +} + +static void update_ise_list (void) +{ + // Request ISF to update ISE list, below codes are very important, donot remove + char **iselist = NULL; + int count = isf_control_get_ise_list (&iselist); + + for (int i = 0; i < count; i++) { + SCIM_DEBUG_MAIN (3) << " [" << i << " : " << iselist[i] << "] \n"; + delete [] (iselist[i]); + } + if (iselist != NULL) + free (iselist); +} + +static void load_config_data (ConfigPointer config) +{ + int tmp_cap = 0; + int tmp_period = 0; + vconf_get_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, &tmp_cap); + vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &tmp_period); + if (tmp_cap == true) + _auto_capitalisation = EINA_TRUE; + if (tmp_period == true) + _auto_full_stop = EINA_TRUE; +} + +ConfigPointer isf_imf_context_get_config (void); +static void load_config_module (void) +{ + _config = isf_imf_context_get_config (); + if (_config.null ()) { + std::cerr << "Create dummy config!!!\n"; + _config = new DummyConfig (); + } + + if (_config.null ()) { + std::cerr << "Can not create Config Object!\n"; + } +} + +static void hw_connection_change_cb (ug_data *ugd) +{ + // enable/disable switch + elm_object_item_disabled_set (ugd->autocapital_item, !elm_object_item_disabled_get (ugd->autocapital_item)); + elm_object_item_disabled_set (ugd->sw_ise_item_tizen, !elm_object_item_disabled_get (ugd->sw_ise_item_tizen)); + elm_object_item_disabled_set (ugd->hw_ise_item_tizen, !elm_object_item_disabled_get (ugd->hw_ise_item_tizen)); + if (_hw_kbd_connected || !find_ise_option_module ((const char *)_sw_ise_name)) + elm_object_item_disabled_set (ugd->sw_ise_opt_item_tizen, EINA_TRUE); + else + elm_object_item_disabled_set (ugd->sw_ise_opt_item_tizen, EINA_FALSE); + + if (!_hw_kbd_connected || !find_ise_option_module ((const char *)_hw_ise_name)) + elm_object_item_disabled_set (ugd->hw_ise_opt_item_tizen, EINA_TRUE); + else + elm_object_item_disabled_set (ugd->hw_ise_opt_item_tizen, EINA_FALSE); + + if (!_hw_kbd_connected) { + String uuid; + for (unsigned int i = 0; i < _names.size (); i++) { + if (strcmp (_names[i].c_str (), _sw_ise_name) == 0) + uuid = _uuids[i]; + } + isf_control_set_active_ise_by_uuid (uuid.c_str ()); + } +} + +static Eina_Bool x_window_property_change_cb (void *data, int ev_type, void *ev) +{ + Ecore_X_Event_Window_Property *event = (Ecore_X_Event_Window_Property *)ev; + unsigned int val = 0; + + if (event->win != _root_win || event->atom != _prop_x_ext_keyboard_exist) + return ECORE_CALLBACK_PASS_ON; + + if (!ecore_x_window_prop_card32_get (event->win, _prop_x_ext_keyboard_exist, &val, 1) > 0) + return ECORE_CALLBACK_PASS_ON; + + if (val != 0) + _hw_kbd_connected = true; + else + _hw_kbd_connected = false; + + ug_data *ugd = (ug_data *)data; + hw_connection_change_cb (ugd); + _hw_kbd_num = val; + + return ECORE_CALLBACK_PASS_ON; +} + +static void init_hw_keyboard_listener (ug_data *ugd) +{ + if (_prop_change_handler) + return; + + _root_win = ecore_x_window_root_first_get (); + ecore_x_event_mask_set (_root_win, ECORE_X_EVENT_MASK_WINDOW_PROPERTY); + + _prop_change_handler = ecore_event_handler_add (ECORE_X_EVENT_WINDOW_PROPERTY, x_window_property_change_cb, (void *)ugd); + + if (!_prop_x_ext_keyboard_exist) + _prop_x_ext_keyboard_exist = ecore_x_atom_get (PROP_X_EXT_KEYBOARD_EXIST); + + if (!ecore_x_window_prop_card32_get (_root_win, _prop_x_ext_keyboard_exist, &_hw_kbd_num, 1)) { + std::cerr << "ecore_x_window_prop_card32_get () is failed!!!\n"; + return; + } + + if (_hw_kbd_num == 0) + _hw_kbd_connected = false; + else + _hw_kbd_connected = true; +} + +static void reload_config_cb (const ConfigPointer &config) +{ + uint32 option = 0; + String uuid, name; + isf_get_keyboard_ise (_config, uuid, name, option); + snprintf (_hw_ise_name, sizeof (_hw_ise_name), "%s", name.c_str ()); + update_setting_main_view (_common_ugd); + //std::cout << " " << __func__ << " (keyboard ISE : " << name << ")\n"; +} + +static void *on_create (ui_gadget_h ug, enum ug_mode mode, service_h s, void *priv) +{ + Evas_Object *parent = NULL; + Evas_Object *content = NULL; + + if (ug == NULL || priv == NULL) + return NULL; + + bindtextdomain (SETTING_PACKAGE, SETTING_LOCALEDIR); + struct ug_data *ugd = (struct ug_data *)priv; + ugd->ug = ug; + parent = (Evas_Object *) ug_get_parent_layout (ug); + if (parent == NULL) + return NULL; + + if (_imf_context == NULL) { + const char *ctx_id = ecore_imf_context_default_id_get (); + if (ctx_id) { + _imf_context = ecore_imf_context_add (ctx_id); + } + } + + load_config_module (); + load_config_data (_config); + scim_get_setup_module_list (_setup_modules); + update_ise_list (); + isf_load_ise_information (ALL_ISE, _config); + init_hw_keyboard_listener (ugd); + + _reload_signal_connection = _config->signal_connect_reload (slot (reload_config_cb)); + + //-------------------------- ise infomation ---------------------------- + + Evas_Object *parent_win = (Evas_Object *)ug_get_window (); + Evas_Object *conform = elm_conformant_add (parent_win); + + // Create keyboard setting UI + if (mode == UG_MODE_FULLVIEW) + ugd->layout_main = create_fullview (conform, ugd); + else + ugd->layout_main = create_frameview (conform, ugd); + + if (ugd->layout_main != NULL) { + content = create_setting_main_view (ugd); + elm_object_part_content_set (ugd->layout_main, "elm.swallow.content", content); + + evas_object_size_hint_weight_set (conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set (conform, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_win_resize_object_add (parent_win, conform); + elm_object_content_set (conform, ugd->layout_main); + evas_object_show (conform); + } + return (void *)ugd->layout_main; +} + +static void on_start (ui_gadget_h ug, service_h s, void *priv) +{ +} + +static void on_pause (ui_gadget_h ug, service_h s, void *priv) +{ + if (ug == NULL || priv == NULL) + return; + struct ug_data *ugd = (struct ug_data *) priv; + if (ugd->key_end_cb == ise_option_view_set_cb) + {//inside ise setup module + _mdl->save_config (_config); + _config->reload (); + + helper_ise_reload_config (); + elm_naviframe_item_pop_to(nf_main_it); + ugd->key_end_cb = back_cb; + } + else if (ugd->key_end_cb == sw_keyboard_selection_view_set_cb) + set_active_sw_ise(); + else if (ugd->key_end_cb == hw_keyboard_selection_view_set_cb) + set_active_hw_ise(); +} + +static void on_resume (ui_gadget_h ug, service_h s, void *priv) +{ + +} + +static void on_destroy (ui_gadget_h ug, service_h s, void *priv) +{ + if (ug == NULL || priv == NULL) + return; + + if (_imf_context != NULL) { + ecore_imf_context_del (_imf_context); + _imf_context = NULL; + } + + struct ug_data *ugd = (struct ug_data *) priv; + + if (ugd->naviframe != NULL) { + evas_object_del (ugd->naviframe); + ugd->naviframe = NULL; + } + + if (ugd->layout_main != NULL) { + evas_object_del (ugd->layout_main); + ugd->layout_main = NULL; + } + + if (ugd->opt_eo != NULL) { + evas_object_del (ugd->opt_eo); + ugd->opt_eo = NULL; + } + + if (_mdl) { + delete _mdl; + _mdl = NULL; + } + + if (!_config.null ()) { + _config->flush (); + _config.reset (); + } + + for (int i = 0; i < ITEM_TOTAL_COUNT; i++) { + if (_p_items[i] != NULL) { + if (_p_items[i]->text) { + free (_p_items[i]->text); + _p_items[i]->text = NULL; + } + if (_p_items[i]->sub_text) { + free (_p_items[i]->sub_text); + _p_items[i]->sub_text = NULL; + } + free (_p_items[i]); + _p_items[i] = NULL; + } + } + + if (_prop_change_handler != NULL) { + ecore_event_handler_del (_prop_change_handler); + _prop_change_handler = NULL; + } + + _reload_signal_connection.disconnect (); +} + +static void on_message (ui_gadget_h ug, service_h msg, service_h data, void *priv) +{ +} + +static void on_event (ui_gadget_h ug, enum ug_event event, service_h s, void *priv) +{ + switch (event) { + case UG_EVENT_LOW_MEMORY: + break; + case UG_EVENT_LOW_BATTERY: + break; + case UG_EVENT_LANG_CHANGE: + break; + case UG_EVENT_ROTATE_PORTRAIT: + break; + case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN: + break; + case UG_EVENT_ROTATE_LANDSCAPE: + break; + case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN: + break; + default: + break; + } +} + +static void on_key_event (ui_gadget_h ug, enum ug_key_event event, service_h s, void *priv) +{ + if (ug == NULL || priv == NULL) + return; + + struct ug_data *ugd = (struct ug_data *)priv; + Elm_Object_Item *top_it; + + switch (event) { + case UG_KEY_EVENT_END: + top_it = elm_naviframe_top_item_get (ugd->naviframe); + // ISE option maybe multiple layouts + if (top_it && (elm_object_item_content_get (top_it) != ugd->opt_eo) && (ugd->key_end_cb == ise_option_view_set_cb)) + _mdl->key_proceeding (TYPE_KEY_END); + else + ugd->key_end_cb (priv, NULL, NULL); + + break; + default: + break; + } +} + +#ifdef __cplusplus +extern "C" +{ +#endif + UG_MODULE_API int UG_MODULE_INIT (struct ug_module_ops *ops) + { + if (ops == NULL) + return -1; + + struct ug_data *ugd = (ug_data*)calloc (1, sizeof (struct ug_data)); + if (ugd == NULL) + return -1; + + _common_ugd = ugd; + ops->create = on_create; + ops->start = on_start; + ops->pause = on_pause; + ops->resume = on_resume; + ops->destroy = on_destroy; + ops->message = on_message; + ops->event = on_event; + ops->key_event = on_key_event; + ops->priv = ugd; + ops->opt = UG_OPT_INDICATOR_ENABLE; + + return 0; + } + + UG_MODULE_API void UG_MODULE_EXIT (struct ug_module_ops *ops) + { + if (ops == NULL) + return; + + struct ug_data *ugd = (struct ug_data *)(ops->priv); + if (ugd != NULL) + free (ugd); + } + + // Reset keyboard setting + UG_MODULE_API int setting_plugin_reset (service_h s, void *priv) + { + if (vconf_set_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, true) == -1) + return -1; + if (vconf_set_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, false) == -1) + return -1; + + load_config_module (); + isf_load_ise_information (ALL_ISE, _config); + + String uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_INITIAL_ISE_UUID), String (SCIM_COMPOSE_KEY_FACTORY_UUID)); + TOOLBAR_MODE_T type = (TOOLBAR_MODE_T)scim_global_config_read (String (SCIM_GLOBAL_CONFIG_INITIAL_ISE_TYPE), TOOLBAR_KEYBOARD_MODE); + if (ecore_x_window_prop_card32_get (ecore_x_window_root_first_get (), ecore_x_atom_get (PROP_X_EXT_KEYBOARD_EXIST), &_hw_kbd_num, 1) > 0) { + if (_hw_kbd_num != 0) { + if (type != TOOLBAR_KEYBOARD_MODE) { + _config->write (String (SCIM_CONFIG_DEFAULT_HELPER_ISE), uuid); + _config->flush (); + uuid = String (SCIM_COMPOSE_KEY_FACTORY_UUID); + } + } + } + + isf_control_set_active_ise_by_uuid (uuid.c_str ()); + + String mdl_name; + for (unsigned int i = 0; i < _module_names.size (); i++) { + if (_modes[i] == TOOLBAR_KEYBOARD_MODE) + mdl_name = _module_names[i] + String ("-imengine-setup"); + else + mdl_name = _module_names[i] + String ("-setup"); + + SetupModule *setup_module = new SetupModule (mdl_name); + if (setup_module != NULL && setup_module->valid ()) { + if (setup_module->option_reset (_config) == false) + std::cerr << mdl_name << " failed to reset option!\n"; + } else { + std::cerr << "Load " << mdl_name << " is failed!!!\n"; + } + if (setup_module) { + delete setup_module; + setup_module = NULL; + } + } + + _config->reload (); + helper_ise_reload_config (); + return 0; + } + +#ifdef __cplusplus +} +#endif + +/* +vi:ts=4:ai:nowrap:expandtab + */ diff --git a/ism/extras/efl_setting/isf_setting_wizard.cpp b/ism/extras/efl_setting/isf_setting_wizard.cpp new file mode 100644 index 0000000..ba108a8 --- /dev/null +++ b/ism/extras/efl_setting/isf_setting_wizard.cpp @@ -0,0 +1,562 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef UG_WIZARD_MODULE_API +#define UG_WIZARD_MODULE_API __attribute__ ((visibility("default"))) +#endif + +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_HELPER_MODULE + +#include +#include +#include +#include "isf_control.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "scim.h" +#include "scim_stl_map.h" +#include "isf_setting_wizard.h" +#include "../efl_panel/isf_panel_utility.h" + + +using namespace scim; + + +#define WIZARD_PACKAGE "keyboard-setting-wizard-efl" +#define WIZARD_LOCALEDIR "/usr/ug/res/locale" +#define T_(s) dgettext(WIZARD_PACKAGE, s) +#define LOG_TAG "isfsettingwizard" + +static Elm_Genlist_Item_Class itc1,itcSeparator; +static int mark = 0; + + +static Ecore_IMF_Context *imf_context = NULL; + +static Evas_Object *sw_radio_grp = NULL; //sw view raido group +static std::vector sw_iselist; + +static ConfigPointer _config; + +static char ise_bak[256] = {'\0'}; +static char _active_ise_name[256] = {'\0'}; + + +extern std::vector _names; +extern std::vector _uuids; +extern std::vector _module_names; +extern std::vector _langs; + +static String uuid_to_name(String uuid) +{ + String tmpName(""); + for(unsigned int i = 0;i<_uuids.size();i++) + { + if (strcmp(uuid.c_str(),_uuids[i].c_str())== 0) { + tmpName = _names[i]; + break; + } + } + return tmpName; +} + +static Evas_Object *_create_bg(Evas_Object *win) +{ + Evas_Object *bg = elm_bg_add(win); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(bg); + return bg; +} + +static Evas_Object *create_fullview (Evas_Object *parent, struct ug_data *ugd) +{ + Evas_Object *bg = _create_bg(parent); + Evas_Object *layout_main = NULL; + + layout_main = elm_layout_add (parent); + + if (layout_main == NULL) + return NULL; + + elm_layout_theme_set (layout_main, "layout","application","default"); + elm_object_style_set(bg, "group_list"); + elm_object_part_content_set (layout_main, "elm.swallow.bg", bg); + + return layout_main; +} + +static Evas_Object *create_frameview (Evas_Object *parent, struct ug_data *ugd) +{ + Evas_Object *bg = _create_bg(parent); + Evas_Object *layout_main = elm_layout_add (parent); + if (layout_main == NULL) + return NULL; + elm_layout_theme_set (layout_main, "layout", "application", "default"); + elm_object_style_set(bg, "group_list"); + elm_object_part_content_set (layout_main, "elm.swallow.bg", bg); + + return layout_main; +} + +static void back_cb (void *data, Evas_Object *obj, void *event_info) +{ + if (data == NULL) + return; + + struct ug_data *ugd = (struct ug_data *)data; + ug_destroy_me (ugd->ug); +} + +static Evas_Object* _create_naviframe_layout (Evas_Object* parent) +{ + Evas_Object *naviframe = elm_naviframe_add (parent); + elm_object_part_content_set (parent, "elm.swallow.content", naviframe); + evas_object_show (naviframe); + + return naviframe; +} + +static bool in_exit = false; +static void sw_keyboard_selection_view_back_cb (void *data, Evas_Object *obj, void *event_info) +{ + if (in_exit) { + LOGD("do nothing ,exit!\n"); + return; + } + in_exit = true; + + if (data == NULL) + return; + + struct ug_data *ugd = NULL; + ugd = (ug_data *)data; + + if (strcmp (ise_bak, _active_ise_name) != 0) { + //if _active_ise_name is changed , active _active_ise_name. + //find the uuid of the active + String uuid; + for (unsigned int i = 0; i < _names.size (); i++) { + if (strcmp (_names[i].c_str (), _active_ise_name) == 0) + uuid = _uuids[i]; + } + isf_control_set_active_ise_by_uuid ( uuid.c_str ()); + + snprintf (ise_bak, sizeof (ise_bak), "%s", _active_ise_name); + } + + service_h s = NULL; + service_create(&s); + service_add_extra_data(s, "name", "keyboard-setting-wizard-efl"); + service_add_extra_data(s, "description", "previous clicked"); + ug_send_result(ugd->ug, s); + service_destroy(s); + + back_cb(data,obj,event_info); + + LOGD("End of %s", __func__); +} + +static void sw_keyboard_selection_view_set_cb (void *data, Evas_Object *obj, void *event_info) +{ + if (in_exit) + return; + in_exit = true; + + if (data == NULL) + return; + + struct ug_data *ugd = (struct ug_data *)data; + + if (strcmp (ise_bak, _active_ise_name) != 0) { + //if _active_ise_name is changed , active _active_ise_name. + //find the uuid of the active + String uuid; + for (unsigned int i = 0; i < _names.size (); i++) { + if (strcmp (_names[i].c_str (), _active_ise_name) == 0) + uuid = _uuids[i]; + } + isf_control_set_active_ise_by_uuid ( uuid.c_str ()); + + snprintf (ise_bak, sizeof (ise_bak), "%s", _active_ise_name); + LOGD("Set active ISE : %s", ise_bak); + } + + service_h s = NULL; + service_create(&s); + service_add_extra_data(s, "name", "keyboard-setting-wizard-efl"); + service_add_extra_data(s, "description", "next clicked"); + ug_send_result(ugd->ug, s); + service_destroy(s); + + back_cb(data,obj,event_info); + + LOGD("End of %s", __func__); +// call next ug +} + +static void _gl_sel(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + elm_genlist_item_selected_set(item, 0); + mark = (int) (data); + snprintf (_active_ise_name, sizeof (_active_ise_name), "%s", sw_iselist[mark].c_str ()); + elm_genlist_item_update(item); + return; +} + +static void _sw_radio_cb (void *data, Evas_Object *obj, void *event_info) +{ + int index = GPOINTER_TO_INT(data); + elm_radio_value_set (sw_radio_grp, index); + snprintf (_active_ise_name, sizeof (_active_ise_name), "%s", sw_iselist[index].c_str ()); +} + +static char *_gl_label_get(void *data, Evas_Object *obj, const char *part) +{ + int index = (int)(data); + if (!strcmp(part, "elm.text")) { + return strdup(sw_iselist[index].c_str()); + } + return NULL; +} + +static Evas_Object *_gl_icon_get(void *data, Evas_Object *obj, const char *part) +{ + if (!strcmp(part, "elm.icon")) { + + int index = (int)(data); + Evas_Object *radio = elm_radio_add (obj); + elm_radio_state_value_set (radio, index); + if (sw_radio_grp == NULL) + sw_radio_grp = elm_radio_add(obj); + elm_radio_group_add (radio, sw_radio_grp); + evas_object_show (radio); + evas_object_smart_callback_add (radio, "changed", _sw_radio_cb, (void *) (index)); + if (mark == index) { + elm_radio_value_set (sw_radio_grp, mark); + } + return radio; + } + return NULL; +} + +static Eina_Bool _gl_state_get(void *data, Evas_Object *obj, const char *part) +{ + return EINA_FALSE; +} + +static void _gl_del(void *data, Evas_Object *obj) +{ + return; +} + +static Evas_Object *isf_setting_main_view_tizen(ug_data * ugd) +{ + String tmpStr = _config->read(SCIM_CONFIG_DEFAULT_HELPER_ISE,String("b70bf6cc-ff77-47dc-a137-60acc32d1e0c")); + snprintf (_active_ise_name, sizeof (_active_ise_name), "%s", (uuid_to_name(tmpStr)).c_str()); + snprintf (ise_bak, sizeof (ise_bak), "%s", _active_ise_name); + LOGD("Default ISE Name : %s", ise_bak); + + ugd->naviframe = _create_naviframe_layout (ugd->layout_main); + char *navi_btn_l_lable = NULL; + char *navi_btn_r_lable = NULL; + service_get_extra_data(ugd->data, "navi_btn_left",&navi_btn_l_lable); + service_get_extra_data(ugd->data, "navi_btn_right",&navi_btn_r_lable); + if (sw_radio_grp != NULL) + { + evas_object_del(sw_radio_grp); + sw_radio_grp = NULL; + } + + Evas_Object *genlist = elm_genlist_add(ugd->naviframe); + elm_object_style_set(genlist, "dialogue"); + evas_object_show(genlist); + + Elm_Object_Item *nf_it; + Evas_Object *cbar = elm_toolbar_add (ugd->naviframe); + elm_toolbar_shrink_mode_set(cbar, ELM_TOOLBAR_SHRINK_EXPAND); + if (cbar == NULL) return NULL; + + if (navi_btn_l_lable!= NULL) { + elm_toolbar_item_append(cbar, NULL, navi_btn_l_lable, sw_keyboard_selection_view_back_cb, ugd); + elm_toolbar_item_append(cbar, NULL, navi_btn_r_lable, sw_keyboard_selection_view_set_cb, ugd); + + nf_it = elm_naviframe_item_push(ugd->naviframe, T_("Keyboard"), NULL, NULL, genlist, NULL); + elm_object_item_part_content_set(nf_it, "controlbar", cbar); + } + else { + elm_toolbar_item_append(cbar, NULL, navi_btn_r_lable, sw_keyboard_selection_view_set_cb, ugd); + nf_it = elm_naviframe_item_push(ugd->naviframe, T_("Keyboard"), NULL, NULL, genlist, NULL); + elm_object_item_part_content_set(nf_it, "controlbar", cbar); + } + + if (navi_btn_l_lable!= NULL) + free (navi_btn_l_lable); + if (navi_btn_r_lable!= NULL) + free (navi_btn_r_lable); + unsigned int i = 0; + + sw_iselist.clear (); + std::vector selected_langs, all_langs, uuid_list; + + isf_get_all_languages (all_langs); + isf_get_helper_ises_in_languages (all_langs, uuid_list, sw_iselist); + std::sort (sw_iselist.begin (), sw_iselist.end ()); + + if (sw_iselist.size () > 0) { + // Set item class for dialogue group seperator + itcSeparator.item_style = "dialogue/separator/21/with_line"; + itcSeparator.func.text_get = NULL; + itcSeparator.func.content_get = NULL; + itcSeparator.func.state_get = NULL; + itcSeparator.func.del = NULL; + + //separator + Elm_Object_Item *item; + item = elm_genlist_item_append( + genlist, // genlist object + &itcSeparator, // item class + NULL, // data + NULL, + ELM_GENLIST_ITEM_NONE, + NULL, + NULL); + elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + + for (i = 0; i < sw_iselist.size (); i++) { + if (strcmp (_active_ise_name, sw_iselist[i].c_str ()) == 0) { + mark = i; + break; + } + } + + //set item class for 1text.1icon(text+radiobutton) + itc1.item_style = "dialogue/1text.1icon.2"; + itc1.func.text_get = _gl_label_get; + itc1.func.content_get = _gl_icon_get; + itc1.func.state_get = _gl_state_get; + itc1.func.del = _gl_del; + for (i = 0;i < sw_iselist.size();i++) { + elm_genlist_item_append(genlist, &itc1, + (void *)(i), NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, + (void *)(i)); + } + + return ugd->naviframe; +} + +ConfigPointer isf_imf_context_get_config(void); +static void *on_create (ui_gadget_h ug, enum ug_mode mode, service_h s, void *priv) +{ + Evas_Object *parent = NULL; + Evas_Object *content = NULL; + + if ( ug == NULL || priv == NULL) + return NULL; + + bindtextdomain (WIZARD_PACKAGE, WIZARD_LOCALEDIR); + + struct ug_data *ugd = (struct ug_data *)priv; + ugd->ug = ug; + ugd->data = s; + parent = (Evas_Object *) ug_get_parent_layout (ug); + if (parent == NULL) + return NULL; + //-------------------------- ise infomation ---------------------------- + + const char *ctx_id = ecore_imf_context_default_id_get (); + if (ctx_id != NULL) { + imf_context = ecore_imf_context_add (ctx_id); + } + + _config = isf_imf_context_get_config (); + if (_config.null ()) { + std::cerr << "Create dummy config!!!\n"; + _config = new DummyConfig (); + } + + if (_config.null ()) { + std::cerr << "Can not create Config Object!\n"; + } + + //only helper ISEs will be needed in isfsetting according to phone requirement. + isf_load_ise_information (HELPER_ONLY, _config); + // Request ISF to update ISE list, below codes are very important, dont remove + char **iselist = NULL; + int count = isf_control_get_ise_list (&iselist); + for (unsigned int i = 0; i < (unsigned int)count; i++) { + SCIM_DEBUG_MAIN (3) << " [" << i << " : " << iselist[i] << "] \n"; + if (iselist[i] != NULL) + delete [] (iselist[i]); + } + + if (iselist!=NULL) + free(iselist); + //-------------------------- ise infomation ---------------------------- + + //construct the UI part of the isfsetting module + if (mode == UG_MODE_FULLVIEW) + ugd->layout_main = create_fullview (parent, ugd); + else + ugd->layout_main = create_frameview (parent, ugd); + + if (ugd->layout_main != NULL) { + content = isf_setting_main_view_tizen(ugd); + elm_object_part_content_set (ugd->layout_main, "elm.swallow.content", content); + } + return (void *)ugd->layout_main; +} + +static void on_start (ui_gadget_h ug, service_h s, void *priv) +{ +} + +static void on_pause (ui_gadget_h ug, service_h s, void *priv) +{ + +} + +static void on_resume (ui_gadget_h ug, service_h s, void *priv) +{ + +} + +static void on_destroy (ui_gadget_h ug, service_h s, void *priv) +{ + if ( ug == NULL|| priv == NULL) + return; + + if (imf_context != NULL) { + ecore_imf_context_del(imf_context); + imf_context = NULL; + } + + struct ug_data *ugd = (struct ug_data *) priv; + + if (ugd->naviframe != NULL) { + evas_object_del (ugd->naviframe); + ugd->naviframe = NULL; + } + + if (ugd->layout_main != NULL) { + evas_object_del (ugd->layout_main); + ugd->layout_main = NULL; + } + + if (!_config.null ()) { + _config->flush (); + _config.reset (); + } +} + +static void on_message (ui_gadget_h ug, service_h msg, service_h data, void *priv) +{ +} + +static void on_event (ui_gadget_h ug, enum ug_event event, service_h s, void *priv) +{ + switch (event) { + case UG_EVENT_LOW_MEMORY: + break; + case UG_EVENT_LOW_BATTERY: + break; + case UG_EVENT_LANG_CHANGE: + break; + case UG_EVENT_ROTATE_PORTRAIT: + break; + case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN: + break; + case UG_EVENT_ROTATE_LANDSCAPE: + break; + case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN: + break; + default: + break; + } +} + +static void on_key_event(ui_gadget_h ug, enum ug_key_event event, service_h s, void *priv) +{ + if (ug == NULL) + return; + + switch (event) { + case UG_KEY_EVENT_END: + ug_destroy_me(ug); + break; + default: + break; + } +} + +#ifdef __cplusplus +extern "C" +{ +#endif + UG_WIZARD_MODULE_API int UG_MODULE_INIT (struct ug_module_ops *ops) { + if (ops == NULL) + return -1; + + struct ug_data *ugd = (ug_data*)calloc (1, sizeof (struct ug_data)); + if (ugd == NULL) + return -1; + + ops->create = on_create; + ops->start = on_start; + ops->pause = on_pause; + ops->resume = on_resume; + ops->destroy = on_destroy; + ops->message = on_message; + ops->event = on_event; + ops->key_event = on_key_event; + ops->priv = ugd; + ops->opt = UG_OPT_INDICATOR_PORTRAIT_ONLY; + + return 0; + } + + UG_WIZARD_MODULE_API void UG_MODULE_EXIT (struct ug_module_ops *ops) { + if (ops == NULL) + return; + + struct ug_data *ugd = (struct ug_data *)(ops->priv); + if (ugd != NULL) + free (ugd); + } + +#ifdef __cplusplus +} +#endif +/* +vi:ts=4:ai:nowrap:expandtab +*/ + diff --git a/ism/extras/efl_setting/scim_setup_module_efl.cpp b/ism/extras/efl_setting/scim_setup_module_efl.cpp new file mode 100644 index 0000000..1c0a3a4 --- /dev/null +++ b/ism/extras/efl_setting/scim_setup_module_efl.cpp @@ -0,0 +1,205 @@ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_setup_module.cpp,v 1.9 2005/01/10 08:30:45 suzhe Exp $ + * + */ + +#define Uses_SCIM_CONFIG_BASE +#define Uses_SCIM_MODULE + + +#include "scim_private.h" +#include "scim.h" +#include "scim_setup_module_efl.h" + +SetupModule::SetupModule () + : m_create_ui (0), + m_get_category (0), + m_get_name (0), + m_get_description (0), + m_load_config (0), + m_save_config (0), + m_query_changed (0), + m_key_proceeding (0), + m_option_reset (0) +{ +} + +SetupModule::SetupModule (const String &name) + : m_create_ui (0), + m_get_category (0), + m_get_name (0), + m_get_description (0), + m_load_config (0), + m_save_config (0), + m_query_changed (0), + m_key_proceeding (0), + m_option_reset (0) +{ + load (name); +} + +bool +SetupModule::load (const String &name) +{ + if (!m_module.load (name, "SetupUI")) + return false; + + m_create_ui = (SetupModuleCreateUIFunc) m_module.symbol ("scim_setup_module_create_ui"); + m_get_category = (SetupModuleGetCategoryFunc) m_module.symbol ("scim_setup_module_get_category"); + m_get_name = (SetupModuleGetNameFunc) m_module.symbol ("scim_setup_module_get_name"); + m_get_description = (SetupModuleGetDescriptionFunc) m_module.symbol ("scim_setup_module_get_description"); + m_load_config = (SetupModuleLoadConfigFunc) m_module.symbol ("scim_setup_module_load_config"); + m_save_config = (SetupModuleSaveConfigFunc) m_module.symbol ("scim_setup_module_save_config"); + m_query_changed = (SetupModuleQueryChangedFunc) m_module.symbol ("scim_setup_module_query_changed"); + m_key_proceeding = (SetupModuleKeyProceedingFunc) m_module.symbol ("scim_setup_module_key_proceeding"); + m_option_reset = (SetupModuleOptionResetFunc) m_module.symbol ("scim_setup_module_option_reset"); + + + if (!m_create_ui || !m_get_category || !m_get_name || + !m_load_config || !m_save_config || !m_key_proceeding || !m_option_reset) + { + m_module.unload (); + m_create_ui = 0; + m_get_category = 0; + m_get_name = 0; + m_get_description = 0; + m_load_config = 0; + m_save_config = 0; + m_query_changed = 0; + m_key_proceeding = 0; + m_option_reset = 0; + return false; + } + return true; +} + +bool +SetupModule::unload () +{ + m_module.unload (); + + m_create_ui = 0; + m_get_category = 0; + m_get_name = 0; + m_get_description = 0; + m_load_config = 0; + m_save_config = 0; + m_query_changed = 0; + m_key_proceeding = 0; + m_option_reset = 0; + return true; +} + +bool +SetupModule::valid () const +{ + return (m_module.valid () && + m_create_ui && m_get_category && m_get_name && + m_load_config && m_save_config && m_key_proceeding && m_option_reset); +} + +Evas_Object* +SetupModule::create_ui (Evas_Object *parent, Evas_Object *layout) const +{ + if (valid ()) + return m_create_ui (parent,layout); + + return 0; +} + +String +SetupModule::get_category () const +{ + if (valid ()) + return m_get_category (); + + return String (); +} + +String +SetupModule::get_name () const +{ + if (valid ()) + return m_get_name (); + + return String (); +} + +String +SetupModule::get_description () const +{ + if (valid () && m_get_description) + return m_get_description (); + + return String (); +} + +void +SetupModule::load_config (const ConfigPointer &config) const +{ + if (valid ()) + m_load_config (config); +} + +void +SetupModule::save_config (const ConfigPointer &config) const +{ + if (valid ()) + m_save_config (config); +} + +bool +SetupModule::query_changed () const +{ + if (valid () && m_query_changed) + return m_query_changed (); + return false; +} + +bool +SetupModule::key_proceeding (int key_type) const +{ + if (valid () && m_key_proceeding) + return m_key_proceeding (key_type); + return false; +} + +bool +SetupModule::option_reset (const ConfigPointer &config) const +{ + if (valid () && m_option_reset) + return m_option_reset (config); + return false; +} + +int scim_get_setup_module_list (std::vector & mod_list) +{ + return scim_get_module_list (mod_list, "SetupUI"); +} + + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/gtk2_immodule/Makefile.am b/ism/extras/gtk2_immodule/Makefile.am new file mode 100644 index 0000000..4e3c829 --- /dev/null +++ b/ism/extras/gtk2_immodule/Makefile.am @@ -0,0 +1,48 @@ +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = im-scim.version-script + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/data \ + -I$(top_srcdir)/ism/utils \ + -I$(top_srcdir)/ism/extras/panel \ + -I$(top_srcdir)/idm/src \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" \ + -DSCIM_KEYBOARD_ICON_FILE=\"@SCIM_ICONDIR@/keyboard.png\" + +if SCIM_BUILD_GTK2_IMMODULE +CONFIG_GTK2_IMMODULE = im-scim.la +endif + +if SCIM_LD_VERSION_SCRIPT +LD_VERSION_SCRIPT_OPTION="-Wl,--version-script=$(srcdir)/im-scim.version-script" +endif + +noinst_HEADERS = gtkimcontextscim.h + +moduledir = @GTK_IM_MODULEDIR@ + +module_LTLIBRARIES = $(CONFIG_GTK2_IMMODULE) + +im_scim_la_SOURCES = gtkimcontextscim.cpp imscim.cpp + +im_scim_la_CXXFLAGS=@GTK2_CFLAGS@ +im_scim_la_CFLAGS =@GTK2_CFLAGS@ + +im_scim_la_LDFLAGS = -rpath $(moduledir) \ + -avoid-version \ + -module \ + -lstdc++ \ + $(LD_VERSION_SCRIPT_OPTION) \ + -L@GTK_LIBDIR@ -lgtk-x11-2.0 -lgdk-x11-2.0 -lglib-2.0 -lgobject-2.0 -lpango-1.0 + +im_scim_la_LIBADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la diff --git a/ism/extras/gtk2_immodule/gtkimcontextscim.cpp b/ism/extras/gtk2_immodule/gtkimcontextscim.cpp new file mode 100644 index 0000000..b897c2a --- /dev/null +++ b/ism/extras/gtk2_immodule/gtkimcontextscim.cpp @@ -0,0 +1,2967 @@ +/** @file gtkimcontextscim.cpp + * @brief immodule for GTK2. + */ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Implement GTK context auto-restore when PanelAgent is crashed + * 2. Add new interface APIs for helper ISE + * a. panel_slot_reset_keyboard_ise () + * b. panel_slot_show_preedit_string (), panel_slot_hide_preedit_string () and panel_slot_update_preedit_string () + * + * $Id: gtkimcontextscim.cpp,v 1.170.2.13 2007/06/16 06:23:38 suzhe Exp $ + */ + +#define Uses_SCIM_DEBUG +#define Uses_SCIM_BACKEND +#define Uses_SCIM_IMENGINE +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_CONFIG +#define Uses_SCIM_CONFIG_MODULE +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_TRANSACTION +#define Uses_SCIM_HOTKEY +#define Uses_SCIM_PANEL_CLIENT +#define Uses_C_STRING +#define Uses_C_STDIO +#define Uses_C_STDLIB +#define Uses_STL_IOSTREAM +#define Uses_SCIM_UTILITY + +#include +#include +#include +#include +#include +#include +#include + +#undef GDK_WINDOWING_X11 +#ifdef GDK_WINDOWING_X11 +#include +#include +#include +#include +#endif + +#include +static struct timeval _scim_start; + +#include "scim_private.h" +#include "scim.h" + +#ifdef GDK_WINDOWING_X11 +#include "scim_x11_utils.h" +#endif + +using namespace scim; + +#include "gtkimcontextscim.h" + +//#define USING_ISF_MAINWINDOW_AUTOSCROLL + + +#define GTK_TYPE_IM_CONTEXT_SCIM _gtk_type_im_context_scim +#define GTK_IM_CONTEXT_SCIM(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_IM_CONTEXT_SCIM, GtkIMContextSCIM)) +#define GTK_IM_CONTEXT_SCIM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_SCIM, GtkIMContextSCIMClass)) +#define GTK_IS_IM_CONTEXT_SCIM(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_IM_CONTEXT_SCIM)) +#define GTK_IS_IM_CONTEXT_SCIM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_SCIM)) +#define GTK_IM_CONTEXT_SCIM_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_SCIM, GtkIMContextSCIMClass)) + +#define SCIM_CONFIG_FRONTEND_GTK_IMMODULE_USE_KEY_SNOOPER "/FrontEnd/GtkIMModule/UseKeySnooper" +#define ISE_KEY_FLUSH 0x8001 +#ifdef ISF_PROF +static void gettime (const char* str) +{ + struct tms tiks_buf; + double clock_tiks = (double)sysconf (_SC_CLK_TCK); + clock_t times_tiks = times (&tiks_buf); + double times_secs = (double)times_tiks / clock_tiks; + double utime = (double)tiks_buf.tms_utime / clock_tiks; + double stime = (double)tiks_buf.tms_stime / clock_tiks; + printf ("Times: %3f \t User: %.3f \t System: %.3f \n", (double)times_secs, (double)utime , (double)stime); +} +#endif + +static void print_time (const char *str_info) +{ +#ifdef ISF_PROF + struct timeval current_time; + int used_time = 0; + + gettimeofday (¤t_time, NULL); + used_time = 1000000 * (current_time.tv_sec - _scim_start.tv_sec) + current_time.tv_usec - _scim_start.tv_usec; + printf (mzc_red "%s : %d usec" mzc_normal ".\n", str_info, used_time); + //printf ("Current time : %d sec %d usec\n", current_time.tv_sec, current_time.tv_usec); + gettime (str_info); +#endif +} + +/* Typedef */ +struct _GtkIMContextSCIMImpl +{ + GtkIMContextSCIM *parent; + IMEngineInstancePointer si; + GdkWindow *client_window; + WideString preedit_string; + AttributeList preedit_attrlist; + gint preedit_caret; + gint cursor_x; + gint cursor_y; + gint cursor_top_y; + gboolean use_preedit; + bool is_on; + bool shared_si; + bool preedit_started; + bool preedit_updating; + bool need_commit_preedit; + + GtkIMContextSCIMImpl *next; +}; + +/* Input Context handling functions. */ +static GtkIMContextSCIMImpl * new_ic_impl (GtkIMContextSCIM *parent); +static void delete_ic_impl (GtkIMContextSCIMImpl *impl); +static void delete_all_ic_impl (); + +static GtkIMContextSCIM * find_ic (int siid); + +/* Methods declaration */ +static void gtk_im_context_scim_class_init (GtkIMContextSCIMClass *klass, + gpointer *klass_data); +static void gtk_im_context_scim_init (GtkIMContextSCIM *context_scim, + GtkIMContextSCIMClass *klass); +static void gtk_im_context_scim_finalize (GObject *obj); +static void gtk_im_context_scim_finalize_partial (GtkIMContextSCIM *context_scim); +static void gtk_im_context_scim_set_client_window (GtkIMContext *context, + GdkWindow *client_window); +static gboolean gtk_im_context_scim_filter_keypress (GtkIMContext *context, + GdkEventKey *key); +static void gtk_im_context_scim_reset (GtkIMContext *context); +static void gtk_im_context_scim_focus_in (GtkIMContext *context); +static void gtk_im_context_scim_focus_out (GtkIMContext *context); +static void gtk_im_context_scim_set_cursor_location (GtkIMContext *context, + GdkRectangle *area); +static void gtk_im_context_scim_set_use_preedit (GtkIMContext *context, + gboolean use_preedit); +static void gtk_im_context_scim_get_preedit_string (GtkIMContext *context, + gchar **str, + PangoAttrList **attrs, + gint *cursor_pos); + +static gboolean gtk_scim_key_snooper (GtkWidget *grab_widget, + GdkEventKey *event, + gpointer data); + +static void gtk_im_slave_commit_cb (GtkIMContext *context, + const char *str, + GtkIMContextSCIM *context_scim); + +/* private functions */ +static void panel_slot_reload_config (int context); +static void panel_slot_exit (int context); +static void panel_slot_update_lookup_table_page_size(int context, + int page_size); +static void panel_slot_lookup_table_page_up (int context); +static void panel_slot_lookup_table_page_down (int context); +static void panel_slot_trigger_property (int context, + const String &property); +static void panel_slot_process_helper_event (int context, + const String &target_uuid, + const String &helper_uuid, + const Transaction &trans); +static void panel_slot_move_preedit_caret (int context, + int caret_pos); +static void panel_slot_select_candidate (int context, + int cand_index); +static void panel_slot_process_key_event (int context, + const KeyEvent &key); +static void panel_slot_commit_string (int context, + const WideString &wstr); +static void panel_slot_forward_key_event (int context, + const KeyEvent &key); +static void panel_slot_request_help (int context); +static void panel_slot_request_factory_menu (int context); +static void panel_slot_change_factory (int context, + const String &uuid); +static void panel_slot_reset_keyboard_ise (int context); +static void panel_slot_show_preedit_string (int context); +static void panel_slot_hide_preedit_string (int context); +static void panel_slot_update_preedit_string (int context, + const WideString &str, + const AttributeList &attrs); + +static void panel_req_focus_in (GtkIMContextSCIM *ic); +static void panel_req_update_screen (GtkIMContextSCIM *ic); +static void panel_req_update_factory_info (GtkIMContextSCIM *ic); +static void panel_req_update_spot_location (GtkIMContextSCIM *ic); +static void panel_req_show_help (GtkIMContextSCIM *ic); +static void panel_req_show_factory_menu (GtkIMContextSCIM *ic); + +/* Panel iochannel handler*/ +static bool panel_initialize (); +static void panel_finalize (); +static gboolean panel_iochannel_handler (GIOChannel *source, + GIOCondition condition, + gpointer user_data); + +/* utility functions */ +static bool filter_hotkeys (GtkIMContextSCIM *ic, + const KeyEvent &key); +static void turn_on_ic (GtkIMContextSCIM *ic); +static void turn_off_ic (GtkIMContextSCIM *ic); + +static void set_ic_capabilities (GtkIMContextSCIM *ic); + +static KeyEvent keyevent_gdk_to_scim (const GtkIMContextSCIM *ic, + const GdkEventKey &gdkevent); + +static GdkEventKey keyevent_scim_to_gdk (const GtkIMContextSCIM *ic, + const KeyEvent &scimkey, gboolean send_event); + +static void initialize (void); + +static void finalize (void); + +static void open_next_factory (GtkIMContextSCIM *ic); +static void open_previous_factory (GtkIMContextSCIM *ic); +static void open_specific_factory (GtkIMContextSCIM *ic, + const String &uuid); + +static void attach_instance (const IMEngineInstancePointer &si); + +/* slot functions */ +static void slot_show_preedit_string (IMEngineInstanceBase *si); +static void slot_show_aux_string (IMEngineInstanceBase *si); +static void slot_show_lookup_table (IMEngineInstanceBase *si); + +static void slot_hide_preedit_string (IMEngineInstanceBase *si); +static void slot_hide_aux_string (IMEngineInstanceBase *si); +static void slot_hide_lookup_table (IMEngineInstanceBase *si); + +static void slot_update_preedit_caret (IMEngineInstanceBase *si, + int caret); +static void slot_update_preedit_string (IMEngineInstanceBase *si, + const WideString &str, + const AttributeList &attrs); +static void slot_update_aux_string (IMEngineInstanceBase *si, + const WideString &str, + const AttributeList &attrs); +static void slot_commit_string (IMEngineInstanceBase *si, + const WideString &str); +static void slot_forward_key_event (IMEngineInstanceBase *si, + const KeyEvent &key); +static void slot_update_lookup_table (IMEngineInstanceBase *si, + const LookupTable &table); + +static void slot_register_properties (IMEngineInstanceBase *si, + const PropertyList &properties); +static void slot_update_property (IMEngineInstanceBase *si, + const Property &property); +static void slot_beep (IMEngineInstanceBase *si); +static void slot_start_helper (IMEngineInstanceBase *si, + const String &helper_uuid); +static void slot_stop_helper (IMEngineInstanceBase *si, + const String &helper_uuid); +static void slot_send_helper_event (IMEngineInstanceBase *si, + const String &helper_uuid, + const Transaction &trans); +static bool slot_get_surrounding_text (IMEngineInstanceBase *si, + WideString &text, + int &cursor, + int maxlen_before, + int maxlen_after); +static bool slot_delete_surrounding_text (IMEngineInstanceBase *si, + int offset, + int len); + +static void reload_config_callback (const ConfigPointer &config); + +static void fallback_commit_string_cb (IMEngineInstanceBase *si, + const WideString &str); + + + + +/* Local variables declaration */ +static String _language; +static GtkIMContextSCIMImpl *_used_ic_impl_list = 0; +static GtkIMContextSCIMImpl *_free_ic_impl_list = 0; +static GtkIMContextSCIM *_ic_list = 0; + +static GType _gtk_type_im_context_scim = 0; +static GObjectClass *_parent_klass = 0; + +static KeyboardLayout _keyboard_layout = SCIM_KEYBOARD_Default; +static int _valid_key_mask = SCIM_KEY_AllMasks; + +static FrontEndHotkeyMatcher _frontend_hotkey_matcher; +static IMEngineHotkeyMatcher _imengine_hotkey_matcher; + +static IMEngineInstancePointer _default_instance; + +static ConfigModule *_config_module = 0; +static ConfigPointer _config; +static BackEndPointer _backend; + +static GtkIMContextSCIM *_focused_ic = 0; +static GtkWidget *_focused_widget = 0; + +static bool _scim_initialized = false; + +static GdkColor _normal_bg; +static GdkColor _normal_text; +static GdkColor _active_bg; +static GdkColor _active_text; + +static gint _snooper_id = 0; +static bool _snooper_installed = false; + +static int _instance_count = 0; +static int _context_count = 0; + +static IMEngineFactoryPointer _fallback_factory; +static IMEngineInstancePointer _fallback_instance; + +static PanelClient _panel_client; + +static GIOChannel *_panel_iochannel = 0; +static guint _panel_iochannel_read_source= 0; +static guint _panel_iochannel_err_source = 0; +static guint _panel_iochannel_hup_source = 0; + +static bool _on_the_spot = true; +static bool _shared_input_method = false; +static bool _use_key_snooper = false; + +static GdkColor *_theme_color = NULL; + +// A hack to shutdown the immodule cleanly even if im_module_exit () is not called when exiting. +class FinalizeHandler +{ +public: + FinalizeHandler () { + SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::FinalizeHandler ()\n"; + } + ~FinalizeHandler () { + SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::~FinalizeHandler ()\n"; + gtk_im_context_scim_shutdown (); + } +}; + +static FinalizeHandler _finalize_handler; + +/* Function Implementations */ + +static GtkIMContextSCIMImpl * +new_ic_impl (GtkIMContextSCIM *parent) +{ + GtkIMContextSCIMImpl *impl = NULL; + + if (_free_ic_impl_list != NULL) { + impl = _free_ic_impl_list; + _free_ic_impl_list = _free_ic_impl_list->next; + } else { + impl = new GtkIMContextSCIMImpl; + if (impl == NULL) + return NULL; + } + + impl->next = _used_ic_impl_list; + _used_ic_impl_list = impl; + + impl->parent = parent; + + return impl; +} + +static void +delete_ic_impl (GtkIMContextSCIMImpl *impl) +{ + GtkIMContextSCIMImpl *rec = _used_ic_impl_list, *last = 0; + + for (; rec != 0; last = rec, rec = rec->next) { + if (rec == impl) { + if (last != 0) + last->next = rec->next; + else + _used_ic_impl_list = rec->next; + + rec->next = _free_ic_impl_list; + _free_ic_impl_list = rec; + + rec->parent = 0; + rec->si.reset (); + rec->client_window = 0; + rec->preedit_string = WideString (); + rec->preedit_attrlist.clear (); + + return; + } + } +} + + +static void +delete_all_ic_impl () +{ + GtkIMContextSCIMImpl *it = _used_ic_impl_list; + + + while (it != 0) { + _used_ic_impl_list = it->next; + delete it; + it = _used_ic_impl_list; + } + + it = _free_ic_impl_list; + while (it != 0) { + _free_ic_impl_list = it->next; + delete it; + it = _free_ic_impl_list; + } +} + +static GtkIMContextSCIM * +find_ic (int id) +{ + GtkIMContextSCIMImpl *rec = _used_ic_impl_list; + + while (rec != 0) { + if (rec->parent && rec->parent->id == id) + return rec->parent; + rec = rec->next; + } + + return 0; +} + + +/* Public functions */ +/** + * gtk_im_context_scim_new + * + * This function will be called by gtk. + * Create a instance of type GtkIMContext. + * + * Return value: A pointer to the newly created GtkIMContextSCIM instance + * + **/ +GtkIMContext * +gtk_im_context_scim_new (void) +{ + print_time ("enter gtk_im_context_scim_new"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_new...\n"; + + GtkIMContextSCIM *result = NULL; + + result = GTK_IM_CONTEXT_SCIM (g_object_new (GTK_TYPE_IM_CONTEXT_SCIM, NULL)); + + print_time ("exit gtk_im_context_scim_new"); + return GTK_IM_CONTEXT (result); +} + +/** + * gtk_im_context_scim_new + * + * Register the new type GtkIMContextSCIM to glib + * + **/ +void +gtk_im_context_scim_register_type (GTypeModule *type_module) +{ + gettimeofday (&_scim_start, NULL); + print_time ("enter gtk_im_context_scim_register_type"); + static const GTypeInfo im_context_scim_info = + { + sizeof (GtkIMContextSCIMClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gtk_im_context_scim_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GtkIMContextSCIM), + 0, + (GtkObjectInitFunc) gtk_im_context_scim_init, + }; + + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_register_type...\n"; + + if (!_gtk_type_im_context_scim) { + _gtk_type_im_context_scim = + g_type_module_register_type (type_module, + GTK_TYPE_IM_CONTEXT, + "GtkIMContextSCIM", + &im_context_scim_info, + (GTypeFlags) 0); + g_type_module_use (type_module); + } + print_time ("exit gtk_im_context_scim_register_type"); +} + +/** + * gtk_im_context_scim_shutdown + * + * It will be called when the scim im module is unloaded by gtk. It will do some cleanup + * job. + * + **/ +void +gtk_im_context_scim_shutdown (void) +{ + print_time ("enter gtk_im_context_scim_shutdown"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_shutdown...\n"; + + if (_scim_initialized) { + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_shutdown: call finalize ()...\n"; + finalize (); + _scim_initialized = false; + } + print_time ("exit gtk_im_context_scim_shutdown"); +} + +/* Private functions */ +static void +gtk_im_context_scim_class_init (GtkIMContextSCIMClass *klass, + gpointer *klass_data) +{ + print_time ("enter gtk_im_context_scim_class_init"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_class_init...\n"; + + GtkIMContextClass *im_context_klass = GTK_IM_CONTEXT_CLASS (klass); + GObjectClass *gobject_klass = G_OBJECT_CLASS (klass); + + _parent_klass = (GObjectClass *) g_type_class_peek_parent (klass); + + im_context_klass->set_client_window = gtk_im_context_scim_set_client_window; + im_context_klass->filter_keypress = gtk_im_context_scim_filter_keypress; + im_context_klass->reset = gtk_im_context_scim_reset; + im_context_klass->get_preedit_string = gtk_im_context_scim_get_preedit_string; + im_context_klass->focus_in = gtk_im_context_scim_focus_in; + im_context_klass->focus_out = gtk_im_context_scim_focus_out; + im_context_klass->set_cursor_location = gtk_im_context_scim_set_cursor_location; + im_context_klass->set_use_preedit = gtk_im_context_scim_set_use_preedit; + gobject_klass->finalize = gtk_im_context_scim_finalize; + + if (!_scim_initialized) { + initialize (); + _scim_initialized = true; + } + print_time ("exit gtk_im_context_scim_class_init"); +} + +static void +gtk_im_context_scim_init (GtkIMContextSCIM *context_scim, + GtkIMContextSCIMClass *klass) +{ + print_time ("enter gtk_im_context_scim_init"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_init...\n"; + + context_scim->impl = NULL; + + /* slave exists for using gtk+'s table based input method */ + context_scim->slave = gtk_im_context_simple_new (); + g_signal_connect(G_OBJECT(context_scim->slave), + "commit", + G_CALLBACK(gtk_im_slave_commit_cb), + context_scim); + + if (_backend.null ()) return; + + IMEngineInstancePointer si; + + // Use the default instance if "shared input method" mode is enabled. + if (_shared_input_method && !_default_instance.null ()) { + si = _default_instance; + SCIM_DEBUG_FRONTEND(2) << "use default instance: " << si->get_id () << " " << si->get_factory_uuid () << "\n"; + } + + // Not in "shared input method" mode, or no default instance, create an instance. + if (si.null ()) { + IMEngineFactoryPointer factory = _backend->get_default_factory (_language, "UTF-8"); + if (factory.null ()) return; + si = factory->create_instance ("UTF-8", _instance_count++); + if (si.null ()) return; + attach_instance (si); + SCIM_DEBUG_FRONTEND(2) << "create new instance: " << si->get_id () << " " << si->get_factory_uuid () << "\n"; + } + + // If "shared input method" mode is enabled, and there is no default instance, + // then store this instance as default one. + if (_shared_input_method && _default_instance.null ()) { + SCIM_DEBUG_FRONTEND(2) << "update default instance.\n"; + _default_instance = si; + } + + context_scim->impl = new_ic_impl (context_scim); + if (context_scim->impl == NULL) + { + std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n"; + return; + } + + context_scim->impl->si = si; + context_scim->impl->client_window = NULL; + context_scim->impl->preedit_caret = 0; + context_scim->impl->cursor_x = 0; + context_scim->impl->cursor_y = 0; + context_scim->impl->cursor_top_y = 0; + context_scim->impl->is_on = FALSE; + context_scim->impl->shared_si = _shared_input_method; + context_scim->impl->use_preedit = _on_the_spot; + context_scim->impl->preedit_started = false; + context_scim->impl->preedit_updating = false; + context_scim->impl->need_commit_preedit = false; + + if (_context_count == 0) _context_count = time (NULL); + context_scim->id = _context_count++; + if (!_ic_list) + context_scim->next = NULL; + else + context_scim->next = _ic_list; + _ic_list = context_scim; + + if (_shared_input_method) + context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); + + _panel_client.prepare (context_scim->id); + _panel_client.register_input_context (context_scim->id, si->get_factory_uuid ()); + set_ic_capabilities (context_scim); + _panel_client.send (); + + SCIM_DEBUG_FRONTEND(2) << "input context created: id = " << context_scim->id << "\n"; + print_time ("exit gtk_im_context_scim_init"); +} + +static void +gtk_im_context_scim_finalize_partial (GtkIMContextSCIM *context_scim) +{ + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_finalize_partial id=" << context_scim->id << "\n"; + + if (context_scim->impl) { + _panel_client.prepare (context_scim->id); + + if (context_scim == _focused_ic) + context_scim->impl->si->focus_out (); + + // Delete the instance. + // FIXME: + // In case the instance send out some helper event, + // and this context has been focused out, + // we need set the focused_ic to this context temporary. + GtkIMContextSCIM *old_focused = _focused_ic; + _focused_ic = context_scim; + context_scim->impl->si.reset (); + _focused_ic = old_focused; + + if (context_scim == _focused_ic) { + _panel_client.turn_off (context_scim->id); + _panel_client.focus_out (context_scim->id); + } + + _panel_client.remove_input_context (context_scim->id); + _panel_client.send (); + + if (context_scim->impl->client_window) + g_object_unref (context_scim->impl->client_window); + + delete_ic_impl (context_scim->impl); + + context_scim->impl = 0; + } + + if (context_scim == _focused_ic) + _focused_ic = 0; +} + +static void +gtk_im_context_scim_finalize (GObject *obj) +{ + print_time ("enter gtk_im_context_scim_finalize"); + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (obj); + + if (context_scim == NULL) + return; + + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_finalize id=" << context_scim->id << "\n"; + + if ((_ic_list != NULL)) + { + if(context_scim->id != _ic_list->id) { + GtkIMContextSCIM * pre = _ic_list; + GtkIMContextSCIM * cur = _ic_list->next; + while (cur != NULL) { + if (cur->id == context_scim->id) { + pre->next = cur->next; + break; + } + pre = cur; + cur = cur->next; + } + } else + _ic_list = _ic_list->next; + } + + if (_theme_color != NULL) { + gdk_color_free (_theme_color); + _theme_color = NULL; + } + + g_signal_handlers_disconnect_by_func(context_scim->slave, + (void *)gtk_im_slave_commit_cb, + (void *)context_scim); + g_object_unref(context_scim->slave); + + gtk_im_context_scim_finalize_partial (context_scim); + + _parent_klass->finalize (obj); + print_time ("exit gtk_im_context_scim_finalize"); +} + +/** + * gtk_im_context_scim_set_client_window: + * @context: a #GtkIMContext + * @window: the client window. This may be %NULL to indicate + * that the previous client window no longer exists. + * + * This function will be called by gtk. + * Set the client window for the input context; this is the + * #GdkWindow in which the input appears. This window is + * used in order to correctly position status windows, and may + * also be used for purposes internal to the input method. + * + **/ +static void +gtk_im_context_scim_set_client_window (GtkIMContext *context, + GdkWindow *client_window) +{ + print_time ("enter gtk_im_context_scim_set_client_window"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_set_client_window...\n"; + + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); + + if (context_scim && context_scim->impl) { + if (client_window) + g_object_ref (client_window); + + if (context_scim->impl->client_window) + g_object_unref (context_scim->impl->client_window); + + context_scim->impl->client_window = client_window; + } + print_time ("exit gtk_im_context_scim_set_client_window"); +} + +/** + * gtk_im_context_scim_filter_keypress: + * @context: a #GtkIMContext + * @event: the key event + * + * This function will be called by gtk. + * Allow an input method to internally handle key press and release + * events. If this function returns %TRUE, then no further processing + * should be done for this key event. + * + * Return value: %TRUE if the input method handled the key event. + * + **/ +static gboolean +gtk_im_context_scim_filter_keypress (GtkIMContext *context, + GdkEventKey *event) +{ + print_time ("enter gtk_im_context_scim_filter_keypress"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_filter_keypress...\n"; + + if (event->keyval == 255 && (event->keyval & GDK_SHIFT_MASK)) + return (gboolean)TRUE; + + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); + + gboolean ret = FALSE; + + if (context_scim) { + if (!_snooper_installed) + ret = gtk_scim_key_snooper (0, event, 0); + + if (!ret && context_scim->slave) + ret = gtk_im_context_filter_keypress (context_scim->slave, event); + } + + print_time ("exit gtk_im_context_scim_filter_keypress"); + return ret; +} + +/** + * gtk_im_context_scim_reset: + * @context: a #GtkIMContext + * + * This function will be called by gtk. + * Notify the input method that a change such as a change in cursor + * position has been made. This will typically cause the input + * method to clear the preedit state. + **/ +static void +gtk_im_context_scim_reset (GtkIMContext *context) +{ + print_time ("enter gtk_im_context_scim_reset"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_reset...\n"; + + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); + + if (context_scim && context_scim->impl && context_scim == _focused_ic) { + WideString wstr = context_scim->impl->preedit_string; + + _panel_client.prepare (context_scim->id); + context_scim->impl->si->reset (); + _panel_client.send (); + + if (context_scim->impl->need_commit_preedit) + { + panel_slot_hide_preedit_string (context_scim->id); + + if (wstr.length ()) + g_signal_emit_by_name (context_scim, "commit", utf8_wcstombs (wstr).c_str ()); + + _panel_client.prepare (context_scim->id); + _panel_client.reset_input_context (context_scim->id); + _panel_client.send (); + } + } + print_time ("exit gtk_im_context_scim_reset"); +} + +/** + * gtk_im_context_scim_focus_in: + * @context: a #GtkIMContext + * + * This function will be called by gtk. + * Notify the input method that the widget to which this + * input context corresponds has gained focus. The input method + * may, for example, change the displayed feedback to reflect + * this change. + **/ +static void +gtk_im_context_scim_focus_in (GtkIMContext *context) +{ + print_time ("enter gtk_im_context_scim_focus_in"); + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); + + if (context_scim) + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_focus_in(" << context_scim->id << ")...\n"; + + if (_focused_ic) { + if (_focused_ic == context_scim) { + SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n"; + return; + } + SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n"; + gtk_im_context_scim_focus_out (GTK_IM_CONTEXT (_focused_ic)); + } + + // Only use key snooper when use_key_snooper option is enabled and a gtk main loop is running. + if (_use_key_snooper && !_snooper_installed && gtk_main_level () > 0) { + SCIM_DEBUG_FRONTEND(2) << "Install key snooper.\n"; + _snooper_id = gtk_key_snooper_install ((GtkKeySnoopFunc)gtk_scim_key_snooper, NULL); + _snooper_installed = true; + } + + bool need_cap = false; + bool need_reset = false; + bool need_reg = false; + + if (context_scim && context_scim->impl) { + _focused_ic = context_scim; + _panel_client.prepare (context_scim->id); + + // Handle the "Shared Input Method" mode. + if (_shared_input_method) { + SCIM_DEBUG_FRONTEND(2) << "shared input method.\n"; + IMEngineFactoryPointer factory = _backend->get_default_factory (_language, "UTF-8"); + if (!factory.null ()) { + if (_default_instance.null () || _default_instance->get_factory_uuid () != factory->get_uuid ()) { + _default_instance = factory->create_instance ("UTF-8", _default_instance.null () ? _instance_count++ : _default_instance->get_id ()); + attach_instance (_default_instance); + SCIM_DEBUG_FRONTEND(2) << "create new default instance: " << _default_instance->get_id () << " " << _default_instance->get_factory_uuid () << "\n"; + } + + context_scim->impl->shared_si = true; + context_scim->impl->si = _default_instance; + + context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); + context_scim->impl->preedit_string.clear (); + context_scim->impl->preedit_attrlist.clear (); + context_scim->impl->preedit_caret = 0; + context_scim->impl->preedit_started = false; + need_cap = true; + need_reset = true; + need_reg = true; + } + } else if (context_scim->impl->shared_si) { + SCIM_DEBUG_FRONTEND(2) << "exit shared input method.\n"; + IMEngineFactoryPointer factory = _backend->get_default_factory (_language, "UTF-8"); + if (!factory.null ()) { + context_scim->impl->si = factory->create_instance ("UTF-8", _instance_count++); + context_scim->impl->preedit_string.clear (); + context_scim->impl->preedit_attrlist.clear (); + context_scim->impl->preedit_caret = 0; + context_scim->impl->preedit_started = false; + attach_instance (context_scim->impl->si); + need_cap = true; + need_reg = true; + context_scim->impl->shared_si = false; + SCIM_DEBUG_FRONTEND(2) << "create new instance: " << context_scim->impl->si->get_id () << " " << context_scim->impl->si->get_factory_uuid () << "\n"; + } + } + + context_scim->impl->si->set_frontend_data (static_cast (context_scim)); + + if (need_reg) _panel_client.register_input_context (context_scim->id, context_scim->impl->si->get_factory_uuid ()); + if (need_cap) set_ic_capabilities (context_scim); + if (need_reset) context_scim->impl->si->reset (); + + panel_req_focus_in (context_scim); +// panel_req_update_screen (context_scim); + panel_req_update_spot_location (context_scim); + panel_req_update_factory_info (context_scim); + + if (context_scim->impl->is_on) { + _panel_client.turn_on (context_scim->id); +// _panel_client.hide_preedit_string (context_scim->id); +// _panel_client.hide_aux_string (context_scim->id); +// _panel_client.hide_lookup_table (context_scim->id); + context_scim->impl->si->focus_in (); + } else { + _panel_client.turn_off (context_scim->id); + } + + if (!context_scim->impl->is_on) + turn_on_ic (context_scim); + + _panel_client.send (); + } + + // Get theme color for preedit background color +/* if (_theme_color != NULL) { + gdk_color_free (_theme_color); + _theme_color = NULL; + }*/ + + /* + if (_theme_color == NULL) + { + GtkWidget *temp_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_realize (temp_window); + gtk_widget_style_get (temp_window, "theme-color", &_theme_color, NULL); + if (GTK_IS_WIDGET (temp_window)) + gtk_widget_destroy (temp_window); + } + */ + + print_time ("exit gtk_im_context_scim_focus_in"); +} + +/** + * gtk_im_context_scim_focus_out: + * @context: a #GtkIMContext + * + * This function will be called by gtk. + * Notify the input method that the widget to which this + * input context corresponds has lost focus. The input method + * may, for example, change the displayed feedback or reset the contexts + * state to reflect this change. + **/ +static void +gtk_im_context_scim_focus_out (GtkIMContext *context) +{ + print_time ("enter gtk_im_context_scim_focus_out"); + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); + + if (context_scim) + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_focus_out(" << context_scim->id << ")...\n"; + + if (_snooper_installed) { + SCIM_DEBUG_FRONTEND(2) << "Remove key snooper.\n"; + gtk_key_snooper_remove (_snooper_id); + _snooper_installed = false; + } + + if (context_scim && context_scim->impl && context_scim == _focused_ic) { + + WideString wstr = context_scim->impl->preedit_string; + + //sehwan added + if (context_scim->impl->need_commit_preedit) + { + panel_slot_hide_preedit_string (context_scim->id); + + if (wstr.length ()) + g_signal_emit_by_name (context_scim, "commit", utf8_wcstombs (wstr).c_str ()); + + _panel_client.prepare (context_scim->id); + _panel_client.reset_input_context (context_scim->id); + _panel_client.send (); + } + + _panel_client.prepare (context_scim->id); + context_scim->impl->si->focus_out (); + context_scim->impl->si->reset (); + //if (context_scim->impl->shared_si) context_scim->impl->si->reset (); + _panel_client.focus_out (context_scim->id); + _panel_client.send (); + _focused_ic = 0; + } + print_time ("exit gtk_im_context_scim_focus_out"); +} + +/** + * gtk_im_context_scim_set_cursor_location: + * @context: a #GtkIMContext + * @area: new location + * + * This function will be called gtk. + * Notify the input method that a change in cursor + * position has been made. The location is relative to the client + * window. + **/ +static void +gtk_im_context_scim_set_cursor_location (GtkIMContext *context, + GdkRectangle *area) +{ + print_time ("enter gtk_im_context_scim_set_cursor_location"); + SCIM_DEBUG_FRONTEND(4) << "gtk_im_context_scim_set_cursor_location...\n"; + + gint x, y; + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); +#ifdef USING_ISF_MAINWINDOW_AUTOSCROLL + gtk_ise_set_cursor_location (area); +#endif + ISF_PROF_DEBUG("last message"); +#if 1 + if (context_scim && context_scim->impl && context_scim->impl->client_window && context_scim == _focused_ic) { + // Don't update spot location while updating preedit string. + if (context_scim->impl->preedit_updating) + return; + + gdk_window_get_origin(context_scim->impl->client_window, &x, &y); + if (context_scim->impl->cursor_x != x + area->x + area->width || + context_scim->impl->cursor_y != y + area->y + area->height) { + context_scim->impl->cursor_x = x + area->x + area->width; + context_scim->impl->cursor_y = y + area->y + area->height; + context_scim->impl->cursor_top_y = y + area->y; +// if (area->y > 0) +// context_scim->impl->cursor_top_y = y + area->y - 4; + + _panel_client.prepare (context_scim->id); + panel_req_update_spot_location (context_scim); + _panel_client.send (); + SCIM_DEBUG_FRONTEND(2) << "new cursor location = " << context_scim->impl->cursor_x << "," << context_scim->impl->cursor_y << "\n"; + } + } +#endif + print_time ("exit gtk_im_context_scim_set_cursor_location"); +} + +/** + * gtk_im_context_scim_set_use_preedit: + * @context: a #GtkIMContext + * @area: new location + * + * This function will be called by gtk. + * Notify the input method that a change in cursor + * position has been made. The location is relative to the client + * window. + **/ +static void +gtk_im_context_scim_set_use_preedit (GtkIMContext *context, + gboolean use_preedit) +{ + print_time ("enter gtk_im_context_scim_set_use_preedit"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_set_use_preedit = " << (use_preedit ? "true" : "false") << "...\n"; + + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); + + if (!_on_the_spot) return; + + if (context_scim && context_scim->impl) { + bool old = context_scim->impl->use_preedit; + context_scim->impl->use_preedit = use_preedit; + if (context_scim == _focused_ic) { + _panel_client.prepare (context_scim->id); + + if (old != use_preedit) + set_ic_capabilities (context_scim); + + if (context_scim->impl->preedit_string.length ()) + slot_show_preedit_string (context_scim->impl->si); + + _panel_client.send (); + } + } + print_time ("exit gtk_im_context_scim_set_use_preedit"); +} + +/** + * gtk_im_context_scim_get_preedit_string: + * @context: a #GtkIMContext + * @str: location to store the retrieved string. The + * string retrieved must be freed with g_free (). + * @attrs: location to store the retrieved attribute list. + * When you are done with this list, you must + * unreference it with pango_attr_list_unref(). + * @cursor_pos: location to store position of cursor (in characters) + * within the preedit string. + * + * This function will be called by gtk + * Retrieve the current preedit string for the input context, + * and a list of attributes to apply to the string. + * This string should be displayed inserted at the insertion + * point. + **/ +static void +gtk_im_context_scim_get_preedit_string (GtkIMContext *context, + gchar **str, + PangoAttrList **attrs, + gint *cursor_pos) +{ + print_time ("enter gtk_im_context_scim_get_preedit_string"); + SCIM_DEBUG_FRONTEND(1) << "gtk_im_context_scim_get_preedit_string...\n"; + + GtkIMContextSCIM *context_scim = GTK_IM_CONTEXT_SCIM (context); + + if (context_scim && context_scim->impl && context_scim->impl->is_on) { + String mbs = utf8_wcstombs (context_scim->impl->preedit_string); + + if (str) { + if (mbs.length ()) + *str = g_strdup (mbs.c_str ()); + else + *str = g_strdup (""); + } + + if (cursor_pos) { + *cursor_pos = context_scim->impl->preedit_caret; + } + + if (attrs) { + *attrs = pango_attr_list_new (); + + if (mbs.length ()) { + guint start_index, end_index; + guint wlen = context_scim->impl->preedit_string.length (); + + PangoAttribute *attr = NULL; + AttributeList::const_iterator i; + //bool underline = false; + bool *attrs_flag = new bool [mbs.length ()]; + + memset (attrs_flag, 0, mbs.length () * sizeof (bool)); + + for (i = context_scim->impl->preedit_attrlist.begin (); + i != context_scim->impl->preedit_attrlist.end (); ++i) { + start_index = i->get_start (); + end_index = i->get_end (); + + if (end_index <= wlen && start_index < end_index && i->get_type () != SCIM_ATTR_DECORATE_NONE) { + start_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_start ()) - mbs.c_str (); + end_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_end ()) - mbs.c_str (); + + if (i->get_type () == SCIM_ATTR_DECORATE) { + if (i->get_value () == scim::SCIM_ATTR_DECORATE_UNDERLINE) { + attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); + if (attr == NULL) + continue; + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (*attrs, attr); + //underline = true; + } else if (i->get_value () == SCIM_ATTR_DECORATE_REVERSE) { + attr = pango_attr_foreground_new (_normal_bg.red, _normal_bg.green, _normal_bg.blue); + if (attr == NULL) + continue; + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (*attrs, attr); + + attr = pango_attr_background_new (_normal_text.red, _normal_text.green, _normal_text.blue); + if (attr == NULL) + continue; + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (*attrs, attr); + } else if (i->get_value () == SCIM_ATTR_DECORATE_HIGHLIGHT) { + attr = pango_attr_foreground_new (_active_text.red, _active_text.green, _active_text.blue); + if (attr == NULL) + continue; + //attr = pango_attr_foreground_new (65535, 65535, 65535); + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (*attrs, attr); + + attr = pango_attr_background_new (_active_bg.red, _active_bg.green, _active_bg.blue); + if (attr == NULL) + continue; + //attr = pango_attr_background_new (32767, 32767, 32767); + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (*attrs, attr); + } + } else if (i->get_type () == SCIM_ATTR_FOREGROUND) { + unsigned int color = i->get_value (); + + attr = pango_attr_foreground_new (SCIM_RGB_COLOR_RED(color) * 256, SCIM_RGB_COLOR_GREEN(color) * 256, SCIM_RGB_COLOR_BLUE(color) * 256); + if (attr == NULL) + continue; + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (*attrs, attr); + } else if (i->get_type () == SCIM_ATTR_BACKGROUND) { + unsigned int color = i->get_value (); + + attr = pango_attr_background_new (SCIM_RGB_COLOR_RED(color) * 256, SCIM_RGB_COLOR_GREEN(color) * 256, SCIM_RGB_COLOR_BLUE(color) * 256); + if (attr == NULL) + continue; + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (*attrs, attr); + } + + // Record which character has attribute. + for (guint pos = start_index; pos < end_index; ++pos) + attrs_flag [pos] = 1; + } + } + + // Add underline for all characters which don't have attribute. + for (guint pos = 0; pos < mbs.length (); ++pos) { + if (!attrs_flag [pos]) { + guint begin_pos = pos; + + while (pos < mbs.length () && !attrs_flag [pos]) + ++pos; + + // use REVERSE style as default + attr = pango_attr_foreground_new (_normal_bg.red, _normal_bg.green, _normal_bg.blue); + if (attr == NULL) + continue; + attr->start_index = begin_pos; + attr->end_index = pos; + pango_attr_list_insert (*attrs, attr); + + attr = pango_attr_background_new (_normal_text.red, _normal_text.green, _normal_text.blue); + if (attr == NULL) + continue; + attr->start_index = begin_pos; + attr->end_index = pos; + pango_attr_list_insert (*attrs, attr); + + /* + attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); + attr->start_index = begin_pos; + attr->end_index = pos; + pango_attr_list_insert (*attrs, attr); + */ + } + } + + delete [] attrs_flag; + } + } + } else { + if (str) + *str = g_strdup (""); + + if (cursor_pos) + *cursor_pos = 0; + + if (attrs) + *attrs = pango_attr_list_new (); + } + print_time ("exit gtk_im_context_scim_get_preedit_string"); +} + +static gboolean +gtk_scim_key_snooper (GtkWidget *grab_widget, + GdkEventKey *event, + gpointer data) +{ + SCIM_DEBUG_FRONTEND(3) << "gtk_scim_key_snooper...\n"; + + gboolean ret = FALSE; + + if (_focused_ic && _focused_ic->impl && (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) && !event->send_event) { + _focused_widget = grab_widget; + + KeyEvent key = keyevent_gdk_to_scim (_focused_ic, *event); + + key.mask &= _valid_key_mask; + + key.layout = _keyboard_layout; + + _panel_client.prepare (_focused_ic->id); + + if (!filter_hotkeys (_focused_ic, key)) { + if (!_focused_ic->impl->is_on || !_focused_ic->impl->si->process_key_event (key)) { + SCIM_DEBUG_FRONTEND(3) << "Failed to process: " + << (!_focused_ic->impl->is_on ? "IC is off" : "IC doesn't process") + << ".\n"; + ret = _fallback_instance->process_key_event (key); + } else { + ret = TRUE; + } + } else { + ret = TRUE; + } + + _panel_client.send (); + + _focused_widget = 0; + } else { + SCIM_DEBUG_FRONTEND(3) << "Failed snooper: " + << ((!_focused_ic || !_focused_ic->impl) ? "Invalid focused ic" : + (event->send_event ? "send event is set" : "unknown")) + << "\n"; + } + + return ret; +} + +static void +gtk_im_slave_commit_cb (GtkIMContext *context, + const char *str, + GtkIMContextSCIM *context_scim) +{ + g_return_if_fail(str); + g_signal_emit_by_name(context_scim, "commit", str); +} + +/* Panel Slot functions */ +static void +panel_slot_reload_config (int context) +{ + SCIM_DEBUG_FRONTEND(1) << "panel_slot_reload_config...\n"; + _config->reload (); +} + +static void +panel_slot_exit (int /* context */) +{ + SCIM_DEBUG_FRONTEND(1) << "panel_slot_exit...\n"; + + finalize (); +} + +static void +panel_slot_update_lookup_table_page_size (int context, int page_size) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_update_lookup_table_page_size context=" << context << " page_size=" << page_size << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->update_lookup_table_page_size (page_size); + _panel_client.send (); + } +} + +static void +panel_slot_lookup_table_page_up (int context) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_lookup_table_page_up context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->lookup_table_page_up (); + _panel_client.send (); + } +} + +static void +panel_slot_lookup_table_page_down (int context) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_lookup_table_page_down context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->lookup_table_page_down (); + _panel_client.send (); + } +} + +static void +panel_slot_trigger_property (int context, const String &property) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_trigger_property context=" << context << " property=" << property << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->trigger_property (property); + _panel_client.send (); + } +} + +static void +panel_slot_process_helper_event (int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_process_helper_event context=" << context << " target=" << target_uuid + << " helper=" << helper_uuid << " ic=" << ic << " ic->impl=" << (ic ? ic->impl : 0) << " ic-uuid=" + << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid () : "" ) << "\n"; + if (ic && ic->impl && ic->impl->si->get_factory_uuid () == target_uuid) { + _panel_client.prepare (ic->id); + SCIM_DEBUG_FRONTEND(2) << "call process_helper_event\n"; + ic->impl->si->process_helper_event (helper_uuid, trans); + _panel_client.send (); + } +} + +static void +panel_slot_move_preedit_caret (int context, int caret_pos) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_move_preedit_caret context=" << context << " caret=" << caret_pos << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->move_preedit_caret (caret_pos); + _panel_client.send (); + } +} + +static void +panel_slot_select_candidate (int context, int cand_index) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_select_candidate context=" << context << " candidate=" << cand_index << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + ic->impl->si->select_candidate (cand_index); + _panel_client.send (); + } +} + +static void +panel_slot_process_key_event (int context, const KeyEvent &key) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_process_key_event context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n"; + + if (ic && ic->impl) { + // Just send it to key_snooper and bypass to client directly (because send_event is set to TRUE). + GdkEventKey gdkevent = keyevent_scim_to_gdk (ic, key, FALSE); + gdk_event_put ((GdkEvent *)&gdkevent); + } +} + +static void +panel_slot_commit_string (int context, const WideString &wstr) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_commit_string context=" << context << " str=" << utf8_wcstombs (wstr) << " ic=" << ic << "\n"; + + if (_focused_ic != ic) + return; + + if (ic && ic->impl) + g_signal_emit_by_name (ic, "commit", utf8_wcstombs (wstr).c_str ()); +} + +static void +panel_slot_forward_key_event (int context, const KeyEvent &key) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_forward_key_event context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n"; + + if (ic && ic->impl) { + // Just send it to key_snooper and bypass to client directly (because send_event is set to TRUE). + GdkEventKey gdkevent = keyevent_scim_to_gdk (ic, key, TRUE); + gdk_event_put ((GdkEvent *)&gdkevent); + } +} + +static void +panel_slot_request_help (int context) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_request_help context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + panel_req_show_help (ic); + _panel_client.send (); + } +} + +static void +panel_slot_request_factory_menu (int context) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_request_factory_menu context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) { + _panel_client.prepare (ic->id); + panel_req_show_factory_menu (ic); + _panel_client.send (); + } +} + +static void +panel_slot_change_factory (int context, const String &uuid) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_change_factory context=" << context << " factory=" << uuid << " ic=" << ic << "\n"; + if (ic && ic->impl) { + ic->impl->si->reset (); + _panel_client.prepare (ic->id); + open_specific_factory (ic, uuid); + _panel_client.send (); + } +} + +static void +panel_slot_reset_keyboard_ise (int context) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_reset_keyboard_ise context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) + { + WideString wstr = ic->impl->preedit_string; + if (ic->impl->need_commit_preedit) + { + panel_slot_hide_preedit_string (ic->id); + + if (wstr.length ()) + g_signal_emit_by_name (ic, "commit", utf8_wcstombs (wstr).c_str ()); + } + ic->impl->si->reset (); + } +} + +static void +panel_slot_show_preedit_string (int context) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_show_preedit_string context=" << context << "\n"; + + if (ic && ic->impl) + { + if (!ic->impl->is_on) + ic->impl->is_on = true; + + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + KeyEvent key (0xff, SCIM_KEY_ShiftMask); + + GdkEventKey gdkevent = keyevent_scim_to_gdk (ic, key, TRUE); + + gdk_event_put ((GdkEvent *)&gdkevent); + + g_signal_emit_by_name (_focused_ic, "preedit-start"); + ic->impl->preedit_started = true; + ic->impl->need_commit_preedit = true; + } + } + } +} + +static void +panel_slot_hide_preedit_string (int context) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_hide_preedit_string context=" << context << "\n"; + + if (ic && ic->impl) + { + if (!ic->impl->is_on) + ic->impl->is_on = true; + + bool emit = false; + if (ic->impl->preedit_string.length ()) { + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + ic->impl->preedit_attrlist.clear (); + emit = true; + } + if (ic->impl->use_preedit) { + if (emit) g_signal_emit_by_name (ic, "preedit-changed"); + if (ic->impl->preedit_started) { + g_signal_emit_by_name (ic, "preedit-end"); + ic->impl->preedit_started = false; + ic->impl->need_commit_preedit = false; + } + } + } +} + +static void +panel_slot_update_preedit_string (int context, + const WideString &str, + const AttributeList &attrs) +{ + GtkIMContextSCIM *ic = find_ic (context); + SCIM_DEBUG_FRONTEND(1) << "panel_slot_update_preedit_string context=" << context << "\n"; + + if (ic && ic->impl) + { + if (!ic->impl->is_on) + ic->impl->is_on = true; + + if (ic->impl->preedit_string != str || str.length ()) { + ic->impl->preedit_string = str; + ic->impl->preedit_attrlist = attrs; + + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + g_signal_emit_by_name(_focused_ic, "preedit-start"); + ic->impl->preedit_started = true; + ic->impl->need_commit_preedit = true; + } + ic->impl->preedit_caret = str.length (); + ic->impl->preedit_updating = true; + g_signal_emit_by_name(ic, "preedit-changed"); + ic->impl->preedit_updating = false; + } + } + } +} + +/* Panel Requestion functions. */ +static void +panel_req_update_screen (GtkIMContextSCIM *ic) +{ +#if GDK_MULTIHEAD_SAFE + if (ic->impl->client_window) { + GdkScreen *screen = gdk_drawable_get_screen (GDK_DRAWABLE (ic->impl->client_window)); + if (screen) { + int number = gdk_screen_get_number (screen); + _panel_client.update_screen (ic->id, number); + } + } +#endif +} + +static void +panel_req_show_help (GtkIMContextSCIM *ic) +{ + String help; + + help = String (_("Smart Common Input Method platform ")) + + String (SCIM_VERSION) + + String (_("\n(C) 2002-2005 James Su \n\n")); + + if (ic && ic->impl) { + IMEngineFactoryPointer sf = _backend->get_factory (ic->impl->si->get_factory_uuid ()); + if (sf) { + help += utf8_wcstombs (sf->get_name ()); + help += String (_(":\n\n")); + + help += utf8_wcstombs (sf->get_help ()); + help += String (_("\n\n")); + + help += utf8_wcstombs (sf->get_credits ()); + } + + _panel_client.show_help (ic->id, help); + } +} + +static void +panel_req_show_factory_menu (GtkIMContextSCIM *ic) +{ + std::vector factories; + std::vector menu; + + _backend->get_factories_for_encoding (factories, "UTF-8"); + + for (size_t i = 0; i < factories.size (); ++ i) { + menu.push_back (PanelFactoryInfo ( + factories [i]->get_uuid (), + utf8_wcstombs (factories [i]->get_name ()), + factories [i]->get_language (), + factories [i]->get_icon_file ())); + } + + if (menu.size ()) + _panel_client.show_factory_menu (ic->id, menu); +} + +static void +panel_req_update_factory_info (GtkIMContextSCIM *ic) +{ + if (ic && ic->impl && ic == _focused_ic) { + PanelFactoryInfo info; + if (ic->impl->is_on) { + IMEngineFactoryPointer sf = _backend->get_factory (ic->impl->si->get_factory_uuid ()); + if (sf) + info = PanelFactoryInfo (sf->get_uuid (), utf8_wcstombs (sf->get_name ()), sf->get_language (), sf->get_icon_file ()); + } else { + info = PanelFactoryInfo (String (""), String (_("English/Keyboard")), String ("C"), String (SCIM_KEYBOARD_ICON_FILE)); + } + _panel_client.update_factory_info (ic->id, info); + } +} + +static void +panel_req_focus_in (GtkIMContextSCIM *ic) +{ + _panel_client.focus_in (ic->id, ic->impl->si->get_factory_uuid ()); +} + +static void +panel_req_update_spot_location (GtkIMContextSCIM *ic) +{ + _panel_client.update_spot_location (ic->id, ic->impl->cursor_x, ic->impl->cursor_y, ic->impl->cursor_top_y); +} + + +static bool +filter_hotkeys (GtkIMContextSCIM *ic, const KeyEvent &key) +{ + bool ret = false; + + _frontend_hotkey_matcher.push_key_event (key); + _imengine_hotkey_matcher.push_key_event (key); + + FrontEndHotkeyAction hotkey_action = _frontend_hotkey_matcher.get_match_result (); + + if (hotkey_action == SCIM_FRONTEND_HOTKEY_TRIGGER) { + if (!ic->impl->is_on) + turn_on_ic (ic); + else + turn_off_ic (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON) { + if (!ic->impl->is_on) + turn_on_ic (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF) { + if (ic->impl->is_on) + turn_off_ic (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_NEXT_FACTORY) { + open_next_factory (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY) { + open_previous_factory (ic); + ret = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) { + panel_req_show_factory_menu (ic); + ret = true; + } else if (_imengine_hotkey_matcher.is_matched ()) { + ISEInfo info = _imengine_hotkey_matcher.get_match_result (); + ISE_TYPE type = info.type; + if (type == IMENGINE_T) + open_specific_factory (ic, info.uuid); + else if (type == HELPER_T) + _panel_client.start_helper (ic->id, info.uuid); + ret = true; + } + return ret; +} + +static bool +panel_initialize () +{ + String display_name; + + { +#if GDK_MULTIHEAD_SAFE + const char *p = gdk_display_get_name (gdk_display_get_default ()); +#else + const char *p = getenv ("DISPLAY"); +#endif + if (p) display_name = String (p); + } + + SCIM_DEBUG_FRONTEND(1) << "panel_initialize..\n"; + + if (_panel_client.open_connection (_config->get_name (), display_name) >= 0) { + int fd = _panel_client.get_connection_number (); + _panel_iochannel = g_io_channel_unix_new (fd); + + _panel_iochannel_read_source = g_io_add_watch (_panel_iochannel, G_IO_IN, panel_iochannel_handler, 0); + _panel_iochannel_err_source = g_io_add_watch (_panel_iochannel, G_IO_ERR, panel_iochannel_handler, 0); + _panel_iochannel_hup_source = g_io_add_watch (_panel_iochannel, G_IO_HUP, panel_iochannel_handler, 0); + + SCIM_DEBUG_FRONTEND(2) << " Panel FD= " << fd << "\n"; + + /* + * When the PanelAgent process crash, the application will try restarting and + * connecting the PanelAgent process. + * After it, it will register the previous input contexts to the PanelAgent. + */ + GtkIMContextSCIM *context_scim = _ic_list; + while (context_scim != NULL) { + _panel_client.prepare (context_scim->id); + _panel_client.register_input_context (context_scim->id, context_scim->impl->si->get_factory_uuid ()); + _panel_client.send (); + context_scim = context_scim->next; + } + + if (_focused_ic) { + _panel_client.prepare (_focused_ic->id); + panel_req_focus_in (_focused_ic); + _panel_client.send (); + } + + return true; + } + return false; +} + +static void +panel_finalize () +{ + _panel_client.close_connection (); + + if (_panel_iochannel) { + g_io_channel_unref (_panel_iochannel); + g_source_remove (_panel_iochannel_read_source); + g_source_remove (_panel_iochannel_err_source); + g_source_remove (_panel_iochannel_hup_source); + _panel_iochannel = 0; + _panel_iochannel_read_source = 0; + _panel_iochannel_err_source = 0; + _panel_iochannel_hup_source = 0; + } +} + +static gboolean +panel_iochannel_handler (GIOChannel *source, GIOCondition condition, gpointer user_data) +{ + if (condition == G_IO_IN) { + if (!_panel_client.filter_event ()) { + panel_finalize (); + panel_initialize (); + return (gboolean)FALSE; + } + } else if (condition == G_IO_ERR || condition == G_IO_HUP) { + panel_finalize (); + panel_initialize (); + return (gboolean)FALSE; + } + return (gboolean)TRUE; +} + +static void +turn_on_ic (GtkIMContextSCIM *ic) +{ + if (ic && ic->impl && !ic->impl->is_on) { + ic->impl->is_on = true; + + if (ic == _focused_ic) { + panel_req_focus_in (ic); +// panel_req_update_screen (ic); + panel_req_update_spot_location (ic); + panel_req_update_factory_info (ic); + _panel_client.turn_on (ic->id); +// _panel_client.hide_preedit_string (ic->id); +// _panel_client.hide_aux_string (ic->id); +// _panel_client.hide_lookup_table (ic->id); + ic->impl->si->focus_in (); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { + g_signal_emit_by_name(ic, "preedit-start"); + g_signal_emit_by_name(ic, "preedit-changed"); + ic->impl->preedit_started = true; + } + } +} + +static void +turn_off_ic (GtkIMContextSCIM *ic) +{ + if (ic && ic->impl && ic->impl->is_on) { + ic->impl->is_on = false; + + if (ic == _focused_ic) { + ic->impl->si->focus_out (); + +// panel_req_update_factory_info (ic); + _panel_client.turn_off (ic->id); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { + g_signal_emit_by_name(ic, "preedit-changed"); + g_signal_emit_by_name(ic, "preedit-end"); + ic->impl->preedit_started = false; + } + } +} + +static void +set_ic_capabilities (GtkIMContextSCIM *ic) +{ + if (ic && ic->impl) { + unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES; + + if (!_on_the_spot || !ic->impl->use_preedit) + cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT; + + ic->impl->si->update_client_capabilities (cap); + } +} + +static KeyEvent +keyevent_gdk_to_scim (const GtkIMContextSCIM *ic, const GdkEventKey &gdkevent) +{ + KeyEvent key; + + // Use Key Symbole provided by gtk. + key.code = gdkevent.keyval; + +#ifdef GDK_WINDOWING_X11 + Display *display = 0; + + if (ic && ic->impl && ic->impl->client_window) + display = GDK_WINDOW_XDISPLAY (ic->impl->client_window); + else + display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + + key.mask = scim_x11_keymask_x11_to_scim (display, gdkevent.state); + + // Special treatment for two backslash keys on jp106 keyboard. + if (key.code == SCIM_KEY_backslash) { + int keysym_size = 0; + KeySym *keysyms = XGetKeyboardMapping (display, gdkevent.hardware_keycode, 1, &keysym_size); + if (keysyms != NULL) { + if (keysyms[0] == XK_backslash && + (keysym_size > 1 && keysyms[1] == XK_underscore)) + key.mask |= SCIM_KEY_QuirkKanaRoMask; + XFree (keysyms); + } + } +#else + if (gdkevent.state & GDK_SHIFT_MASK) key.mask |=SCIM_KEY_ShiftMask; + if (gdkevent.state & GDK_LOCK_MASK) key.mask |=SCIM_KEY_CapsLockMask; + if (gdkevent.state & GDK_CONTROL_MASK) key.mask |=SCIM_KEY_ControlMask; + if (gdkevent.state & GDK_MOD1_MASK) key.mask |=SCIM_KEY_AltMask; + if (gdkevent.state & GDK_MOD2_MASK) key.mask |=SCIM_KEY_NumLockMask; +#endif + + if (gdkevent.type == GDK_KEY_RELEASE) key.mask |= SCIM_KEY_ReleaseMask; + + return key; +} + +static GdkKeymap * +get_gdk_keymap (GdkWindow *window) +{ + GdkKeymap *keymap = NULL; + +#if GDK_MULTIHEAD_SAFE + if (window) + keymap = gdk_keymap_get_for_display (gdk_drawable_get_display (window)); + else +#endif + keymap = gdk_keymap_get_default (); + + return keymap; +} + +static guint32 +get_time (void) +{ + int tint; + struct timeval tv; + struct timezone tz; /* is not used since ages */ + gettimeofday (&tv, &tz); + tint = (int) tv.tv_sec * 1000; + tint = tint / 1000 * 1000; + tint = tint + tv.tv_usec / 1000; + return ((guint32) tint); +} + +static GdkEventKey +keyevent_scim_to_gdk (const GtkIMContextSCIM *ic, + const KeyEvent &scimkey, gboolean send_event) +{ + GdkEventKey gdkevent; + +#ifdef GDK_WINDOWING_X11 + Display *display = 0; + + if (ic && ic->impl && ic->impl->client_window) + display = GDK_WINDOW_XDISPLAY (ic->impl->client_window); + else + display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + + gdkevent.state = scim_x11_keymask_scim_to_x11 (display, scimkey.mask); +#else + gdkevent.state = 0; + if (scimkey.is_shift_down ()) gdkevent.state |= GDK_SHIFT_MASK; + if (scimkey.is_caps_lock_down ()) gdkevent.state |= GDK_LOCK_MASK; + if (scimkey.is_control_down ()) gdkevent.state |= GDK_CONTROL_MASK; + if (scimkey.is_alt_down ()) gdkevent.state |= GDK_MOD1_MASK; + if (scimkey.is_num_lock_down ()) gdkevent.state |= GDK_MOD2_MASK; +#endif + + if (scimkey.is_key_release ()) gdkevent.state |= GDK_RELEASE_MASK; + + gdkevent.type = (scimkey.is_key_release () ? GDK_KEY_RELEASE : GDK_KEY_PRESS); + gdkevent.window = ((ic && ic->impl) ? ic->impl->client_window : 0); + gdkevent.send_event = send_event; + gdkevent.time = get_time (); + gdkevent.keyval = scimkey.code; + gdkevent.length = 0; + gdkevent.string = 0; + gdkevent.is_modifier = 0; + + GdkKeymap *keymap = get_gdk_keymap (gdkevent.window); + + GdkKeymapKey *keys = NULL; + gint n_keys; + + if (gdk_keymap_get_entries_for_keyval (keymap, gdkevent.keyval, &keys, &n_keys)) { + gdkevent.hardware_keycode = keys [0].keycode; + gdkevent.group = keys [0].group; + } else { + gdkevent.hardware_keycode = 0; + gdkevent.group = 0; + } + + if (keys) g_free (keys); + + return gdkevent; +} + +static bool +check_socket_frontend () +{ + SocketAddress address; + SocketClient client; + + uint32 magic; + + address.set_address (scim_get_default_socket_frontend_address ()); + + if (!client.connect (address)) + return false; + + if (!scim_socket_open_connection (magic, + String ("ConnectionTester"), + String ("SocketFrontEnd"), + client, + 1000)) { + return false; + } + + return true; +} + +static void +initialize (void) +{ + std::vector config_list; + std::vector engine_list; + std::vector helper_list; + std::vector load_engine_list; + + std::vector::iterator it; + + std::vector debug_mask_list; + int debug_verbose = 0; + + size_t i; + + bool manual = false; + + bool socket = true; + + String config_module_name = "simple"; + + // Get debug info + { + char *str = NULL; + + str = getenv ("GTK_IM_SCIM_DEBUG_VERBOSE"); + + if (str != NULL) + debug_verbose = atoi (str); + + DebugOutput::set_verbose_level (debug_verbose); + + str = getenv ("GTK_IM_SCIM_DEBUG_MASK"); + + if (str != NULL) { + scim_split_string_list (debug_mask_list, String (str), ','); + if (debug_mask_list.size ()) { + DebugOutput::disable_debug (SCIM_DEBUG_AllMask); + for (i=0; ivalid ()) + _config = _config_module->create_config (); + } + + if (_config.null ()) { + SCIM_DEBUG_FRONTEND(1) << "Config module cannot be loaded, using dummy Config.\n"; + + if (_config_module) delete _config_module; + _config_module = NULL; + + _config = new DummyConfig (); + config_module_name = "dummy"; + } + + // Init colors. + gdk_color_parse ("white", &_normal_bg); + gdk_color_parse ("black", &_normal_text); + gdk_color_parse ("black", &_active_bg); + gdk_color_parse ("white", &_active_text); + + reload_config_callback (_config); + _config->signal_connect_reload (slot (reload_config_callback)); + + // create backend + _backend = new CommonBackEnd (_config, load_engine_list.size () ? load_engine_list : engine_list); + + if (_backend.null ()) { + fprintf (stderr, "GTK IM Module : Cannot create BackEnd Object!\n"); + } else { + _backend->initialize (_config, load_engine_list.size () ? load_engine_list : engine_list, false, false); + _fallback_factory = _backend->get_factory (SCIM_COMPOSE_KEY_FACTORY_UUID); + } + + if (_fallback_factory.null ()) _fallback_factory = new DummyIMEngineFactory (); + + _fallback_instance = _fallback_factory->create_instance (String ("UTF-8"), 0); + _fallback_instance->signal_connect_commit_string (slot (fallback_commit_string_cb)); + + // Attach Panel Client signal. + _panel_client.signal_connect_reload_config (slot (panel_slot_reload_config)); + _panel_client.signal_connect_exit (slot (panel_slot_exit)); + _panel_client.signal_connect_update_lookup_table_page_size (slot (panel_slot_update_lookup_table_page_size)); + _panel_client.signal_connect_lookup_table_page_up (slot (panel_slot_lookup_table_page_up)); + _panel_client.signal_connect_lookup_table_page_down (slot (panel_slot_lookup_table_page_down)); + _panel_client.signal_connect_trigger_property (slot (panel_slot_trigger_property)); + _panel_client.signal_connect_process_helper_event (slot (panel_slot_process_helper_event)); + _panel_client.signal_connect_move_preedit_caret (slot (panel_slot_move_preedit_caret)); + _panel_client.signal_connect_select_candidate (slot (panel_slot_select_candidate)); + _panel_client.signal_connect_process_key_event (slot (panel_slot_process_key_event)); + _panel_client.signal_connect_commit_string (slot (panel_slot_commit_string)); + _panel_client.signal_connect_forward_key_event (slot (panel_slot_forward_key_event)); + _panel_client.signal_connect_request_help (slot (panel_slot_request_help)); + _panel_client.signal_connect_request_factory_menu (slot (panel_slot_request_factory_menu)); + _panel_client.signal_connect_change_factory (slot (panel_slot_change_factory)); + _panel_client.signal_connect_reset_keyboard_ise (slot (panel_slot_reset_keyboard_ise)); + _panel_client.signal_connect_show_preedit_string (slot (panel_slot_show_preedit_string)); + _panel_client.signal_connect_hide_preedit_string (slot (panel_slot_hide_preedit_string)); + _panel_client.signal_connect_update_preedit_string (slot (panel_slot_update_preedit_string)); + + if (!panel_initialize ()) { + fprintf (stderr, "GTK IM Module : Cannot connect to Panel!\n"); + } +} + +static void +finalize (void) +{ + SCIM_DEBUG_FRONTEND(1) << "Finalizing GTK2 IMModule...\n"; + + if (_snooper_installed) { + gtk_key_snooper_remove(_snooper_id); + _snooper_installed=false; + _snooper_id = 0; + } + + // Reset this first so that the shared instance could be released correctly afterwards. + _default_instance.reset (); + + SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n"; + while (_used_ic_impl_list) { + // In case in "shared input method" mode, + // all contexts share only one instance, + // so we need point the reference pointer correctly before finalizing. + _used_ic_impl_list->si->set_frontend_data (static_cast (_used_ic_impl_list->parent)); + gtk_im_context_scim_finalize_partial (_used_ic_impl_list->parent); + } + + delete_all_ic_impl (); + + _fallback_instance.reset (); + _fallback_factory.reset (); + + SCIM_DEBUG_FRONTEND(2) << " Releasing BackEnd...\n"; + _backend.reset (); + + SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n"; + _config.reset (); + + if (_config_module) { + SCIM_DEBUG_FRONTEND(2) << " Deleting _config_module...\n"; + delete _config_module; + _config_module = 0; + } + + _focused_ic = 0; + _focused_widget = 0; + + _scim_initialized = false; + + panel_finalize (); +} + +static void +open_next_factory (GtkIMContextSCIM *ic) +{ + SCIM_DEBUG_FRONTEND(2) << "open_next_factory context=" << ic->id << "\n"; + IMEngineFactoryPointer sf = _backend->get_next_factory ("", "UTF-8", ic->impl->si->get_factory_uuid ()); + + if (!sf.null ()) { + turn_off_ic (ic); + ic->impl->si = sf->create_instance ("UTF-8", ic->impl->si->get_id ()); + ic->impl->si->set_frontend_data (static_cast (ic)); + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + attach_instance (ic->impl->si); + _backend->set_default_factory (_language, sf->get_uuid ()); + _panel_client.register_input_context (ic->id, sf->get_uuid ()); + set_ic_capabilities (ic); + turn_on_ic (ic); + + if (_shared_input_method) { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + } +} + +static void +open_previous_factory (GtkIMContextSCIM *ic) +{ + SCIM_DEBUG_FRONTEND(2) << "open_previous_factory context=" << ic->id << "\n"; + IMEngineFactoryPointer sf = _backend->get_previous_factory ("", "UTF-8", ic->impl->si->get_factory_uuid ()); + + if (!sf.null ()) { + turn_off_ic (ic); + ic->impl->si = sf->create_instance ("UTF-8", ic->impl->si->get_id ()); + ic->impl->si->set_frontend_data (static_cast (ic)); + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + attach_instance (ic->impl->si); + _backend->set_default_factory (_language, sf->get_uuid ()); + _panel_client.register_input_context (ic->id, sf->get_uuid ()); + set_ic_capabilities (ic); + turn_on_ic (ic); + + if (_shared_input_method) { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + } +} + +static void +open_specific_factory (GtkIMContextSCIM *ic, + const String &uuid) +{ + if (!(ic && ic->impl)) + return; + + SCIM_DEBUG_FRONTEND(2) << "open_specific_factory context=" << ic->id << "\n"; + + // The same input method is selected, just turn on the IC. + if (ic->impl->si && ic->impl->si->get_factory_uuid () == uuid) { + turn_on_ic (ic); + return; + } + + IMEngineFactoryPointer sf = _backend->get_factory (uuid); + + if (uuid.length () && !sf.null ()) { + turn_off_ic (ic); + ic->impl->si = sf->create_instance ("UTF-8", ic->impl->si->get_id ()); + ic->impl->si->set_frontend_data (static_cast (ic)); + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + attach_instance (ic->impl->si); + _backend->set_default_factory (_language, sf->get_uuid ()); + _panel_client.register_input_context (ic->id, sf->get_uuid ()); + set_ic_capabilities (ic); + turn_on_ic (ic); + + if (_shared_input_method) { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + } else { + // turn_off_ic comment out panel_req_update_factory_info() + // turn_off_ic (ic); + if (ic && ic->impl && ic->impl->is_on) { + ic->impl->is_on = false; + + if (ic == _focused_ic) { + ic->impl->si->focus_out (); + + panel_req_update_factory_info (ic); + _panel_client.turn_off (ic->id); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { + g_signal_emit_by_name(ic, "preedit-changed"); + g_signal_emit_by_name(ic, "preedit-end"); + ic->impl->preedit_started = false; + } + } + } +} + +static void +attach_instance (const IMEngineInstancePointer &si) +{ + si->signal_connect_show_preedit_string ( + slot (slot_show_preedit_string)); + si->signal_connect_show_aux_string ( + slot (slot_show_aux_string)); + si->signal_connect_show_lookup_table ( + slot (slot_show_lookup_table)); + + si->signal_connect_hide_preedit_string ( + slot (slot_hide_preedit_string)); + si->signal_connect_hide_aux_string ( + slot (slot_hide_aux_string)); + si->signal_connect_hide_lookup_table ( + slot (slot_hide_lookup_table)); + + si->signal_connect_update_preedit_caret ( + slot (slot_update_preedit_caret)); + si->signal_connect_update_preedit_string ( + slot (slot_update_preedit_string)); + si->signal_connect_update_aux_string ( + slot (slot_update_aux_string)); + si->signal_connect_update_lookup_table ( + slot (slot_update_lookup_table)); + + si->signal_connect_commit_string ( + slot (slot_commit_string)); + + si->signal_connect_forward_key_event ( + slot (slot_forward_key_event)); + + si->signal_connect_register_properties ( + slot (slot_register_properties)); + + si->signal_connect_update_property ( + slot (slot_update_property)); + + si->signal_connect_beep ( + slot (slot_beep)); + + si->signal_connect_start_helper ( + slot (slot_start_helper)); + + si->signal_connect_stop_helper ( + slot (slot_stop_helper)); + + si->signal_connect_send_helper_event ( + slot (slot_send_helper_event)); + + si->signal_connect_get_surrounding_text ( + slot (slot_get_surrounding_text)); + + si->signal_connect_delete_surrounding_text ( + slot (slot_delete_surrounding_text)); +} + +// Implementation of slot functions +/** + * @brief Show the preedit string area. + * + * The preedit string should be updated by calling + * update_preedit_string before or right after this call. + * + * @param si the IMEngineInstace pointer + */ +static void +slot_show_preedit_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_show_preedit_string...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) { + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + g_signal_emit_by_name (_focused_ic, "preedit-start"); + ic->impl->preedit_started = true; + } + //if (ic->impl->preedit_string.length ()) + // g_signal_emit_by_name (_focused_ic, "preedit-changed"); + } else { + _panel_client.show_preedit_string (ic->id); + } + } +} + +/** + * @brief Show the aux string area. + * + * The aux string should be updated by calling + * update_aux_string before or right after this call. + * + * The aux string can contain any additional information whatever + * the input method engine want. + * + * @param si the IMEngineInstace pointer + */ +static void +slot_show_aux_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_show_aux_string...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.show_aux_string (ic->id); +} + +/** + * @brief Show the lookup table area. + * + * The lookup table should be updated by calling + * update_lookup_table before or right after this call. + * + * @param si the IMEngineInstace pointer + */ +static void +slot_show_lookup_table (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_show_lookup_table...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.show_lookup_table (ic->id); +} + +/** + * @brief Hide the preedit string area. + * + * @param si the IMEngineInstace pointer + */ +static void +slot_hide_preedit_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_hide_preedit_string...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) { + bool emit = false; + if (ic->impl->preedit_string.length ()) { + ic->impl->preedit_string = WideString (); + ic->impl->preedit_caret = 0; + ic->impl->preedit_attrlist.clear (); + emit = true; + } + if (ic->impl->use_preedit) { + if (emit) g_signal_emit_by_name (ic, "preedit-changed"); + if (ic->impl->preedit_started) { + g_signal_emit_by_name (ic, "preedit-end"); + ic->impl->preedit_started = false; + } + } else { + _panel_client.hide_preedit_string (ic->id); + } + } +} + +/** + * @brief Hide the aux string area. + * + * @param si the IMEngineInstace pointer + */ +static void +slot_hide_aux_string (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_hide_aux_string...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.hide_aux_string (ic->id); +} + +/** + * @brief Hide the lookup table area. + * + * @param si the IMEngineInstace pointer + */ +static void +slot_hide_lookup_table (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_hide_lookup_table...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.hide_lookup_table (ic->id); +} + +/** + * @brief Update the preedit caret position in the preedit string. + * + * @param si the IMEngineInstace pointer + * @param caret - the new position of the preedit caret. + */ +static void +slot_update_preedit_caret (IMEngineInstanceBase *si, int caret) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_update_preedit_caret...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret) { + ic->impl->preedit_caret = caret; + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + g_signal_emit_by_name(_focused_ic, "preedit-start"); + ic->impl->preedit_started = true; + } + g_signal_emit_by_name(ic, "preedit-changed"); + } else { + _panel_client.update_preedit_caret (ic->id, caret); + } + } +} + +/** + * @brief Update the content of the preedit string, + * + * @param si the IMEngineInstace pointer + * @param str - the string content + * @param attrs - the string attributes + */ +static void +slot_update_preedit_string (IMEngineInstanceBase *si, + const WideString & str, + const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_update_preedit_string...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic && (ic->impl->preedit_string != str || str.length ())) { + ic->impl->preedit_string = str; + ic->impl->preedit_attrlist = attrs; + if (ic->impl->use_preedit) { + if (!ic->impl->preedit_started) { + g_signal_emit_by_name(_focused_ic, "preedit-start"); + ic->impl->preedit_started = true; + } + ic->impl->preedit_caret = str.length (); + ic->impl->preedit_updating = true; + g_signal_emit_by_name(ic, "preedit-changed"); + ic->impl->preedit_updating = false; + } else { + _panel_client.update_preedit_string (ic->id, str, attrs); + } + } +} + +/** + * @brief Update the content of the aux string, + * + * @param si the IMEngineInstace pointer + * @param str - the string content + * @param attrs - the string attribute + */ +static void +slot_update_aux_string (IMEngineInstanceBase *si, + const WideString & str, + const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_update_aux_string...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_aux_string (ic->id, str, attrs); +} + +/** + * @brief Commit a string to the client application. + * + * The preedit string should be hid before calling + * this method. Otherwise the clients which use + * OnTheSpot input mode will flicker annoyingly. + * + * @param si the IMEngineInstace pointer + * @param str - the string to be committed. + */ +static void +slot_commit_string (IMEngineInstanceBase *si, + const WideString & str) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_commit_string...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic) + g_signal_emit_by_name (ic, "commit", utf8_wcstombs (str).c_str ()); +} + +/** + * @brief Forward a key event to the client application. + * + * @param si the IMEngineInstace pointer + * @param key - the key event to be forwarded. + */ +static void +slot_forward_key_event (IMEngineInstanceBase *si, + const KeyEvent & key) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_forward_key_event...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && _focused_ic == ic) { + GdkEventKey gdkevent = keyevent_scim_to_gdk (ic, key, TRUE); + if (!_fallback_instance->process_key_event (key) && + !gtk_im_context_filter_keypress (GTK_IM_CONTEXT (ic->slave), &gdkevent)) { + + // To avoid timing issue, we need emit the signal directly, rather than put the event into the queue. + if (_focused_widget) { + gboolean result; + g_signal_emit_by_name(_focused_widget, key.is_key_press () ? "key-press-event" : "key-release-event", &gdkevent, &result); + } else { + gdk_event_put ((GdkEvent *) &gdkevent); + } + } + } +} + +/** + * @brief Update the content of the lookup table, + * + * @param si the IMEngineInstace pointer + * @param table - the new LookupTable + */ +static void +slot_update_lookup_table (IMEngineInstanceBase *si, + const LookupTable & table) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_update_lookup_table...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_lookup_table (ic->id, table); +} + +/** + * @brief Register all properties of this IMEngineInstance into the FrontEnd. + * + * The old properties previously registered by other IMEngineInstance will be discarded, + * so for each time focus_in() is called, all properties should be registered + * no matter whether they had been registered before. + * + * @param si the IMEngineInstace pointer + * @param properties the PropertyList contains all of the properties. + */ +static void +slot_register_properties (IMEngineInstanceBase *si, + const PropertyList & properties) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_register_properties...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.register_properties (ic->id, properties); +} + +/** + * @brief Update a registered property. + * + * Update a property which already registered by register_properties () method. + * + * @param si the IMEngineInstace pointer + * @param property the property to be updated. + */ +static void +slot_update_property (IMEngineInstanceBase *si, + const Property & property) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_update_property ...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_property (ic->id, property); +} + +/** + * @brief Generate a short beep. + * + * @param si the IMEngineInstace pointer + */ +static void +slot_beep (IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_beep ...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + gdk_beep (); +} + +/** + * @brief Start a Client Helper process. + * + * @param si the IMEngineInstace pointer + * @param helper_uuid The UUID of the Helper object. + */ +static void +slot_start_helper (IMEngineInstanceBase *si, + const String &helper_uuid) +{ + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + SCIM_DEBUG_FRONTEND(1) << "slot_start_helper helper= " << helper_uuid << " context=" + << (ic ? ic->id : -1) << " ic=" << ic + << " ic-uuid=" << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid () : "") << "...\n"; + + if (ic && ic->impl) + _panel_client.start_helper (ic->id, helper_uuid); +} + +/** + * @brief Stop a Client Helper process which was started by start_helper. + * + * @param si the IMEngineInstace pointer + * @param helper_uuid The UUID of the Helper object. + */ +static void +slot_stop_helper (IMEngineInstanceBase *si, + const String &helper_uuid) +{ + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + SCIM_DEBUG_FRONTEND(1) << "slot_stop_helper helper= " << helper_uuid << " context=" << (ic ? ic->id : -1) << " ic=" << ic << "...\n"; + + if (ic && ic->impl) + _panel_client.stop_helper (ic->id, helper_uuid); +} + +/** + * @brief Send an events transaction to a client helper process. + * + * @param si the IMEngineInstace pointer + * @param helper_uuid The UUID of the Helper object. + * @param trans The transaction which contains events. + */ +static void +slot_send_helper_event (IMEngineInstanceBase *si, + const String &helper_uuid, + const Transaction &trans) +{ + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + SCIM_DEBUG_FRONTEND(1) << "slot_send_helper_event helper= " << helper_uuid << " context=" + << (ic ? ic->id : -1) << " ic=" << ic + << " ic-uuid=" << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid () : "") << "...\n"; + + if (ic && ic->impl) + _panel_client.send_helper_event (ic->id, helper_uuid, trans); +} + +/** + * @brief Retrieves context around the insertion point. + * + * @param si the IMEngineInstace pointer + * @param text location to store the context string around the insertion point. + * @param cursor location to store index of the insertion cursor within @text. + * @param maxlen_before the maxmium length of context string to be retrieved + * before the cursor; -1 means unlimited. + * @param maxlen_after the maxmium length of context string to be retrieved + * after the cursor; -1 means unlimited. + * + * @return true if surrounding text was provided. + */ +static bool +slot_get_surrounding_text (IMEngineInstanceBase *si, + WideString &text, + int &cursor, + int maxlen_before, + int maxlen_after) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_get_surrounding_text ...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) { + gchar *surrounding = NULL; + gint cursor_index; + if (gtk_im_context_get_surrounding (GTK_IM_CONTEXT (_focused_ic), &surrounding, &cursor_index)) { + SCIM_DEBUG_FRONTEND(2) << "Surrounding text: " << surrounding <<"\n"; + SCIM_DEBUG_FRONTEND(2) << "Cursor Index : " << cursor_index <<"\n"; + WideString before (utf8_mbstowcs (String (surrounding, surrounding + cursor_index))); + WideString after (utf8_mbstowcs (String (surrounding + cursor_index))); + if (maxlen_before > 0 && ((unsigned int)maxlen_before) < before.length ()) + before = WideString (before.begin () + (before.length () - maxlen_before), before.end ()); + else if (maxlen_before == 0) before = WideString (); + if (maxlen_after > 0 && ((unsigned int)maxlen_after) < after.length ()) + after = WideString (after.begin (), after.begin () + maxlen_after); + else if (maxlen_after == 0) after = WideString (); + text = before + after; + cursor = before.length (); + return true; + } + } + return false; +} + +/** + * @brief Ask the client to delete characters around the cursor position. + * + * @param si the IMEngineInstace pointer + * @param offset offset from cursor position in chars; + * a negative value means start before the cursor. + * @param len number of characters to delete. + * + * @return true if the signal was handled. + */ +static bool +slot_delete_surrounding_text (IMEngineInstanceBase *si, + int offset, + int len) +{ + SCIM_DEBUG_FRONTEND(1) << "slot_delete_surrounding_text ...\n"; + + GtkIMContextSCIM *ic = static_cast (si->get_frontend_data ()); + + if (ic && ic->impl && _focused_ic == ic) + return gtk_im_context_delete_surrounding (GTK_IM_CONTEXT (_focused_ic), offset, len); + return false; +} + +static void +reload_config_callback (const ConfigPointer &config) +{ + SCIM_DEBUG_FRONTEND(1) << "reload_config_callback...\n"; + + _frontend_hotkey_matcher.load_hotkeys (config); + _imengine_hotkey_matcher.load_hotkeys (config); + + KeyEvent key; + + scim_string_to_key (key, + config->read (String (SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK), + String ("Shift+Control+Alt+Lock"))); + + _valid_key_mask = (key.mask > 0)?(key.mask):0xFFFF; + _valid_key_mask |= SCIM_KEY_ReleaseMask; + // Special treatment for two backslash keys on jp106 keyboard. + _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask; + + _on_the_spot = config->read (String (SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot); + _shared_input_method = config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method); + _use_key_snooper = config->read (String (SCIM_CONFIG_FRONTEND_GTK_IMMODULE_USE_KEY_SNOOPER), _use_key_snooper); + + // Get keyboard layout setting + // Flush the global config first, in order to load the new configs from disk. + scim_global_config_flush (); + + _keyboard_layout = scim_get_default_keyboard_layout (); +} + +static void +fallback_commit_string_cb (IMEngineInstanceBase *si, + const WideString &str) +{ + if (_focused_ic && _focused_ic->impl) + g_signal_emit_by_name (_focused_ic, "commit", utf8_wcstombs (str).c_str ()); +} + +/* +vi:ts=4:expandtab:nowrap +*/ diff --git a/ism/extras/gtk2_immodule/gtkimcontextscim.h b/ism/extras/gtk2_immodule/gtkimcontextscim.h new file mode 100644 index 0000000..4b2bcf3 --- /dev/null +++ b/ism/extras/gtk2_immodule/gtkimcontextscim.h @@ -0,0 +1,68 @@ +/** @file gtkimcontextscim.h + * @brief immodule for GTK2. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Implement GTK context auto-restore when PanelAgent is crashed + * 2. Add new interface APIs for helper ISE + * a. panel_slot_reset_keyboard_ise () + * b. panel_slot_show_preedit_string (), panel_slot_hide_preedit_string () and panel_slot_update_preedit_string () + * + * $Id: gtkimcontextscim.h,v 1.12 2005/06/27 15:31:49 suzhe Exp $ + */ + +#ifndef __GTK_IM_CONTEXT_SCIM_H__ +#define __GTK_IM_CONTEXT_SCIM_H__ + +#include + +typedef struct _GtkIMContextSCIM GtkIMContextSCIM; +typedef struct _GtkIMContextSCIMClass GtkIMContextSCIMClass; +typedef struct _GtkIMContextSCIMImpl GtkIMContextSCIMImpl; + +struct _GtkIMContextSCIM +{ + GtkIMContext object; + GtkIMContext *slave; + + GtkIMContextSCIMImpl *impl; + + int id; /* Input Context id*/ + struct _GtkIMContextSCIM *next; +}; + +struct _GtkIMContextSCIMClass +{ + GtkIMContextClass parent_class; +}; + +GtkIMContext *gtk_im_context_scim_new (void); + +void gtk_im_context_scim_register_type (GTypeModule *type_module); +void gtk_im_context_scim_shutdown (void); + +#endif /* __GTK_IM_CONTEXT_SCIM_H__ */ diff --git a/ism/extras/gtk2_immodule/im-scim.version-script b/ism/extras/gtk2_immodule/im-scim.version-script new file mode 100755 index 0000000..db36cf0 --- /dev/null +++ b/ism/extras/gtk2_immodule/im-scim.version-script @@ -0,0 +1,16 @@ +IM_SCIM_1.0 { + global: + extern "C" { + im_module_init; + im_module_create; + im_module_list; + im_module_exit; + }; + + local: + extern "C++" { + __gnu_cxx::*; + std::*; + *std::*_S_construct*; + }; +}; diff --git a/ism/extras/gtk2_immodule/imscim.cpp b/ism/extras/gtk2_immodule/imscim.cpp new file mode 100644 index 0000000..1b1745d --- /dev/null +++ b/ism/extras/gtk2_immodule/imscim.cpp @@ -0,0 +1,80 @@ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include "gtkimcontextscim.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static const GtkIMContextInfo scim_info = { + "scim", /* ID */ + "Input Service Framework(It has been derived by SCIM)", /* Human readable name */ + "scim", /* Translation domain */ + SCIM_LOCALEDIR, /* Dir for bindtextdomain (not strictly needed for "gtk+") */ + "en:ja:ko:zh" /* Languages for which this module is the default */ +}; + +static const GtkIMContextInfo *info_list[] = { + &scim_info +}; + +void +im_module_init (GTypeModule *type_module) +{ + gtk_im_context_scim_register_type (type_module); +} + +void +im_module_exit (void) +{ + gtk_im_context_scim_shutdown (); +} + +void +im_module_list (const GtkIMContextInfo ***contexts, + int *n_contexts) +{ + *contexts = info_list; + *n_contexts = G_N_ELEMENTS (info_list); +} + +GtkIMContext * +im_module_create (const gchar *context_id) +{ + if (strcmp (context_id, "scim") == 0) + return gtk_im_context_scim_new (); + else + return NULL; +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + diff --git a/ism/extras/gtk_panel/Makefile.am b/ism/extras/gtk_panel/Makefile.am new file mode 100644 index 0000000..d9f60d1 --- /dev/null +++ b/ism/extras/gtk_panel/Makefile.am @@ -0,0 +1,55 @@ +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/data \ + -I$(top_srcdir)/ism/utils \ + -I$(includedir) \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" + +noinst_HEADERS = scim_setup_module.h \ + isf_ise_setup_win.h \ + isf_help_win.h \ + isf_setup_win.h \ + isf_lang_win.h \ + isf_setup_utility.h + +if SCIM_BUILD_PANEL_GTK +CONFIG_SCIM_PANEL_GTK = scim-panel-gtk +endif + +bin_PROGRAMS = $(CONFIG_SCIM_PANEL_GTK) + +scim_panel_gtk_SOURCES = scim_panel_gtk.cpp \ + isf_ise_setup_win.cpp \ + scim_setup_module.cpp \ + isf_help_win.cpp \ + isf_setup_win.cpp \ + isf_lang_win.cpp \ + isf_setup_utility.cpp + +scim_panel_gtk_LDFLAGS = @LTLIBINTL@ -rpath $(libdir) + +if ISF_BUILD_WITH_GCONF +scim_panel_gtk_CXXFLAGS = @GTK2_CFLAGS@ @GTHREAD2_CFLAGS@ @GCONF_CFLAGS@ +scim_panel_gtk_LDADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la \ + $(top_builddir)/ism/utils/libscim-gtkutils@SCIM_EPOCH@.la \ + -lgthread-2.0 -lphonestatus -lnoti \ + @GTK2_LIBS@ @GTHREAD2_LIBS@ @GCONF_LIBS@ @X_LIBS@ +else +scim_panel_gtk_CXXFLAGS = @GTK2_CFLAGS@ @GTHREAD2_CFLAGS@ +scim_panel_gtk_LDADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la \ + $(top_builddir)/ism/utils/libscim-gtkutils@SCIM_EPOCH@.la \ + -lgthread-2.0 @GTK2_LIBS@ @GTHREAD2_LIBS@ @X_LIBS@ +endif + diff --git a/ism/extras/gtk_panel/isf_help_win.cpp b/ism/extras/gtk_panel/isf_help_win.cpp new file mode 100644 index 0000000..41492d1 --- /dev/null +++ b/ism/extras/gtk_panel/isf_help_win.cpp @@ -0,0 +1,127 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include "isf_help_win.h" + +static GtkWidget *_main_window = 0; +static GtkWidget *_content_box = 0; +static GtkWidget *_help_label = 0; +static GtkWidget *_form = 0; + + +extern int _screen_width; +extern float _width_rate; +extern float _height_rate; + +ISFHelpWin::ISFHelpWin () +{ +#if HAVE_GCONF + if (!_main_window) { + _main_window = gtk_main_window_new (GTK_WIN_STYLE_DEFAULT); + gtk_main_window_set_title_style (GTK_MAIN_WINDOW (_main_window), GTK_WIN_TITLE_STYLE_TEXT_ICON); + + _form = gtk_form_new (TRUE); + gtk_form_set_title (GTK_FORM (_form), "Help"); + GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (_form), scroll); + + _content_box = gtk_vbox_new (false, 0); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), _content_box); + +#ifdef USING_ISF_SWITCH_BUTTON + GtkWidget *softkey = GTK_WIDGET (gtk_form_get_softkey_bar (GTK_FORM (_form))); + gtk_softkey_bar_use_ise_switch (GTK_SOFTKEY_BAR (softkey), false); + gtk_softkey_bar_set_softkey (GTK_SOFTKEY_BAR (softkey), SOFTKEY4, + "Exit", NULL, + (SoftkeyActionType) SOFTKEY_CALLBACK, + (gpointer) (on_isf_help_back_callback), + (gpointer) this); +#else + gtk_form_add_softkey(GTK_FORM(_form), "Exit", NULL, SOFTKEY_CALLBACK, (void *)on_isf_help_back_callback, NULL); + +#endif + + gtk_main_window_add_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (_form)); + gtk_main_window_set_current_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (_form)); + gtk_widget_show_all (_form); + } +#endif +} + + +ISFHelpWin::~ISFHelpWin () +{ + if (_main_window) { + gtk_widget_destroy (_main_window); + _main_window = 0; + } + if (_content_box) { + gtk_widget_destroy (_content_box); + _content_box = 0; + } + if (_help_label) { + gtk_widget_destroy (_help_label); + _help_label = 0; + } + if (_form) { + gtk_widget_destroy (_form); + _form = 0; + } +} + +void ISFHelpWin::show_help (const char *title, const char *help_info) +{ + if (!_help_label) { + _help_label = gtk_label_new (help_info); + gtk_box_pack_start (GTK_BOX (_content_box), _help_label, true, true, 0); +#if HAVE_GCONF + gtk_form_set_title (GTK_FORM (_form), (gchar *)title); +#endif + gtk_widget_show_all (_form); + gtk_widget_show_all (_main_window); + gtk_window_present (GTK_WINDOW (_main_window)); + gtk_main (); + } else { + gtk_window_present (GTK_WINDOW (_main_window)); + } +} + +void ISFHelpWin::on_isf_help_back_callback (GtkWidget *softkey, + gpointer user_data) +{ + gtk_widget_hide (_main_window); + if (_help_label) { + gtk_widget_destroy (_help_label); + _help_label = 0; + } + gtk_main_quit (); +} + + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_help_win.h b/ism/extras/gtk_panel/isf_help_win.h new file mode 100644 index 0000000..7edccbf --- /dev/null +++ b/ism/extras/gtk_panel/isf_help_win.h @@ -0,0 +1,50 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_HELP_WIN_H +#define __ISF_HELP_WIN_H + +#include +#include "scim_private.h" +#include "scim.h" + +using namespace scim; + +class ISFHelpWin +{ +public: + ISFHelpWin (); + ~ISFHelpWin (); + + void show_help (const char *title, const char *help_info); +private: + static void on_isf_help_back_callback (GtkWidget *softkey, + gpointer user_data); +}; + +#endif // __ISF_HELP_WIN_H + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_ise_setup_win.cpp b/ism/extras/gtk_panel/isf_ise_setup_win.cpp new file mode 100644 index 0000000..dbe001c --- /dev/null +++ b/ism/extras/gtk_panel/isf_ise_setup_win.cpp @@ -0,0 +1,226 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_PANEL_AGENT + + +#include +#include +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "scim_setup_module.h" +#include "isf_setup_utility.h" +#include "isf_ise_setup_win.h" + + +static gboolean _is_module_running = false; +static GtkWidget *_main_window = 0; +static GtkWidget *_work_area = 0; +static GtkWidget *_current_widget = 0; +static SetupModule *_current_module = 0; +static ConfigPointer _config; + +extern PanelAgent *_panel_agent; +extern int _screen_width; +extern float _width_rate; +extern float _height_rate; + +SetupUI::SetupUI (const ConfigPointer & config) +{ + _config = config; + + create_main_ui (); +} + +SetupUI::~SetupUI () +{ + if (_current_widget) { + gtk_widget_destroy (_current_widget); + _current_widget = 0; + } + if (_work_area) { + gtk_widget_destroy (_work_area); + _work_area = 0; + } + if (_main_window) { + gtk_widget_destroy (_main_window); + _main_window = 0; + } +} + +bool SetupUI::add_module (SetupModule *module) +{ + if (_is_module_running) { + std::cerr << "One ISE Setup is running...\n"; + return false; + } else if (!module || !module->valid ()) { + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (_main_window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + _("No setup for this ISE!\n")); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return false; + } + + _is_module_running = true; + + GtkWidget *module_widget = module->create_ui (); + String module_label = module->get_name (); + String module_category = module->get_category (); + + if (!module_widget || !module_label.length () || !module_category.length ()) + return false; + + if (!_config.null ()) { + module->load_config (_config); + } + + _current_widget = module_widget; + _current_module = module; + + gtk_box_pack_start (GTK_BOX (_work_area), _current_widget, TRUE, TRUE, 0); + gtk_widget_show_all (_work_area); + run (); + + return true; +} + +void SetupUI::run (void) +{ + if (_main_window) { + gtk_widget_show_all (_main_window); + gtk_window_present (GTK_WINDOW (_main_window)); + } + gtk_main (); + + SCIM_DEBUG_MAIN(1) << "exit SetupUI::run ()\n"; +} + +void SetupUI::create_main_ui (void) +{ +#if HAVE_GCONF + if (!_main_window) { + _main_window = gtk_main_window_new (GTK_WIN_STYLE_DEFAULT); + gtk_main_window_set_title_style (GTK_MAIN_WINDOW (_main_window), GTK_WIN_TITLE_STYLE_TEXT_ICON); + + GtkWidget *form = gtk_form_new (TRUE); + gtk_form_set_title (GTK_FORM (form), "ISE Option"); + gtk_widget_show (form); + + GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (form), scroll); + gtk_widget_show (scroll); + + _work_area = gtk_vbox_new (false, 0); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), _work_area); + +#ifdef USING_ISF_SWITCH_BUTTON + GtkWidget *softkey = GTK_WIDGET (gtk_form_get_softkey_bar (GTK_FORM (form))); + + gtk_softkey_bar_use_ise_switch (GTK_SOFTKEY_BAR(softkey), false); + + gtk_softkey_bar_set_softkey (GTK_SOFTKEY_BAR (softkey), SOFTKEY1, + "Save", NULL, + (SoftkeyActionType) SOFTKEY_CALLBACK, + (gpointer) (softkey_ok_clicked_cb), + (gpointer) this); + + gtk_softkey_bar_set_softkey (GTK_SOFTKEY_BAR (softkey), SOFTKEY4, + "Exit", NULL, + (SoftkeyActionType) SOFTKEY_CALLBACK, + (gpointer) (softkey_exit_clicked_cb), + (gpointer) this); +#else + gtk_form_add_softkey (GTK_FORM (form), "Save", NULL, SOFTKEY_CALLBACK, (void *)softkey_ok_clicked_cb, NULL); + gtk_form_add_softkey (GTK_FORM (form), "Exit", NULL, SOFTKEY_CALLBACK, (void *)softkey_exit_clicked_cb, NULL); + +#endif + + gtk_main_window_add_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (form)); + gtk_main_window_set_current_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (form)); + + g_signal_connect (G_OBJECT (_main_window), "delete_event", G_CALLBACK (hide), this); + } +#endif +} + + +void SetupUI::save_and_exit (gpointer user_data) +{ + _current_module->save_config (_config); + _config->flush (); + + struct timeval start, end; + int timeuse = 0; + + gettimeofday (&start, NULL); + + _config->reload (); + _panel_agent->reload_config (); + gettimeofday (&end, NULL); + timeuse = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; + printf (mzc_red "ISF config reload time : %d usec" mzc_normal ".\n", timeuse); + + hide (user_data); +} + +void SetupUI::exit_without_save (gpointer user_data) +{ + hide (user_data); +} + +void SetupUI::softkey_ok_clicked_cb (GtkWidget * softkey, gpointer user_data) +{ + save_and_exit (user_data); +} + +void SetupUI::softkey_exit_clicked_cb (GtkWidget * softkey, gpointer user_data) +{ + exit_without_save (user_data); +} + + +void SetupUI::hide (gpointer user_data) +{ + _current_module->unload (); + _is_module_running = false; + if (_current_widget) { + gtk_widget_destroy (_current_widget); + _current_widget = 0; + } + gtk_widget_hide (_main_window); + gtk_main_quit (); +} + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_ise_setup_win.h b/ism/extras/gtk_panel/isf_ise_setup_win.h new file mode 100644 index 0000000..7f11ce4 --- /dev/null +++ b/ism/extras/gtk_panel/isf_ise_setup_win.h @@ -0,0 +1,60 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#if !defined (__ISF_ISE_SETUP_WIN_H) +#define __ISF_ISE_SETUP_WIN_H + +#include + +using namespace scim; + +class SetupUI +{ + SetupUI (const SetupUI &); + SetupUI & operator = (const SetupUI &); + +public: + SetupUI (const ConfigPointer & config); + ~SetupUI (); + bool add_module (SetupModule * module); + +private: + void create_main_ui (void); + + void run (void); + + static void save_and_exit (gpointer user_data); + static void exit_without_save (gpointer user_data); + static void softkey_ok_clicked_cb (GtkWidget *softkey, + gpointer user_data); + static void softkey_exit_clicked_cb (GtkWidget *softkey, + gpointer user_data); + static void hide (gpointer usr_data); +}; + +#endif // __ISF_ISE_SETUP_WIN_H + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_lang_win.cpp b/ism/extras/gtk_panel/isf_lang_win.cpp new file mode 100644 index 0000000..135d6f9 --- /dev/null +++ b/ism/extras/gtk_panel/isf_lang_win.cpp @@ -0,0 +1,312 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_EVENT +#define Uses_SCIM_CONFIG_PATH + +#include +#include "scim_private.h" +#include "scim.h" +#include "isf_lang_win.h" +#include "isf_setup_utility.h" + + +enum { + LANG_LIST_ENABLE = 0, + LANG_LIST_NAME, + LANG_LIST_NUM_COLUMS +}; + +extern MapStringVectorSizeT _groups; +extern MapStringVectorString _disabled_ise_map; +extern std::vector _disabled_langs; +extern MapStringVectorString _disabled_ise_map_bak; +extern std::vector _disabled_langs_bak; + +extern gboolean _lang_selected_changed; + +extern int _screen_width; +extern float _width_rate; +extern float _height_rate; + +static GtkWidget *_main_window = 0; +static GtkListStore *_lang_list_store = 0; +static unsigned int _lang_num = 0; + + +static gboolean lang_list_set_enable_func (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + gchar *lang = 0; + gtk_tree_model_get (model, iter, LANG_LIST_NAME, &lang, -1); + + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), String (lang)) ==_disabled_langs.end ()) + gtk_list_store_set (_lang_list_store, iter, LANG_LIST_ENABLE, true, -1); + else + gtk_list_store_set (_lang_list_store, iter, LANG_LIST_ENABLE, false, -1); + if (lang) { + g_free (lang); + lang = 0; + } + + return (gboolean)false; +} + +ISFLangWin::ISFLangWin () +{ +#if HAVE_GCONF + if (!_main_window) { + _main_window = gtk_main_window_new (GTK_WIN_STYLE_DEFAULT); + gtk_main_window_set_title_style (GTK_MAIN_WINDOW (_main_window), GTK_WIN_TITLE_STYLE_TEXT_ICON); + + GtkWidget *form = gtk_form_new (TRUE); + gtk_form_set_title (GTK_FORM (form), "ISF Language"); + + GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (form), scroll); + gtk_widget_show (scroll); + + GtkWidget *isf_lang = create_isf_lang_list_view (); + + gtk_container_add (GTK_CONTAINER (scroll), isf_lang); + gtk_widget_show (isf_lang); + +#ifdef USING_ISF_SWITCH_BUTTON + GtkWidget *softkey = GTK_WIDGET (gtk_form_get_softkey_bar (GTK_FORM (form))); + gtk_softkey_bar_use_ise_switch (GTK_SOFTKEY_BAR (softkey), false); + + gtk_softkey_bar_set_softkey (GTK_SOFTKEY_BAR (softkey), SOFTKEY1, + "Save", NULL, + (SoftkeyActionType) SOFTKEY_CALLBACK, + (gpointer) (isf_lang_save_callback), + (gpointer) NULL); + + gtk_softkey_bar_set_softkey (GTK_SOFTKEY_BAR (softkey), SOFTKEY4, + "Exit", NULL, + (SoftkeyActionType) SOFTKEY_CALLBACK, + (gpointer) (isf_lang_back_callback), + (gpointer) NULL); +#else + gtk_form_add_softkey (GTK_FORM (form), "Save", NULL, SOFTKEY_CALLBACK, (void *)isf_lang_save_callback, NULL); + gtk_form_add_softkey (GTK_FORM (form), "Exit", NULL, SOFTKEY_CALLBACK, (void *)isf_lang_back_callback, NULL); +#endif + + gtk_main_window_add_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (form)); + gtk_main_window_set_current_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (form)); + + gtk_widget_show_all (form); + } +#endif +} + +ISFLangWin::~ISFLangWin () +{ + if (_main_window) { + gtk_widget_destroy (_main_window); + _main_window = 0; + } + if (_lang_list_store) { + delete[] _lang_list_store; + _lang_list_store = 0; + } +} + +void ISFLangWin::show_window (void) +{ + gtk_tree_model_foreach (GTK_TREE_MODEL (_lang_list_store), + lang_list_set_enable_func, + NULL); + + gtk_widget_show_all (_main_window); + gtk_window_present (GTK_WINDOW (_main_window)); + gtk_main (); +} + + +GtkWidget *ISFLangWin::create_isf_lang_list_view (void) +{ + GtkWidget *view = NULL; + + GtkCellRenderer *renderer = NULL; + GtkTreeViewColumn *column = NULL; + + view = gtk_tree_view_new (); + g_object_set (view, "enable-grid-lines", GTK_TREE_VIEW_GRID_LINES_NONE, NULL); + gtk_widget_show (view); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), false); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), false); + + // Enable column + column = gtk_tree_view_column_new (); + renderer = gtk_cell_renderer_toggle_new (); + gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer), false); + gtk_tree_view_column_pack_start (column, renderer, FALSE); + gtk_cell_renderer_set_fixed_size (renderer, (int)(40*_width_rate), (int)(40*_height_rate)); + g_object_set (renderer, "radio", 0, NULL); + g_object_set (renderer, "indicator-size", (gint)(26*(_width_rate < _height_rate ? _width_rate : _height_rate)), NULL); + gtk_tree_view_column_set_attributes (column, renderer, "active", LANG_LIST_ENABLE, NULL); + + g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (on_lang_enable_box_clicked), + (gpointer) view); + + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + // Name column + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Name")); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, "text", LANG_LIST_NAME, NULL); + gtk_cell_renderer_set_fixed_size (renderer, (int) (_screen_width - 40*_width_rate), (int)(40*_height_rate)); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + g_object_set (renderer, "xpad", 4, NULL); + + //gtk_cell_renderer_set_cell_font_size (renderer, GTK_CELL_RENDERER_NORMAL, 22); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + // Create model. + _lang_list_store = gtk_list_store_new (LANG_LIST_NUM_COLUMS, G_TYPE_BOOLEAN, G_TYPE_STRING); + + // Fill the model + GtkTreeIter iter; + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + _lang_num++; + lang_name = scim_get_language_name (it->first); + gtk_list_store_append (_lang_list_store, &iter); + gtk_list_store_set (_lang_list_store, &iter, LANG_LIST_NAME, lang_name.c_str (), -1); + } + + gtk_tree_model_foreach (GTK_TREE_MODEL (_lang_list_store), lang_list_set_enable_func, NULL); + + gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (_lang_list_store)); + + return view; +} + +void ISFLangWin::on_lang_enable_box_clicked (GtkCellRendererToggle *cell, + gchar *arg1, gpointer data) +{ + GtkTreeIter iter; + GtkTreePath *path = 0; + gboolean enable = FALSE; + + std::vector::iterator it; + + _lang_selected_changed = true; + + path = gtk_tree_path_new_from_string (arg1); + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (_lang_list_store), &iter, path)) { + gtk_tree_model_get (GTK_TREE_MODEL (_lang_list_store), &iter, + LANG_LIST_ENABLE, &enable, -1); + + gtk_list_store_set (GTK_LIST_STORE (_lang_list_store), &iter, + LANG_LIST_ENABLE, !enable, -1); + } + + if (path) { + gtk_tree_path_free (path); + path = 0; + } + + gchar *lang = 0; + + gtk_tree_model_get (GTK_TREE_MODEL (_lang_list_store), &iter, + LANG_LIST_NAME, &lang, -1); + String lang_str (lang); + if (lang) { + g_free (lang); + lang = 0; + } + + it = std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_str); + + if (it != _disabled_langs.end ()) + _disabled_langs.erase (it); + else + _disabled_langs.push_back (lang_str); +} + +void ISFLangWin::isf_lang_save_callback (GtkWidget *softkey, + gpointer user_data) +{ + if (_disabled_langs.size ()) { + if (_disabled_langs.size () == _lang_num) { + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (_main_window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + _("At least select one language!\n")); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return; + } + _disabled_langs_bak.clear (); + for (size_t j = 0; j < _disabled_langs.size (); j++) { + _disabled_langs_bak.push_back (_disabled_langs[j]); + } + } + + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DISABLED_LANGS), _disabled_langs); + + std::vector enable_langs; + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + String lang_name; + lang_name = scim_get_language_name (it->first); + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_name) == _disabled_langs.end ()) { + enable_langs.push_back (lang_name); + } + } + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_ISF_DEFAULT_LANGUAGES), enable_langs); + scim_global_config_flush (); + + gtk_widget_hide (_main_window); + gtk_main_quit (); +} + +void ISFLangWin::isf_lang_back_callback (GtkWidget *softkey, + gpointer user_data) +{ + _lang_selected_changed = false; + _disabled_langs.clear (); + if (_disabled_langs_bak.size ()) { + for (size_t j = 0; j < _disabled_langs_bak.size (); j++) { + _disabled_langs.push_back (_disabled_langs_bak[j]); + } + } + + gtk_widget_hide (_main_window); + gtk_main_quit (); +} + + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_lang_win.h b/ism/extras/gtk_panel/isf_lang_win.h new file mode 100644 index 0000000..4e77baf --- /dev/null +++ b/ism/extras/gtk_panel/isf_lang_win.h @@ -0,0 +1,59 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#if !defined (__ISF_LANG_WIN_H) +#define __ISF_LANG_WIN_H + +#include + +using namespace scim; + +class ISFLangWin +{ + ISFLangWin (const ISFLangWin &); + ISFLangWin & operator = (const ISFLangWin &); + +public: + ISFLangWin (); + ~ISFLangWin (); + + void show_window (void); +private: + + GtkWidget *create_isf_lang_list_view (void); + static void on_lang_enable_box_clicked (GtkCellRendererToggle *cell, + gchar *arg1, gpointer data); + static void isf_lang_save_callback (GtkWidget *softkey, + gpointer user_data); + static void isf_lang_back_callback (GtkWidget *softkey, + gpointer user_data); + +}; + +#endif // __ISF_LANG_WIN_H + +/* +vi:ts=4:ai:nowrap:expandtab +*/ + diff --git a/ism/extras/gtk_panel/isf_setup_utility.cpp b/ism/extras/gtk_panel/isf_setup_utility.cpp new file mode 100644 index 0000000..11bf0c1 --- /dev/null +++ b/ism/extras/gtk_panel/isf_setup_utility.cpp @@ -0,0 +1,110 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_PANEL_AGENT + + +#include "isf_setup_utility.h" + +MapStringVectorSizeT _groups; +std::vector < String > _uuids; +std::vector < String > _names; +std::vector < String > _module_names; +std::vector < String > _langs; +std::vector < String > _icons; +std::vector < uint32 > _options; +std::vector _modes; +MapStringString _keyboard_ise_help_map; +MapStringVectorString _disabled_ise_map; +std::vector < String > _disabled_langs; +MapStringVectorString _disabled_ise_map_bak; +std::vector < String > _disabled_langs_bak; +std::vector < String > _isf_app_list; +gboolean _ise_list_changed = false; +gboolean _setup_enable_changed = false; +gboolean _lang_selected_changed = false; + + +void get_all_languages (std::vector &all_langs) +{ + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + all_langs.push_back (lang_name); + } +} + +void get_selected_languages (std::vector &selected_langs) +{ + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_name) == _disabled_langs.end ()) + selected_langs.push_back (lang_name); + } +} + +void get_all_iselist_in_languages (std::vector lang_list, std::vector &all_iselist) +{ + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + + if (std::find (lang_list.begin (), lang_list.end (), lang_name) != lang_list.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + if (std::find (all_iselist.begin (), all_iselist.end (), _names[it->second[i]]) == all_iselist.end ()) + all_iselist.push_back (_names[it->second[i]]); + } + } + } +} + +void get_interested_iselist_in_languages (std::vector lang_list, std::vector &interested) +{ + String lang_name; + String active_app = _isf_app_list [0]; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name_english (it->first); + if (std::find(lang_list.begin(), lang_list.end(), lang_name) != lang_list.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + if (std::find (_disabled_ise_map[active_app].begin (), _disabled_ise_map[active_app].end (), _uuids[it->second[i]]) + ==_disabled_ise_map[active_app].end ()) { + // Protect from add the same ise more than once in case of multiple langs.-->f_show list + if (std::find (interested.begin (), interested.end (), _names[it->second[i]]) == interested.end ()) + interested.push_back (_names[it->second[i]]); + } + } + } + } +} + + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_setup_utility.h b/ism/extras/gtk_panel/isf_setup_utility.h new file mode 100644 index 0000000..4f4e4fb --- /dev/null +++ b/ism/extras/gtk_panel/isf_setup_utility.h @@ -0,0 +1,92 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#if !defined (__ISF_SETUP_UTILITY_H) +#define __ISF_SETUP_UTILITY_H + + +#include "scim.h" +#include "scim_stl_map.h" +#include +#include +//#include /* for include USING_ISF_SWITCH_BUTTON - by jyjeon */ + +using namespace scim; + +#if SCIM_USE_STL_EXT_HASH_MAP +typedef __gnu_cxx::hash_map , scim_hash_string> MapStringVectorSizeT; +typedef __gnu_cxx::hash_map MapStringKeyEventList; +typedef std::map > MapStringVectorString; +typedef std::map MapStringString; +#elif SCIM_USE_STL_HASH_MAP +typedef std::hash_map , scim_hash_string> MapStringVectorSizeT; +typedef std::hash_map MapStringKeyEventList; +typedef std::map > MapStringVectorString; +typedef std::map MapStringString; +#else +typedef std::map > MapStringVectorSizeT; +typedef std::map MapStringKeyEventList; +typedef std::map > MapStringVectorString; +typedef std::map MapStringString; +#endif + + +#define SCIM_UP_ICON_FILE (SCIM_ICONDIR "/up.png") +#define SCIM_DOWN_ICON_FILE (SCIM_ICONDIR "/down.png") +#define SCIM_LEFT_ICON_FILE (SCIM_ICONDIR "/left.png") +#define SCIM_RIGHT_ICON_FILE (SCIM_ICONDIR "/right.png") + +#define ISF_PANEL_BG_FILE (SCIM_ICONDIR "/ISF_panel_bg.png") +#define ISF_ICON_HELP_FILE (SCIM_ICONDIR "/ISF_icon_31_help.png") +#define ISF_ICON_HELP_T_FILE (SCIM_ICONDIR "/ISF_icon_31_help_t.png") +#define ISF_CANDIDATE_BG_FILE (SCIM_ICONDIR "/ISF_candidate_bg.png") +#define ISF_CANDIDATE_DIVIDER_FILE (SCIM_ICONDIR "/ISF_candidate_divider.png") + +#define BASE_SCREEN_WIDTH 240.0 +#define BASE_SCREEN_HEIGHT 400.0 +#define BASE_SOFTKEYBAR_HEIGHT 48.0 +#define BASE_PANEL_WIDTH 230.0 +#define BASE_PANEL_HEIGHT 198.0 + +/*setup button*/ +#define BASE_SETUP_BUTTON_WIDTH 75.0 +#define BASE_SETUP_BUTTON_HEIGHT 31.0 + +/*help button*/ +#define BASE_HELP_ICON_WIDTH 31.0 +#define BASE_HELP_ICON_HEIGHT 31.0 + +//#define USING_ISF_SWITCH_BUTTON + + +void get_all_languages (std::vector &all_langs); +void get_selected_languages (std::vector &selected_langs); +void get_all_iselist_in_languages (std::vector lang_list, std::vector &all_iselist); +void get_interested_iselist_in_languages (std::vector lang_list, std::vector &interested); + +#endif // __ISF_SETUP_UTILITY_H + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_setup_win.cpp b/ism/extras/gtk_panel/isf_setup_win.cpp new file mode 100644 index 0000000..f26937a --- /dev/null +++ b/ism/extras/gtk_panel/isf_setup_win.cpp @@ -0,0 +1,632 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_PANEL_AGENT + + +#include +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "isf_setup_win.h" +#include "isf_setup_utility.h" +#include "scim_setup_module.h" +#include "isf_ise_setup_win.h" +#include "isf_help_win.h" +#include "isf_lang_win.h" + +#define LIST_ICON_SIZE 20 + +enum { + FACTORY_LIST_ENABLE = 0, + FACTORY_LIST_ICON, + FACTORY_LIST_NAME, + FACTORY_LIST_MODULE_NAME, + FACTORY_LIST_UUID, + FACTORY_LIST_TYPE, + FACTORY_LIST_OPTION_PIX, + FACTORY_LIST_HELP_PIX, + FACTORY_LIST_NUM_COLUMNS +}; + +static SetupUI *_setup_ui = 0; +static ISFHelpWin *_ise_help_win = 0; +static ISFLangWin *_isf_lang_win = 0; +static GtkListStore *_app_list_store = 0; +static GtkListStore *_factory_list_store = 0; +static GtkTreePath *_app_combo_default_path = 0; +static GtkWidget *_combo_app = 0; +static GtkWidget *_main_window = 0; +static int _display_selected_items = 0; +static ConfigPointer _config; + +extern std::vector _isf_app_list; +extern MapStringVectorSizeT _groups; +extern std::vector < String > _uuids; +extern std::vector < String > _names; +extern std::vector < String > _module_names; +extern std::vector < String > _langs; +extern std::vector < String > _icons; +extern std::vector _modes; +extern MapStringString _keyboard_ise_help_map; +extern MapStringVectorString _disabled_ise_map; +extern std::vector _disabled_langs; +extern MapStringVectorString _disabled_ise_map_bak; +extern std::vector _disabled_langs_bak; +extern gboolean _lang_selected_changed; +extern gboolean _ise_list_changed; +extern gboolean _setup_enable_changed; +extern int _screen_width; +extern float _width_rate; +extern float _height_rate; + + +ISFSetupWin::ISFSetupWin (const ConfigPointer & config) +{ + _config = config; +#if HAVE_GCONF + if (!_main_window) { + _main_window = gtk_main_window_new (GTK_WIN_STYLE_DEFAULT); + gtk_main_window_set_title_style (GTK_MAIN_WINDOW (_main_window), GTK_WIN_TITLE_STYLE_TEXT_ICON); + + GtkWidget *form = gtk_form_new (TRUE); + gtk_form_set_title (GTK_FORM (form), "ISF Setup"); + + GtkWidget *isf_setup = create_isf_setup_widget (); + + gtk_container_add (GTK_CONTAINER (form), isf_setup); + +#ifdef USING_ISF_SWITCH_BUTTON + GtkWidget *softkey = GTK_WIDGET (gtk_form_get_softkey_bar (GTK_FORM (form))); + gtk_softkey_bar_use_ise_switch (GTK_SOFTKEY_BAR (softkey), false); + + gtk_softkey_bar_set_softkey (GTK_SOFTKEY_BAR (softkey), SOFTKEY1, + "Save", NULL, + (SoftkeyActionType) SOFTKEY_CALLBACK, + (gpointer) (isf_setup_save_callback), + (gpointer) NULL); + + gtk_softkey_bar_set_softkey (GTK_SOFTKEY_BAR (softkey), SOFTKEY4, + "Exit", NULL, + (SoftkeyActionType) SOFTKEY_CALLBACK, + (gpointer) (isf_setup_back_callback), + (gpointer) NULL); +#else + gtk_form_add_softkey (GTK_FORM (form), "Save", NULL, SOFTKEY_CALLBACK, (void *)isf_setup_save_callback, NULL); + gtk_form_add_softkey (GTK_FORM (form), "Exit", NULL, SOFTKEY_CALLBACK, (void *)isf_setup_back_callback, NULL); +#endif + + gtk_main_window_add_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (form)); + gtk_main_window_set_current_form (GTK_MAIN_WINDOW (_main_window), GTK_FORM (form)); + + gtk_widget_show_all (form); + } +#endif +} + +ISFSetupWin::~ISFSetupWin () +{ + if (_main_window) { + gtk_widget_destroy (_main_window); + _main_window = 0; + } + if (_setup_ui) { + delete _setup_ui; + _setup_ui = 0; + } + if (_ise_help_win) { + delete _ise_help_win; + _ise_help_win = 0; + } + if (_isf_lang_win) { + delete _isf_lang_win; + _isf_lang_win = 0; + } +} + +void ISFSetupWin::show_window (void) +{ + GtkTreeIter it; + gtk_tree_model_get_iter (GTK_TREE_MODEL (_app_list_store), &it, + _app_combo_default_path); + gtk_combo_box_set_active_iter ((GtkComboBox *) _combo_app, &it); + + update_factory_list_store (); + + gtk_widget_show_all (_main_window); + gtk_window_present (GTK_WINDOW (_main_window)); + gtk_main (); +} + + +void ISFSetupWin::app_selection_changed_callback (GtkComboBox * combo, gpointer data) +{ + ISFSetupWin *obj = (ISFSetupWin *)data; + obj->update_factory_list_store (); +} + + +void ISFSetupWin::on_language_button_clicked_callback (GtkButton * button, + gpointer user_data) +{ + ISFSetupWin *obj = (ISFSetupWin *)user_data; + + if (!_isf_lang_win) + _isf_lang_win = new ISFLangWin (); + if (_isf_lang_win) + _isf_lang_win->show_window (); + + if (_lang_selected_changed) { + _ise_list_changed = true; + obj->update_factory_list_store (); + } +} + +GtkWidget *ISFSetupWin::create_isf_setup_widget (void) +{ + GtkWidget *language_button = NULL, *hbox = NULL, *vbox = NULL, *scroll = NULL; + + GtkTreeIter iter, it; + GtkCellRenderer *cell = NULL; + + vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox); + gtk_box_pack_start (GTK_BOX (vbox), hbox, false, false, 0); + gtk_widget_set_size_request (hbox, _screen_width, (int)(40*_height_rate)); + gtk_container_set_border_width (GTK_CONTAINER (hbox),(int)( 5*_height_rate)); + + // Create application list combox + _combo_app = gtk_combo_box_new (); + cell = gtk_cell_renderer_text_new (); + _app_list_store = gtk_list_store_new (1, G_TYPE_STRING); + + for (unsigned int i = 0; i < _isf_app_list.size (); i++) { + gtk_list_store_prepend (_app_list_store, &iter); + gtk_list_store_set (_app_list_store, &iter, 0, _isf_app_list[_isf_app_list.size () - i - 1].c_str (), -1); + } + + _app_combo_default_path = gtk_tree_model_get_path (GTK_TREE_MODEL (_app_list_store), &iter); + + gtk_cell_layout_pack_start ((GtkCellLayout *) _combo_app, cell, TRUE); + gtk_cell_layout_set_attributes ((GtkCellLayout *) _combo_app, cell, "text", 0, NULL); + gtk_combo_box_set_model ((GtkComboBox *) _combo_app, (GtkTreeModel *) _app_list_store); + gtk_tree_model_get_iter (GTK_TREE_MODEL (_app_list_store), &it, _app_combo_default_path); + gtk_combo_box_set_active_iter ((GtkComboBox *) _combo_app, &it); +// gtk_widget_show (_combo_app); //hide the app list combox temp + g_signal_connect ((gpointer) _combo_app, "changed", + G_CALLBACK (app_selection_changed_callback), (gpointer)this); + + // Create language button + language_button = gtk_button_new_with_label ("Language"); + GtkStyle *style1 = gtk_rc_get_style (language_button); + GtkWidget *newlabel = gtk_label_new ("Language"); + if (newlabel) { + GtkWidget * old = gtk_bin_get_child (GTK_BIN (language_button)); + if (old) + gtk_container_remove (GTK_CONTAINER (language_button), old); + gtk_container_add (GTK_CONTAINER (language_button), newlabel); + } + if(style1) + { + gtk_widget_modify_font (language_button, style1->font_desc); + } + gtk_widget_show (language_button); + gtk_box_pack_start (GTK_BOX (hbox), language_button, true, true, 0); + g_signal_connect ((gpointer) language_button, "clicked", + G_CALLBACK (on_language_button_clicked_callback), (gpointer)this); + + // Create ISE list view + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (vbox), scroll); + gtk_widget_show (scroll); + + GtkWidget *view = create_factory_list_view (); + create_and_fill_factory_list_store (); + gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (_factory_list_store)); + gtk_container_add (GTK_CONTAINER (scroll), view); + gtk_widget_show (view); + + return vbox; +} + +// Show all ISEs in the view +void ISFSetupWin::create_and_fill_factory_list_store (void) +{ + _factory_list_store = gtk_list_store_new (FACTORY_LIST_NUM_COLUMNS, G_TYPE_BOOLEAN, + GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_INT, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF); + update_factory_list_store (); +} + +void ISFSetupWin::update_factory_list_store (void) +{ + GtkTreeIter iter; + + GdkPixbuf *icon = NULL, *icon2 = NULL; + GtkWidget *pix = NULL, *pix2 = NULL; + + _display_selected_items = 0; + pix = gtk_image_new_from_file (ISE_SETUP_ICON_FILE); + icon = gtk_image_get_pixbuf (GTK_IMAGE (pix)); + pix2 = gtk_image_new_from_file (ISE_HELP_ICON_FILE); + icon2 = gtk_image_get_pixbuf (GTK_IMAGE (pix2)); + + String _app_name = gtk_combo_box_get_active_text ((GtkComboBox *) _combo_app); + + gtk_list_store_clear (_factory_list_store); + std::vector f_show; + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + String lang_name; + lang_name = scim_get_language_name (it->first); + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_name) == _disabled_langs.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + // protect from add the same ise more than once in case of multiple langs.-->f_show list + if (std::find (f_show.begin (), f_show.end (), _uuids[it->second[i]]) == f_show.end ()) { + gtk_list_store_append (_factory_list_store, &iter); + gtk_list_store_set (_factory_list_store, &iter, + FACTORY_LIST_NAME, + _names[it->second[i]].c_str (), + FACTORY_LIST_MODULE_NAME, + _module_names[it->second[i]].c_str (), + FACTORY_LIST_UUID, + _uuids[it->second[i]].c_str (), + FACTORY_LIST_TYPE, (gint)_modes[it->second[i]], + FACTORY_LIST_OPTION_PIX, icon, + FACTORY_LIST_HELP_PIX,icon2, + -1); + f_show.push_back (_uuids[it->second[i]]); + + + if (std::find (_disabled_ise_map[_app_name].begin (), _disabled_ise_map[_app_name].end (), _uuids[it->second[i]]) + ==_disabled_ise_map[_app_name].end ()) { + gtk_list_store_set (_factory_list_store, &iter, FACTORY_LIST_ENABLE, true, -1); + _display_selected_items++; + } else { + gtk_list_store_set (_factory_list_store, &iter, FACTORY_LIST_ENABLE, false, -1); + } + } + } + } + } + + if (icon) { + gdk_pixbuf_unref (icon); + icon = 0; + } + if (icon2) { + gdk_pixbuf_unref (icon2); + icon2 = 0; + } +} + +GtkWidget * ISFSetupWin::create_factory_list_view (void) +{ + GtkCellRenderer* renderer = NULL; + GtkTreeViewColumn* column = NULL; + + GtkWidget *tv = gtk_tree_view_new (); + g_object_set (tv, "enable-grid-lines", GTK_TREE_VIEW_GRID_LINES_NONE, NULL); + column = gtk_tree_view_column_new (); + + //toggle renderer + renderer = gtk_cell_renderer_toggle_new (); + g_object_set (renderer, "activatable", TRUE, NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, FALSE); + gtk_cell_renderer_set_fixed_size (renderer, _screen_width/8, (gint)(40*_height_rate)); + g_object_set (renderer, "xalign", 0.5, NULL); + g_object_set (renderer, "radio", 0, NULL); + g_object_set (renderer, "indicator-size", (gint)(26*(_width_rate < _height_rate ? _width_rate : _height_rate)), NULL); + gtk_tree_view_column_set_attributes (column, renderer, "active", FACTORY_LIST_ENABLE, NULL); + g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (on_factory_enable_box_clicked), (gpointer) NULL); + + // text renderer + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, FALSE); + gtk_tree_view_column_set_attributes (column, renderer, "text", FACTORY_LIST_NAME, NULL); + gtk_cell_renderer_set_fixed_size (renderer, (gint)(_screen_width*5/8), (gint)(40*_height_rate)); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + g_object_set (renderer, "xalign", 0.0, NULL); +#if HAVE_GCONF + gtk_cell_renderer_set_cell_flag (tv, renderer, GTK_CELL_RENDERER_MAINCELL); +#endif + gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); + + // pixbuf render + column = gtk_tree_view_column_new (); + renderer = gtk_cell_renderer_pixbuf_new (); +#if HAVE_GCONF + renderer->cell_type = GTK_CELL_RENDERER_ICONCELL; +#endif + gtk_tree_view_column_pack_start (column, renderer, FALSE); + gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", FACTORY_LIST_HELP_PIX, NULL); + gtk_cell_renderer_set_fixed_size (renderer, _screen_width/11, _screen_width/10); + g_object_set (renderer, "xalign", 0.5, NULL); + g_object_set (renderer, "yalign", 0.5, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); + + // pixbuf render + column = gtk_tree_view_column_new (); + renderer = gtk_cell_renderer_pixbuf_new (); +#if HAVE_GCONF + renderer->cell_type = GTK_CELL_RENDERER_ICONCELL; +#endif + gtk_tree_view_column_pack_start (column, renderer, FALSE); + gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", FACTORY_LIST_OPTION_PIX, NULL); + gtk_cell_renderer_set_fixed_size (renderer, _screen_width/11, _screen_width/10); + g_object_set (renderer, "yalign", 0.5, NULL); + g_object_set (renderer, "xalign", 0.5, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); + +#if HAVE_GCONF + gtk_tree_view_set_special_row_selection_indicator (GTK_TREE_VIEW (tv), TRUE); +#endif + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv), false); + g_signal_connect (GTK_TREE_VIEW (tv), "button_press_event", G_CALLBACK (button_press_cb), this); + gtk_widget_show_all (tv); + + return tv; +} + +gboolean ISFSetupWin::button_press_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + ISFSetupWin *obj = (ISFSetupWin *)data; + GtkTreePath *path = NULL; + GtkTreeModel *model = GTK_TREE_MODEL (_factory_list_store); + GtkTreeIter iter; + gchar *module_name = NULL, *title = NULL; + int type; + int cell_x, cell_y; + + GtkTreeViewColumn *column = NULL; + if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), + (gint)event->x, (gint)event->y, + &path, &column, &cell_x, &cell_y)) + return (gboolean)FALSE; + + if (path != NULL) { + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + gtk_tree_model_get (model, &iter, FACTORY_LIST_MODULE_NAME, + &module_name, FACTORY_LIST_NAME, &title, FACTORY_LIST_TYPE, &type, -1); + + GtkTreeView *tree_view = NULL; + tree_view = GTK_TREE_VIEW (widget); + if (event->window == gtk_tree_view_get_bin_window (tree_view)) { + if (event->type == GDK_BUTTON_PRESS) { + if (column == gtk_tree_view_get_column (tree_view, 1)) { + obj->create_ise_help_main (type, module_name, title); + return (gboolean)TRUE; + } else if (column == gtk_tree_view_get_column (tree_view, 2)) { + obj->create_ise_option_main (module_name); + return (gboolean)TRUE; + } + } + } + } + return (gboolean)FALSE; +} + +void ISFSetupWin::create_ise_option_main (const char *str) +{ + if (!_setup_ui) + _setup_ui = new SetupUI (_config); + if (!_setup_ui) + return; + + String setup_module_name; + setup_module_name = utf8_wcstombs (utf8_mbstowcs (str)) + String ("-imengine-setup"); + + SetupModule *setup_module = new SetupModule (setup_module_name); + + if (setup_module) { + _setup_ui->add_module (setup_module); + delete setup_module; + } +} + + +void ISFSetupWin::create_ise_help_main (gint type, char *name, char *title) +{ + if (!_ise_help_win) + _ise_help_win = new ISFHelpWin (); + if (!_ise_help_win) + return; + + TOOLBAR_MODE_T mode = TOOLBAR_MODE_T (type); + // for mutually exclusive ISEs + if (TOOLBAR_HELPER_MODE == mode) { + String help_filename, help_line; + + if (TOOLBAR_HELPER_MODE == mode) { + help_filename = String (SCIM_MODULE_PATH) + String (SCIM_PATH_DELIM_STRING) + + String (SCIM_BINARY_VERSION) + String (SCIM_PATH_DELIM_STRING) + String ("Helper") + + String (SCIM_PATH_DELIM_STRING) + String (name) + + String (".help"); + } + + std::ifstream helpfile (help_filename.c_str ()); + if (!helpfile) { + std::cerr << "Can't open help file : " << help_filename << "!!!!!!!!!! \n"; + + help_line = String (_("Input Service Framework ")) + + String (_("\n(C) 2008 SAMSUNG")) + + String (_("\n\n Help file is needed!!")); + } else { + /* FIXME -- 256 char per line for now -- */ + char str[256]; + while (helpfile.getline (str, sizeof (str))) { + help_line = help_line + String (str) + String("\n"); + } + helpfile.close (); + } + _ise_help_win->show_help (title, (char *)help_line.c_str ()); + } else { + // FIXME + _ise_help_win->show_help (title, (char *)_keyboard_ise_help_map[String(name)].c_str ()); + } +} + +// Check before back +int ISFSetupWin::get_app_active_ise_number (String app_name) +{ + if (app_name.length () <= 0) + return 0; + + int nCount = 0; + String lang_name; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + lang_name = scim_get_language_name (it->first); + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_name) == _disabled_langs.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + if (std::find (_disabled_ise_map_bak[app_name].begin (), _disabled_ise_map_bak[app_name].end (), _uuids[it->second[i]]) + ==_disabled_ise_map_bak[app_name].end ()) { + nCount++; + } + } + } + } + return nCount; +} + +void ISFSetupWin::isf_setup_save_callback (GtkWidget *softkey, gpointer user_data) +{ + if (_display_selected_items == 0) { + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (_main_window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + _("At least select one ISE!\n")); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return; + } + + for (size_t i = 0; i < _isf_app_list.size (); i++) { + String app = _isf_app_list[i]; + _disabled_ise_map_bak[app].clear (); + if (_disabled_ise_map[app].size ()) { + for (size_t j = 0; j < _disabled_ise_map[app].size (); j++) { + _disabled_ise_map_bak[app].push_back (_disabled_ise_map[app][j]); + } + } + } + + if (_setup_enable_changed) { + for (size_t i = 0; i < _isf_app_list.size (); i++) { + String app = _isf_app_list[i]; + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DISABLED_IMENGINE_FACTORIES + "/") + _isf_app_list[i], _disabled_ise_map[app]); + } + scim_global_config_flush (); + } + gtk_widget_hide (_main_window); + gtk_main_quit (); +} + +void ISFSetupWin::isf_setup_back_callback (GtkWidget *softkey, gpointer user_data) +{ + if (get_app_active_ise_number (_isf_app_list[0]) == 0) { + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (_main_window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + _("Please select ISE, then save.\n")); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return; + } + _setup_enable_changed = false; + for (size_t i = 0; i < _isf_app_list.size (); i++) { + String app = _isf_app_list[i]; + _disabled_ise_map[app].clear (); + if (_disabled_ise_map_bak[app].size ()) { + for (size_t j = 0; j < _disabled_ise_map_bak[app].size (); j++) { + _disabled_ise_map[app].push_back (_disabled_ise_map_bak[app][j]); + } + } + } + + gtk_widget_hide (_main_window); + gtk_main_quit (); +} + +void ISFSetupWin::on_factory_enable_box_clicked (GtkCellRendererToggle *cell, gchar *arg1, gpointer data) +{ + GtkTreePath *path = 0; + GtkTreeIter iter; + gboolean enable; + + std::vector < String >::iterator it; + + _setup_enable_changed = true; + + path = gtk_tree_path_new_from_string (arg1); + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (_factory_list_store), &iter, path)) { + gtk_tree_model_get (GTK_TREE_MODEL (_factory_list_store), &iter, + FACTORY_LIST_ENABLE, &enable, -1); + gtk_list_store_set (GTK_LIST_STORE (_factory_list_store), &iter, + FACTORY_LIST_ENABLE, !enable, -1); + if (enable) + _display_selected_items--; + else + _display_selected_items++; + } + if (path) { + gtk_tree_path_free (path); + path = 0; + } + + gchar *cuuid = 0; + String uuid; + gtk_tree_model_get (GTK_TREE_MODEL (_factory_list_store), + &iter, FACTORY_LIST_UUID, + &cuuid, -1); + uuid = (String)cuuid; + if (cuuid) { + g_free (cuuid); + cuuid = 0; + } + String _app_name = gtk_combo_box_get_active_text ((GtkComboBox *) _combo_app); + it = std::find (_disabled_ise_map[_app_name].begin (), _disabled_ise_map[_app_name].end (), uuid); + + if (it != _disabled_ise_map[_app_name].end ()) + _disabled_ise_map[_app_name].erase (it); + else + _disabled_ise_map[_app_name].push_back (uuid); +} + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/gtk_panel/isf_setup_win.h b/ism/extras/gtk_panel/isf_setup_win.h new file mode 100644 index 0000000..2686cf9 --- /dev/null +++ b/ism/extras/gtk_panel/isf_setup_win.h @@ -0,0 +1,71 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Shuo Liu , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#if !defined (__ISF_SETUP_WIN_H) +#define __ISF_SETUP_WIN_H + +#include + +using namespace scim; + + +#define ISE_SETUP_ICON_FILE (SCIM_ICONDIR "/ISF_icon_option.png") +#define ISE_HELP_ICON_FILE (SCIM_ICONDIR "/ISF_icon_help.png") +#define ISE_SETUP_ICON_T_FILE (SCIM_ICONDIR "/ISF_icon_option_t.png") +#define ISE_HELP_ICON_T_FILE (SCIM_ICONDIR "/ISF_icon_help_t.png") + + +class ISFSetupWin +{ + ISFSetupWin (const ISFSetupWin &); + ISFSetupWin & operator = (const ISFSetupWin &); + +public: + ISFSetupWin (const ConfigPointer & config); + ~ISFSetupWin (); + + void show_window (void); +private: + GtkWidget *create_factory_list_view (void); + GtkWidget *create_isf_setup_widget (void); + void create_and_fill_factory_list_store (void); + void update_factory_list_store (void); + void on_isf_help_back_callback (GtkWidget * softkey, gpointer user_data); + void create_ise_option_main (const char *str); + void create_ise_help_main (gint type, char *name, char *title); + + static gboolean button_press_cb (GtkWidget *widget, GdkEventButton *event, gpointer data); + static int get_app_active_ise_number (String app_name); + static void isf_setup_save_callback (GtkWidget *softkey, gpointer user_data); + static void isf_setup_back_callback (GtkWidget *softkey, gpointer user_data); + static void on_factory_enable_box_clicked (GtkCellRendererToggle *cell, gchar *arg1, gpointer data); + static void app_selection_changed_callback (GtkComboBox *combo, gpointer data); + static void on_language_button_clicked_callback (GtkButton *button, gpointer user_data); +}; + +#endif // __ISF_SETUP_WIN_H + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/extras/gtk_panel/scim_panel_gtk.cpp b/ism/extras/gtk_panel/scim_panel_gtk.cpp new file mode 100644 index 0000000..2a9258c --- /dev/null +++ b/ism/extras/gtk_panel/scim_panel_gtk.cpp @@ -0,0 +1,5033 @@ +/** @file scim_panel_gtk.cpp + */ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Implement new candidate style, include portrait and landscape + * + * $Id: scim_panel_gtk.cpp,v 1.118.2.15 2007/04/11 11:30:31 suzhe Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#undef GDK_WINDOWING_X11 +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include +#include +#include +#include + +#define Uses_C_STDIO +#define Uses_C_STDLIB +#define Uses_SCIM_LOOKUP_TABLE +#define Uses_SCIM_SOCKET +#define Uses_SCIM_TRANSACTION +#define Uses_SCIM_TRANS_COMMANDS +#define Uses_SCIM_CONFIG +#define Uses_SCIM_CONFIG_MODULE +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_DEBUG +#define Uses_SCIM_HELPER +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_PANEL_AGENT + +#define Uses_SCIM_MODULE +#define Uses_SCIM_COMPOSE_KEY +#define Uses_SCIM_CONFIG_BASE +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_HOTKEY +#define Uses_SCIM_FILTER_MANAGER +#define Uses_SCIM_UTILITY + +#include "scim_private.h" +#include "scim.h" +#include "scim_stl_map.h" +#include "scimstringview.h" + +#if HAVE_GCONF +#include +#include +#include +#include +#include "limo-event-delivery.h" +#endif + +#include "scim_setup_module.h" +#include "isf_setup_utility.h" +#include "isf_help_win.h" +#include "isf_setup_win.h" + +using namespace scim; + +#include "icons/up.xpm" +#include "icons/down.xpm" +#include "icons/left.xpm" +#include "icons/right.xpm" + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of macro. +///////////////////////////////////////////////////////////////////////////// +#define MAX_FONT_STR_SIZE 200 +#define FONT_SIZE_OF_CANDIDATE_WIDGET change_screen_resolution_P_H_RATE(11) + +#define SCIM_CONFIG_PANEL_GTK_FONT "/Panel/Gtk/Font" +#define SCIM_CONFIG_PANEL_GTK_COLOR_NORMAL_BG "/Panel/Gtk/Color/NormalBackground" +#define SCIM_CONFIG_PANEL_GTK_COLOR_ACTIVE_BG "/Panel/Gtk/Color/ActiveBackground" +#define SCIM_CONFIG_PANEL_GTK_COLOR_NORMAL_TEXT "/Panel/Gtk/Color/NormalText" +#define SCIM_CONFIG_PANEL_GTK_COLOR_ACTIVE_TEXT "/Panel/Gtk/Color/ActiveText" +#define SCIM_CONFIG_PANEL_GTK_COLOR_HIGHLIGHT_TEXT "/Panel/Gtk/Color/HighlightText" +#define SCIM_CONFIG_PANEL_GTK_COLOR_SEPARATOR "/Panel/Gtk/Color/Separator" +#define SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_VERTICAL "/Panel/Gtk/LookupTableVertical" +#define SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_STYLE "/Panel/Gtk/LookupTableStyle" +#define SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_MODE "/Panel/Gtk/LookupTableMode" +#define SCIM_CONFIG_PANEL_GTK_DEFAULT_STICKED "/Panel/Gtk/DefaultSticked" + +#define LOOKUP_ICON_SIZE 12 + +#define BLANK_SIZE 0 +#define VERTICAL_SHOW_LINE 7 + +#define CANDIDATE_TABLE 0 +#define ASSOCIATE_TABLE 1 + +#define PORTRAIT_DEGREE 0 +#define LANDSCAPE_DEGREE 90 + +///////////////////////////////////////////////////////////////////////////// +// Declaration of external variables. +///////////////////////////////////////////////////////////////////////////// +extern MapStringVectorSizeT _groups; +extern std::vector < String > _uuids; +extern std::vector < String > _names; +extern std::vector < String > _module_names; +extern std::vector < String > _langs; +extern std::vector < String > _icons; +extern std::vector < uint32 > _options; +extern std::vector _modes; +extern MapStringString _keyboard_ise_help_map; +extern MapStringVectorString _disabled_ise_map; +extern std::vector < String > _disabled_langs; +extern MapStringVectorString _disabled_ise_map_bak; +extern std::vector < String > _disabled_langs_bak; +extern std::vector < String > _isf_app_list; +extern gboolean _ise_list_changed; +extern gboolean _setup_enable_changed; + +extern CommonLookupTable g_isf_candidate_table; + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal data types. +///////////////////////////////////////////////////////////////////////////// +enum { + IME_SETTING_KEYPAD_TYPE_3X4 = 0, + IME_SETTING_KEYPAD_TYPE_QTY, + IME_SETTING_KEYPAD_TYPE_NUM +}; + +typedef enum { + IME_BIT_0 = 0, + IME_BIT_1, + IME_BIT_2, + IME_BIT_3, + IME_BIT_4, + IME_BIT_5, + IME_BIT_6, + IME_BIT_7, + IME_BITL_MAX +} ImeBitPosition_E; + +typedef struct _ImeSettingPredictionEngineOptionInfo_S { + gint keypad_type; /* IME_SETTING_KEYPAD_TYPE_3X4, IME_SETTING_KEYPAD_TYPE_QTY */ + + gint word_cmpletion_point; /* 0(Off) - 6 */ + gboolean spell_correction; /* On - Off */ + gboolean next_word_prediction; /* On - Off */ + gboolean auto_substitution; /* On - Off */ + gboolean multitap_word_completion; /* On - Off */ + gboolean regional_input; /* On - Off */ + + gint word_cmpletion_point_prev; /* 0(Off) - 6 */ + gboolean spell_correction_prev; /* On - Off */ + gboolean next_word_prediction_prev; /* On - Off */ + gboolean auto_substitution_prev; /* On - Off */ + gboolean multitap_word_completion_prev; /* On - Off */ + gboolean regional_input_prev; /* On - Off */ +} ImeSettingPredictionEngineOptionInfo_S; + +enum { + ACTIVE_ISE_LIST_ENABLE = 0, + ACTIVE_ISE_NAME, + ACTIVE_ISE_UUID, + ACTIVE_ISE_TYPE, + ACTIVE_ISE_ICON, + ACTIVE_ISE_OPTION, + ACTIVE_ISE_NUM_COLUMS +}; + +typedef enum +{ + SCIM_CANDIDATE_STYLE = 0, + PREDICTION_ENGINE_CANDIDATE_STYLE, +} GTK_CANDIDATE_STYLE_T; + +typedef enum +{ + PORTRAIT_HORIZONTAL_CANDIDATE_MODE = 0, + PORTRAIT_VERTICAL_CANDIDATE_MODE, + LANDSCAPE_HORIZONTAL_CANDIDATE_MODE, + LANDSCAPE_VERTICAL_CANDIDATE_MODE, + PORTRAIT_MORE_CANDIDATE_MODE, + LANDSCAPE_MORE_CANDIDATE_MODE, +} GTK_CANDIDATE_MODE_T; + +#if SCIM_USE_STL_EXT_HASH_MAP +typedef __gnu_cxx::hash_map , scim_hash_string> MapStringVectorSizeT; +#elif SCIM_USE_STL_HASH_MAP +typedef std::hash_map , scim_hash_string> MapStringVectorSizeT; +#else +typedef std::map > MapStringVectorSizeT; +#endif + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal functions. +///////////////////////////////////////////////////////////////////////////// +static void update_active_ise_list_store (bool set_default_ise); +static void ui_config_reload_callback (const ConfigPointer &config); +static void ui_load_config (void); +static void ui_initialize (void); +static void ui_settle_input_window (bool relative = false, + bool force = false); +static int ui_screen_width (void); +static int ui_screen_height (void); + +#if GDK_MULTIHEAD_SAFE +static void ui_switch_screen (GdkScreen *screen); +#endif + +static GdkPixbuf* ui_scale_pixbuf (GdkPixbuf *pixbuf, + int width, + int height); +static GtkWidget* ui_create_icon (const String &iconfile, + const char **xpm = NULL, + int width = -1, + int height = -1, + bool force_create = false); +static GtkWidget* ui_create_up_icon (void); +static GtkWidget* ui_create_down_icon (void); +static GtkWidget* ui_create_left_icon (void); +static GtkWidget* ui_create_right_icon (void); + +// callback functions +static void ui_preedit_area_move_cursor_cb (ScimStringView *view, + guint position); +static gboolean ui_lookup_table_vertical_click_cb (GtkWidget *item, + GdkEventButton *event, + gpointer user_data); +static void ui_lookup_table_horizontal_click_cb (GtkWidget *item, + guint position, + gpointer user_data); +static void ui_lookup_table_up_button_click_cb (GtkButton *button, + gpointer user_data); +static void ui_lookup_table_down_button_click_cb (GtkButton *button, + gpointer user_data); +static gboolean ui_associate_table_vertical_click_cb (GtkWidget *item, + GdkEventButton *event, + gpointer user_data); +static void ui_associate_table_horizontal_click_cb (GtkWidget *item, + guint position, + gpointer user_data); +static void ui_associate_table_up_button_click_cb (GtkButton *button, + gpointer user_data); +static void ui_associate_table_down_button_click_cb (GtkButton *button, + gpointer user_data); +static gboolean ui_input_window_motion_cb (GtkWidget *window, + GdkEventMotion *event, + gpointer user_data); +static gboolean ui_input_window_click_cb (GtkWidget *window, + GdkEventButton *event, + gpointer user_data); + +static bool ui_can_hide_input_window (void); +static PangoAttrList * create_pango_attrlist (const String &str, + const AttributeList &attrs); + +// PanelAgent related functions +static bool initialize_panel_agent (const String &config, const String &display, bool resident); +static bool run_panel_agent (void); +static gpointer panel_agent_thread_func (gpointer data); + +static void slot_transaction_start (void); +static void slot_transaction_end (void); +static void slot_reload_config (void); +static void slot_turn_on (void); +static void slot_turn_off (void); +static void slot_focus_in (void); +static void slot_focus_out (void); +static void slot_show_panel (void); +static void slot_hide_panel (void); +static void slot_update_screen (int screen); +static void slot_update_spot_location (int x, int y, int top_y); +static void slot_update_factory_info (const PanelFactoryInfo &info); +static void slot_show_preedit_string (void); +static void slot_show_aux_string (void); +static void slot_show_lookup_table (void); +static void slot_show_associate_table (void); +static void slot_hide_preedit_string (void); +static void slot_hide_aux_string (void); +static void slot_hide_lookup_table (void); +static void slot_hide_associate_table (void); +static void slot_update_preedit_string (const String &str, const AttributeList &attrs); +static void slot_update_preedit_caret (int caret); +static void slot_update_aux_string (const String &str, const AttributeList &attrs); +static void slot_update_candidate_table (const LookupTable &table); +static void slot_update_associate_table (const LookupTable &table); +static void slot_set_active_ise_by_uuid (const String &uuid, bool); +static bool slot_get_ise_list (std::vector &name); +static bool slot_get_keyboard_ise_list (std::vector &name); +static void slot_get_language_list (std::vector &name); +static void slot_get_all_language (std::vector &lang); +static void slot_get_ise_language (char *, std::vector &name); +static void slot_set_isf_language (const String &language); +static bool slot_get_ise_info_by_uuid (const String &uuid, ISE_INFO &info); +static void slot_set_candidate_ui (int style, int mode); +static void slot_get_candidate_ui (int &style, int &mode); +static void slot_set_candidate_position (int left, int top); +static void slot_get_candidate_geometry (struct rectinfo &info); +static void slot_set_keyboard_ise (const String &ise_uuid); +static void slot_get_keyboard_ise (String &ise_name, String &ise_uuid); +static void slot_start_default_ise (); +static void slot_send_key_event (const KeyEvent &key); +static void slot_lock (void); +static void slot_unlock (void); + +static gboolean candidate_show_timeout_cb (gpointer data); +static gboolean check_exit_timeout_cb (gpointer data); + +///////////////////////////////////////////////////////////////////////////// +// Declaration of internal variables. +///////////////////////////////////////////////////////////////////////////// +#if GDK_MULTIHEAD_SAFE +static GdkScreen *_current_screen = 0; +#endif + +static GtkWidget *_input_window = 0; +static GtkWidget *_preedit_area = 0; +static GtkWidget *_aux_area = 0; + +static GtkWidget *_lookup_table_window = 0; +static GtkWidget *_lookup_table_up_button = 0; +static GtkWidget *_lookup_table_down_button = 0; +static GtkWidget *_lookup_table_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; + +static GtkWidget *_associate_table_window = 0; +static GtkWidget *_associate_table_up_button = 0; +static GtkWidget *_associate_table_down_button = 0; +static GtkWidget *_associate_table_items [SCIM_LOOKUP_TABLE_MAX_PAGESIZE]; + +static GtkWidget *_toolbar_window = 0; + +static PangoFontDescription *_default_font_desc = 0; + +static gboolean _input_window_draging = FALSE; +static gint _input_window_drag_x = 0; +static gint _input_window_drag_y = 0; +static gint _input_window_x = 0; +static gint _input_window_y = 0; + +static bool _lookup_table_vertical = false; +static bool _window_sticked = false; + +static int _spot_location_x = -1; +static int _spot_location_y = -1; +static int _spot_location_top_y = -1; + +static int _lookup_table_index [SCIM_LOOKUP_TABLE_MAX_PAGESIZE+1]; +static int _associate_table_index [SCIM_LOOKUP_TABLE_MAX_PAGESIZE+1]; +static int _lookup_table_index_pos [SCIM_LOOKUP_TABLE_MAX_PAGESIZE+1]; +static int _associate_table_index_pos [SCIM_LOOKUP_TABLE_MAX_PAGESIZE+1]; + +static GdkColor _normal_bg; +static GdkColor _normal_text; +static GdkColor _active_bg; +static GdkColor _active_text; +static GdkColor *_theme_color = NULL; + +static ConfigPointer _config; + +static guint _check_exit_timeout = 0; +static bool _should_exit = false; + +static bool _panel_is_on = true; + +static GThread *_panel_agent_thread = 0; +PanelAgent *_panel_agent = 0; + +static std::vector _helper_list; +static std::vector _load_ise_list; + +static DEFAULT_ISE_T _initial_ise; + +static int _lookup_icon_size = 0; + +int _screen_width = 0; +static int _screen_height = 0; +float _width_rate = 0; +float _height_rate = 0; +static int _softkeybar_height = 0; +static int _panel_width = 0; +static int _panel_height = 0; +static int _setup_button_width = 0; +static int _setup_button_height = 0; +static int _help_icon_width = 0; +static int _help_icon_height = 0; + + +static bool _candidate_is_showed = false; +static GTK_CANDIDATE_STYLE_T _candidate_style = PREDICTION_ENGINE_CANDIDATE_STYLE; +static GTK_CANDIDATE_MODE_T _candidate_mode = PORTRAIT_HORIZONTAL_CANDIDATE_MODE; +static GtkWidget *_candidate_scroll = 0; +static GtkWidget *_associate_scroll = 0; +static GtkWidget *_candidate_separator = 0; +static GtkWidget *_associate_separator = 0; +static GtkWidget *_middle_separator = 0; +static int _candidate_left = -1; +static int _candidate_top = -1; +static bool _show_scroll = false; +static int _candidate_motion = 0; +static gdouble _scroll_start = -10000; +static String _split_string1 = String (""); +static String _split_string2 = String (""); +static String _space_string = String (""); + +static guint _candidate_timer = 0; + +#if HAVE_GCONF +static const gchar *_ime_setting_ed_id[] = { "PhoneStatus.Application.Ise.NWordCompPoint", + "PhoneStatus.Application.Ise.QWordCompPoint", + "PhoneStatus.Application.Ise.KeyboardEngineOption" }; +static const gint _ime_setting_ed_number = sizeof (_ime_setting_ed_id) / sizeof (gchar*); +static unsigned int _ed_subscription_id[_ime_setting_ed_number] = {0}; +#endif + +static GdkBitmap *_panel_window_mask = 0; +static GdkPixbuf *_panel_bg_pixbuf = 0; + +static ISFSetupWin *_isf_setup_win = 0; +static ISFHelpWin *_isf_help_win = 0; +static GtkListStore *_active_ise_list_store = 0; + +static clock_t _clock_start; + +G_LOCK_DEFINE_STATIC (_global_resource_lock); +G_LOCK_DEFINE_STATIC (_panel_agent_lock); + + +///////////////////////////////////////////////////////////////////////////// +// Implementation of internal functions. +///////////////////////////////////////////////////////////////////////////// +/** + * @brief Print system time point for panel performance. + * + * @param str_info The output information. + */ +static void check_time (const char *str_info) +{ + gettime (_clock_start, str_info); +} + +#if HAVE_GCONF +/** + * @brief Set default language by given language ID. + * + * @param id The given language ID. + */ +static void set_default_language_by_id (int id) +{ + String sys_input_language = String (SCIM_CONFIG_SYSTEM_INPUT_LANGUAGE); +#if HAVE_GCONF + switch (id) { + case SETTINGS_LANGUAGE_ENGLISH: + _config->write (sys_input_language, String ("English")); + break; + case SETTINGS_LANGUAGE_GERMAN: + _config->write (sys_input_language, String ("German")); + break; + case SETTINGS_LANGUAGE_FRENCH: + _config->write (sys_input_language, String ("French")); + break; + case SETTINGS_LANGUAGE_ITALIAN: + _config->write (sys_input_language, String ("Italian")); + break; + case SETTINGS_LANGUAGE_DUTCH: + _config->write (sys_input_language, String ("Dutch")); + break; + case SETTINGS_LANGUAGE_SPANISH: + _config->write (sys_input_language, String ("Spanish")); + break; + case SETTINGS_LANGUAGE_GREEK: + _config->write (sys_input_language, String ("Greek")); + break; + case SETTINGS_LANGUAGE_PORTUGUESE: + _config->write (sys_input_language, String ("Portuguese")); + break; + case SETTINGS_LANGUAGE_TURKISH: + _config->write (sys_input_language, String ("Turkish")); + break; + default: + _config->write (sys_input_language, String ("English")); + break; + } +#endif + + _config->flush (); + _config->reload (); + //_panel_agent->reload_config (); +} + +/** + * @brief Callback function for input language change. + * + * @param client The GConf client handler. + * @param cnxn_id An ID. + * @param entry The handler of GConf entry. + * @param user_data The data to pass to this callback. + */ +static void input_lang_key_changed_callback (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + GConfValue *value = gconf_entry_get_value (entry); + if (value->type == GCONF_VALUE_INT) { + int id = gconf_value_get_int (value); + set_default_language_by_id (id); + + String sys_input_lang; + sys_input_lang = _config->read (String (SCIM_CONFIG_SYSTEM_INPUT_LANGUAGE), sys_input_lang); + + String lang_info ("English"); + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + String lang_name; + lang_name = scim_get_language_name (it->first); + if (!strcmp (sys_input_lang.c_str (), lang_name.c_str ())) + lang_info = sys_input_lang; + } + + _disabled_langs.clear (); + _disabled_langs_bak.clear (); + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + String lang_name; + lang_name = scim_get_language_name (it->first); + if (strcmp (lang_info.c_str (), lang_name.c_str ())) { + _disabled_langs.push_back (lang_name); + _disabled_langs_bak.push_back (lang_name); + } + } + + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_ISF_DEFAULT_LANGUAGES), lang_info); + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DISABLED_LANGS), _disabled_langs); + + for (size_t i = 0; i < _isf_app_list.size (); i++) { + String active_app = _isf_app_list[i]; + + _disabled_ise_map[active_app].clear (); + _disabled_ise_map_bak[active_app].clear (); + } + + for (size_t i = 0; i < _isf_app_list.size (); i++) { + String app = _isf_app_list[i]; + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DISABLED_IMENGINE_FACTORIES + "/") + _isf_app_list[i], _disabled_ise_map[app]); + } + + scim_global_config_flush (); + + update_active_ise_list_store (true); + } +} +#endif + +/** + * @brief This function is used to judge whether ISE should be hidden in control panel. + * + * @param uuid The ISE uuid. + * + * @return true if ISE should be hidden, otherwise return false. + */ +static bool hide_ise_in_control_panel (String uuid) +{ + if (uuid.length () <= 0) + return true; + + for (unsigned int i = 0; i < _helper_list.size (); i++) { + if (uuid == _helper_list[i].uuid) { + if (_helper_list[i].option & ISM_ISE_HIDE_IN_CONTROL_PANEL) + return true; + else + return false; + } + } + + return false; +} + +/** + * @brief Update active ISE list in control panel. + * + * @param set_default_ise The variable decides whether default ISE is set when update. + */ +static void update_active_ise_list_store (bool set_default_ise) +{ + String ise_name = _panel_agent->get_current_ise_name (); + + bool find_current_ise = false; + + gtk_list_store_clear (_active_ise_list_store); + GtkTreeIter iter; + std::vector f_show; + String active_app = _isf_app_list [0]; + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + String lang_name = scim_get_language_name (it->first); + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_name) == _disabled_langs.end ()) { + for (size_t i = 0; i < it->second.size (); i++) { + if (std::find (_disabled_ise_map[active_app].begin (), _disabled_ise_map[active_app].end (), _uuids[it->second[i]]) + ==_disabled_ise_map[active_app].end ()) { + if (hide_ise_in_control_panel (_uuids[it->second[i]])) + continue; + + // Protect from add the same ISE more than once in case of multiple langs + if (std::find (f_show.begin (), f_show.end (), _uuids[it->second[i]]) == f_show.end ()) { + gtk_list_store_append (_active_ise_list_store, &iter); + gtk_list_store_set (_active_ise_list_store, &iter, + ACTIVE_ISE_NAME, _names[it->second[i]].c_str (), + ACTIVE_ISE_UUID, _uuids[it->second[i]].c_str (), + ACTIVE_ISE_TYPE, (gint)_modes[it->second[i]], + ACTIVE_ISE_ICON, _icons[it->second[i]].c_str (), + ACTIVE_ISE_OPTION, (gint)_options[it->second[i]], -1); + f_show.push_back (_uuids[it->second[i]]); + + if (!strcmp (_names[it->second[i]].c_str (), ise_name.c_str ())) { + gtk_list_store_set (GTK_LIST_STORE (_active_ise_list_store), &iter, + ACTIVE_ISE_LIST_ENABLE, TRUE, -1); + find_current_ise = true; + } else { + gtk_list_store_set (GTK_LIST_STORE (_active_ise_list_store), &iter, + ACTIVE_ISE_LIST_ENABLE, FALSE, -1); + } + } + } + } + } + } + + if (!find_current_ise && set_default_ise) { + std::cerr << " not find current ISE : " << ise_name << "\n"; + _panel_agent->set_default_ise (_initial_ise); + } +} + +/** + * @brief Callback function for setup button of control panel. + * + * @param button The GtkButton handler. + * @param user_data Data to pass when it is called. + */ +static void on_isf_setup_button_clicked (GtkButton * button, + gpointer user_data) +{ + gboolean has_lookup_popwin = false; + gboolean has_input_popwin = false; + + slot_hide_panel (); + // Check whether candidate window is showed + if (_lookup_table_window && GTK_WIDGET_VISIBLE (_lookup_table_window)) { + has_lookup_popwin = true; + gtk_widget_hide (_lookup_table_window); + } + if (_input_window && GTK_WIDGET_VISIBLE (_input_window)) { + has_input_popwin = true; + gtk_widget_hide (_input_window); + } + + if (!_isf_setup_win) + _isf_setup_win = new ISFSetupWin (_config); + if (_isf_setup_win) + _isf_setup_win->show_window (); + + if (_ise_list_changed ||_setup_enable_changed) { + update_active_ise_list_store (true); + _ise_list_changed = false; + _setup_enable_changed = false; + } + + if (has_input_popwin) { + gtk_widget_show (_input_window); + gdk_window_raise (_input_window->window); + ui_settle_input_window (false, true); + } + if (has_lookup_popwin) + gtk_widget_show (_lookup_table_window); + slot_show_panel (); +} + +/** + * @brief Callback function for help button of control panel. + * + * @param button The GtkButton handler. + * @param user_data Data to pass when it is called. + */ +static void on_isf_help_button_clicked (GtkButton * button, + gpointer user_data) +{ + gboolean has_lookup_popwin = false; + gboolean has_input_popwin = false; + + slot_hide_panel (); + // Check whether candidate window is showed + if (_lookup_table_window && GTK_WIDGET_VISIBLE (_lookup_table_window)) { + has_lookup_popwin = true; + gtk_widget_hide (_lookup_table_window); + } + if (_input_window && GTK_WIDGET_VISIBLE (_input_window)) { + has_input_popwin = true; + gtk_widget_hide (_input_window); + } + + if (!_isf_help_win) + _isf_help_win = new ISFHelpWin (); + if (_isf_help_win) + _isf_help_win->show_help ("ISF Help", "ISF (Input Service Framework)\n © 2008 SAMSUNG"); + + if (has_input_popwin) { + gtk_widget_show (_input_window); + gdk_window_raise (_input_window->window); + ui_settle_input_window (false, true); + } + if (has_lookup_popwin) + gtk_widget_show (_lookup_table_window); + slot_show_panel (); +} + +/** + * @brief Callback function for press event of ISE help button. + * + * @param button The GtkButton handler. + * @param user_data Data to pass when it is called. + */ +static void on_isf_help_button_pressed (GtkButton * button, + gpointer user_data) +{ + GtkWidget *isf_help_bt_img = ui_create_icon (ISF_ICON_HELP_T_FILE, NULL, _help_icon_width, _help_icon_height, TRUE); + gtk_button_set_image (GTK_BUTTON (button), isf_help_bt_img); +} + +/** + * @brief Callback function for release event of ISE help button. + * + * @param button The GtkButton handler. + * @param user_data Data to pass when it is called. + */ +static void on_isf_help_button_released (GtkButton * button, + gpointer user_data) +{ + GtkWidget *isf_help_bt_img = ui_create_icon (ISF_ICON_HELP_FILE, NULL, _help_icon_width, _help_icon_height, TRUE); + gtk_button_set_image (GTK_BUTTON (button), isf_help_bt_img); +} + +/** + * @brief Change keyboard ISE. + * + * @param uuid The keyboard ISE's uuid. + * @param uuid The keyboard ISE's name. + * @param uuid The keyboard ISE's icon. + * @param uuid The keyboard ISE's option. + * + * @return false if keyboard ISE change is failed, otherwise return true. + */ +static bool ui_active_ise_box_keyboardise_activate_cb (String &uuid, String &name, String &icon, uint32 &option) +{ + SCIM_DEBUG_MAIN (1) << "ui_active_ise_box_keyboardise_activate_cb\n"; + + TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode (); + + if (TOOLBAR_HELPER_MODE == mode) { + String pre_uuid = _panel_agent->get_current_helper_uuid (); + _panel_agent->stop_helper (pre_uuid); + } else if (TOOLBAR_KEYBOARD_MODE == mode) { + String pre_name = _panel_agent->get_current_ise_name (); + if (!pre_name.compare (name)) + return false; + } + + mode = TOOLBAR_KEYBOARD_MODE; + _panel_agent->set_current_toolbar_mode (mode); + _panel_agent->set_current_ise_name (name); + + uint32 style = (option & ISM_ISE_FULL_STYLE) != 0; + _panel_agent->set_current_ise_style (style); + + String language = String ("~other");//scim_get_locale_language (scim_get_current_locale ()); + _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, uuid); + _config->flush (); + + _panel_agent->change_factory (uuid); + + return true; +} + +/** + * @brief Change helper ISE. + * + * @param uuid The helper ISE's uuid. + * @param uuid The helper ISE's name. + * @param uuid The helper ISE's icon. + * @param uuid The helper ISE's option. + * + * @return false if helper ISE change is failed, otherwise return true. + */ +static bool ui_active_ise_box_helper_activate_cb (String &uuid, String &name, String &icon, uint32 &option) +{ + SCIM_DEBUG_MAIN (1) << "ui_active_ise_box_helper_activate_cb\n"; + + TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode (); + + if (TOOLBAR_HELPER_MODE == mode) { + String pre_uuid = _panel_agent->get_current_helper_uuid (); + if (!pre_uuid.compare (uuid)) + return false; + _panel_agent->stop_helper (pre_uuid); + } else if (TOOLBAR_KEYBOARD_MODE == mode) { + //_panel_agent->change_factory (""); + } + + _panel_agent->set_current_toolbar_mode (TOOLBAR_HELPER_MODE); + _panel_agent->set_current_ise_name (name); + _panel_agent->set_current_factory_icon (icon); + + uint32 style = (option & ISM_ISE_FULL_STYLE) != 0; + _panel_agent->set_current_ise_style (style); + + _panel_agent->start_helper (uuid); + PanelFactoryInfo not_an_factoryinfo (uuid, name, "", icon); + slot_update_factory_info (not_an_factoryinfo); + + return true; +} + +/** + * @brief Callback function for click event of ISE enable button. + * + * @param cell The GtkCellRendererToggle handler. + * @param arg1 The string for GtkTreePath. + * @param data Data pointer to pass when it is called. + */ +static void on_active_ise_enable_box_clicked (GtkCellRendererToggle * cell, + gchar * arg1, gpointer data) +{ + bool ise_changed = false; + GtkTreePath *path = 0; + GtkTreePath *path_valid = 0; + GtkTreeIter iter, iter_valid; + + std::vector < String >::iterator it; + + path_valid = gtk_tree_path_new_from_string (arg1); + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (_active_ise_list_store), &iter_valid, path_valid)) { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (_active_ise_list_store), &iter)) { + do { + path = gtk_tree_model_get_path (GTK_TREE_MODEL (_active_ise_list_store), &iter); + if (gtk_tree_path_compare (path, path_valid) == 0) { + gtk_list_store_set (GTK_LIST_STORE (_active_ise_list_store), &iter, + ACTIVE_ISE_LIST_ENABLE, TRUE, -1); + } else { + gtk_list_store_set (GTK_LIST_STORE (_active_ise_list_store), &iter, + ACTIVE_ISE_LIST_ENABLE, FALSE, -1); + } + if (path) { + gtk_tree_path_free (path); + path = 0; + } + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (_active_ise_list_store), &iter)); + } + + gchar *g_name = 0; + gchar *g_uuid = 0; + gchar *g_icon = 0; + gint g_mode; + gint g_option; + + gtk_tree_model_get (GTK_TREE_MODEL (_active_ise_list_store), + &iter_valid, + ACTIVE_ISE_NAME,&g_name, + ACTIVE_ISE_UUID,&g_uuid, + ACTIVE_ISE_ICON,&g_icon, + ACTIVE_ISE_TYPE,&g_mode, + ACTIVE_ISE_OPTION,&g_option, + -1); + + TOOLBAR_MODE_T mode = (TOOLBAR_MODE_T) g_mode; + String name (g_name); + String uuid (g_uuid); + String icon (g_icon); + uint32 option = (uint32) g_option; + + if (g_name) { + g_free (g_name); + g_name = 0; + } + if (g_uuid) { + g_free (g_uuid); + g_uuid = 0; + } + if (g_icon) { + g_free (g_icon); + g_icon = 0; + } + + if (TOOLBAR_KEYBOARD_MODE == mode) + ise_changed = ui_active_ise_box_keyboardise_activate_cb (uuid, name, icon, option); + else if (TOOLBAR_HELPER_MODE == mode) + ise_changed = ui_active_ise_box_helper_activate_cb (uuid, name, icon, option); + + if (ise_changed) { + _panel_agent->update_ise_name (name); + uint32 style = (option & ISM_ISE_FULL_STYLE) != 0; + _panel_agent->update_ise_style (style); + + DEFAULT_ISE_T default_ise; + default_ise.type = mode; + default_ise.uuid = uuid; + default_ise.name = name; + _panel_agent->set_default_ise (default_ise); + //slot_hide_panel (); + } + } + + if (path_valid) { + gtk_tree_path_free (path_valid); + path_valid = 0; + } +} + +/** + * @brief Create active ISE list view. + * + * @return The GtkWidget handler of active ise list view. + */ +static GtkWidget *create_active_ise_list_view (void) +{ + GtkWidget *view = NULL; + + GtkCellRenderer *renderer = NULL; + GtkTreeViewColumn *column = NULL; + + view = gtk_tree_view_new (); + g_object_set (view, "enable-grid-lines", GTK_TREE_VIEW_GRID_LINES_NONE, NULL); + gtk_widget_show (view); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), false); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), false); + + // Invoke ISE in mutually-exclusive + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), + GTK_SELECTION_SINGLE); + + // Enable column + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Enable")); + + renderer = gtk_cell_renderer_toggle_new (); + g_object_set (renderer, "indicator-size", (gint)(26*(_width_rate < _height_rate ? _width_rate : _height_rate)), NULL); + g_object_set (renderer, "xpad", 0, NULL); + gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer), true); + gtk_tree_view_column_pack_start (column, renderer, FALSE); + gtk_cell_renderer_set_fixed_size (renderer, -1, (gint)(31*_height_rate)); + gtk_tree_view_column_set_attributes (column, renderer, "active", ACTIVE_ISE_LIST_ENABLE, NULL); + + g_signal_connect (G_OBJECT (renderer), "toggled", + G_CALLBACK (on_active_ise_enable_box_clicked), + (gpointer) view); + + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + // Name column + column = gtk_tree_view_column_new (); + //gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); + //gtk_tree_view_column_set_fixed_width (column, 232); + + gtk_tree_view_column_set_title (column, _("Name")); + + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, "foreground", "black", NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, "text", ACTIVE_ISE_NAME, NULL); + gtk_cell_renderer_set_fixed_size (renderer, -1, (gint)(31*_height_rate)); + g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + g_object_set (renderer, "xpad", (gint)(4*_width_rate), NULL); + //gtk_cell_renderer_set_cell_font_size (renderer, GTK_CELL_RENDERER_NORMAL, 18); + + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + return view; +} + +/** + * @brief Create and fill active ISE list store. + */ +static void create_and_fill_active_ise_list_store (void) +{ + // Create model. + _active_ise_list_store = gtk_list_store_new (ACTIVE_ISE_NUM_COLUMS, G_TYPE_BOOLEAN, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT); + + update_active_ise_list_store (false); +} + +/** + * @brief Normalize language string. + * + * @param src_str The source string for language. + * + * @return The normalized language string. + */ +static String get_langs (String src_str) +{ + std::vector str_list, dst_list; + scim_split_string_list (str_list, src_str); + + for (size_t i = 0; i < str_list.size (); i++) + dst_list.push_back (scim_get_normalized_language (str_list[i])); + + String dst_str = scim_combine_string_list (dst_list); + + return dst_str; +} + +/** + * @brief Load all ISEs to initialize. + * + * @param config The config pointer for loading keyboard ISE. + * @param uuids The ISE uuid list. + * @param names The ISE name list. + * @param module_names The ISE module name list. + * @param langs The ISE language list. + * @param icons The ISE icon list. + * @param modes The ISE type list. + * @param options The ISE option list. + */ +static void get_factory_list (const ConfigPointer & config, + std::vector < String > &uuids, + std::vector < String > &names, + std::vector < String > &module_names, + std::vector < String > &langs, + std::vector < String > &icons, + std::vector &modes, + std::vector &options) +{ + std::vector < String > imengine_list; + std::vector < String > helper_list; + std::vector::iterator it; + + IMEngineFactoryPointer factory; + IMEngineModule ime_module; + + HelperModule helper_module; + HelperInfo helper_info; + + scim_get_imengine_module_list (imengine_list); + scim_get_helper_module_list (helper_list); + + uuids.clear (); + names.clear (); + module_names.clear (); + langs.clear (); + icons.clear (); + modes.clear (); + + // Add "English/Keyboard" factory first. + factory = new ComposeKeyFactory (); + uuids.push_back (factory->get_uuid ()); + names.push_back (utf8_wcstombs (factory->get_name ())); + String module_name = String ("English/Keyboard"); + module_names.push_back (module_name); + langs.push_back (get_langs (factory->get_language ())); + _keyboard_ise_help_map[utf8_wcstombs (factory->get_name ())] = utf8_wcstombs (factory->get_help ()); + icons.push_back (factory->get_icon_file ()); + modes.push_back (TOOLBAR_KEYBOARD_MODE); + options.push_back (0); + + for (size_t i = 0; i < imengine_list.size (); ++i) { + if (_load_ise_list.size () > 0) { + if (std::find (_load_ise_list.begin (), _load_ise_list.end (), imengine_list [i]) == _load_ise_list.end ()) + continue; + } + + if (imengine_list[i] != "socket") { + ime_module.load (imengine_list[i], config); + + if (ime_module.valid ()) { + for (size_t j = 0; j < ime_module.number_of_factories (); ++j) { + try { + factory = ime_module.create_factory (j); + } catch (...) { + factory.reset (); + } + + if (!factory.null ()) { + if (std::find (uuids.begin (), uuids.end (), factory->get_uuid ()) == uuids.end ()) { + uuids.push_back (factory->get_uuid ()); + names.push_back (utf8_wcstombs (factory->get_name ())); + module_name = imengine_list[i]; + module_names.push_back (module_name); + _keyboard_ise_help_map[module_name] = utf8_wcstombs (factory->get_help ()); + langs.push_back (get_langs (factory->get_language ())); + icons.push_back (factory->get_icon_file ()); + modes.push_back (TOOLBAR_KEYBOARD_MODE); + options.push_back (0); + } + factory.reset (); + } + } + ime_module.unload (); + } + } + } + + for (size_t i = 0; i < helper_list.size (); ++i) { + if (_load_ise_list.size () > 0) { + if (std::find (_load_ise_list.begin (), _load_ise_list.end (), helper_list [i]) == _load_ise_list.end ()) + continue; + } + + helper_module.load (helper_list[i]); + if (helper_module.valid ()) { + for (size_t j = 0; j < helper_module.number_of_helpers (); ++j) { + helper_module.get_helper_info (j, helper_info); + uuids.push_back (helper_info.uuid); + names.push_back (helper_info.name); + langs.push_back (get_langs (helper_module.get_helper_lang (j))); + module_names.push_back (helper_list[i]); + icons.push_back (helper_info.icon); + modes.push_back (TOOLBAR_HELPER_MODE); + options.push_back (helper_info.option); + } + helper_module.unload (); + } + } +} + +/** + * @brief Load all disabled languages. + * + * @param disabled This variable is used to store disabled language. + */ +static void load_disabled_lang_list (std::vector &disabled) +{ + disabled = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DISABLED_LANGS), disabled); +} + +/** + * @brief Load ISF configuration and ISEs information. + */ +static void isf_load_config (void) +{ + // Load app list + _isf_app_list.push_back ("Default"); + + // Load ISE engine info + get_factory_list (_config, _uuids, _names, _module_names, _langs, _icons, _modes, _options); + + std::vector ise_langs; + + for (size_t i = 0; i < _uuids.size (); ++i) { + scim_split_string_list (ise_langs, _langs[i]); + for (size_t j = 0; j < ise_langs.size (); j++) { + if (std::find (_groups[ise_langs[j]].begin (), _groups[ise_langs[j]].end (), i) == _groups[ise_langs[j]].end ()) + _groups[ise_langs[j]].push_back (i); + } + ise_langs.clear (); + } + + std::vector isf_default_langs; + isf_default_langs = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_ISF_DEFAULT_LANGUAGES), isf_default_langs); + + // No default ISF lang + if (isf_default_langs.size () == 0) { + String sys_input_lang, lang_info ("English"); + sys_input_lang = _config->read (String (SCIM_CONFIG_SYSTEM_INPUT_LANGUAGE), sys_input_lang); + MapStringVectorSizeT::iterator g = _groups.find (sys_input_lang); + if (g != _groups.end ()) + lang_info = sys_input_lang; + else + std::cerr << "System input language is not included in the ISF languages.\n"; + + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + String lang_name = scim_get_language_name (it->first); + if (strcmp (lang_info.c_str (), lang_name.c_str ())) { + _disabled_langs.push_back (lang_name); + _disabled_langs_bak.push_back (lang_name); + } + } + } else { + std::vector disabled; + + load_disabled_lang_list (disabled); + for (size_t i = 0; i < disabled.size (); i++) { + _disabled_langs.push_back (disabled[i]); + _disabled_langs_bak.push_back (disabled[i]); + } + } +} + +/** + * @brief Create control panel window. + */ +static void create_panel_window (void) +{ + check_time ("\nEnter create_panel_window"); + + GtkWidget *isf_setup_bt = NULL; + GtkWidget *isf_help_bt = NULL; + GtkWidget *scroll = NULL; + GtkWidget *view = NULL; + + gint softkeybar_height = _softkeybar_height; + + if (_toolbar_window) { + gtk_widget_destroy (_toolbar_window); + _toolbar_window = 0; + } + + _toolbar_window = gtk_window_new (GTK_WINDOW_POPUP); + +#ifdef USING_ISF_SWITCH_BUTTON + GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (_toolbar_window)); + g_object_get (settings, "gtk-softkeybar-height", &softkeybar_height, NULL); +#endif + + gint panel_x = (_screen_width - _panel_width) / 2; + gint panel_y = _screen_height - softkeybar_height - _panel_height; + gtk_window_move (GTK_WINDOW (_toolbar_window), panel_x, panel_y); + gtk_widget_set_size_request (GTK_WIDGET (_toolbar_window), _panel_width, _panel_height); + gtk_window_set_policy (GTK_WINDOW (_toolbar_window), TRUE, TRUE, FALSE); + //gtk_window_set_accept_focus (GTK_WINDOW (_toolbar_window), FALSE); + gtk_window_set_resizable (GTK_WINDOW (_toolbar_window), FALSE); + + GtkWidget *fixed = gtk_fixed_new (); + gtk_container_add (GTK_CONTAINER (_toolbar_window), fixed); + gtk_widget_show (fixed); + + GtkWidget *panel_bg = ui_create_icon (ISF_PANEL_BG_FILE, NULL, _panel_width, _panel_height, TRUE); + _panel_bg_pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (panel_bg)); + gtk_fixed_put (GTK_FIXED (fixed), panel_bg, 0, 0); + gtk_widget_show (panel_bg); + + isf_setup_bt = gtk_button_new_with_label ("Setup"); + + GtkWidget *newlabel = gtk_label_new ("Setup"); + gtk_label_set_markup (GTK_LABEL (newlabel), "Setup"); + + if (newlabel) { + GtkWidget *old = gtk_bin_get_child (GTK_BIN (isf_setup_bt)); + if (old) + gtk_container_remove (GTK_CONTAINER (isf_setup_bt), old); + gtk_container_add (GTK_CONTAINER (isf_setup_bt), newlabel); + gtk_widget_show (newlabel); + } + gtk_widget_set_size_request (isf_setup_bt, _setup_button_width, _setup_button_height); + + gint setup_button_x = (int)(_panel_width - (75+3+31+11)*_width_rate); + gint setup_button_y = (int)(9 * _height_rate); + + gtk_fixed_put (GTK_FIXED (fixed), isf_setup_bt, setup_button_x, setup_button_y); + gtk_widget_show (isf_setup_bt); + + g_signal_connect ((gpointer) isf_setup_bt, "clicked", + G_CALLBACK (on_isf_setup_button_clicked), NULL); + + GtkWidget *isf_help_bt_img = ui_create_icon (ISF_ICON_HELP_FILE, NULL, _help_icon_width, _help_icon_height, TRUE); + isf_help_bt = gtk_button_new (); + gtk_widget_set_size_request (isf_help_bt, _help_icon_width, _help_icon_height); + gtk_button_set_image (GTK_BUTTON (isf_help_bt), isf_help_bt_img); + gtk_widget_show (isf_help_bt_img); + + gint help_icon_x = setup_button_x + _setup_button_width + 3*_width_rate; + gint help_icon_y = setup_button_y; + gtk_fixed_put (GTK_FIXED (fixed), isf_help_bt, help_icon_x, help_icon_y); + gtk_widget_show (isf_help_bt); + g_signal_connect ((gpointer) isf_help_bt, "clicked", + G_CALLBACK (on_isf_help_button_clicked), NULL); + g_signal_connect ((gpointer) isf_help_bt, "pressed", + G_CALLBACK (on_isf_help_button_pressed), NULL); + g_signal_connect ((gpointer) isf_help_bt, "released", + G_CALLBACK (on_isf_help_button_released), NULL); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gint scroll_width = (gint)(_panel_width - 16*_width_rate - 16*_width_rate); + gint scroll_height = (gint)(_panel_height - 43*_height_rate); + gtk_widget_set_size_request (scroll, scroll_width, scroll_height); + + gint scroll_x = (gint)(16 * _width_rate); + gint scroll_y = (gint)(43 * _height_rate); + gtk_fixed_put (GTK_FIXED (fixed), scroll, scroll_x, scroll_y); + gtk_widget_show (scroll); + + view = create_active_ise_list_view (); + if (view && view->style) { + gtk_widget_modify_bg (view, GTK_STATE_NORMAL, &(view->style->white)); + + gtk_tree_view_set_model (GTK_TREE_VIEW (view), + GTK_TREE_MODEL (_active_ise_list_store)); + + gtk_container_add (GTK_CONTAINER (scroll), view); + gtk_widget_show (view); + } + check_time ("Exit create_panel_window"); +} + +/** + * @brief Create SCIM style candidate window. + * + * @param vertical An indicator for vertical window or horizontal window. + */ +static void create_scim_candidate_window (bool vertical) +{ + GtkWidget *input_window_vbox = NULL; + GtkWidget *input_window_hbox = NULL; + gint input_window_width; + gint thickness = 1; + + input_window_width = gdk_screen_width (); + + _lookup_icon_size = input_window_width / 24; + if (_lookup_icon_size < LOOKUP_ICON_SIZE) + _lookup_icon_size = LOOKUP_ICON_SIZE; + + // Create input window + { + GtkWidget *vbox = NULL; + GtkWidget *hbox = NULL; + GtkWidget *frame = NULL; + + _input_window = gtk_window_new (GTK_WINDOW_POPUP); + + if (_candidate_mode == LANDSCAPE_HORIZONTAL_CANDIDATE_MODE) { +#if HAVE_GCONF + gtk_window_set_rotate (GTK_WINDOW (_input_window), LANDSCAPE_DEGREE); +#endif + gtk_widget_set_size_request (GTK_WIDGET (_input_window), gdk_screen_height (), -1); + } else if (_candidate_mode == LANDSCAPE_VERTICAL_CANDIDATE_MODE) { +#if HAVE_GCONF + gtk_window_set_rotate (GTK_WINDOW (_input_window), LANDSCAPE_DEGREE); +#endif + } + + //gtk_window_set_keep_above (GTK_WINDOW (_input_window), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (_input_window), 5); + //gtk_widget_modify_bg (_input_window, GTK_STATE_NORMAL, &(_active_bg)); + gtk_widget_modify_bg (_input_window, GTK_STATE_NORMAL, &_normal_bg); + gtk_window_set_policy (GTK_WINDOW (_input_window), TRUE, TRUE, FALSE); + gtk_window_set_accept_focus (GTK_WINDOW (_input_window), FALSE); + gtk_window_set_resizable (GTK_WINDOW (_input_window), FALSE); + gtk_widget_add_events (_input_window, GDK_BUTTON_PRESS_MASK); + gtk_widget_add_events (_input_window, GDK_BUTTON_RELEASE_MASK); + gtk_widget_add_events (_input_window, GDK_POINTER_MOTION_MASK); + g_signal_connect (G_OBJECT (_input_window), "button-press-event", + G_CALLBACK (ui_input_window_click_cb), + GINT_TO_POINTER (0)); + g_signal_connect (G_OBJECT (_input_window), "button-release-event", + G_CALLBACK (ui_input_window_click_cb), + GINT_TO_POINTER (1)); + + frame = gtk_frame_new (0); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT); + gtk_container_add (GTK_CONTAINER (_input_window), frame); + gtk_widget_show (frame); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (frame), hbox); + gtk_widget_show (hbox); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show (vbox); + input_window_vbox = vbox; + + // Create preedit area + _preedit_area = scim_string_view_new (); + //if (_default_font_desc) + // gtk_widget_modify_font (_preedit_area, _default_font_desc); + gtk_widget_modify_base (_preedit_area, GTK_STATE_NORMAL, &_normal_bg); + gtk_widget_modify_base (_preedit_area, GTK_STATE_ACTIVE, &_active_bg); + gtk_widget_modify_text (_preedit_area, GTK_STATE_NORMAL, &_normal_text); + gtk_widget_modify_text (_preedit_area, GTK_STATE_ACTIVE, &_active_text); + scim_string_view_set_width_chars (SCIM_STRING_VIEW (_preedit_area), 24); + scim_string_view_set_forward_event (SCIM_STRING_VIEW (_preedit_area), TRUE); + scim_string_view_set_auto_resize (SCIM_STRING_VIEW (_preedit_area), TRUE); + scim_string_view_set_has_frame (SCIM_STRING_VIEW (_preedit_area), FALSE); + g_signal_connect (G_OBJECT (_preedit_area), "move_cursor", + G_CALLBACK (ui_preedit_area_move_cursor_cb), + 0); + gtk_box_pack_start (GTK_BOX (vbox), _preedit_area, TRUE, TRUE, 0); + + // Create aux area + _aux_area = scim_string_view_new (); + //if (_default_font_desc) + // gtk_widget_modify_font (_aux_area, _default_font_desc); + gtk_widget_modify_base (_aux_area, GTK_STATE_NORMAL, &_normal_bg); + gtk_widget_modify_base (_aux_area, GTK_STATE_ACTIVE, &_active_bg); + gtk_widget_modify_text (_aux_area, GTK_STATE_NORMAL, &_normal_text); + gtk_widget_modify_text (_aux_area, GTK_STATE_ACTIVE, &_active_text); + scim_string_view_set_width_chars (SCIM_STRING_VIEW (_aux_area), 24); + scim_string_view_set_draw_cursor (SCIM_STRING_VIEW (_aux_area), FALSE); + scim_string_view_set_forward_event (SCIM_STRING_VIEW (_aux_area), TRUE); + scim_string_view_set_auto_resize (SCIM_STRING_VIEW (_aux_area), TRUE); + scim_string_view_set_has_frame (SCIM_STRING_VIEW (_aux_area), FALSE); + gtk_box_pack_start (GTK_BOX (vbox), _aux_area, TRUE, TRUE, 0); + } + + // Create lookup table window + { + GtkWidget *vbox = NULL; + GtkWidget *hbox = NULL; + GtkWidget *lookup_table_parent = NULL; + GtkWidget *image = NULL; + GtkWidget *separator = NULL; + + _lookup_table_window = gtk_vbox_new (FALSE, 0); + if (vertical) { + input_window_hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (input_window_vbox), input_window_hbox, TRUE, TRUE, 0); + gtk_widget_show (input_window_hbox); + gtk_box_pack_start (GTK_BOX (input_window_hbox), _lookup_table_window, TRUE, TRUE, 0); + } else { + gtk_box_pack_start (GTK_BOX (input_window_vbox), _lookup_table_window, TRUE, TRUE, 0); + } + lookup_table_parent = _lookup_table_window; + _candidate_separator = gtk_hseparator_new (); + GtkStyle *style = gtk_widget_get_style (_candidate_separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (_candidate_separator, style); + } + gtk_box_pack_start (GTK_BOX (lookup_table_parent), _candidate_separator, FALSE, FALSE, 0); + gtk_widget_show (_candidate_separator); + + // Vertical lookup table + if (vertical) { + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (lookup_table_parent), vbox); + gtk_widget_show (vbox); + + // New table items + for (int i=0; ixthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (separator, style); + } + //gtk_box_pack_end (GTK_BOX (vbox), separator, FALSE, FALSE, 0); + gtk_widget_show (separator); + } else { + gtk_widget_set_size_request (GTK_WIDGET (_input_window), input_window_width, -1); + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (lookup_table_parent), hbox); + gtk_widget_show (hbox); + + _lookup_table_items [0] = scim_string_view_new (); + //if (_default_font_desc) + // gtk_widget_modify_font (_lookup_table_items [0], _default_font_desc); + gtk_widget_modify_base (_lookup_table_items [0], GTK_STATE_NORMAL, &_normal_bg); + gtk_widget_modify_base (_lookup_table_items [0], GTK_STATE_ACTIVE, &_active_bg); + gtk_widget_modify_text (_lookup_table_items [0], GTK_STATE_NORMAL, &_normal_text); + gtk_widget_modify_text (_lookup_table_items [0], GTK_STATE_ACTIVE, &_active_text); + scim_string_view_set_forward_event (SCIM_STRING_VIEW (_lookup_table_items [0]), TRUE); + scim_string_view_set_auto_resize (SCIM_STRING_VIEW (_lookup_table_items [0]), TRUE); + scim_string_view_set_has_frame (SCIM_STRING_VIEW (_lookup_table_items [0]), FALSE); + scim_string_view_set_draw_cursor (SCIM_STRING_VIEW (_lookup_table_items [0]), FALSE); + scim_string_view_set_auto_move_cursor (SCIM_STRING_VIEW (_lookup_table_items [0]), FALSE); + g_signal_connect (G_OBJECT (_lookup_table_items [0]), "move_cursor", + G_CALLBACK (ui_lookup_table_horizontal_click_cb), + 0); + gtk_box_pack_start (GTK_BOX (hbox), _lookup_table_items [0], TRUE, TRUE, 0); + gtk_widget_show (_lookup_table_items [0]); + + separator = gtk_vseparator_new (); + GtkStyle *style = gtk_widget_get_style (separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (separator, style); + } + //gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); + gtk_widget_show (separator); + + // New left button + image = ui_create_left_icon (); + _lookup_table_up_button = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (_lookup_table_up_button), image); + gtk_widget_show (image); + gtk_box_pack_start (GTK_BOX (hbox), _lookup_table_up_button, FALSE, FALSE, 0); + gtk_widget_show (_lookup_table_up_button); + g_signal_connect (G_OBJECT (_lookup_table_up_button), "clicked", + G_CALLBACK (ui_lookup_table_up_button_click_cb), + image); + + // New right button + image = ui_create_right_icon (); + _lookup_table_down_button = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (_lookup_table_down_button), image); + gtk_widget_show (image); + gtk_box_pack_start (GTK_BOX (hbox), _lookup_table_down_button, FALSE, FALSE, 0); + gtk_widget_show (_lookup_table_down_button); + g_signal_connect (G_OBJECT (_lookup_table_down_button), "clicked", + G_CALLBACK (ui_lookup_table_down_button_click_cb), + image); + } + + gtk_button_set_relief (GTK_BUTTON (_lookup_table_up_button), GTK_RELIEF_NONE); + gtk_widget_modify_bg (_lookup_table_up_button, GTK_STATE_ACTIVE, &_normal_bg); + gtk_widget_modify_bg (_lookup_table_up_button, GTK_STATE_INSENSITIVE, &_normal_bg); + gtk_widget_modify_bg (_lookup_table_up_button, GTK_STATE_PRELIGHT, &_normal_bg); + + gtk_button_set_relief (GTK_BUTTON (_lookup_table_down_button), GTK_RELIEF_NONE); + gtk_widget_modify_bg (_lookup_table_down_button, GTK_STATE_ACTIVE, &_normal_bg); + gtk_widget_modify_bg (_lookup_table_down_button, GTK_STATE_INSENSITIVE, &_normal_bg); + gtk_widget_modify_bg (_lookup_table_down_button, GTK_STATE_PRELIGHT, &_normal_bg); + } + + // Create associate table window + { + GtkWidget *vbox = NULL; + GtkWidget *hbox = NULL; + GtkWidget *image = NULL; + GtkWidget *separator = NULL; + GtkWidget *associate_table_parent = NULL; + + _associate_table_window = gtk_vbox_new (FALSE, 0); + if (vertical) { + _middle_separator = gtk_vseparator_new (); + GtkStyle *style = gtk_widget_get_style (_middle_separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (_middle_separator, style); + } + gtk_box_pack_start (GTK_BOX (input_window_hbox), _middle_separator, FALSE, FALSE, 0); + gtk_widget_show (_middle_separator); + + gtk_box_pack_start (GTK_BOX (input_window_hbox), _associate_table_window, TRUE, TRUE, 0); + } else { + gtk_box_pack_start (GTK_BOX (input_window_vbox), _associate_table_window, TRUE, TRUE, 0); + } + associate_table_parent = _associate_table_window; + _associate_separator = gtk_hseparator_new (); + GtkStyle *style = gtk_widget_get_style (_associate_separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (_associate_separator, style); + } + gtk_box_pack_start (GTK_BOX (associate_table_parent), _associate_separator, FALSE, FALSE, 0); + gtk_widget_show (_associate_separator); + + if (vertical) { + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (associate_table_parent), vbox); + gtk_widget_show (vbox); + + for (int i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) { + _associate_table_items [i] = scim_string_view_new (); + //if (_default_font_desc) + // gtk_widget_modify_font (_associate_table_items [i], _default_font_desc); + gtk_widget_modify_base (_associate_table_items [i], GTK_STATE_NORMAL, &_normal_bg); + gtk_widget_modify_base (_associate_table_items [i], GTK_STATE_ACTIVE, &_active_bg); + gtk_widget_modify_text (_associate_table_items [i], GTK_STATE_NORMAL, &_normal_text); + gtk_widget_modify_text (_associate_table_items [i], GTK_STATE_ACTIVE, &_active_text); + scim_string_view_set_width_chars (SCIM_STRING_VIEW (_associate_table_items [i]), 80); + scim_string_view_set_has_frame (SCIM_STRING_VIEW (_associate_table_items [i]), FALSE); + scim_string_view_set_forward_event (SCIM_STRING_VIEW (_associate_table_items [i]), TRUE); + scim_string_view_set_auto_resize (SCIM_STRING_VIEW (_associate_table_items [i]), TRUE); + scim_string_view_set_draw_cursor (SCIM_STRING_VIEW (_associate_table_items [i]), FALSE); + scim_string_view_set_auto_move_cursor (SCIM_STRING_VIEW (_associate_table_items [i]), FALSE); + g_signal_connect (G_OBJECT (_associate_table_items [i]), "button-press-event", + G_CALLBACK (ui_associate_table_vertical_click_cb), + GINT_TO_POINTER (i)); + gtk_box_pack_start (GTK_BOX (vbox), _associate_table_items [i], FALSE, FALSE, 0); + } + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + // New down button + image = ui_create_down_icon (); + _associate_table_down_button = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (_associate_table_down_button), image); + gtk_widget_show (image); + gtk_box_pack_end (GTK_BOX (hbox), _associate_table_down_button, TRUE, TRUE, 0); + gtk_widget_show (_associate_table_down_button); + g_signal_connect (G_OBJECT (_associate_table_down_button), "clicked", + G_CALLBACK (ui_associate_table_down_button_click_cb), + image); + + // New up button + image = ui_create_up_icon (); + _associate_table_up_button = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (_associate_table_up_button), image); + gtk_widget_show (image); + gtk_box_pack_end (GTK_BOX (hbox), _associate_table_up_button, TRUE, TRUE, 0); + gtk_widget_show (_associate_table_up_button); + g_signal_connect (G_OBJECT (_associate_table_up_button), "clicked", + G_CALLBACK (ui_associate_table_up_button_click_cb), + image); + + separator = gtk_hseparator_new (); + GtkStyle *style = gtk_widget_get_style (separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (separator, style); + } + //gtk_box_pack_end (GTK_BOX (vbox), separator, FALSE, FALSE, 0); + gtk_widget_show (separator); + } else { + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (associate_table_parent), hbox); + gtk_widget_show (hbox); + + _associate_table_items [0] = scim_string_view_new (); + //if (_default_font_desc) + // gtk_widget_modify_font (_associate_table_items [0], _default_font_desc); + gtk_widget_modify_base (_associate_table_items [0], GTK_STATE_NORMAL, &_normal_bg); + gtk_widget_modify_base (_associate_table_items [0], GTK_STATE_ACTIVE, &_active_bg); + gtk_widget_modify_text (_associate_table_items [0], GTK_STATE_NORMAL, &_normal_text); + gtk_widget_modify_text (_associate_table_items [0], GTK_STATE_ACTIVE, &_active_text); + scim_string_view_set_forward_event (SCIM_STRING_VIEW (_associate_table_items [0]), TRUE); + scim_string_view_set_auto_resize (SCIM_STRING_VIEW (_associate_table_items [0]), TRUE); + scim_string_view_set_has_frame (SCIM_STRING_VIEW (_associate_table_items [0]), FALSE); + scim_string_view_set_draw_cursor (SCIM_STRING_VIEW (_associate_table_items [0]), FALSE); + scim_string_view_set_auto_move_cursor (SCIM_STRING_VIEW (_associate_table_items [0]), FALSE); + g_signal_connect (G_OBJECT (_associate_table_items [0]), "move_cursor", + G_CALLBACK (ui_associate_table_horizontal_click_cb), + 0); + gtk_box_pack_start (GTK_BOX (hbox), _associate_table_items [0], TRUE, TRUE, 0); + gtk_widget_show (_associate_table_items [0]); + + separator = gtk_vseparator_new (); + GtkStyle *style = gtk_widget_get_style (separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (separator, style); + } + //gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); + gtk_widget_show (separator); + + // New right button + image = ui_create_left_icon (); + _associate_table_up_button = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (_associate_table_up_button), image); + gtk_widget_show (image); + gtk_box_pack_start (GTK_BOX (hbox), _associate_table_up_button, FALSE, FALSE, 0); + gtk_widget_show (_associate_table_up_button); + g_signal_connect (G_OBJECT (_associate_table_up_button), "clicked", + G_CALLBACK (ui_associate_table_up_button_click_cb), + image); + + // New left button + image = ui_create_right_icon (); + _associate_table_down_button = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (_associate_table_down_button), image); + gtk_widget_show (image); + gtk_box_pack_start (GTK_BOX (hbox), _associate_table_down_button, FALSE, FALSE, 0); + gtk_widget_show (_associate_table_down_button); + g_signal_connect (G_OBJECT (_associate_table_down_button), "clicked", + G_CALLBACK (ui_associate_table_down_button_click_cb), + image); + } + + gtk_button_set_relief (GTK_BUTTON (_associate_table_up_button), GTK_RELIEF_NONE); + gtk_widget_modify_bg (_associate_table_up_button, GTK_STATE_ACTIVE, &_normal_bg); + gtk_widget_modify_bg (_associate_table_up_button, GTK_STATE_INSENSITIVE, &_normal_bg); + gtk_widget_modify_bg (_associate_table_up_button, GTK_STATE_PRELIGHT, &_normal_bg); + + gtk_button_set_relief (GTK_BUTTON (_associate_table_down_button), GTK_RELIEF_NONE); + gtk_widget_modify_bg (_associate_table_down_button, GTK_STATE_ACTIVE, &_normal_bg); + gtk_widget_modify_bg (_associate_table_down_button, GTK_STATE_INSENSITIVE, &_normal_bg); + gtk_widget_modify_bg (_associate_table_down_button, GTK_STATE_PRELIGHT, &_normal_bg); + } +} + +/** + * @brief Callback function for press event of candidate scroller. + * + * @param widget The handler of candidate scroller. + * @param event The GdkEvent pointer for this event. + * @param user_data Data pointer to pass when it is called. + */ +static gboolean candidate_scroll_button_press_cb (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << "[candidate_scroll_button_press_cb] event type=" << event->type << "\n"; + + if (_scroll_start < -9999) { + GtkWidget *hscrollbar = gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW (widget)); + _scroll_start = gtk_range_get_value (GTK_RANGE (hscrollbar)); + } + _show_scroll = true; + + return FALSE; +} + +/** + * @brief Callback function for motion event of candidate scroller. + * + * @param widget The handler of candidate scroller. + * @param event The GdkEvent pointer for this event. + * @param user_data Data pointer to pass when it is called. + */ +static gboolean candidate_scroll_motion_cb (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << "[candidate_scroll_motion_cb] event type=" << event->type << "\n"; + + _candidate_motion++; + if (_candidate_motion > 1) + _show_scroll = true; + + return FALSE; +} + +/** + * @brief Callback function for flick event of candidate scroller. + * + * @param widget The handler of candidate scroller. + * @param event The GdkEvent pointer for this event. + * @param user_data Data pointer to pass when it is called. + */ +static gboolean candidate_scroll_flick_cb (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << "[candidate_scroll_flick_cb] event type=" << event->type << "\n"; + + int *index_pos = NULL; + if (GPOINTER_TO_INT (user_data) == 1) { + scim_string_view_set_highlight (SCIM_STRING_VIEW (_lookup_table_items [0]), -1, -1); + index_pos = _lookup_table_index_pos; + } else if (GPOINTER_TO_INT (user_data) == 2) { + scim_string_view_set_highlight (SCIM_STRING_VIEW (_associate_table_items [0]), -1, -1); + index_pos = _associate_table_index_pos; + } + + if (event->type != GDK_BUTTON_RELEASE && index_pos != NULL) { + GtkWidget *hscrollbar = gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW (widget)); + gdouble pos = gtk_range_get_value (GTK_RANGE (hscrollbar)); + int new_pos = 0; + for (int i = 1; (int)pos > 0; i++) { + if (index_pos[i] <= 0 || ((pos-index_pos[i] > -0.01) && (pos-index_pos[i] < 0.01))) + break; + if (pos < index_pos[i]) { + if (_scroll_start < pos) + new_pos = index_pos[i]; + else + new_pos = index_pos[i-1]; + gtk_range_set_value (GTK_RANGE (hscrollbar), new_pos); + break; + } + } + } + + _candidate_motion = 0; + _scroll_start = -10000; + _show_scroll = false; + + return FALSE; +} + +/** + * @brief Create prediction engine style candidate window. + * + * @param vertical An indicator for vertical window or horizontal window. + */ +static void create_prediction_engine_candidate_window (bool vertical) +{ + GtkWidget *input_window_vbox = NULL; + GtkWidget *input_window_hbox = NULL; + gint input_window_width; + gint thickness = 1; + gint border_width = 2; + gint new_height = ((69 * gdk_screen_height ()) / 800) - (2 * border_width); + + input_window_width = gdk_screen_width (); + + _lookup_icon_size = input_window_width / 24; + if (_lookup_icon_size < LOOKUP_ICON_SIZE) + _lookup_icon_size = LOOKUP_ICON_SIZE; + + GtkWidget *default_label = gtk_label_new ("default label"); + GtkStyle *label_style = gtk_widget_get_style (default_label); +#ifdef USING_ISF_SWITCH_BUTTON + GdkColor base_normal = label_style->base[GTK_STATE_NORMAL]; + GdkColor base_active = label_style->base[GTK_STATE_ACTIVE]; + GdkColor text_normal = label_style->text[GTK_STATE_NORMAL]; + GdkColor text_active = label_style->text[GTK_STATE_ACTIVE]; +#else + GdkColor base_normal = label_style->bg[GTK_STATE_NORMAL]; + GdkColor base_active = label_style->bg[GTK_STATE_ACTIVE]; + GdkColor text_normal = label_style->fg[GTK_STATE_NORMAL]; + GdkColor text_active = label_style->fg[GTK_STATE_ACTIVE]; +#endif + + GdkColor text_insensitive; + gdk_color_parse ("#333333", &text_insensitive); + //String strColor = _config->read (String (SCIM_CONFIG_PANEL_GTK_COLOR_SEPARATOR), String ("#333333")); + //gdk_color_parse (strColor.c_str (), &text_insensitive); + //_config->write (String (SCIM_CONFIG_PANEL_GTK_COLOR_SEPARATOR), strColor); + + gdk_color_parse ("#2B2B2B", &base_normal); + + // Create input window + { + GtkWidget *vbox = NULL; + GtkWidget *hbox = NULL; + GtkWidget *frame = NULL; + GtkWidget *event_box = NULL; + + _input_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint (GTK_WINDOW (_input_window), GDK_WINDOW_TYPE_HINT_UTILITY); + + if (!vertical) + gtk_widget_set_size_request (GTK_WIDGET (_input_window), input_window_width, -1); + if (_candidate_mode == LANDSCAPE_HORIZONTAL_CANDIDATE_MODE) { +#if HAVE_GCONF + gtk_window_set_rotate (GTK_WINDOW (_input_window), LANDSCAPE_DEGREE); +#endif + gtk_widget_set_size_request (GTK_WIDGET (_input_window), gdk_screen_height (), -1); + } else if (_candidate_mode == LANDSCAPE_VERTICAL_CANDIDATE_MODE) { +#if HAVE_GCONF + gtk_window_set_rotate (GTK_WINDOW (_input_window), LANDSCAPE_DEGREE); +#endif + } + + //gtk_window_set_type_hint (GTK_WINDOW (_input_window), GDK_WINDOW_TYPE_HINT_NOTIFICATION); + //gtk_window_set_keep_above (GTK_WINDOW (_input_window), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (_input_window), border_width); + //gtk_widget_modify_bg (_input_window, GTK_STATE_NORMAL, &(text_insensitive)); + gtk_window_set_policy (GTK_WINDOW (_input_window), TRUE, TRUE, FALSE); + gtk_window_set_accept_focus (GTK_WINDOW (_input_window), FALSE); + gtk_window_set_resizable (GTK_WINDOW (_input_window), FALSE); + gtk_widget_add_events (_input_window, GDK_BUTTON_PRESS_MASK); + gtk_widget_add_events (_input_window, GDK_BUTTON_RELEASE_MASK); + gtk_widget_add_events (_input_window, GDK_POINTER_MOTION_MASK); + g_signal_connect (G_OBJECT (_input_window), "button-press-event", + G_CALLBACK (ui_input_window_click_cb), + GINT_TO_POINTER (0)); + g_signal_connect (G_OBJECT (_input_window), "button-release-event", + G_CALLBACK (ui_input_window_click_cb), + GINT_TO_POINTER (1)); + + event_box = gtk_event_box_new (); + gtk_container_add (GTK_CONTAINER (_input_window), event_box); + gtk_widget_show (event_box); + + frame = gtk_frame_new (0); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT); + gtk_container_add (GTK_CONTAINER (event_box), frame); + gtk_widget_show (frame); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (frame), hbox); + gtk_widget_show (hbox); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show (vbox); + input_window_vbox = vbox; + + // Create preedit area + _preedit_area = scim_string_view_new (); + gtk_widget_modify_base (_preedit_area, GTK_STATE_NORMAL, &(base_normal)); + gtk_widget_modify_base (_preedit_area, GTK_STATE_ACTIVE, &(base_active)); + gtk_widget_modify_text (_preedit_area, GTK_STATE_NORMAL, &(text_normal)); + gtk_widget_modify_text (_preedit_area, GTK_STATE_ACTIVE, &(text_active)); + scim_string_view_set_width_chars (SCIM_STRING_VIEW (_preedit_area), 24); + scim_string_view_set_forward_event (SCIM_STRING_VIEW (_preedit_area), TRUE); + scim_string_view_set_auto_resize (SCIM_STRING_VIEW (_preedit_area), TRUE); + scim_string_view_set_has_frame (SCIM_STRING_VIEW (_preedit_area), FALSE); + g_signal_connect (G_OBJECT (_preedit_area), "move_cursor", + G_CALLBACK (ui_preedit_area_move_cursor_cb), + 0); + gtk_box_pack_start (GTK_BOX (vbox), _preedit_area, TRUE, TRUE, 0); + + // Create aux area + _aux_area = scim_string_view_new (); + if (_default_font_desc) + gtk_widget_modify_font (_aux_area, _default_font_desc); + gtk_widget_modify_base (_aux_area, GTK_STATE_NORMAL, &(base_normal)); + gtk_widget_modify_base (_aux_area, GTK_STATE_ACTIVE, &(base_active)); + gtk_widget_modify_text (_aux_area, GTK_STATE_NORMAL, &(text_normal)); + gtk_widget_modify_text (_aux_area, GTK_STATE_ACTIVE, &(text_active)); + scim_string_view_set_width_chars (SCIM_STRING_VIEW (_aux_area), 24); + scim_string_view_set_draw_cursor (SCIM_STRING_VIEW (_aux_area), FALSE); + scim_string_view_set_forward_event (SCIM_STRING_VIEW (_aux_area), TRUE); + scim_string_view_set_auto_resize (SCIM_STRING_VIEW (_aux_area), TRUE); + scim_string_view_set_has_frame (SCIM_STRING_VIEW (_aux_area), FALSE); + gtk_box_pack_start (GTK_BOX (vbox), _aux_area, TRUE, TRUE, 0); + } + + // Create lookup table window + { + GtkWidget *vbox = NULL; + GtkWidget *hbox = NULL; + GtkWidget *lookup_table_parent = NULL; + + { + _lookup_table_window = gtk_vbox_new (FALSE, 0); + if (vertical) { + input_window_hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (input_window_vbox), input_window_hbox, TRUE, TRUE, 0); + gtk_widget_show (input_window_hbox); + gtk_box_pack_start (GTK_BOX (input_window_hbox), _lookup_table_window, TRUE, TRUE, 0); + } else { + gtk_box_pack_start (GTK_BOX (input_window_vbox), _lookup_table_window, TRUE, TRUE, 0); + } + lookup_table_parent = _lookup_table_window; + _candidate_separator = gtk_hseparator_new (); + GtkStyle *style = gtk_widget_get_style (_candidate_separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (_candidate_separator, style); + } + gtk_box_pack_start (GTK_BOX (lookup_table_parent), _candidate_separator, FALSE, FALSE, 0); + gtk_widget_show (_candidate_separator); + } + + // Vertical lookup table + if (vertical) { + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (lookup_table_parent), vbox); + gtk_widget_show (vbox); + + _candidate_scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (_candidate_scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_widget_set_size_request (_candidate_scroll, -1, gdk_screen_height () / 3); + gtk_box_pack_start (GTK_BOX (vbox), _candidate_scroll, TRUE, TRUE, 0); + gtk_widget_show (_candidate_scroll); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (_candidate_scroll), hbox); + gtk_widget_show (hbox); + + GtkWidget *ilabel = gtk_label_new (" "); + gtk_widget_set_size_request (ilabel, BLANK_SIZE, -1); + gtk_box_pack_start (GTK_BOX (hbox), ilabel, FALSE, FALSE, 0); + gtk_widget_show (ilabel); + + GtkWidget *vbox_candidate = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox_candidate, TRUE, TRUE, 0); + gtk_widget_show (vbox_candidate); + + // New table items + for (int i=0; i= new_height) { + gtk_widget_set_size_request (GTK_WIDGET (_candidate_scroll), -1, scroll_size.height); + } else { + gtk_widget_size_request (_lookup_table_items [0], &lookup_size); + gtk_widget_set_size_request (GTK_WIDGET (_candidate_scroll), -1, new_height); + gtk_widget_set_size_request (GTK_WIDGET (_lookup_table_items [0]), -1, + lookup_size.height + (new_height - scroll_size.height)); + } + } + } + + //Create associate table window + { + GtkWidget *vbox = NULL; + GtkWidget *hbox = NULL; + GtkWidget *associate_table_parent = NULL; + + _associate_table_window = gtk_vbox_new (FALSE, 0); + if (vertical) { + _middle_separator = gtk_vseparator_new (); + GtkStyle *style = gtk_widget_get_style (_middle_separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (_middle_separator, style); + } + //gtk_box_pack_start (GTK_BOX (input_window_hbox), _middle_separator, FALSE, FALSE, 0); + gtk_widget_show (_middle_separator); + + gtk_box_pack_start (GTK_BOX (input_window_hbox), _associate_table_window, TRUE, TRUE, 0); + } else { + gtk_box_pack_start (GTK_BOX (input_window_vbox), _associate_table_window, TRUE, TRUE, 0); + } + associate_table_parent = _associate_table_window; + _associate_separator = gtk_hseparator_new (); + GtkStyle *style = gtk_widget_get_style (_associate_separator); + if (style != NULL) { + style->xthickness = thickness; + style->ythickness = thickness; + gtk_widget_set_style (_associate_separator, style); + } + gtk_box_pack_start (GTK_BOX (associate_table_parent), _associate_separator, FALSE, FALSE, 0); + gtk_widget_show (_associate_separator); + + if (vertical) { + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (associate_table_parent), vbox); + gtk_widget_show (vbox); + + _associate_scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (_associate_scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_widget_set_size_request (_associate_scroll, -1, gdk_screen_height () / 3); + gtk_box_pack_start (GTK_BOX (vbox), _associate_scroll, TRUE, TRUE, 0); + gtk_widget_show (_associate_scroll); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (_associate_scroll), hbox); + gtk_widget_show (hbox); + + GtkWidget *ilabel = gtk_label_new (" "); + gtk_widget_set_size_request (ilabel, BLANK_SIZE, -1); + gtk_box_pack_start (GTK_BOX (hbox), ilabel, FALSE, FALSE, 0); + gtk_widget_show (ilabel); + + GtkWidget *vbox_associate = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox_associate, TRUE, TRUE, 0); + gtk_widget_show (vbox_associate); + + // New table items + for (int i=0; i= new_height) { + gtk_widget_set_size_request (GTK_WIDGET (_associate_scroll), -1, scroll_size.height); + } else { + gtk_widget_size_request (_associate_table_items [0], &lookup_size); + gtk_widget_set_size_request (GTK_WIDGET (_associate_scroll), -1, new_height); + gtk_widget_set_size_request (GTK_WIDGET (_associate_table_items [0]), -1, + lookup_size.height + (new_height - scroll_size.height)); + } + } + } + + // Load background and divider + { + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (ISF_CANDIDATE_BG_FILE, NULL); + if (pixbuf != NULL && _input_window != NULL) { + gtk_widget_set_app_paintable (_input_window, TRUE); + gtk_widget_realize (_input_window); + GdkPixmap *pixmap = gdk_pixmap_new (_input_window->window, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), -1); + if (pixmap != NULL) { + gdk_draw_pixbuf (pixmap, + _input_window->style->fg_gc[GTK_STATE_NORMAL], + pixbuf, + 0, 0, 0, 0, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); + gdk_window_set_back_pixmap (_input_window->window, pixmap, FALSE); + } + g_object_unref (pixbuf); + } + + pixbuf = gdk_pixbuf_new_from_file (ISF_CANDIDATE_DIVIDER_FILE, NULL); + if (pixbuf != NULL && _input_window != NULL) { + GdkPixmap *pixmap = gdk_pixmap_new (_input_window->window, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), -1); + gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, NULL, 0); + if (pixmap != NULL) { + scim_string_view_set_divider (SCIM_STRING_VIEW (_lookup_table_items [0]), pixmap); + scim_string_view_set_divider (SCIM_STRING_VIEW (_associate_table_items [0]), pixmap); + } + g_object_unref (pixbuf); + } + } + + // Get split string according to screen width + String str; + GtkRequisition size; + size.width = 0; + _split_string1 = String (""); + _split_string2 = String (""); + do { + _split_string1 = _split_string1 + String (" "); + _split_string2 = _split_string2 + String (" "); + str = _split_string2 + _split_string1; + scim_string_view_set_text (SCIM_STRING_VIEW (_lookup_table_items [0]), str.c_str ()); + gtk_widget_size_request (_lookup_table_items [0], &size); + } while (size.width < (15*_width_rate)); + + // Get space string + _space_string = _split_string1; +} + +/** + * @brief Create candidate window. + * + * @param style The candidate window style. + * @param vertical An indicator for vertical window or horizontal window. + */ +static void create_candidate_window (GTK_CANDIDATE_STYLE_T style, bool vertical) +{ + check_time ("\nEnter create_candidate_window"); + SCIM_DEBUG_MAIN (1) << "Create candidate window...\n"; + + if (_associate_table_window) { + gtk_widget_destroy (_associate_table_window); + _associate_table_window = 0; + } + if (_lookup_table_window) { + gtk_widget_destroy (_lookup_table_window); + _lookup_table_window = 0; + } + if (_input_window) { + gtk_widget_destroy (_input_window); + _input_window = 0; + } + + if (style == PREDICTION_ENGINE_CANDIDATE_STYLE) + create_prediction_engine_candidate_window (vertical); + else + create_scim_candidate_window (vertical); +/* + if (_candidate_mode == LANDSCAPE_HORIZONTAL_CANDIDATE_MODE) { + gtk_window_set_rotate (GTK_WINDOW (_input_window), LANDSCAPE_DEGREE); + gtk_widget_set_size_request (GTK_WIDGET (_input_window), gdk_screen_height (), -1); + } else if (_candidate_mode == LANDSCAPE_VERTICAL_CANDIDATE_MODE) { + gtk_window_set_rotate (GTK_WINDOW (_input_window), LANDSCAPE_DEGREE); + } +*/ + check_time ("Exit create_candidate_window"); +} + +/** + * @brief Update separator for candidate window. + */ +static void update_separator_status (void) +{ + if (_lookup_table_vertical) { + if (GTK_WIDGET_VISIBLE (_aux_area)) { + gtk_widget_show (_candidate_separator); + gtk_widget_show (_associate_separator); + } else { + gtk_widget_hide (_candidate_separator); + gtk_widget_hide (_associate_separator); + } + + if (GTK_IS_WIDGET (_middle_separator)) { + if (GTK_WIDGET_VISIBLE (_lookup_table_window) && GTK_WIDGET_VISIBLE (_associate_table_window)) + gtk_widget_show (_middle_separator); + else + gtk_widget_hide (_middle_separator); + } + } else { + if (GTK_WIDGET_VISIBLE (_aux_area)) + gtk_widget_show (_candidate_separator); + else + gtk_widget_hide (_candidate_separator); + + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) { + if (GTK_WIDGET_VISIBLE (_aux_area) && !GTK_WIDGET_VISIBLE (_lookup_table_window)) + gtk_widget_show (_associate_separator); + else + gtk_widget_hide (_associate_separator); + } else { + if (GTK_WIDGET_VISIBLE (_aux_area) || GTK_WIDGET_VISIBLE (_lookup_table_window)) + gtk_widget_show (_associate_separator); + else + gtk_widget_hide (_associate_separator); + } + + if (GTK_IS_WIDGET (_middle_separator)) { + if (GTK_WIDGET_VISIBLE (_middle_separator)) + gtk_widget_hide (_middle_separator); + } + } +} + +/** + * @brief Set active ISE by uuid. + * + * @param uuid The ISE's uuid. + * + * @return false if ISE change is failed, otherwise return true. + */ +static bool set_active_ise_by_uuid (const String &ise_uuid, bool changeDefault) +{ + if (ise_uuid.length () <= 0) + return false; + + GtkTreePath *path = 0; + gchar *uuid = 0; + gchar *arg1 = 0; + GtkTreeIter iter; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (_active_ise_list_store), &iter)) { + do { + gtk_tree_model_get (GTK_TREE_MODEL (_active_ise_list_store), &iter, ACTIVE_ISE_UUID, &uuid, -1); + if (uuid != NULL && !strcmp (uuid, ise_uuid.c_str ())) { + path = gtk_tree_model_get_path (GTK_TREE_MODEL (_active_ise_list_store), &iter); + arg1 = gtk_tree_path_to_string (path); + on_active_ise_enable_box_clicked (NULL, arg1, NULL); + if (path) { + gtk_tree_path_free (path); + path = 0; + } + if (arg1) { + g_free (arg1); + arg1 = 0; + } + if (uuid) { + g_free (uuid); + uuid = 0; + } + return true; + } + if (uuid) { + g_free (uuid); + uuid = 0; + } + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (_active_ise_list_store), &iter)); + } + + return false; +} + +/** + * @brief Reload config callback function for ISF panel. + * + * @param config The config pointer. + */ +static void ui_config_reload_callback (const ConfigPointer &config) +{ + _config = config; + ui_initialize (); +} + +/** + * @brief Load ISF configuration and ISEs information. + */ +static void ui_load_config (void) +{ + String str; + bool shared_ise = false; + gchar font_description_string[MAX_FONT_STR_SIZE]; + + // Read configurations. + gdk_color_parse ("gray92", &_normal_bg); + gdk_color_parse ("black", &_normal_text); + gdk_color_parse ("light blue", &_active_bg); + gdk_color_parse ("black", &_active_text); + + if (_default_font_desc) { + pango_font_description_free (_default_font_desc); + _default_font_desc = 0; + } + + if (!_config.null ()) { + str = _config->read (String (SCIM_CONFIG_PANEL_GTK_FONT), String ("default")); + + if (str != String ("default")) { +#if HAVE_GCONF + snprintf (font_description_string, sizeof (font_description_string), "Vodafone Rg Bold %d", FONT_SIZE_OF_CANDIDATE_WIDGET); +#endif + } else { + snprintf (font_description_string, sizeof (font_description_string), "default"); + } + _default_font_desc = pango_font_description_from_string (font_description_string); + + str = _config->read (String (SCIM_CONFIG_PANEL_GTK_COLOR_NORMAL_BG), String ("gray92")); + gdk_color_parse (str.c_str (), &_normal_bg); + + str = _config->read (String (SCIM_CONFIG_PANEL_GTK_COLOR_NORMAL_TEXT), String ("black")); + gdk_color_parse (str.c_str (), &_normal_text); + + str = _config->read (String (SCIM_CONFIG_PANEL_GTK_COLOR_ACTIVE_BG), String ("light blue")); + gdk_color_parse (str.c_str (), &_active_bg); + + str = _config->read (String (SCIM_CONFIG_PANEL_GTK_COLOR_ACTIVE_TEXT), String ("black")); + gdk_color_parse (str.c_str (), &_active_text); + + _window_sticked = _config->read (String (SCIM_CONFIG_PANEL_GTK_DEFAULT_STICKED), _window_sticked); + _candidate_style = (GTK_CANDIDATE_STYLE_T)_config->read (String (SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_STYLE), _candidate_style); + _candidate_mode = (GTK_CANDIDATE_MODE_T)_config->read (String (SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_MODE), _candidate_mode); + _lookup_table_vertical = _config->read (String (SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_VERTICAL), _lookup_table_vertical); + shared_ise = _config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), shared_ise); + _panel_agent->set_should_shared_ise (shared_ise); + } +} + +#ifdef GDK_WINDOWING_X11 +/** + * @brief GDK X event filter function. + * + * @param gdk_xevent The handler of GDK X event. + * @param event The GdkEvent handler. + * @param data The data pointer to pass when it is called. + * + * @return GDK_FILTER_CONTINUE. + */ +static GdkFilterReturn ui_event_filter (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) +{ + g_return_val_if_fail (gdk_xevent, GDK_FILTER_CONTINUE); + + XEvent *xev = (XEvent*)gdk_xevent; + + if (xev->type == PropertyNotify) { + if (xev->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_WORKAREA") || + xev->xproperty.atom == gdk_x11_get_xatom_by_name ("_NET_CURRENT_DESKTOP")) { + } + } + + return GDK_FILTER_CONTINUE; +} +#endif + +/** + * @brief UI initialize function. + */ +static void ui_initialize (void) +{ + SCIM_DEBUG_MAIN (1) << "Initialize UI...\n"; + + ui_load_config (); + +#if GDK_MULTIHEAD_SAFE + // Initialize the Display and Screen. + _current_screen = gdk_screen_get_default (); +#endif + + isf_load_config (); + create_and_fill_active_ise_list_store (); + +#ifdef GDK_WINDOWING_X11 + // Add an event filter function to observe X root window's properties. + GdkWindow *root_window = gdk_get_default_root_window (); +#if GDK_MULTIHEAD_SAFE + if (_current_screen) + root_window = gdk_screen_get_root_window (_current_screen); +#endif + gdk_window_set_events (root_window, (GdkEventMask)GDK_PROPERTY_NOTIFY); + gdk_window_add_filter (root_window, ui_event_filter, NULL); +#endif +} + +/** + * @brief Settle candidate window position. + * + * @param relative It indicates whether candidate position is relative. + * @param force It indicates whether candidate position is forced to update. + */ +static void ui_settle_input_window (bool relative, bool force) +{ + SCIM_DEBUG_MAIN (2) << " Settle input window...\n"; + if (!_input_window) + return; + + if (_window_sticked) { + if (force) + gtk_window_move (GTK_WINDOW (_input_window), _input_window_x, _input_window_y); + return; + } + + GtkRequisition ws; + gint spot_x, spot_y; + gint screen_width, screen_height; + + if (_candidate_mode == LANDSCAPE_HORIZONTAL_CANDIDATE_MODE || + _candidate_mode == LANDSCAPE_VERTICAL_CANDIDATE_MODE) { + screen_width = ui_screen_height (); + screen_height = ui_screen_width (); + } else { + screen_width = ui_screen_width (); + screen_height = ui_screen_height (); + } + + gtk_widget_size_request (_input_window, &ws); + + if (_candidate_left >= 0 || _candidate_top >= 0) { + spot_x = _candidate_left; + spot_y = _candidate_top; + if (spot_x + ws.width > screen_width) + spot_x = screen_width - ws.width; + if (spot_y + ws.height > screen_height) + spot_y = screen_height - ws.height; + } else { + rectinfo ise_rect; + _panel_agent->get_current_ise_geometry (ise_rect); + //std::cout << " ise x : " << ise_rect.pos_x << " ise y : " << ise_rect.pos_y; + //std::cout << " ise width : " << ise_rect.width << " ise height : " << ise_rect.height << "\n"; + + if (!relative) { + spot_x = _spot_location_x; + spot_y = _spot_location_y; + } else { + spot_x = _input_window_x; + spot_y = _input_window_y; + } + + if (ise_rect.pos_y > 0 && spot_y + ws.height > (int)ise_rect.pos_y + && spot_y < (int)(ise_rect.pos_y + ise_rect.height / 2)) + spot_y = _spot_location_top_y - ws.height; + + if (spot_x + ws.width > screen_width) + spot_x = screen_width - ws.width; + if (spot_y + ws.height > screen_height) + spot_y = _spot_location_top_y - ws.height; + } + + if (spot_x < 0) spot_x = 0; + if (spot_y < 0) spot_y = 0; + + gtk_window_get_position (GTK_WINDOW (_input_window), &_input_window_x, &_input_window_y); + + if (spot_x != _input_window_x || spot_y != _input_window_y || force) { + if (!_lookup_table_vertical) + spot_x = 0; + + gtk_window_move (GTK_WINDOW (_input_window), spot_x, spot_y); + + _input_window_x = spot_x; + _input_window_y = spot_y; + //std::cout << " candidate x : " << spot_x << " candidate y : " << spot_y << "\n"; + } +} + +/** + * @brief Get screen width. + * + * @return screen width. + */ +static int ui_screen_width (void) +{ +#if GDK_MULTIHEAD_SAFE + if (_current_screen) + return gdk_screen_get_width (_current_screen); +#endif + return gdk_screen_width (); +} + +/** + * @brief Get screen height. + * + * @return screen height. + */ +static int ui_screen_height (void) +{ +#if GDK_MULTIHEAD_SAFE + if (_current_screen) + return gdk_screen_get_height (_current_screen); +#endif + return gdk_screen_height (); +} + +#if GDK_MULTIHEAD_SAFE +/** + * @brief Switch screen. + * + * @param screen The GdkScreen pointer. + */ +static void ui_switch_screen (GdkScreen *screen) +{ + if (screen) { + if (_input_window) { + gtk_window_set_screen (GTK_WINDOW (_input_window), screen); + + _input_window_x = ui_screen_width (); + _input_window_y = ui_screen_height (); + + gtk_window_move (GTK_WINDOW (_input_window), _input_window_x, _input_window_y); + } + + if (_toolbar_window) { + gtk_window_set_screen (GTK_WINDOW (_toolbar_window), screen); + } + +#ifdef GDK_WINDOWING_X11 + GdkWindow *root_window = gdk_get_default_root_window (); + if (_current_screen) + root_window = gdk_screen_get_root_window (_current_screen); + gdk_window_set_events (root_window, (GdkEventMask)GDK_PROPERTY_NOTIFY); + gdk_window_add_filter (root_window, ui_event_filter, NULL); +#endif + + ui_settle_input_window (); + } +} +#endif + +/** + * @brief Scale pixbuf. + * + * @param pixbuf The GdkPixbuf pointer. + * @param width The dest width. + * @param height The dest height. + * + * @return the pointer of dest GdkPixbuf. + */ +static GdkPixbuf * ui_scale_pixbuf (GdkPixbuf *pixbuf, + int width, + int height) +{ + if (pixbuf) { + if (gdk_pixbuf_get_width (pixbuf) != width || + gdk_pixbuf_get_height (pixbuf) != height) { + GdkPixbuf *dest = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR); + g_object_unref (pixbuf); + pixbuf = dest; + } + } + return pixbuf; +} + +/** + * @brief Create icon. + * + * @param iconfile The icon file path. + * @param xpm The GdkPixbuf pointer of icon. + * @param width The dest icon width. + * @param height The dest icon height. + * @param force_create It indicates whether create one icon when error occurs. + * + * @return the GtkWidget pointer of dest icon. + */ +static GtkWidget * ui_create_icon (const String &iconfile, + const char **xpm, + int width, + int height, + bool force_create) +{ + String path = iconfile; + GdkPixbuf *pixbuf = 0; + + if (path.length ()) { + // Not a absolute path, prepend SCIM_ICONDIR + if (path [0] != SCIM_PATH_DELIM) + path = String (SCIM_ICONDIR) + String (SCIM_PATH_DELIM_STRING) + path; + + pixbuf = gdk_pixbuf_new_from_file (path.c_str (), 0); + } + + if (!pixbuf && xpm) { + pixbuf = gdk_pixbuf_new_from_xpm_data (xpm); + } + + if (!pixbuf && force_create) { + if (width <= 0 || height <= 0) + return 0; + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, true, 8, width, height); + + if (!pixbuf) + return 0; + + gdk_pixbuf_fill (pixbuf, 0); + } + + if (pixbuf) { + if (width <= 0) width = gdk_pixbuf_get_width (pixbuf); + if (height <= 0) height = gdk_pixbuf_get_height (pixbuf); + + pixbuf = ui_scale_pixbuf (pixbuf, width, height); + + GtkWidget *icon = gtk_image_new_from_pixbuf (pixbuf); + gtk_widget_show (icon); + + gdk_pixbuf_unref (pixbuf); + + return icon; + } + return 0; +} + +/** + * @brief Create up icon. + * + * @return the GtkWidget pointer of up icon. + */ +static GtkWidget * ui_create_up_icon (void) +{ + return ui_create_icon (SCIM_UP_ICON_FILE, + (const char **) up_xpm, + _lookup_icon_size, + _lookup_icon_size); +} + +/** + * @brief Create left icon. + * + * @return the GtkWidget pointer of left icon. + */ +static GtkWidget * ui_create_left_icon (void) +{ + return ui_create_icon (SCIM_LEFT_ICON_FILE, + (const char **) left_xpm, + _lookup_icon_size, + _lookup_icon_size); +} + +/** + * @brief Create right icon. + * + * @return the GtkWidget pointer of right icon. + */ +static GtkWidget * ui_create_right_icon (void) +{ + return ui_create_icon (SCIM_RIGHT_ICON_FILE, + (const char **) right_xpm, + _lookup_icon_size, + _lookup_icon_size); +} + +/** + * @brief Create down icon. + * + * @return the GtkWidget pointer of down icon. + */ +static GtkWidget * ui_create_down_icon (void) +{ + return ui_create_icon (SCIM_DOWN_ICON_FILE, + (const char **) down_xpm, + _lookup_icon_size, + _lookup_icon_size); +} + +// Implementation of callback functions +/** + * @brief Callback function for cursor move event of preedit area. + * + * @param view The ScimStringView pointer. + * @param position The caret position. + */ +static void ui_preedit_area_move_cursor_cb (ScimStringView *view, + guint position) +{ + SCIM_DEBUG_MAIN (3) << " ui_preedit_area_move_cursor_cb...\n"; + + _panel_agent->move_preedit_caret (position); +} + +/** + * @brief Callback function for click event of vertical candidate table. + * + * @param item The GtkWidget handler. + * @param event The GdkEventButton handler for this event. + * @param user_data Data pointer to pass when it is called. + * + * @return true. + */ +static gboolean ui_lookup_table_vertical_click_cb (GtkWidget *item, + GdkEventButton *event, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_lookup_table_vertical_click_cb...\n"; + + _panel_agent->select_candidate ((uint32)GPOINTER_TO_INT (user_data)); + + return (gboolean)TRUE; +} + +/** + * @brief Callback function for click event of horizontal candidate table. + * + * @param item The GtkWidget handler of candidate string view. + * @param position The click position. + * @param user_data Data pointer to pass when it is called. + */ +static void ui_lookup_table_horizontal_click_cb (GtkWidget *item, + guint position, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_lookup_table_horizontal_click_cb...\n"; + uint32 type = (uint32)GPOINTER_TO_INT (user_data); + + int *index = _lookup_table_index; + int pos = (int) position - 1; + for (int i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE && index [i] >= 0; ++i) { + if (pos >= index [i] && pos < index [i+1]) { + if (type == 0) { // button press event + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) { + //gtk_widget_style_get (_input_window, "theme-color", &_theme_color, NULL); + if (_theme_color != NULL) { + gtk_widget_modify_base (item, GTK_STATE_ACTIVE, _theme_color); + gdk_color_free (_theme_color); + _theme_color = NULL; + } + } + scim_string_view_set_highlight (SCIM_STRING_VIEW (item), index [i], index [i+1]); + } else { // button release event + _panel_agent->select_candidate ((uint32) i); + scim_string_view_set_highlight (SCIM_STRING_VIEW (item), -1, - 1); + } + + return; + } + } + scim_string_view_set_highlight (SCIM_STRING_VIEW (item), -1, - 1); +} + +/** + * @brief Callback function for up button of candidate table. + * + * @param button The GtkButton handler. + * @param user_data Data pointer to pass when it is called. + */ +static void ui_lookup_table_up_button_click_cb (GtkButton *button, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_lookup_table_up_button_click_cb...\n"; + + _panel_agent->lookup_table_page_up (); +} + +/** + * @brief Callback function for down button of candidate table. + * + * @param button The GtkButton handler. + * @param user_data Data pointer to pass when it is called. + */ +static void ui_lookup_table_down_button_click_cb (GtkButton *button, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_lookup_table_down_button_click_cb...\n"; + + _panel_agent->lookup_table_page_down (); +} + +/** + * @brief Callback function for click event of vertical associate table. + * + * @param item The GtkWidget handler. + * @param event The GdkEventButton handler for this event. + * @param user_data Data pointer to pass when it is called. + * + * @return true. + */ +static gboolean ui_associate_table_vertical_click_cb (GtkWidget *item, + GdkEventButton *event, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_associate_table_vertical_click_cb...\n"; + + _panel_agent->select_associate ((uint32)GPOINTER_TO_INT (user_data)); + + return (gboolean)TRUE; +} + +/** + * @brief Callback function for click event of horizontal associate table. + * + * @param item The GtkWidget handler of candidate string view. + * @param position The click position. + * @param user_data Data pointer to pass when it is called. + */ +static void ui_associate_table_horizontal_click_cb (GtkWidget *item, + guint position, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_associate_table_horizontal_click_cb...\n"; + uint32 type = (uint32)GPOINTER_TO_INT (user_data); + + int *index = _associate_table_index; + int pos = (int) position - 1; + + for (int i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE && index [i] >= 0; ++i) { + if (pos >= index [i] && pos < index [i+1]) { + if (type == 0) { // button press event + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) { + //gtk_widget_style_get (_input_window, "theme-color", &_theme_color, NULL); + if (_theme_color != NULL) { + gtk_widget_modify_base (item, GTK_STATE_ACTIVE, _theme_color); + gdk_color_free (_theme_color); + _theme_color = NULL; + } + } + scim_string_view_set_highlight (SCIM_STRING_VIEW (item), index [i], index [i+1]); + } else { // button release event + _panel_agent->select_associate ((uint32) i); + scim_string_view_set_highlight (SCIM_STRING_VIEW (item), -1, - 1); + } + + return; + } + } + scim_string_view_set_highlight (SCIM_STRING_VIEW (item), -1, - 1); +} + +/** + * @brief Callback function for up button of associate table. + * + * @param button The GtkButton handler. + * @param user_data Data pointer to pass when it is called. + */ +static void ui_associate_table_up_button_click_cb (GtkButton *button, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_associate_table_up_button_click_cb...\n"; + + _panel_agent->associate_table_page_up (); +} + +/** + * @brief Callback function for down button of associate table. + * + * @param button The GtkButton handler. + * @param user_data Data pointer to pass when it is called. + */ +static void ui_associate_table_down_button_click_cb (GtkButton *button, + gpointer user_data) +{ + SCIM_DEBUG_MAIN (3) << " ui_associate_table_down_button_click_cb...\n"; + + _panel_agent->associate_table_page_down (); +} + +/** + * @brief Callback function for motion event of candidate window. + * + * @param window The GtkWidget handler. + * @param event The GdkEventMotion handler. + * @param user_data Data pointer to pass when it is called. + * + * @return FALSE. + */ +static gboolean ui_input_window_motion_cb (GtkWidget *window, + GdkEventMotion *event, + gpointer user_data) +{ + return FALSE; +} + +/** + * @brief Callback function for click event of candidate window. + * + * @param window The GtkWidget handler. + * @param event The GdkEventMotion handler. + * @param user_data Data pointer to pass when it is called. + * + * @return TRUE if this operation is successful, otherwise return FALSE. + */ +static gboolean ui_input_window_click_cb (GtkWidget *window, + GdkEventButton *event, + gpointer user_data) +{ + int click_type = GPOINTER_TO_INT (user_data); + static gulong motion_handler; + + if (click_type == 0) { + if (_input_window_draging) + return (gboolean)FALSE; + + // Connection pointer motion handler to this window. + motion_handler = g_signal_connect (G_OBJECT (window), "motion-notify-event", + G_CALLBACK (ui_input_window_motion_cb), + NULL); + + _input_window_draging = TRUE; + _input_window_drag_x = (gint) event->x_root; + _input_window_drag_y = (gint) event->y_root; +#ifdef ENABLE_CHANGE_CURSOR + cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW); + + // Grab the cursor to prevent losing events. + gdk_pointer_grab (window->window, TRUE, + (GdkEventMask) (GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK), + NULL, cursor, event->time); + gdk_cursor_unref (cursor); +#endif + return (gboolean)TRUE; + } else if (click_type == 1) { + if (!_input_window_draging) + return (gboolean)FALSE; + + g_signal_handler_disconnect (G_OBJECT (window), motion_handler); + gdk_pointer_ungrab (event->time); + _input_window_draging = FALSE; + + gtk_window_get_position (GTK_WINDOW (window), &_input_window_x, &_input_window_y); + + return (gboolean)TRUE; + } + + return (gboolean)FALSE; +} + +/** + * @brief This function is used to judge whether candidate window should be hidden. + * + * @return true if candidate window should be hidden, otherwise return false. + */ +static bool ui_can_hide_input_window (void) +{ + if (!_panel_is_on) + return true; + + if (GTK_WIDGET_VISIBLE (_preedit_area) || + GTK_WIDGET_VISIBLE (_aux_area) || + GTK_WIDGET_VISIBLE (_associate_table_window) || + GTK_WIDGET_VISIBLE (_lookup_table_window)) + return false; + return true; +} + +/** + * @brief Create pango attribute list. + * + * @param mbs The source string. + * @param attrs The attribute list. + * + * @return the pointer of PangoAttrList. + */ +static PangoAttrList * create_pango_attrlist (const String &mbs, + const AttributeList &attrs) +{ + PangoAttrList *attrlist = pango_attr_list_new (); + PangoAttribute *attr = NULL; + + guint start_index, end_index; + guint wlen = g_utf8_strlen (mbs.c_str (), mbs.length ()); + + for (int i=0; i < (int) attrs.size (); ++i) { + start_index = attrs[i].get_start (); + end_index = attrs[i].get_end (); + + if (end_index <= wlen && start_index < end_index) { + start_index = g_utf8_offset_to_pointer (mbs.c_str (), attrs[i].get_start ()) - mbs.c_str (); + end_index = g_utf8_offset_to_pointer (mbs.c_str (), attrs[i].get_end ()) - mbs.c_str (); + + if (attrs[i].get_type () == SCIM_ATTR_DECORATE) { + if (attrs[i].get_value () == SCIM_ATTR_DECORATE_UNDERLINE) { + attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); + if (attr != NULL) { + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (attrlist, attr); + } + } else if (attrs[i].get_value () == SCIM_ATTR_DECORATE_REVERSE) { + attr = pango_attr_foreground_new (_normal_bg.red, _normal_bg.green, _normal_bg.blue); + if (attr != NULL) { + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (attrlist, attr); + } + + attr = pango_attr_background_new (_normal_text.red, _normal_text.green, _normal_text.blue); + if (attr != NULL) { + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (attrlist, attr); + } + } else if (attrs[i].get_value () == SCIM_ATTR_DECORATE_HIGHLIGHT) { + attr = pango_attr_foreground_new (_active_text.red, _active_text.green, _active_text.blue); + if (attr != NULL) { + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (attrlist, attr); + } + + attr = pango_attr_background_new (_active_bg.red, _active_bg.green, _active_bg.blue); + if (attr != NULL) { + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (attrlist, attr); + } + } + } else if (attrs[i].get_type () == SCIM_ATTR_FOREGROUND) { + unsigned int color = attrs[i].get_value (); + + attr = pango_attr_foreground_new (SCIM_RGB_COLOR_RED(color) * 256, SCIM_RGB_COLOR_GREEN(color) * 256, SCIM_RGB_COLOR_BLUE(color) * 256); + if (attr != NULL) { + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (attrlist, attr); + } + } else if (attrs[i].get_type () == SCIM_ATTR_BACKGROUND) { + unsigned int color = attrs[i].get_value (); + + attr = pango_attr_background_new (SCIM_RGB_COLOR_RED(color) * 256, SCIM_RGB_COLOR_GREEN(color) * 256, SCIM_RGB_COLOR_BLUE(color) * 256); + if (attr != NULL) { + attr->start_index = start_index; + attr->end_index = end_index; + pango_attr_list_insert (attrlist, attr); + } + } + } + } + return attrlist; +} + +////////////////////////////////////////////////////////////////////// +// Start of PanelAgent Functions +////////////////////////////////////////////////////////////////////// +/** + * @brief Initialize panel agent. + * + * @param config The config string for PanelAgent. + * @param display The current display. + * @param resident The variable indicates whether panel will be resident. + * + * @return true if initialize is successful, otherwise return false. + */ +static bool initialize_panel_agent (const String &config, const String &display, bool resident) +{ + _panel_agent = new PanelAgent (); + + if (!_panel_agent || !_panel_agent->initialize (config, display, resident)) + return false; + + _panel_agent->signal_connect_transaction_start (slot (slot_transaction_start)); + _panel_agent->signal_connect_transaction_end (slot (slot_transaction_end)); + _panel_agent->signal_connect_reload_config (slot (slot_reload_config)); + _panel_agent->signal_connect_turn_on (slot (slot_turn_on)); + _panel_agent->signal_connect_turn_off (slot (slot_turn_off)); + _panel_agent->signal_connect_focus_in (slot (slot_focus_in)); + _panel_agent->signal_connect_focus_out (slot (slot_focus_out)); + _panel_agent->signal_connect_show_panel (slot (slot_show_panel)); + _panel_agent->signal_connect_hide_panel (slot (slot_hide_panel)); + _panel_agent->signal_connect_update_screen (slot (slot_update_screen)); + _panel_agent->signal_connect_update_spot_location (slot (slot_update_spot_location)); + _panel_agent->signal_connect_update_factory_info (slot (slot_update_factory_info)); + _panel_agent->signal_connect_start_default_ise (slot (slot_start_default_ise)); + _panel_agent->signal_connect_set_candidate_ui (slot (slot_set_candidate_ui)); + _panel_agent->signal_connect_get_candidate_ui (slot (slot_get_candidate_ui)); + _panel_agent->signal_connect_set_candidate_position (slot (slot_set_candidate_position)); + _panel_agent->signal_connect_get_candidate_geometry (slot (slot_get_candidate_geometry)); + _panel_agent->signal_connect_set_keyboard_ise (slot (slot_set_keyboard_ise)); + _panel_agent->signal_connect_get_keyboard_ise (slot (slot_get_keyboard_ise)); + _panel_agent->signal_connect_show_preedit_string (slot (slot_show_preedit_string)); + _panel_agent->signal_connect_show_aux_string (slot (slot_show_aux_string)); + _panel_agent->signal_connect_show_lookup_table (slot (slot_show_lookup_table)); + _panel_agent->signal_connect_show_associate_table (slot (slot_show_associate_table)); + _panel_agent->signal_connect_hide_preedit_string (slot (slot_hide_preedit_string)); + _panel_agent->signal_connect_hide_aux_string (slot (slot_hide_aux_string)); + _panel_agent->signal_connect_hide_lookup_table (slot (slot_hide_lookup_table)); + _panel_agent->signal_connect_hide_associate_table (slot (slot_hide_associate_table)); + _panel_agent->signal_connect_update_preedit_string (slot (slot_update_preedit_string)); + _panel_agent->signal_connect_update_preedit_caret (slot (slot_update_preedit_caret)); + _panel_agent->signal_connect_update_aux_string (slot (slot_update_aux_string)); + _panel_agent->signal_connect_update_lookup_table (slot (slot_update_candidate_table)); + _panel_agent->signal_connect_update_associate_table (slot (slot_update_associate_table)); + _panel_agent->signal_connect_set_active_ise_by_uuid (slot (slot_set_active_ise_by_uuid)); + _panel_agent->signal_connect_get_ise_list (slot (slot_get_ise_list)); + _panel_agent->signal_connect_get_keyboard_ise_list (slot (slot_get_keyboard_ise_list)); + _panel_agent->signal_connect_get_language_list (slot (slot_get_language_list)); + _panel_agent->signal_connect_get_all_language (slot (slot_get_all_language)); + _panel_agent->signal_connect_get_ise_language (slot (slot_get_ise_language)); + _panel_agent->signal_connect_set_isf_language (slot (slot_set_isf_language)); + _panel_agent->signal_connect_get_ise_info_by_uuid (slot (slot_get_ise_info_by_uuid)); + _panel_agent->signal_connect_send_key_event (slot (slot_send_key_event)); + _panel_agent->signal_connect_lock (slot (slot_lock)); + _panel_agent->signal_connect_unlock (slot (slot_unlock)); + + _panel_agent->get_helper_list (_helper_list); + _panel_agent->get_active_ise_list (_load_ise_list); + + return true; +} + +/** + * @brief Run PanelAgent thread. + * + * @return ture if run PanelAgent thread is successful, otherwise return false. + */ +static bool run_panel_agent (void) +{ + SCIM_DEBUG_MAIN(1) << "run_panel_agent ()\n"; + + _panel_agent_thread = NULL; + + if (_panel_agent && _panel_agent->valid ()) + _panel_agent_thread = g_thread_create (panel_agent_thread_func, NULL, TRUE, NULL); + + return (_panel_agent_thread != NULL); +} + +/** + * @brief PanelAgent thread function. + * + * @param data Data to pass when it is called. + * + * @return NULL. + */ +static gpointer panel_agent_thread_func (gpointer data) +{ + SCIM_DEBUG_MAIN(1) << "panel_agent_thread_func ()\n"; + + if (!_panel_agent->run ()) + std::cerr << "Failed to run Panel.\n"; + + G_LOCK (_global_resource_lock); + _should_exit = true; + G_UNLOCK (_global_resource_lock); + + g_thread_exit (NULL); + return ((gpointer) NULL); +} + +/** + * @brief Start transaction slot function for PanelAgent. + */ +static void slot_transaction_start (void) +{ + gdk_threads_enter (); +} + +/** + * @brief End transaction slot function for PanelAgent. + */ +static void slot_transaction_end (void) +{ + gdk_threads_leave (); +} + +/** + * @brief Reload config slot function for PanelAgent. + */ +static void slot_reload_config (void) +{ + if (!_config.null ()) _config->reload (); +} + +/** + * @brief Turn on slot function for PanelAgent. + */ +static void slot_turn_on (void) +{ + _panel_is_on = true; + + if (_input_window) { + gtk_widget_hide (_input_window); + gtk_widget_hide (_lookup_table_window); + gtk_widget_hide (_associate_table_window); + gtk_widget_hide (_preedit_area); + gtk_widget_hide (_aux_area); + } +} + +/** + * @brief Turn off slot function for PanelAgent. + */ +static void slot_turn_off (void) +{ + _panel_is_on = false; + + if (_input_window) { + gtk_widget_hide (_input_window); + gtk_widget_hide (_lookup_table_window); + gtk_widget_hide (_associate_table_window); + gtk_widget_hide (_preedit_area); + gtk_widget_hide (_aux_area); + } +} + +/** + * @brief Focus in slot function for PanelAgent. + */ +static void slot_focus_in (void) +{ + if (!GTK_IS_WIDGET (_input_window)) + create_candidate_window (_candidate_style, _lookup_table_vertical); +} + +/** + * @brief Focus out slot function for PanelAgent. + */ +static void slot_focus_out (void) +{ +} + +/** + * @brief Show control panel slot function for PanelAgent. + */ +static void slot_show_panel (void) +{ + if (!_toolbar_window) + create_panel_window (); + + gtk_widget_show (_toolbar_window); + gtk_window_present (GTK_WINDOW (_toolbar_window)); + gdk_window_raise (_toolbar_window->window); + + GdkDrawable * pixmap = (GdkDrawable *) gdk_pixmap_new (_toolbar_window->window, + _panel_width, _panel_height, -1); + + gdk_pixbuf_render_pixmap_and_mask_for_colormap (_panel_bg_pixbuf, + gdk_drawable_get_colormap (pixmap), + &pixmap, + &_panel_window_mask, + 128); + gtk_widget_shape_combine_mask (_toolbar_window, _panel_window_mask, 0, 0); + + _panel_agent->update_isf_control_status (true); +} + +/** + * @brief Hide control panel slot function for PanelAgent. + */ +static void slot_hide_panel (void) +{ + if (_toolbar_window) { + gtk_widget_hide (_toolbar_window); + } + + _panel_agent->update_isf_control_status (false); +} + +/** + * @brief Update screen slot function for PanelAgent. + * + * @param num The screen number. + */ +static void slot_update_screen (int num) +{ +#if GDK_MULTIHEAD_SAFE + if (gdk_display_get_n_screens (gdk_display_get_default ()) > num) { + + GdkScreen *screen = gdk_display_get_screen (gdk_display_get_default (), num); + + if (screen) { +#ifdef GDK_WINDOWING_X11 + GdkWindow *root_window = gdk_get_default_root_window (); + if (_current_screen) + root_window = gdk_screen_get_root_window (_current_screen); + gdk_window_remove_filter (root_window, ui_event_filter, NULL); +#endif + + _current_screen = screen; + ui_switch_screen (screen); + } + } +#endif +} + +/** + * @brief Update keyboard ISE information slot function for PanelAgent. + * + * @param info The information of current Keyboard ISE. + */ +static void slot_update_factory_info (const PanelFactoryInfo &info) +{ + String ise_name = info.name; + String ise_icon = info.icon; + + TOOLBAR_MODE_T mode = _panel_agent->get_current_toolbar_mode (); + + if (TOOLBAR_HELPER_MODE == mode) + ise_name = _panel_agent->get_current_helper_name (); + + if (ise_name.length () > 0) { + _panel_agent->set_current_ise_name (ise_name); + + gchar *name = 0, *icon_file = 0; + GtkTreeIter iter; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (_active_ise_list_store), &iter)) { + do { + gtk_tree_model_get (GTK_TREE_MODEL (_active_ise_list_store), &iter, ACTIVE_ISE_NAME, &name, -1); + + if (name == (void *)0) + continue; + + if (!strcmp (name, ise_name.c_str ())) { + gtk_tree_model_get (GTK_TREE_MODEL (_active_ise_list_store), &iter, ACTIVE_ISE_ICON, &icon_file, -1); + ise_icon = String (icon_file); + gtk_list_store_set (GTK_LIST_STORE (_active_ise_list_store), &iter, + ACTIVE_ISE_LIST_ENABLE, TRUE, -1); + } else { + gtk_list_store_set (GTK_LIST_STORE (_active_ise_list_store), &iter, + ACTIVE_ISE_LIST_ENABLE, FALSE, -1); + } + if (name) { + g_free (name); + name = 0; + } + if (icon_file) { + g_free (icon_file); + icon_file = 0; + } + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (_active_ise_list_store), &iter)); + } + } +} + +/** + * @brief Update cursor position slot function for PanelAgent. + * + * @param x The x position of current cursor. + * @param y The bottom y position of current cursor. + * @param top_y The top y position of current cursor. + */ +static void slot_update_spot_location (int x, int y, int top_y) +{ + if (x >= 0 && x < ui_screen_width () && y >= 0 && y < ui_screen_height ()) { + _spot_location_x = x; + _spot_location_y = y; + _spot_location_top_y = top_y; + + ui_settle_input_window (); + } +} + +/** + * @brief Show preedit slot function for PanelAgent. + */ +static void slot_show_preedit_string (void) +{ + if (!_preedit_area) + return; + + gtk_widget_show (_preedit_area); + + if (_panel_is_on && !GTK_WIDGET_VISIBLE (_input_window)) { + gtk_widget_show (_input_window); + gdk_window_raise (_input_window->window); + } + + ui_settle_input_window (false, true); + update_separator_status (); +} + +/** + * @brief Show aux slot function for PanelAgent. + */ +static void slot_show_aux_string (void) +{ + if (!_aux_area) + return; + + gtk_widget_show (_aux_area); + + if (_panel_is_on && !GTK_WIDGET_VISIBLE (_input_window)) { + gtk_widget_show (_input_window); + gdk_window_raise (_input_window->window); + } + + ui_settle_input_window (false, true); + update_separator_status (); +} + +/** + * @brief Show candidate table slot function for PanelAgent. + */ +static void slot_show_lookup_table (void) +{ + if (!_lookup_table_window) + return; + + gtk_widget_show (_lookup_table_window); + _candidate_is_showed = true; + + if (_panel_is_on) { + if (!GTK_WIDGET_VISIBLE (_input_window)) { + gtk_widget_show (_input_window); + gdk_window_raise (_input_window->window);// Move the window up in case it is not at the top + gtk_window_present (GTK_WINDOW (_input_window)); + } + //ui_settle_input_window (false, true); + } + + update_separator_status (); +} + +/** + * @brief Show associate table slot function for PanelAgent. + */ +static void slot_show_associate_table (void) +{ + if (!_associate_table_window) + return; + + gtk_widget_show (_associate_table_window); + + if (_panel_is_on) { + if (!GTK_WIDGET_VISIBLE (_input_window)) { + gtk_widget_show (_input_window); + gdk_window_raise (_input_window->window); + } + ui_settle_input_window (false, true); + } + + update_separator_status (); +} + +/** + * @brief Hide preedit slot function for PanelAgent. + */ +static void slot_hide_preedit_string (void) +{ + SCIM_DEBUG_MAIN (1) << "slot_hide_preedit_string\n"; + if (!_preedit_area) + return; + + gtk_widget_hide (_preedit_area); + scim_string_view_set_text (SCIM_STRING_VIEW (_preedit_area), ""); + + if (ui_can_hide_input_window ()) + gtk_widget_hide (_input_window); +} + +/** + * @brief Hide aux slot function for PanelAgent. + */ +static void slot_hide_aux_string (void) +{ + if (!_aux_area) + return; + + gtk_widget_hide (_aux_area); + scim_string_view_set_text (SCIM_STRING_VIEW (_aux_area), ""); + + if (ui_can_hide_input_window ()) + gtk_widget_hide (_input_window); + + update_separator_status (); +} + +/** + * @brief Hide candidate table slot function for PanelAgent. + */ +static void slot_hide_lookup_table (void) +{ + if (!_lookup_table_window) + return; + + slot_lock (); + g_isf_candidate_table.clear (); + if (_candidate_timer) { + g_source_remove (_candidate_timer); + _candidate_timer = 0; + } + slot_unlock (); + + gtk_widget_hide (_lookup_table_window); + _candidate_is_showed = false; + + if (ui_can_hide_input_window ()) + gtk_widget_hide (_input_window); + + update_separator_status (); +} + +/** + * @brief Hide associate table slot function for PanelAgent. + */ +static void slot_hide_associate_table (void) +{ + if (!_associate_table_window) + return; + + gtk_widget_hide (_associate_table_window); + + if (ui_can_hide_input_window ()) + gtk_widget_hide (_input_window); + + update_separator_status (); +} + +/** + * @brief Update preedit slot function for PanelAgent. + * + * @param str The new preedit string. + * @param attrs The attribute list of new preedit string. + */ +static void slot_update_preedit_string (const String &str, const AttributeList &attrs) +{ + if (!GTK_IS_WIDGET (_preedit_area)) + create_candidate_window (_candidate_style, _lookup_table_vertical); + + PangoAttrList *attrlist = create_pango_attrlist (str, attrs); + + scim_string_view_set_attributes (SCIM_STRING_VIEW (_preedit_area), attrlist); + scim_string_view_set_text (SCIM_STRING_VIEW (_preedit_area), str.c_str ()); + + pango_attr_list_unref (attrlist); + + ui_settle_input_window (false); +} + +/** + * @brief Update caret slot function for PanelAgent. + * + * @param caret The caret position. + */ +static void slot_update_preedit_caret (int caret) +{ + if (!GTK_IS_WIDGET (_preedit_area)) + create_candidate_window (_candidate_style, _lookup_table_vertical); + + scim_string_view_set_position (SCIM_STRING_VIEW (_preedit_area), caret); +} + +/** + * @brief Update aux slot function for PanelAgent. + * + * @param str The new aux string. + * @param attrs The attribute list of new aux string. + */ +static void slot_update_aux_string (const String &str, const AttributeList &attrs) +{ + if (!GTK_IS_WIDGET (_aux_area)) + create_candidate_window (_candidate_style, _lookup_table_vertical); + + PangoAttrList *attrlist = create_pango_attrlist (str, attrs); + + String strAux = String (" ") + str; + scim_string_view_set_attributes (SCIM_STRING_VIEW (_aux_area), attrlist); + scim_string_view_set_text (SCIM_STRING_VIEW (_aux_area), strAux.c_str ()); + + pango_attr_list_unref (attrlist); + + ui_settle_input_window (false); +} + +/** + * @brief Update candidate/associate table. + * + * @param table_type The table type. + * @param table The lookup table for candidate or associate. + * @param table_items The table items for candidate or associate. + * @param table_index The index for candidate string or associate string. + * @param table_index_pos The index position for candidate or associate. + * @param scroll The candidate scroller or associate scroller. + */ +static void update_table (const int table_type, const LookupTable &table, + GtkWidget *table_items[], int table_index[], int table_index_pos[], + GtkWidget *scroll) +{ + int i; + int item_num = table.get_current_page_size (); + + String mbs, tmp_mbs; + WideString wcs; + WideString label; + GtkRequisition size = {0, 0}; + AttributeList attrs; + PangoAttrList *attrlist = NULL; + int max_width = 0; + + if (_lookup_table_vertical) { + int show_line = VERTICAL_SHOW_LINE; + + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) + gtk_range_set_value (GTK_RANGE ((GTK_SCROLLED_WINDOW (scroll))->vscrollbar), 0); + for (i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++ i) { + if (i < item_num) { + mbs = String (); + + wcs = table.get_candidate_in_current_page (i); + + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) { + label = utf8_mbstowcs (""); + } else { + label = table.get_candidate_label (i); + + if (label.length ()) { + label += utf8_mbstowcs ("."); + } + } + + mbs = utf8_wcstombs (label+wcs); + + scim_string_view_set_text (SCIM_STRING_VIEW (table_items [i]), mbs.c_str ()); + + gtk_widget_size_request (table_items [i], &size); + max_width = max_width > size.width ? max_width : size.width; + + if ((size.height * (i + 1)) > (gdk_screen_height () / 3)) + show_line = show_line < i + 1 ? show_line : i + 1; + + if (_candidate_style != PREDICTION_ENGINE_CANDIDATE_STYLE) { + if ((i + 1) == show_line) + item_num = i + 1; + } + + // Update attributes + attrs = table.get_attributes_in_current_page (i); + + if (attrs.size ()) { + for (AttributeList::iterator ait = attrs.begin (); ait != attrs.end (); ++ait) + ait->set_start (ait->get_start () + label.length ()); + + attrlist = create_pango_attrlist (mbs, attrs); + scim_string_view_set_attributes (SCIM_STRING_VIEW (table_items [i]), attrlist); + pango_attr_list_unref (attrlist); + } else { + scim_string_view_set_attributes (SCIM_STRING_VIEW (table_items [i]), 0); + } + + gtk_widget_show (table_items [i]); + } else { + gtk_widget_hide (table_items [i]); + } + } + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) { + if (item_num < show_line) + gtk_widget_set_size_request (scroll, max_width + size.height*2/3 + BLANK_SIZE, item_num*size.height); + else + gtk_widget_set_size_request (scroll, max_width + size.height*2/3 + BLANK_SIZE, show_line*size.height); + } + } else { + table_index [0] = 0; + table_index_pos [0] = 0; + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) + gtk_range_set_value (GTK_RANGE ((GTK_SCROLLED_WINDOW (scroll))->hscrollbar), 0); + for (i = 0; i < SCIM_LOOKUP_TABLE_MAX_PAGESIZE; ++i) { + if (i < item_num) { + // Update attributes + AttributeList item_attrs = table.get_attributes_in_current_page (i); + size_t attr_start, attr_end; + + if (_candidate_style == PREDICTION_ENGINE_CANDIDATE_STYLE) { + if (i > 0) + label = utf8_mbstowcs (_split_string1); + else + label = utf8_mbstowcs (_space_string); + } else { + label = table.get_candidate_label (i); + + if (label.length ()) { + label += utf8_mbstowcs ("."); + } else { + if (i > 0) + label = utf8_mbstowcs (" "); + } + } + wcs += label; + + attr_start = wcs.length (); + + wcs += table.get_candidate_in_current_page (i); + + attr_end = wcs.length (); + + wcs = wcs + utf8_mbstowcs (_split_string2); + + table_index [i+1] = wcs.length (); + + tmp_mbs = mbs; + mbs = utf8_wcstombs (wcs); + + scim_string_view_set_text (SCIM_STRING_VIEW (table_items [0]), mbs.c_str ()); + + gtk_widget_size_request (table_items [0], &size); + table_index_pos [i+1] = size.width; + if (_candidate_style != PREDICTION_ENGINE_CANDIDATE_STYLE) { + if (i > 0 && size.width > (ui_screen_width () - 2*_lookup_icon_size - 2) && !table.is_page_size_fixed ()) { + item_num = i; + mbs = tmp_mbs; + scim_string_view_set_text (SCIM_STRING_VIEW (table_items [0]), mbs.c_str ()); + } + } + + if (item_attrs.size ()) { + for (AttributeList::iterator ait = item_attrs.begin (); ait != item_attrs.end (); ++ait) { + ait->set_start (ait->get_start () + attr_start); + if (ait->get_end () + attr_start > attr_end) + ait->set_length (attr_end - ait->get_start ()); + } + + attrs.insert (attrs.end (), item_attrs.begin (), item_attrs.end ()); + } + + } else { + table_index [i+1] = -1; + table_index_pos [i+1] = -1; + } + } + + if (attrs.size ()) { + attrlist = create_pango_attrlist (mbs, attrs); + scim_string_view_set_attributes (SCIM_STRING_VIEW (table_items [0]), attrlist); + pango_attr_list_unref (attrlist); + } else { + scim_string_view_set_attributes (SCIM_STRING_VIEW (table_items [0]), 0); + } + } + + int nCandidateCount = table.number_of_candidates (); + if (table_type == CANDIDATE_TABLE) { + if (_candidate_style == SCIM_CANDIDATE_STYLE) { + if (table.get_current_page_start ()) + gtk_widget_set_sensitive (_lookup_table_up_button, TRUE); + else + gtk_widget_set_sensitive (_lookup_table_up_button, FALSE); + + if (table.get_current_page_start () + item_num < nCandidateCount) + gtk_widget_set_sensitive (_lookup_table_down_button, TRUE); + else + gtk_widget_set_sensitive (_lookup_table_down_button, FALSE); + + if (item_num < table.get_current_page_size ()) + _panel_agent->update_lookup_table_page_size (item_num); + } + + if (SCIM_STRING_VIEW (_lookup_table_items [0])->highlight_start != -1 || + SCIM_STRING_VIEW (_lookup_table_items [0])->highlight_end != -1) { + scim_string_view_set_highlight (SCIM_STRING_VIEW (_lookup_table_items [0]), -1, -1); + } + } else if (table_type == ASSOCIATE_TABLE) { + if (_candidate_style == SCIM_CANDIDATE_STYLE) { + if (table.get_current_page_start ()) + gtk_widget_set_sensitive (_associate_table_up_button, TRUE); + else + gtk_widget_set_sensitive (_associate_table_up_button, FALSE); + + if (table.get_current_page_start () + item_num < nCandidateCount) + gtk_widget_set_sensitive (_associate_table_down_button, TRUE); + else + gtk_widget_set_sensitive (_associate_table_down_button, FALSE); + + if (item_num < table.get_current_page_size ()) + _panel_agent->update_associate_table_page_size (item_num); + } + if (SCIM_STRING_VIEW (_associate_table_items [0])->highlight_start != -1 || + SCIM_STRING_VIEW (_associate_table_items [0])->highlight_end != -1) { + scim_string_view_set_highlight (SCIM_STRING_VIEW (_associate_table_items [0]), -1, -1); + } + } + + //ui_settle_input_window (); +} + +/** + * @brief Update candidate table slot function for PanelAgent. + * + * @param table The lookup table for candidate. + */ +static void slot_update_candidate_table (const LookupTable &table) +{ + if (!GTK_IS_WIDGET (_lookup_table_window)) + create_candidate_window (_candidate_style, _lookup_table_vertical); + + //update_table (CANDIDATE_TABLE, table, _lookup_table_items, + // _lookup_table_index, _lookup_table_index_pos, _candidate_scroll); + slot_lock (); + if (_candidate_timer) { + g_source_remove (_candidate_timer); + _candidate_timer = 0; + } + _candidate_timer = g_timeout_add (200, candidate_show_timeout_cb, GINT_TO_POINTER (CANDIDATE_TABLE)); + slot_unlock (); +} + +/** + * @brief Update associate table slot function for PanelAgent. + * + * @param table The lookup table for associate. + */ +static void slot_update_associate_table (const LookupTable &table) +{ + if (!GTK_IS_WIDGET (_associate_table_window)) + create_candidate_window (_candidate_style, _lookup_table_vertical); + + update_table (ASSOCIATE_TABLE, table, _associate_table_items, + _associate_table_index, _associate_table_index_pos, _associate_scroll); +} + +/** + * @brief Set active ISE slot function for PanelAgent. + * + * @param ise_uuid The active ISE's uuid. + */ +static void slot_set_active_ise_by_uuid (const String &ise_uuid, bool changeDefault) +{ + set_active_ise_by_uuid (ise_uuid, changeDefault); + return; +} + +/** + * @brief Get all ISEs list slot function for PanelAgent. + * + * @param list The list is used to store all ISEs. + * + * @return true if this operation is successful, otherwise return false. + */ +static bool slot_get_ise_list (std::vector &list) +{ + bool ret = true; + + std::vector selected_lang; + get_selected_languages (selected_lang); + get_interested_iselist_in_languages (selected_lang, list); + + return ret; +} + +/** + * @brief Get keyboard ISEs list slot function for PanelAgent. + * + * @param list The list is used to store keyboard ISEs. + * + * @return true if this operation is successful, otherwise return false. + */ +static bool slot_get_keyboard_ise_list (std::vector &list) +{ + gchar *uuid = 0; + gint ise_type = 0; + GtkTreeIter iter; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (_active_ise_list_store), &iter)) { + do { + gtk_tree_model_get (GTK_TREE_MODEL (_active_ise_list_store), &iter, + ACTIVE_ISE_UUID, &uuid, + ACTIVE_ISE_TYPE, &ise_type, -1); + if (ise_type == TOOLBAR_KEYBOARD_MODE) + list.push_back (uuid); + if (uuid) { + g_free (uuid); + uuid = 0; + } + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (_active_ise_list_store), &iter)); + } + + return true; +} + +/** + * @brief Get enable languages list slot function for PanelAgent. + * + * @param list The list is used to store languages. + */ +static void slot_get_language_list (std::vector &list) +{ + String lang_name; + MapStringVectorSizeT::iterator iter = _groups.begin (); + + for (; iter != _groups.end (); iter++) { + lang_name = scim_get_language_name (iter->first); + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_name) ==_disabled_langs.end ()) + list.push_back (lang_name); + } + + return; +} + +/** + * @brief Get all languages list slot function for PanelAgent. + * + * @param lang The list is used to store languages. + */ +static void slot_get_all_language (std::vector &lang) +{ + get_all_languages (lang); +} + +/** + * @brief Get specific ISE language list slot function for PanelAgent. + * + * @param name The ISE name. + * @param list The list is used to store ISE languages. + */ +static void slot_get_ise_language (char *name, std::vector &list) +{ + if (name == NULL) + return; + + unsigned int num = _names.size (); + std::vector list_tmp; + list_tmp.clear (); + for (unsigned int i = 0; i < num; i++) { + if (!strcmp (_names[i].c_str (), name)) { + scim_split_string_list (list_tmp, _langs[i], ','); + for (i = 0; i < list_tmp.size (); i++) + list.push_back (scim_get_language_name (list_tmp[i])); + return; + } + } + + return; +} + +/** + * @brief Set ISF language slot function for PanelAgent. + * + * @param language The ISF language string. + */ +static void slot_set_isf_language (const String &language) +{ + SCIM_DEBUG_MAIN (1) << " enter slot_set_isf_language:" << language << "\n"; + + if (language.length () <= 0) + return; + + std::vector langlist, all_langs; + scim_split_string_list (langlist, language); + get_all_languages (all_langs); + + _disabled_langs.clear (); + _disabled_langs_bak.clear (); + for (unsigned int i = 0; i < all_langs.size (); i++) { + if (std::find (langlist.begin (), langlist.end (), all_langs[i]) == langlist.end ()) { + _disabled_langs.push_back (all_langs[i]); + _disabled_langs_bak.push_back (all_langs[i]); + } + } + update_active_ise_list_store (true); + + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DISABLED_LANGS), _disabled_langs); + + std::vector enable_langs; + for (MapStringVectorSizeT::iterator it = _groups.begin (); it != _groups.end (); ++it) { + String lang_name = scim_get_language_name (it->first); + if (std::find (_disabled_langs.begin (), _disabled_langs.end (), lang_name) == _disabled_langs.end ()) + enable_langs.push_back (lang_name); + } + scim_global_config_write (String (SCIM_GLOBAL_CONFIG_ISF_DEFAULT_LANGUAGES), enable_langs); + scim_global_config_flush (); + + return; +} + +/** + * @brief Get ISE information slot function for PanelAgent. + * + * @param uuid The ISE uuid. + * @param info The variable is used to store ISE information. + * + * @return true if this operation is successful, otherwise return false. + */ +static bool slot_get_ise_info_by_uuid (const String &uuid, ISE_INFO &info) +{ + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (!uuid.compare (_uuids[i])) { + info.uuid = _uuids[i]; + info.name = _names[i]; + info.icon = _icons[i]; + info.lang = _langs[i]; + info.option = _options[i]; + info.type = _modes[i]; + return true; + } + } + + return false; +} + +/** + * @brief Set candidate style slot function for PanelAgent. + * + * @param style The new candidate style. + * @param mode The new candidate mode. + */ +static void slot_set_candidate_ui (int style, int mode) +{ + if (GTK_IS_WIDGET (_input_window) && style == _candidate_style && mode == _candidate_mode) + return; + + //int degree = 0; + bool vertical = false; + if (mode == PORTRAIT_VERTICAL_CANDIDATE_MODE || mode == LANDSCAPE_VERTICAL_CANDIDATE_MODE) { + vertical = true; + } + /*if (GTK_IS_WIDGET (_input_window)) + { + gtk_window_get_rotate (GTK_WINDOW (_input_window), °ree); + }*/ + + if (GTK_IS_WIDGET (_input_window) && _candidate_style == style && _lookup_table_vertical == vertical) { + if (mode == LANDSCAPE_HORIZONTAL_CANDIDATE_MODE || mode == LANDSCAPE_VERTICAL_CANDIDATE_MODE) { + //if (degree == PORTRAIT_DEGREE) + { +#if HAVE_GCONF + gtk_window_set_rotate (GTK_WINDOW (_input_window), LANDSCAPE_DEGREE); +#endif + if (mode == LANDSCAPE_HORIZONTAL_CANDIDATE_MODE) + gtk_widget_set_size_request (GTK_WIDGET (_input_window), gdk_screen_height (), -1); + } + } else { + //if (degree == LANDSCAPE_DEGREE) + { +#if HAVE_GCONF + gtk_window_set_rotate (GTK_WINDOW (_input_window), PORTRAIT_DEGREE); +#endif + if (mode == PORTRAIT_HORIZONTAL_CANDIDATE_MODE) + gtk_widget_set_size_request (GTK_WIDGET (_input_window), gdk_screen_width (), -1); + } + } + _candidate_mode = (GTK_CANDIDATE_MODE_T)mode; + _config->write (String (SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_MODE), mode); + _config->flush (); + } else { + _candidate_style = (GTK_CANDIDATE_STYLE_T)style; + _candidate_mode = (GTK_CANDIDATE_MODE_T)mode; + _lookup_table_vertical = vertical; + + _config->write (String (SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_STYLE), style); + _config->write (String (SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_MODE), mode); + _config->write (String (SCIM_CONFIG_PANEL_GTK_LOOKUP_TABLE_VERTICAL), vertical); + _config->flush (); + + //_panel_agent->reset_keyboard_ise (); + slot_hide_preedit_string (); + slot_hide_aux_string (); + slot_hide_lookup_table (); + slot_hide_associate_table (); + create_candidate_window ((GTK_CANDIDATE_STYLE_T)style, vertical); + } +} + +/** + * @brief Get candidate style slot function for PanelAgent. + * + * @param style The current candidate style. + * @param mode The current candidate mode. + */ +static void slot_get_candidate_ui (int &style, int &mode) +{ + style = _candidate_style; + mode = _candidate_mode; +} + +/** + * @brief Set candidate position slot function for PanelAgent. + * + * @param left The new candidate left position. + * @param top The new candidate top position. + */ +static void slot_set_candidate_position (int left, int top) +{ + SCIM_DEBUG_MAIN (3) << "[slot_set_candidate_position] left=" << left << " top=" << top << "\n"; + _candidate_left = left; + _candidate_top = top; + + ui_settle_input_window (); + + // Set a transient window for window stack + // Gets the current XID of the active window into the root window property + if (GTK_IS_WINDOW (_input_window)) { + Atom type_return; + gulong nitems_return; + gulong bytes_after_return; + gint format_return; + guchar *data = NULL; + Window xParentWindow; + GdkDisplay *display = gdk_drawable_get_display (_input_window->window); + gdk_error_trap_push (); + if (XGetWindowProperty (gdk_x11_get_default_xdisplay (), gdk_x11_get_default_root_xwindow (), + gdk_x11_get_xatom_by_name_for_display (display, "_ISF_ACTIVE_WINDOW"), + 0, G_MAXLONG, False, ((Atom) 33), &type_return, + &format_return, &nitems_return, &bytes_after_return, + &data) == Success) { + if ((type_return == ((Atom) 33)) && (format_return == 32) && (data)) { + xParentWindow = *(Window *)data; + + //printf ("#Mcf-Now ISE get the active window XID : %d\n", xParentWindow); + + if (xParentWindow == 0) { + if (!GTK_WIDGET_VISIBLE (GTK_WINDOW (_input_window))) { + gtk_window_set_type_hint (GTK_WINDOW (_input_window), GDK_WINDOW_TYPE_HINT_NOTIFICATION); + } + } else { + if (!GTK_WIDGET_VISIBLE (GTK_WINDOW (_input_window))) { + gtk_window_set_type_hint (GTK_WINDOW (_input_window), GDK_WINDOW_TYPE_HINT_UTILITY); + } + XSetTransientForHint (GDK_WINDOW_XDISPLAY (_input_window->window), + GDK_WINDOW_XID (_input_window->window), + xParentWindow); + } + gdk_window_raise (_input_window->window); + if (data) + XFree (data); + } + } + if (gdk_error_trap_pop ()) { + /* FIXUP: monitor 'Invalid Window' error -mbqu */ + std::cout << "Oops!!!!!! X error in slot_set_candidate_position()!!!" << "\n"; + } + } +} + +/** + * @brief Get candidate window geometry slot function for PanelAgent. + * + * @param info The data is used to store candidate position and size. + */ +static void slot_get_candidate_geometry (struct rectinfo &info) +{ + if (!GTK_IS_WIDGET (_input_window)) + create_candidate_window (_candidate_style, _lookup_table_vertical); + + gint x = 0; + gint y = 0; + gint width = 0; + gint height = 0; + if (GTK_IS_WIDGET (_input_window)) { + gtk_window_get_position (GTK_WINDOW (_input_window), &x, &y); + if (GTK_WIDGET_VISIBLE (_input_window)) { + gtk_window_get_size (GTK_WINDOW (_input_window), &width, &height); + } else { + gtk_widget_hide (_preedit_area); + gtk_widget_hide (_aux_area); + gtk_widget_show (_lookup_table_window); + gtk_widget_hide (_associate_table_window); + gtk_widget_hide (_candidate_separator); + gtk_widget_hide (_associate_separator); + gtk_widget_hide (_middle_separator); + gtk_window_get_size (GTK_WINDOW (_input_window), &width, &height); + gtk_widget_hide (_lookup_table_window); + } + } + info.pos_x = x; + info.pos_y = y; + info.width = width; + info.height = height; + //std::cout << "[slot_get_candidate_rect] x=" << x << " y=" << y << " width=" << width << " height=" << height << "\n"; +} + +/** + * @brief Set keyboard ISE slot function for PanelAgent. + * + * @param ise_uuid The variable is ISE uuid. + */ +static void slot_set_keyboard_ise (const String &ise_uuid) +{ + if (ise_uuid.length () <= 0) + return; + + bool ret = false; + gchar *name = 0; + gchar *uuid = 0; + GtkTreeIter iter; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (_active_ise_list_store), &iter)) { + do { + gtk_tree_model_get (GTK_TREE_MODEL (_active_ise_list_store), &iter, + ACTIVE_ISE_NAME, &name, + ACTIVE_ISE_UUID, &uuid, -1); + if (uuid != NULL && !strcmp (ise_uuid.c_str (), uuid)) { + String language = String ("~other");//scim_get_locale_language (scim_get_current_locale ()); + _config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, String (uuid)); + _config->flush (); + _panel_agent->change_factory (uuid); + ret = true; + } + if (name) { + g_free (name); + name = 0; + } + if (uuid) { + g_free (uuid); + uuid = 0; + } + if (ret) + return; + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (_active_ise_list_store), &iter)); + } +} + +/** + * @brief Get current keyboard ISE name and uuid slot function for PanelAgent. + * + * @param ise_name The variable is used to store ISE name. + * @param ise_uuid The variable is used to store ISE uuid. + */ +static void slot_get_keyboard_ise (String &ise_name, String &ise_uuid) +{ + String language = String ("~other");//scim_get_locale_language (scim_get_current_locale ()); + String uuid = _config->read (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + language, String ("")); + if (ise_uuid.length () > 0) + uuid = ise_uuid; + for (unsigned int i = 0; i < _uuids.size (); i++) { + if (uuid == _uuids[i]) { + ise_name = _names[i]; + ise_uuid = uuid; + return; + } + } + ise_name = String (""); + ise_uuid = String (""); +} + +/** + * @brief Start default ISE slot function for PanelAgent. + */ +static void slot_start_default_ise () +{ + DEFAULT_ISE_T default_ise; + + default_ise.type = (TOOLBAR_MODE_T)scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_TYPE), (int)_initial_ise.type); + default_ise.uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), _initial_ise.uuid); + default_ise.name = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_NAME), _initial_ise.name); + + if (!set_active_ise_by_uuid (default_ise.uuid, 1)) { + if (default_ise.uuid != _initial_ise.uuid) + set_active_ise_by_uuid (_initial_ise.uuid, 1); + } + + return; +} + +/** + * @brief Send key event slot function for PanelAgent. + * + * @param key The key event should be sent. + */ +static void slot_send_key_event (const KeyEvent &key) +{ + //std::cout << "[slot_send_key_event] code : " << key.code << " mask : " << key.mask << "\n"; +} + +/** + * @brief Lock slot function for PanelAgent. + */ +static void slot_lock (void) +{ + G_LOCK (_panel_agent_lock); +} + +/** + * @brief Unlock slot function for PanelAgent. + */ +static void slot_unlock (void) +{ + G_UNLOCK (_panel_agent_lock); +} +////////////////////////////////////////////////////////////////////// +// End of PanelAgent-Functions +////////////////////////////////////////////////////////////////////// + +/** + * @brief Timeout function for candidate show timer. + * + * @param data Data pointer to pass when it is called. + * + * @return FALSE. + */ +static gboolean candidate_show_timeout_cb (gpointer data) +{ + SCIM_DEBUG_MAIN (1) << "candidate_show_timeout_cb......\n"; + + slot_lock (); + if (g_isf_candidate_table.get_current_page_size () && _candidate_timer) { + update_table (CANDIDATE_TABLE, g_isf_candidate_table, _lookup_table_items, + _lookup_table_index, _lookup_table_index_pos, _candidate_scroll); + + if (!_candidate_is_showed) + slot_show_lookup_table (); + } + + _candidate_timer = 0; + slot_unlock (); + + return FALSE; +} + +/** + * @brief Timeout function for check exit timer. + * + * @param data Data pointer to pass when it is called. + * + * return TRUE. + */ +static gboolean check_exit_timeout_cb (gpointer data) +{ + G_LOCK (_global_resource_lock); + if (_should_exit) { + gdk_threads_enter (); + gtk_main_quit (); + gdk_threads_leave (); + } + G_UNLOCK (_global_resource_lock); + + return (gboolean)TRUE; +} + +/** + * @brief Callback function for abnormal signal. + * + * @param sig The signal. + */ +static void signalhandler (int sig) +{ + SCIM_DEBUG_MAIN (1) << "In signal handler...\n"; + + if (_panel_agent != NULL) + _panel_agent->stop (); +} + +#if HAVE_GCONF +/** + * @brief Create prediction engine option information. + * + * @return the pointer of ImeSettingPredictionEngineOptionInfo_S. + */ +static ImeSettingPredictionEngineOptionInfo_S* prediction_engine_option_info_create (void) +{ + ImeSettingPredictionEngineOptionInfo_S *prediction_engine_option_info_s; + + prediction_engine_option_info_s = g_slice_new0 (ImeSettingPredictionEngineOptionInfo_S); + + prediction_engine_option_info_s->keypad_type = IME_SETTING_KEYPAD_TYPE_3X4; + prediction_engine_option_info_s->word_cmpletion_point = 0; + prediction_engine_option_info_s->spell_correction = FALSE; + prediction_engine_option_info_s->next_word_prediction = FALSE; + prediction_engine_option_info_s->auto_substitution = FALSE; + prediction_engine_option_info_s->multitap_word_completion = FALSE; + prediction_engine_option_info_s->regional_input = FALSE; + prediction_engine_option_info_s->word_cmpletion_point_prev = 0; + prediction_engine_option_info_s->spell_correction_prev = FALSE; + prediction_engine_option_info_s->next_word_prediction_prev = FALSE; + prediction_engine_option_info_s->auto_substitution_prev = FALSE; + prediction_engine_option_info_s->multitap_word_completion_prev = FALSE; + prediction_engine_option_info_s->regional_input_prev = FALSE; + + return prediction_engine_option_info_s; +} + +/** + * @brief Get bit mask for prediction engine option. + * + * @param value The source value. + * @param index The index for mask. + * + * @return TRUE or FALSE. + */ +static gboolean prediction_engine_option_get_noti_bit_mask (int value, int index) +{ + int mask; + + mask = 1 << index; + if ((value & mask) ? TRUE : FALSE) + SCIM_DEBUG_MAIN (1) << "true.....\n"; + else + SCIM_DEBUG_MAIN (1) << "false....\n"; + return (value & mask) ? TRUE : FALSE; +} + +/** + * @brief Set prediction engine option information. + * + * @param prediction_engine_option_info_s The ImeSettingPredictionEngineOptionInfo_S pointer. + * @param keypad_type The keypad layout is IME_SETTING_KEYPAD_TYPE_3X4 or IME_SETTING_KEYPAD_TYPE_QTY. + */ +static void prediction_engine_option_info_set (ImeSettingPredictionEngineOptionInfo_S *prediction_engine_option_info_s, gint keypad_type) +{ + GConfValue* value = NULL; + int error_code = 0; + gint gconfvalue = 0; + + g_return_if_fail ((keypad_type >= 0) && (keypad_type < 2)); + + prediction_engine_option_info_s->keypad_type = keypad_type; + + value = gconf_value_new (GCONF_VALUE_INT); + + if (keypad_type == IME_SETTING_KEYPAD_TYPE_3X4) { + // WORD_COMPLETION_POINT + if (!(phonestatus_get ((char *)PS_KEY_APPL_ISE_NWORDCOMPPOINT, value, &error_code))) + g_printf ("\n>>>>>>[%s][%d]Error in get as result is no true,error =%d \n", __FUNCTION__, __LINE__, error_code); + gconfvalue = gconf_value_get_int (value); + + prediction_engine_option_info_s->word_cmpletion_point_prev = prediction_engine_option_info_s->word_cmpletion_point = gconfvalue; + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_3x4_WORD_COMPLETION_POINT), prediction_engine_option_info_s->word_cmpletion_point); + + // OPTIONS + if (!(phonestatus_get ((char *)PS_KEY_APPL_ISE_PREDICTION_ENGINE_OPTION, value, &error_code))) + g_printf ("\n>>>>>>[%s][%d]Error in get as result is no true,error =%d \n", __FUNCTION__, __LINE__, error_code); + gconfvalue = gconf_value_get_int (value); + + SCIM_DEBUG_MAIN (1) << "spell_correction_prev:"; + prediction_engine_option_info_s->spell_correction_prev = prediction_engine_option_info_s->spell_correction = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_0); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_3x4_SPELL_CORRECTION), prediction_engine_option_info_s->spell_correction); + + SCIM_DEBUG_MAIN (1) << "next_word_prediction_prev:"; + prediction_engine_option_info_s->next_word_prediction_prev = prediction_engine_option_info_s->next_word_prediction = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_1); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_3x4_NEXT_WORD_PREDIECTION), prediction_engine_option_info_s->next_word_prediction); + + SCIM_DEBUG_MAIN (1) << "auto_substitution_prev:"; + prediction_engine_option_info_s->auto_substitution_prev = prediction_engine_option_info_s->auto_substitution = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_2); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_3x4_AUTO_SUBSTITUTION), prediction_engine_option_info_s->auto_substitution); + + SCIM_DEBUG_MAIN (1) << "multitap_word_completion_prev:"; + prediction_engine_option_info_s->multitap_word_completion_prev = prediction_engine_option_info_s->multitap_word_completion = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_3); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_3x4_MULTITAP_WORD_COMPLETION), prediction_engine_option_info_s->multitap_word_completion); + + //prediction_engine_option_info_s->regional_input = 0; // unused !! + } else if (keypad_type == IME_SETTING_KEYPAD_TYPE_QTY) { + // WORD_COMPLETION_POINT + if (!(phonestatus_get ((char *)PS_KEY_APPL_ISE_QWORDCOMPPOINT, value, &error_code))) + g_printf ("\n>>>>>>[%s][%d]Error in get as result is no true,error =%d \n", __FUNCTION__, __LINE__, error_code); + gconfvalue = gconf_value_get_int (value); + + prediction_engine_option_info_s->word_cmpletion_point_prev = prediction_engine_option_info_s->word_cmpletion_point = gconfvalue; + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_QWERTY_WORD_COMPLETION_POINT), prediction_engine_option_info_s->word_cmpletion_point); + + // OPTIONS + if (!(phonestatus_get ((char *)PS_KEY_APPL_ISE_PREDICTION_ENGINE_OPTION, value, &error_code))) + g_printf ("\n>>>>>>[%s][%d]Error in get as result is no true,error =%d \n", __FUNCTION__, __LINE__, error_code); + gconfvalue = gconf_value_get_int (value); + + SCIM_DEBUG_MAIN (1) << "spell_correction_prev:"; + prediction_engine_option_info_s->spell_correction_prev = prediction_engine_option_info_s->spell_correction = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_4); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_QWERTY_SPELL_CORRECTION), prediction_engine_option_info_s->spell_correction); + + SCIM_DEBUG_MAIN (1) << "next_word_prediction_prev:"; + prediction_engine_option_info_s->next_word_prediction_prev = prediction_engine_option_info_s->next_word_prediction = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_5); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_QWERTY_NEXT_WORD_PREDIECTION), prediction_engine_option_info_s->next_word_prediction); + + SCIM_DEBUG_MAIN (1) << "auto_substitution_prev:"; + prediction_engine_option_info_s->auto_substitution_prev = prediction_engine_option_info_s->auto_substitution = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_6); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_QWERTY_AUTO_SUBSTITUTION), prediction_engine_option_info_s->auto_substitution); + + SCIM_DEBUG_MAIN (1) << "regional_input_prev:"; + prediction_engine_option_info_s->regional_input_prev = prediction_engine_option_info_s->regional_input = prediction_engine_option_get_noti_bit_mask (gconfvalue, IME_BIT_7); + _config->write (String (SCIM_PREDICTION_ENGINE_CONFIG_QWERTY_REGIONAL_INPUT), prediction_engine_option_info_s->regional_input); + + //prediction_engine_option_info_s->multitap_word_completion = 0; // unused !! + } + + gconf_value_free (value); +} + +/** + * @brief Callback function for prediction engine option setting. + * + * @param t_src_id The source id of system event. + * @param p_noti_id The handler of notice id. + * @param pg_parameters The GArray pointer. + * @param arg Data pointer to pass when it is called. + * + * @return FALSE. + */ +static bool prediction_engine_option_setting_ed_handler (EvtSysEventSourceId_t t_src_id, + const char *p_noti_id, + const GArray *pg_parameters, + void *arg) +{ + if (strcmp (p_noti_id, _ime_setting_ed_id[0]) != 0 && + strcmp (p_noti_id, _ime_setting_ed_id[1]) != 0 && + strcmp (p_noti_id, _ime_setting_ed_id[2]) != 0) + return FALSE; + + ImeSettingPredictionEngineOptionInfo_S *prediction_engine_option_info_s; + prediction_engine_option_info_s = prediction_engine_option_info_create (); + for (gint i = IME_SETTING_KEYPAD_TYPE_3X4; i < IME_SETTING_KEYPAD_TYPE_NUM; i++) { + prediction_engine_option_info_set (prediction_engine_option_info_s, i); + } + + _config->flush (); + _config->reload (); + + g_slice_free (ImeSettingPredictionEngineOptionInfo_S, prediction_engine_option_info_s); + + return FALSE; +} + +/** + * @brief Subscrible prediction engine option setting. + * + * @return event handle if successfully, otherwise return -1. + */ +static int prediction_engine_option_setting_ed_subscribe (void) +{ + int i; + int ret; + int ierror; + int event_handle; + + ierror = EvtSysLibraryOpen (&event_handle); + if (ierror) { + std::cerr << "Error EvtSysLibraryOpen ()!! Return Value :" << ierror << "\n"; + return -1; + } + + EvtSysEventSubscription_t *subscriptions = g_new (EvtSysEventSubscription_t, _ime_setting_ed_number); + + for (i = 0; i < _ime_setting_ed_number; i++) { + subscriptions[i].noti_id = _ime_setting_ed_id[i]; + subscriptions[i].filter_expression = NULL; + subscriptions[i].callback = prediction_engine_option_setting_ed_handler; + subscriptions[i].priv_data = NULL; + } + + if (ret = EvtSysEventMultiSubscribe (event_handle, subscriptions, _ime_setting_ed_number)) { + std::cerr << "Error EvtSysEventMultiSubscribe ()!! Return Value :" << ret << "\n"; + event_handle = -1; + } else { + for (i = 0; i < _ime_setting_ed_number; i++) + _ed_subscription_id[i] = subscriptions[i].subscription_id; + } + if (subscriptions) + g_free (subscriptions); + + return event_handle; +} +#endif + +int main (int argc, char *argv []) +{ + struct tms tiks_buf; + _clock_start = times (&tiks_buf); + + int i; + size_t j; + int ret = 0; +#if HAVE_GCONF + int g_ed_event_handle = -1; + GConfClient *client = 0; + GError *err = 0; + int lang_id; +#endif + + bool daemon = false; + bool should_resident = true; + + int new_argc = 0; + char **new_argv = new char * [40]; + String config_name ("socket"); + ConfigModule *config_module = 0; + String display_name; + + check_time ("\nStarting ISF Panel ...... "); + + DebugOutput::disable_debug (SCIM_DEBUG_AllMask); + DebugOutput::enable_debug (SCIM_DEBUG_MainMask); + + // Parse command options + i = 0; + while (i= argc) break; + + if (String ("-c") == argv [i] || + String ("--config") == argv [i]) { + if (++i >= argc) { + std::cerr << "no argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + config_name = argv [i]; + continue; + } + + if (String ("-h") == argv [i] || + String ("--help") == argv [i]) { + std::cout << "Usage: " << argv [0] << " [option]...\n\n" + << "The options are: \n" + << " --display DISPLAY Run on display DISPLAY.\n" + << " -c, --config NAME Uses specified Config module.\n" + << " -d, --daemon Run " << argv [0] << " as a daemon.\n" + << " -ns, --no-stay Quit if no connected client.\n" +#if ENABLE_DEBUG + << " -v, --verbose LEVEL Enable debug info, to specific LEVEL.\n" + << " -o, --output FILE Output debug information into FILE.\n" +#endif + << " -h, --help Show this help message.\n"; + delete []new_argv; + return 0; + } + + if (String ("-d") == argv [i] || + String ("--daemon") == argv [i]) { + daemon = true; + continue; + } + + if (String ("-ns") == argv [i] || + String ("--no-stay") == argv [i]) { + should_resident = false; + continue; + } + + if (String ("-v") == argv [i] || + String ("--verbose") == argv [i]) { + if (++i >= argc) { + std::cerr << "no argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + DebugOutput::set_verbose_level (atoi (argv [i])); + continue; + } + + if (String ("-o") == argv [i] || + String ("--output") == argv [i]) { + if (++i >= argc) { + std::cerr << "No argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + DebugOutput::set_output (argv [i]); + continue; + } + + if (String ("--display") == argv [i]) { + if (++i >= argc) { + std::cerr << "No argument for option " << argv [i-1] << "\n"; + ret = -1; + goto cleanup; + } + display_name = argv [i]; + continue; + } + + if (String ("--") == argv [i]) + break; + + std::cerr << "Invalid command line option: " << argv [i] << "\n"; + delete []new_argv; + return 0; + } // End of command line parsing. + + new_argv [new_argc ++] = argv [0]; + + // Store the rest argvs into new_argv. + for (++i; i < argc && new_argc < 37; ++i) { + new_argv [new_argc ++] = argv [i]; + } + + // Make up DISPLAY env. + if (display_name.length ()) { + new_argv [new_argc ++] = const_cast ("--display"); + new_argv [new_argc ++] = const_cast (display_name.c_str ()); + + setenv ("DISPLAY", display_name.c_str (), 1); + } + + new_argv [new_argc] = 0; + + if (!config_name.length ()) { + std::cerr << "No Config module is available!\n"; + ret = -1; + goto cleanup; + } + + if (config_name != "dummy") { + // Load config module + config_module = new ConfigModule (config_name); + + if (!config_module || !config_module->valid ()) { + std::cerr << "Can not load " << config_name << " Config module.\n"; + ret = -1; + goto cleanup; + } + } else { + _config = new DummyConfig (); + } + + // Init threads + g_thread_init (NULL); + gdk_threads_init (); + check_time ("gdk_thread_init"); + + signal (SIGQUIT, signalhandler); + signal (SIGTERM, signalhandler); + signal (SIGINT, signalhandler); + //signal (SIGHUP, signalhandler); + + gtk_init (&new_argc, &new_argv); + check_time ("gtk_init"); + + // Get current display. + { +#if GDK_MULTIHEAD_SAFE + const char *p = gdk_display_get_name (gdk_display_get_default ()); +#else + const char *p = getenv ("DISPLAY"); +#endif + if (p) display_name = String (p); + } + + try { + if (!initialize_panel_agent (config_name, display_name, should_resident)) { + std::cerr << "Failed to initialize Panel Agent!\n"; + ret = -1; + goto cleanup; + } + } catch (scim::Exception & e) { + std::cerr << e.what() << "\n"; + ret = -1; + goto cleanup; + } + check_time ("initialize_panel_agent"); + + // Create config instance + if (_config.null () && config_module && config_module->valid()) + _config = config_module->create_config (); + if (_config.null ()) { + std::cerr << "Failed to create Config instance from " << config_name << " Config module.\n"; + ret = -1; + goto cleanup; + } + check_time ("create config instance"); + +#if HAVE_GCONF + //if (gconf_init (argc, argv, &err)) + { + client = gconf_client_get_default (); + if (client && client->engine) { + lang_id = gconf_client_get_int (client, SETTINGS_INPUTLANGUAGETYPE, &err); + if (err) { + std::cerr << "gconf_client_get_int : " << err->message << "\n"; + g_error_free (err); + err = NULL; + } else { + set_default_language_by_id (lang_id); + gconf_client_add_dir (client, "/Application/Settings", GCONF_CLIENT_PRELOAD_NONE, NULL); + gconf_client_notify_add (client, SETTINGS_INPUTLANGUAGETYPE, + input_lang_key_changed_callback, + NULL, NULL, &err); + check_time ("gconf_client_notify_add"); + } + } + } + if (err) { + std::cerr << "gconf error : " << err->message << "\n"; + g_error_free (err); + err = NULL; + } + + g_ed_event_handle = prediction_engine_option_setting_ed_subscribe (); +#endif + + _screen_width = gdk_screen_get_width (gdk_screen_get_default ()); + _screen_height = gdk_screen_get_height (gdk_screen_get_default ()); + _width_rate = (float)(_screen_width / BASE_SCREEN_WIDTH); + _height_rate = (float)(_screen_height / BASE_SCREEN_HEIGHT); + _softkeybar_height = (int)(BASE_SOFTKEYBAR_HEIGHT * _height_rate); + _panel_width = (int)(BASE_PANEL_WIDTH * _width_rate); + _panel_height = (int)(BASE_PANEL_HEIGHT * _height_rate); + _setup_button_width = (int)(BASE_SETUP_BUTTON_WIDTH * _width_rate); + _setup_button_height = (int)(BASE_SETUP_BUTTON_HEIGHT * _height_rate); + _help_icon_width = (int)(BASE_HELP_ICON_WIDTH * _width_rate); + _help_icon_height = (int)(BASE_HELP_ICON_HEIGHT * _height_rate); + + ui_initialize (); + check_time ("ui_initialize"); + + try { + _panel_agent->send_display_name (display_name); + + _initial_ise.type = (TOOLBAR_MODE_T)scim_global_config_read (String (SCIM_GLOBAL_CONFIG_INITIAL_ISE_TYPE), (int)TOOLBAR_HELPER_MODE); + _initial_ise.uuid = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_INITIAL_ISE_UUID), String ("ff110940-b8f0-4062-9ff6-a84f4f3575c0")); + _initial_ise.name = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_INITIAL_ISE_NAME), String ("Input Pad")); + + for (j = 0; j < _uuids.size (); ++j) { + if (!_uuids[j].compare(_initial_ise.uuid)) + break; + } + + if (j == _uuids.size ()) + { + for (j = 0; j < _uuids.size (); ++j) { + if (_modes[j] == TOOLBAR_HELPER_MODE) { + _initial_ise.type = _modes[j]; + _initial_ise.uuid = _uuids[j]; + _initial_ise.name = _names[j]; + } + } + } + + slot_start_default_ise (); + } catch (scim::Exception & e) { + std::cerr << e.what() << "\n"; + ret = -1; + goto cleanup; + } + + if (daemon) { + check_time ("ISF Panel run as daemon"); + scim_daemon (); + } + + // Connect the configuration reload signal. + _config->signal_connect_reload (slot (ui_config_reload_callback)); + + if (!run_panel_agent ()) { + std::cerr << "Failed to run Socket Server!\n"; + ret = -1; + goto cleanup; + } + check_time ("run_panel_agent"); + + _check_exit_timeout = gtk_timeout_add (500, check_exit_timeout_cb, NULL); + + _ise_list_changed = false; + _setup_enable_changed = false; + gdk_threads_enter (); + check_time ("ISF Panel launch time"); + gtk_main (); + gdk_threads_leave (); + + // Exiting... + g_thread_join (_panel_agent_thread); + + // Destroy candidate window + if (GTK_IS_WIDGET (_lookup_table_window)) + gtk_widget_destroy (_lookup_table_window); + if (GTK_IS_WINDOW (_input_window)) + gtk_widget_destroy (_input_window); + + _config->flush (); + ret = 0; + +cleanup: + if (!_config.null ()) + _config.reset (); + if (config_module) + delete config_module; +#if HAVE_GCONF + if (client) + g_object_unref (client); + + if (EvtSysEventHandleExist (g_ed_event_handle)) { + EvtSysEventMultiUnsubscribe (g_ed_event_handle, _ed_subscription_id, _ime_setting_ed_number); + if (g_ed_event_handle != -1) + EvtSysLibraryClose (g_ed_event_handle); + } +#endif + if (_panel_agent) + delete _panel_agent; + + delete []new_argv; + + if (ret == 0) { + std::cerr << "Successfully exited.\n"; + return 0; + } else { + std::cerr << "Abnormally exited.\n"; + return -1; + } +} + +/* +vi:ts=4:nowrap:expandtab +*/ diff --git a/ism/extras/gtk_panel/scim_setup_module.cpp b/ism/extras/gtk_panel/scim_setup_module.cpp new file mode 100644 index 0000000..4186c5d --- /dev/null +++ b/ism/extras/gtk_panel/scim_setup_module.cpp @@ -0,0 +1,178 @@ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_setup_module.cpp,v 1.9 2005/01/10 08:30:45 suzhe Exp $ + * + */ + +#define Uses_SCIM_CONFIG_BASE +#define Uses_SCIM_MODULE + +#include "scim_private.h" +#include "scim.h" +#include "scim_setup_module.h" + +SetupModule::SetupModule () + : m_create_ui (0), + m_get_category (0), + m_get_name (0), + m_get_description (0), + m_load_config (0), + m_save_config (0), + m_query_changed (0) +{ +} + +SetupModule::SetupModule (const String &name) + : m_create_ui (0), + m_get_category (0), + m_get_name (0), + m_get_description (0), + m_load_config (0), + m_save_config (0), + m_query_changed (0) +{ + load (name); +} + +bool +SetupModule::load (const String &name) +{ + if (!m_module.load (name, "SetupUI")) + return false; + + m_create_ui = (SetupModuleCreateUIFunc) m_module.symbol ("scim_setup_module_create_ui"); + m_get_category = (SetupModuleGetCategoryFunc) m_module.symbol ("scim_setup_module_get_category"); + m_get_name = (SetupModuleGetNameFunc) m_module.symbol ("scim_setup_module_get_name"); + m_get_description = (SetupModuleGetDescriptionFunc) m_module.symbol ("scim_setup_module_get_description"); + m_load_config = (SetupModuleLoadConfigFunc) m_module.symbol ("scim_setup_module_load_config"); + m_save_config = (SetupModuleSaveConfigFunc) m_module.symbol ("scim_setup_module_save_config"); + m_query_changed = (SetupModuleQueryChangedFunc) m_module.symbol ("scim_setup_module_query_changed"); + + + if (!m_create_ui || !m_get_category || !m_get_name || + !m_load_config || !m_save_config) { + m_module.unload (); + m_create_ui = 0; + m_get_category = 0; + m_get_name = 0; + m_get_description = 0; + m_load_config = 0; + m_save_config = 0; + m_query_changed = 0; + return false; + } + return true; +} + +bool +SetupModule::unload() +{ + m_module.unload (); + + m_create_ui = 0; + m_get_category = 0; + m_get_name = 0; + m_get_description = 0; + m_load_config = 0; + m_save_config = 0; + m_query_changed = 0; + + return true; +} + +bool +SetupModule::valid () const +{ + return (m_module.valid () && + m_create_ui && m_get_category && m_get_name && + m_load_config && m_save_config); +} + +GtkWidget * +SetupModule::create_ui () const +{ + if (valid ()) + return m_create_ui (); + + return 0; +} + +String +SetupModule::get_category () const +{ + if (valid ()) + return m_get_category (); + + return String (); +} + +String +SetupModule::get_name () const +{ + if (valid ()) + return m_get_name (); + + return String (); +} + +String +SetupModule::get_description () const +{ + if (valid () && m_get_description) + return m_get_description (); + + return String (); +} + +void +SetupModule::load_config (const ConfigPointer &config) const +{ + if (valid ()) + m_load_config (config); +} + +void +SetupModule::save_config (const ConfigPointer &config) const +{ + if (valid ()) + m_save_config (config); +} + +bool +SetupModule::query_changed () const +{ + if (valid () && m_query_changed) + return m_query_changed (); + return false; +} + +int scim_get_setup_module_list (std::vector & mod_list) +{ + return scim_get_module_list (mod_list, "SetupUI"); +} + + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/extras/gtk_panel/scim_setup_module.h b/ism/extras/gtk_panel/scim_setup_module.h new file mode 100644 index 0000000..8acde9f --- /dev/null +++ b/ism/extras/gtk_panel/scim_setup_module.h @@ -0,0 +1,86 @@ +/** @file scim_setup_module.h + * @brief definition of SetupModule related classes. + */ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_setup_module.h,v 1.9 2005/01/10 08:30:45 suzhe Exp $ + */ + +#if !defined (__SCIM_SETUP_MODULE_H) +#define __SCIM_SETUP_MODULE_H + +#include + +using namespace scim; + +typedef GtkWidget * (*SetupModuleCreateUIFunc) (void); +typedef String (*SetupModuleGetCategoryFunc) (void); +typedef String (*SetupModuleGetNameFunc) (void); +typedef String (*SetupModuleGetDescriptionFunc) (void); +typedef void (*SetupModuleLoadConfigFunc) (const ConfigPointer &config); +typedef void (*SetupModuleSaveConfigFunc) (const ConfigPointer &config); +typedef bool (*SetupModuleQueryChangedFunc) (void); + +class SetupModule +{ + Module m_module; + + SetupModuleCreateUIFunc m_create_ui; + SetupModuleGetCategoryFunc m_get_category; + SetupModuleGetNameFunc m_get_name; + SetupModuleGetDescriptionFunc m_get_description; + SetupModuleLoadConfigFunc m_load_config; + SetupModuleSaveConfigFunc m_save_config; + SetupModuleQueryChangedFunc m_query_changed; + + SetupModule (const SetupModule &); + SetupModule & operator= (const SetupModule &); + +public: + SetupModule (); + SetupModule (const String &name); + + bool load (const String &name); + bool unload(); + bool valid () const; + + GtkWidget * create_ui () const; + + String get_category () const; + String get_name () const; + String get_description () const; + + void load_config (const ConfigPointer &config) const; + void save_config (const ConfigPointer &config) const; + + bool query_changed () const; +}; + +int scim_get_setup_module_list (std::vector & mod_list); + +#endif // __SCIM_SETUP_MODULE_H + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/m4/ChangeLog b/ism/m4/ChangeLog new file mode 100755 index 0000000..fa2c827 --- /dev/null +++ b/ism/m4/ChangeLog @@ -0,0 +1,45 @@ +2005-03-07 gettextize + + * gettext.m4: Upgrade to gettext-0.14.1. + * intmax.m4: New file, from gettext-0.14.1. + * inttypes_h.m4: Upgrade to gettext-0.14.1. + * lib-ld.m4: Upgrade to gettext-0.14.1. + * lib-link.m4: Upgrade to gettext-0.14.1. + * lib-prefix.m4: Upgrade to gettext-0.14.1. + * longdouble.m4: New file, from gettext-0.14.1. + * longlong.m4: New file, from gettext-0.14.1. + * nls.m4: New file, from gettext-0.14.1. + * po.m4: New file, from gettext-0.14.1. + * printf-posix.m4: New file, from gettext-0.14.1. + * progtest.m4: Upgrade to gettext-0.14.1. + * signed.m4: New file, from gettext-0.14.1. + * size_max.m4: New file, from gettext-0.14.1. + * stdint_h.m4: Upgrade to gettext-0.14.1. + * uintmax_t.m4: Upgrade to gettext-0.14.1. + * ulonglong.m4: Upgrade to gettext-0.14.1. + * wchar_t.m4: New file, from gettext-0.14.1. + * wint_t.m4: New file, from gettext-0.14.1. + * xsize.m4: New file, from gettext-0.14.1. + * Makefile.am (EXTRA_DIST): Add the new files. + +2004-04-13 gettextize + + * codeset.m4: New file, from gettext-0.11.5. + * gettext.m4: New file, from gettext-0.11.5. + * glibc21.m4: New file, from gettext-0.11.5. + * iconv.m4: New file, from gettext-0.11.5. + * intdiv0.m4: New file, from gettext-0.11.5. + * inttypes.m4: New file, from gettext-0.11.5. + * inttypes_h.m4: New file, from gettext-0.11.5. + * inttypes-pri.m4: New file, from gettext-0.11.5. + * isc-posix.m4: New file, from gettext-0.11.5. + * lcmessage.m4: New file, from gettext-0.11.5. + * lib-ld.m4: New file, from gettext-0.11.5. + * lib-link.m4: New file, from gettext-0.11.5. + * lib-prefix.m4: New file, from gettext-0.11.5. + * progtest.m4: New file, from gettext-0.11.5. + * stdint_h.m4: New file, from gettext-0.11.5. + * uintmax_t.m4: New file, from gettext-0.11.5. + * ulonglong.m4: New file, from gettext-0.11.5. + * Makefile.am: New file. + diff --git a/ism/m4/Makefile.am b/ism/m4/Makefile.am new file mode 100644 index 0000000..8e5299a --- /dev/null +++ b/ism/m4/Makefile.am @@ -0,0 +1,2 @@ +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = intmax.m4 longdouble.m4 longlong.m4 nls.m4 po.m4 printf-posix.m4 signed.m4 size_max.m4 wchar_t.m4 wint_t.m4 xsize.m4 codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 intltool.m4 diff --git a/ism/m4/codeset.m4 b/ism/m4/codeset.m4 new file mode 100755 index 0000000..59535eb --- /dev/null +++ b/ism/m4/codeset.m4 @@ -0,0 +1,23 @@ +# codeset.m4 serial AM1 (gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, + [AC_TRY_LINK([#include ], + [char* cs = nl_langinfo(CODESET);], + am_cv_langinfo_codeset=yes, + am_cv_langinfo_codeset=no) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET, 1, + [Define if you have and nl_langinfo(CODESET).]) + fi +]) diff --git a/ism/m4/gettext.m4 b/ism/m4/gettext.m4 new file mode 100755 index 0000000..a374f03 --- /dev/null +++ b/ism/m4/gettext.m4 @@ -0,0 +1,487 @@ +# gettext.m4 serial 28 (gettext-0.13) +dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define(gt_included_intl, ifelse([$1], [external], [no], [yes])) + define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Set USE_NLS. + AM_NLS + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + dnl Add a version number to the cache macros. + define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) + define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) + define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) + + AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, + [AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings;], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], + gt_cv_func_gnugettext_libc=yes, + gt_cv_func_gnugettext_libc=no)]) + + if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + gt_cv_func_gnugettext_libintl, + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + gt_cv_func_gnugettext_libintl=yes, + gt_cv_func_gnugettext_libintl=no) + dnl Now see whether libintl exists and depends on libiconv. + if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + gt_cv_func_gnugettext_libintl=yes + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if test "$gt_cv_func_gnugettext_libc" = "yes" \ + || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext_libintl" = "yes"; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext_libintl" = "yes"; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE(HAVE_GETTEXT, 1, + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE(HAVE_DCGETTEXT, 1, + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATOBJEXT) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST(DATADIRNAME) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST(INSTOBJEXT) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST(GENCAT) + + dnl For backward compatibility. Some Makefiles may be using this. + if test "$USE_INCLUDED_LIBINTL" = yes; then + INTLOBJS="\$(GETTOBJS)" + fi + AC_SUBST(INTLOBJS) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST(INTLLIBS) + + dnl Make all documented variables known to autoconf. + AC_SUBST(LIBINTL) + AC_SUBST(LTLIBINTL) + AC_SUBST(POSUB) +]) + + +dnl Checks for all prerequisites of the intl subdirectory, +dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. +AC_DEFUN([AM_INTL_SUBDIR], +[ + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([bh_C_SIGNED])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([jm_AC_TYPE_LONG_LONG])dnl + AC_REQUIRE([gt_TYPE_LONGDOUBLE])dnl + AC_REQUIRE([gt_TYPE_WCHAR_T])dnl + AC_REQUIRE([gt_TYPE_WINT_T])dnl + AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([jm_AC_HEADER_STDINT_H]) + AC_REQUIRE([gt_TYPE_INTMAX_T]) + AC_REQUIRE([gt_PRINTF_POSIX]) + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([jm_GLIBC21])dnl + AC_REQUIRE([gt_INTDIV0])dnl + AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl + AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl + AC_REQUIRE([gt_INTTYPES_PRI])dnl + AC_REQUIRE([gl_XSIZE])dnl + + AC_CHECK_TYPE([ptrdiff_t], , + [AC_DEFINE([ptrdiff_t], [long], + [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) + ]) + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ +stdlib.h string.h unistd.h sys/param.h]) + AC_CHECK_FUNCS([asprintf fwprintf getcwd getegid geteuid getgid getuid \ +mempcpy munmap putenv setenv setlocale snprintf stpcpy strcasecmp strdup \ +strtoul tsearch wcslen __argz_count __argz_stringify __argz_next \ +__fsetlocking]) + + dnl Use the _snprintf function only if it is declared (because on NetBSD it + dnl is defined as a weak alias of snprintf; we prefer to use the latter). + gt_CHECK_DECL(_snprintf, [#include ]) + gt_CHECK_DECL(_snwprintf, [#include ]) + + dnl Use the *_unlocked functions only if they are declared. + dnl (because some of them were defined without being declared in Solaris + dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built + dnl on Solaris 2.5.1 to run on Solaris 2.6). + dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. + gt_CHECK_DECL(feof_unlocked, [#include ]) + gt_CHECK_DECL(fgets_unlocked, [#include ]) + gt_CHECK_DECL(getc_unlocked, [#include ]) + + case $gt_cv_func_printf_posix in + *yes) HAVE_POSIX_PRINTF=1 ;; + *) HAVE_POSIX_PRINTF=0 ;; + esac + AC_SUBST([HAVE_POSIX_PRINTF]) + if test "$ac_cv_func_asprintf" = yes; then + HAVE_ASPRINTF=1 + else + HAVE_ASPRINTF=0 + fi + AC_SUBST([HAVE_ASPRINTF]) + if test "$ac_cv_func_snprintf" = yes; then + HAVE_SNPRINTF=1 + else + HAVE_SNPRINTF=0 + fi + AC_SUBST([HAVE_SNPRINTF]) + if test "$ac_cv_func_wprintf" = yes; then + HAVE_WPRINTF=1 + else + HAVE_WPRINTF=0 + fi + AC_SUBST([HAVE_WPRINTF]) + + AM_ICONV + AM_LANGINFO_CODESET + if test $ac_cv_header_locale_h = yes; then + AM_LC_MESSAGES + fi + + dnl intl/plural.c is generated from intl/plural.y. It requires bison, + dnl because plural.y uses bison specific features. It requires at least + dnl bison-1.26 because earlier versions generate a plural.c that doesn't + dnl compile. + dnl bison is only needed for the maintainer (who touches plural.y). But in + dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put + dnl the rule in general Makefile. Now, some people carelessly touch the + dnl files or have a broken "make" program, hence the plural.c rule will + dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not + dnl present or too old. + AC_CHECK_PROGS([INTLBISON], [bison]) + if test -z "$INTLBISON"; then + ac_verc_fail=yes + else + dnl Found it, now check the version. + AC_MSG_CHECKING([version of bison]) +changequote(<<,>>)dnl + ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) +changequote([,])dnl + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + esac + AC_MSG_RESULT([$ac_prog_version]) + fi + if test $ac_verc_fail = yes; then + INTLBISON=: + fi +]) + + +dnl gt_CHECK_DECL(FUNC, INCLUDES) +dnl Check whether a function is declared. +AC_DEFUN([gt_CHECK_DECL], +[ + AC_CACHE_CHECK([whether $1 is declared], ac_cv_have_decl_$1, + [AC_TRY_COMPILE([$2], [ +#ifndef $1 + char *p = (char *) $1; +#endif +], ac_cv_have_decl_$1=yes, ac_cv_have_decl_$1=no)]) + if test $ac_cv_have_decl_$1 = yes; then + gt_value=1 + else + gt_value=0 + fi + AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value], + [Define to 1 if you have the declaration of `$1', and to 0 if you don't.]) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/ism/m4/glibc21.m4 b/ism/m4/glibc21.m4 new file mode 100755 index 0000000..9c9f3db --- /dev/null +++ b/ism/m4/glibc21.m4 @@ -0,0 +1,32 @@ +# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# Test for the GNU C Library, version 2.1 or newer. +# From Bruno Haible. + +AC_DEFUN([jm_GLIBC21], + [ + AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, + ac_cv_gnu_library_2_1, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2_1=yes, + ac_cv_gnu_library_2_1=no) + ] + ) + AC_SUBST(GLIBC21) + GLIBC21="$ac_cv_gnu_library_2_1" + ] +) diff --git a/ism/m4/iconv.m4 b/ism/m4/iconv.m4 new file mode 100755 index 0000000..c5f3579 --- /dev/null +++ b/ism/m4/iconv.m4 @@ -0,0 +1,103 @@ +# iconv.m4 serial AM4 (gettext-0.11.3) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST(LIBICONV) + AC_SUBST(LTLIBICONV) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/ism/m4/intdiv0.m4 b/ism/m4/intdiv0.m4 new file mode 100755 index 0000000..55dddcf --- /dev/null +++ b/ism/m4/intdiv0.m4 @@ -0,0 +1,72 @@ +# intdiv0.m4 serial 1 (gettext-0.11.3) +dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([gt_INTDIV0], +[ + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + + AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], + gt_cv_int_divbyzero_sigfpe, + [ + AC_TRY_RUN([ +#include +#include + +static void +#ifdef __cplusplus +sigfpe_handler (int sig) +#else +sigfpe_handler (sig) int sig; +#endif +{ + /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ + exit (sig != SIGFPE); +} + +int x = 1; +int y = 0; +int z; +int nan; + +int main () +{ + signal (SIGFPE, sigfpe_handler); +/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ +#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) + signal (SIGTRAP, sigfpe_handler); +#endif +/* Linux/SPARC yields signal SIGILL. */ +#if defined (__sparc__) && defined (__linux__) + signal (SIGILL, sigfpe_handler); +#endif + + z = x / y; + nan = y / y; + exit (1); +} +], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, + [ + # Guess based on the CPU. + case "$host_cpu" in + alpha* | i[34567]86 | m68k | s390*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; + esac + ]) + ]) + case "$gt_cv_int_divbyzero_sigfpe" in + *yes) value=1;; + *) value=0;; + esac + AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, + [Define if integer division by zero raises signal SIGFPE.]) +]) diff --git a/ism/m4/intltool.m4 b/ism/m4/intltool.m4 new file mode 100755 index 0000000..4297ba9 --- /dev/null +++ b/ism/m4/intltool.m4 @@ -0,0 +1,215 @@ +## intltool.m4 - Configure intltool for the target system. -*-Shell-script-*- +## Copyright (C) 2001 Eazel, Inc. +## Author: Maciej Stachowiak +## Kenneth Christiansen +## +## 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. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml]) +# serial 2 IT_PROG_INTLTOOL +AC_DEFUN([IT_PROG_INTLTOOL], +[ + +if test -n "$1"; then + AC_MSG_CHECKING(for intltool >= $1) + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ printf "%d", $[1] * 100 + $[2]; }'` + INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { printf $[2]; }' < ${ac_aux_dir}/intltool-update.in` + changequote({{,}}) + INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split(${{2}}, VERSION, "."); printf "%d\n", VERSION[1] * 100 + VERSION[2];}' < ${ac_aux_dir}/intltool-update.in` + changequote([,]) + + if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT"; then + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found]) + else + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found. Your intltool is too old. You need intltool $1 or later.]) + exit 1 + fi +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< [$]@' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< [$]@' + INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + +AC_SUBST(INTLTOOL_DESKTOP_RULE) +AC_SUBST(INTLTOOL_DIRECTORY_RULE) +AC_SUBST(INTLTOOL_KEYS_RULE) +AC_SUBST(INTLTOOL_PROP_RULE) +AC_SUBST(INTLTOOL_OAF_RULE) +AC_SUBST(INTLTOOL_PONG_RULE) +AC_SUBST(INTLTOOL_SERVER_RULE) +AC_SUBST(INTLTOOL_SHEET_RULE) +AC_SUBST(INTLTOOL_SOUNDLIST_RULE) +AC_SUBST(INTLTOOL_UI_RULE) +AC_SUBST(INTLTOOL_XAM_RULE) +AC_SUBST(INTLTOOL_KBD_RULE) +AC_SUBST(INTLTOOL_XML_RULE) +AC_SUBST(INTLTOOL_XML_NOMERGE_RULE) +AC_SUBST(INTLTOOL_CAVES_RULE) +AC_SUBST(INTLTOOL_SCHEMAS_RULE) +AC_SUBST(INTLTOOL_THEME_RULE) + +# Use the tools built into the package, not the ones that are installed. + +INTLTOOL_EXTRACT='$(top_builddir)/intltool-extract' +INTLTOOL_MERGE='$(top_builddir)/intltool-merge' +INTLTOOL_UPDATE='$(top_builddir)/intltool-update' + +AC_SUBST(INTLTOOL_EXTRACT) +AC_SUBST(INTLTOOL_MERGE) +AC_SUBST(INTLTOOL_UPDATE) + +AC_PATH_PROG(INTLTOOL_PERL, perl) +if test -z "$INTLTOOL_PERL"; then + AC_MSG_ERROR([perl not found; required for intltool]) +fi +if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then + AC_MSG_ERROR([perl 5.x required for intltool]) +fi +if test "x$2" != "xno-xml"; then + AC_MSG_CHECKING([for XML::Parser]) + if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then + AC_MSG_RESULT([ok]) + else + AC_MSG_ERROR([XML::Parser perl module is required for intltool]) + fi +fi + +AC_PATH_PROG(INTLTOOL_ICONV, iconv, iconv) +AC_PATH_PROG(INTLTOOL_MSGFMT, msgfmt, msgfmt) +AC_PATH_PROG(INTLTOOL_MSGMERGE, msgmerge, msgmerge) +AC_PATH_PROG(INTLTOOL_XGETTEXT, xgettext, xgettext) + +# Remove file type tags (using []) from po/POTFILES. + +ifdef([AC_DIVERSION_ICMDS],[ + AC_DIVERT_PUSH(AC_DIVERSION_ICMDS) + changequote(,) + mv -f po/POTFILES po/POTFILES.tmp + sed -e '/\[encoding.*\]/d' -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + changequote([,]) + AC_DIVERT_POP() +],[ + ifdef([AC_CONFIG_COMMANDS_PRE],[ + AC_CONFIG_COMMANDS_PRE([ + changequote(,) + mv -f po/POTFILES po/POTFILES.tmp + sed -e '/\[encoding.*\]/d' -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + changequote([,]) + ]) + ]) + +############################################################################ +## Take this bit from AM_PROG_MKDIR_P to set mkdir_p for automake 1.4 users +############################################################################ +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # Keeping the `.' argument allows $(mkdir_p) to be used without + # argument. Indeed, we sometimes output rules like + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. + # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more + # expensive solution, as it forces Make to start a sub-shell.) + mkdir_p='mkdir -p -- .' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p]) +]) + +# Manually sed perl in so people don't have to put the intltool scripts in AC_OUTPUT. + +AC_CONFIG_COMMANDS([intltool], [ + +intltool_edit="-e 's#@INTLTOOL_EXTRACT@#`pwd`/intltool-extract#g' \ + -e 's#@INTLTOOL_ICONV@#${INTLTOOL_ICONV}#g' \ + -e 's#@INTLTOOL_MSGFMT@#${INTLTOOL_MSGFMT}#g' \ + -e 's#@INTLTOOL_MSGMERGE@#${INTLTOOL_MSGMERGE}#g' \ + -e 's#@INTLTOOL_XGETTEXT@#${INTLTOOL_XGETTEXT}#g' \ + -e 's#@INTLTOOL_PERL@#${INTLTOOL_PERL}#g'" + +eval sed ${intltool_edit} < ${ac_aux_dir}/intltool-extract.in \ + > intltool-extract.out +if cmp -s intltool-extract intltool-extract.out 2>/dev/null; then + rm -f intltool-extract.out +else + mv -f intltool-extract.out intltool-extract +fi +chmod ugo+x intltool-extract +chmod u+w intltool-extract + +eval sed ${intltool_edit} < ${ac_aux_dir}/intltool-merge.in \ + > intltool-merge.out +if cmp -s intltool-merge intltool-merge.out 2>/dev/null; then + rm -f intltool-merge.out +else + mv -f intltool-merge.out intltool-merge +fi +chmod ugo+x intltool-merge +chmod u+w intltool-merge + +eval sed ${intltool_edit} < ${ac_aux_dir}/intltool-update.in \ + > intltool-update.out +if cmp -s intltool-update intltool-update.out 2>/dev/null; then + rm -f intltool-update.out +else + mv -f intltool-update.out intltool-update +fi +chmod ugo+x intltool-update +chmod u+w intltool-update + +], INTLTOOL_PERL='${INTLTOOL_PERL}' ac_aux_dir=${ac_aux_dir} +INTLTOOL_EXTRACT='${INTLTOOL_EXTRACT}' ICONV='${INTLTOOL_ICONV}' +MSGFMT='${INTLTOOL_MSGFMT}' MSGMERGE='${INTLTOOL_MSGMERGE}' +XGETTEXT='${INTLTOOL_XGETTEXT}') + +]) + +# deprecated macros +AC_DEFUN([AC_PROG_INTLTOOL], [IT_PROG_INTLTOOL($@)]) + diff --git a/ism/m4/intmax.m4 b/ism/m4/intmax.m4 new file mode 100755 index 0000000..dfb08cc --- /dev/null +++ b/ism/m4/intmax.m4 @@ -0,0 +1,32 @@ +# intmax.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. +dnl Test whether the system has the 'intmax_t' type, but don't attempt to +dnl find a replacement if it is lacking. + +AC_DEFUN([gt_TYPE_INTMAX_T], +[ + AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([jm_AC_HEADER_STDINT_H]) + AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t, + [AC_TRY_COMPILE([ +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +#include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +#include +#endif +], [intmax_t x = -1;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)]) + if test $gt_cv_c_intmax_t = yes; then + AC_DEFINE(HAVE_INTMAX_T, 1, + [Define if you have the 'intmax_t' type in or .]) + fi +]) diff --git a/ism/m4/inttypes-pri.m4 b/ism/m4/inttypes-pri.m4 new file mode 100755 index 0000000..fd007c3 --- /dev/null +++ b/ism/m4/inttypes-pri.m4 @@ -0,0 +1,32 @@ +# inttypes-pri.m4 serial 1 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +# Define PRI_MACROS_BROKEN if exists and defines the PRI* +# macros to non-string values. This is the case on AIX 4.3.3. + +AC_DEFUN([gt_INTTYPES_PRI], +[ + AC_REQUIRE([gt_HEADER_INTTYPES_H]) + if test $gt_cv_header_inttypes_h = yes; then + AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], + gt_cv_inttypes_pri_broken, + [ + AC_TRY_COMPILE([#include +#ifdef PRId32 +char *p = PRId32; +#endif +], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) + ]) + fi + if test "$gt_cv_inttypes_pri_broken" = yes; then + AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, + [Define if exists and defines unusable PRI* macros.]) + fi +]) diff --git a/ism/m4/inttypes.m4 b/ism/m4/inttypes.m4 new file mode 100755 index 0000000..ab370ff --- /dev/null +++ b/ism/m4/inttypes.m4 @@ -0,0 +1,27 @@ +# inttypes.m4 serial 1 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H if exists and doesn't clash with +# . + +AC_DEFUN([gt_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, + [ + AC_TRY_COMPILE( + [#include +#include ], + [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) + ]) + if test $gt_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, + [Define if exists and doesn't clash with .]) + fi +]) diff --git a/ism/m4/inttypes_h.m4 b/ism/m4/inttypes_h.m4 new file mode 100755 index 0000000..f342eba --- /dev/null +++ b/ism/m4/inttypes_h.m4 @@ -0,0 +1,28 @@ +# inttypes_h.m4 serial 5 (gettext-0.12) +dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_inttypes_h=yes, + jm_ac_cv_header_inttypes_h=no)]) + if test $jm_ac_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/ism/m4/isc-posix.m4 b/ism/m4/isc-posix.m4 new file mode 100755 index 0000000..1319dd1 --- /dev/null +++ b/ism/m4/isc-posix.m4 @@ -0,0 +1,26 @@ +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) diff --git a/ism/m4/lcmessage.m4 b/ism/m4/lcmessage.m4 new file mode 100755 index 0000000..ffd4008 --- /dev/null +++ b/ism/m4/lcmessage.m4 @@ -0,0 +1,32 @@ +# lcmessage.m4 serial 3 (gettext-0.11.3) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995. + +# Check whether LC_MESSAGES is available in . + +AC_DEFUN([AM_LC_MESSAGES], +[ + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi +]) diff --git a/ism/m4/lib-ld.m4 b/ism/m4/lib-ld.m4 new file mode 100755 index 0000000..38aeaec --- /dev/null +++ b/ism/m4/lib-ld.m4 @@ -0,0 +1,112 @@ +# lib-ld.m4 serial 3 (gettext-0.13) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/ism/m4/lib-link.m4 b/ism/m4/lib-link.m4 new file mode 100755 index 0000000..eeb200d --- /dev/null +++ b/ism/m4/lib-link.m4 @@ -0,0 +1,551 @@ +# lib-link.m4 serial 4 (gettext-0.12) +dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, +dnl hardcode_direct, hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE(rpath, + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib$1-prefix], +[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib$1-prefix don't search for lib$1 in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) diff --git a/ism/m4/lib-prefix.m4 b/ism/m4/lib-prefix.m4 new file mode 100755 index 0000000..8aff5a9 --- /dev/null +++ b/ism/m4/lib-prefix.m4 @@ -0,0 +1,155 @@ +# lib-prefix.m4 serial 3 (gettext-0.13) +dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) diff --git a/ism/m4/longdouble.m4 b/ism/m4/longdouble.m4 new file mode 100755 index 0000000..1333d2f --- /dev/null +++ b/ism/m4/longdouble.m4 @@ -0,0 +1,30 @@ +# longdouble.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. +dnl Test whether the compiler supports the 'long double' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_LONGDOUBLE], +[ + AC_CACHE_CHECK([for long double], gt_cv_c_long_double, + [if test "$GCC" = yes; then + gt_cv_c_long_double=yes + else + AC_TRY_COMPILE([ + /* The Stardent Vistra knows sizeof(long double), but does not support it. */ + long double foo = 0.0; + /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + int array [2*(sizeof(long double) >= sizeof(double)) - 1]; + ], , + gt_cv_c_long_double=yes, gt_cv_c_long_double=no) + fi]) + if test $gt_cv_c_long_double = yes; then + AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.]) + fi +]) diff --git a/ism/m4/longlong.m4 b/ism/m4/longlong.m4 new file mode 100755 index 0000000..d7d7350 --- /dev/null +++ b/ism/m4/longlong.m4 @@ -0,0 +1,25 @@ +# longlong.m4 serial 4 +dnl Copyright (C) 1999-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG if 'long long' works. + +AC_DEFUN([jm_AC_TYPE_LONG_LONG], +[ + AC_CACHE_CHECK([for long long], ac_cv_type_long_long, + [AC_TRY_LINK([long long ll = 1LL; int i = 63;], + [long long llmax = (long long) -1; + return ll << i | ll >> i | llmax / ll | llmax % ll;], + ac_cv_type_long_long=yes, + ac_cv_type_long_long=no)]) + if test $ac_cv_type_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, + [Define if you have the 'long long' type.]) + fi +]) diff --git a/ism/m4/nls.m4 b/ism/m4/nls.m4 new file mode 100755 index 0000000..36bc493 --- /dev/null +++ b/ism/m4/nls.m4 @@ -0,0 +1,49 @@ +# nls.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) +]) + +AC_DEFUN([AM_MKINSTALLDIRS], +[ + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but $(top_srcdir). + dnl Try to locate it. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + case "$ac_aux_dir" in + /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; + *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; + esac + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) +]) diff --git a/ism/m4/po.m4 b/ism/m4/po.m4 new file mode 100755 index 0000000..e161998 --- /dev/null +++ b/ism/m4/po.m4 @@ -0,0 +1,426 @@ +# po.m4 serial 3 (gettext-0.14) +dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + AC_REQUIRE([AM_NLS])dnl + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU msgfmt. + if test "$GMSGFMT" != ":"; then + dnl If it is no GNU msgfmt we define it as : so that the + dnl Makefiles still can work. + if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && + (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` + AC_MSG_RESULT( + [found $GMSGFMT program is not GNU msgfmt; ignore it]) + GMSGFMT=":" + fi + fi + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && + (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + fi + + AC_OUTPUT_COMMANDS([ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it + # from automake. + eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + +dnl Postprocesses a Makefile in a directory containing PO files. +AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], +[ + # When this code is run, in config.status, two variables have already been + # set: + # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, + # - LINGUAS is the value of the environment variable LINGUAS at configure + # time. + +changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + # Find a way to echo strings without interpreting backslash. + if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='echo' + else + if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='printf %s\n' + else + echo_func () { + cat < "$ac_file.tmp" + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" < /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g'` + cat >> "$ac_file.tmp" <> "$ac_file.tmp" < +#include +/* The string "%2$d %1$d", with dollar characters protected from the shell's + dollar expansion (possibly an autoconf bug). */ +static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; +static char buf[100]; +int main () +{ + sprintf (buf, format, 33, 55); + return (strcmp (buf, "55 33") != 0); +}], gt_cv_func_printf_posix=yes, gt_cv_func_printf_posix=no, + [ + AC_EGREP_CPP(notposix, [ +#if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ + notposix +#endif + ], gt_cv_func_printf_posix="guessing no", + gt_cv_func_printf_posix="guessing yes") + ]) + ]) + case $gt_cv_func_printf_posix in + *yes) + AC_DEFINE(HAVE_POSIX_PRINTF, 1, + [Define if your printf() function supports format strings with positions.]) + ;; + esac +]) diff --git a/ism/m4/progtest.m4 b/ism/m4/progtest.m4 new file mode 100755 index 0000000..8fe527c --- /dev/null +++ b/ism/m4/progtest.m4 @@ -0,0 +1,91 @@ +# progtest.m4 serial 3 (gettext-0.12) +dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1996. + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in ifelse([$5], , $PATH, [$5]); do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) diff --git a/ism/m4/signed.m4 b/ism/m4/signed.m4 new file mode 100755 index 0000000..dc1f54f --- /dev/null +++ b/ism/m4/signed.m4 @@ -0,0 +1,19 @@ +# signed.m4 serial 1 (gettext-0.10.40) +dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([bh_C_SIGNED], +[ + AC_CACHE_CHECK([for signed], bh_cv_c_signed, + [AC_TRY_COMPILE(, [signed char x;], bh_cv_c_signed=yes, bh_cv_c_signed=no)]) + if test $bh_cv_c_signed = no; then + AC_DEFINE(signed, , + [Define to empty if the C compiler doesn't support this keyword.]) + fi +]) diff --git a/ism/m4/size_max.m4 b/ism/m4/size_max.m4 new file mode 100755 index 0000000..5762fc3 --- /dev/null +++ b/ism/m4/size_max.m4 @@ -0,0 +1,61 @@ +# size_max.m4 serial 2 +dnl Copyright (C) 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([gl_SIZE_MAX], +[ + AC_CHECK_HEADERS(stdint.h) + dnl First test whether the system already has SIZE_MAX. + AC_MSG_CHECKING([for SIZE_MAX]) + result= + AC_EGREP_CPP([Found it], [ +#include +#if HAVE_STDINT_H +#include +#endif +#ifdef SIZE_MAX +Found it +#endif +], result=yes) + if test -z "$result"; then + dnl Define it ourselves. Here we assume that the type 'size_t' is not wider + dnl than the type 'unsigned long'. + dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr', + dnl which is guaranteed to work from LONG_MIN to LONG_MAX. + _AC_COMPUTE_INT([~(size_t)0 / 10], res_hi, + [#include ], result=?) + _AC_COMPUTE_INT([~(size_t)0 % 10], res_lo, + [#include ], result=?) + _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint, + [#include ], result=?) + if test "$fits_in_uint" = 1; then + dnl Even though SIZE_MAX fits in an unsigned int, it must be of type + dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. + AC_TRY_COMPILE([#include + extern size_t foo; + extern unsigned long foo; + ], [], fits_in_uint=0) + fi + if test -z "$result"; then + if test "$fits_in_uint" = 1; then + result="$res_hi$res_lo"U + else + result="$res_hi$res_lo"UL + fi + else + dnl Shouldn't happen, but who knows... + result='~(size_t)0' + fi + fi + AC_MSG_RESULT([$result]) + if test "$result" != yes; then + AC_DEFINE_UNQUOTED([SIZE_MAX], [$result], + [Define as the maximum value of type 'size_t', if the system doesn't define it.]) + fi +]) diff --git a/ism/m4/stdint_h.m4 b/ism/m4/stdint_h.m4 new file mode 100755 index 0000000..32ba7ae --- /dev/null +++ b/ism/m4/stdint_h.m4 @@ -0,0 +1,28 @@ +# stdint_h.m4 serial 3 (gettext-0.12) +dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_STDINT_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_STDINT_H], +[ + AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_stdint_h=yes, + jm_ac_cv_header_stdint_h=no)]) + if test $jm_ac_cv_header_stdint_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/ism/m4/uintmax_t.m4 b/ism/m4/uintmax_t.m4 new file mode 100755 index 0000000..b5f28d4 --- /dev/null +++ b/ism/m4/uintmax_t.m4 @@ -0,0 +1,32 @@ +# uintmax_t.m4 serial 7 (gettext-0.12) +dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +AC_PREREQ(2.13) + +# Define uintmax_t to 'unsigned long' or 'unsigned long long' +# if it is not already defined in or . + +AC_DEFUN([jm_AC_TYPE_UINTMAX_T], +[ + AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([jm_AC_HEADER_STDINT_H]) + if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then + AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) + test $ac_cv_type_unsigned_long_long = yes \ + && ac_type='unsigned long long' \ + || ac_type='unsigned long' + AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, + [Define to unsigned long or unsigned long long + if and don't define.]) + else + AC_DEFINE(HAVE_UINTMAX_T, 1, + [Define if you have the 'uintmax_t' type in or .]) + fi +]) diff --git a/ism/m4/ulonglong.m4 b/ism/m4/ulonglong.m4 new file mode 100755 index 0000000..1da8b80 --- /dev/null +++ b/ism/m4/ulonglong.m4 @@ -0,0 +1,25 @@ +# ulonglong.m4 serial 3 +dnl Copyright (C) 1999-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_UNSIGNED_LONG_LONG if 'unsigned long long' works. + +AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], +[ + AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, + [AC_TRY_LINK([unsigned long long ull = 1ULL; int i = 63;], + [unsigned long long ullmax = (unsigned long long) -1; + return ull << i | ull >> i | ullmax / ull | ullmax % ull;], + ac_cv_type_unsigned_long_long=yes, + ac_cv_type_unsigned_long_long=no)]) + if test $ac_cv_type_unsigned_long_long = yes; then + AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, + [Define if you have the 'unsigned long long' type.]) + fi +]) diff --git a/ism/m4/wchar_t.m4 b/ism/m4/wchar_t.m4 new file mode 100755 index 0000000..d8fd1ec --- /dev/null +++ b/ism/m4/wchar_t.m4 @@ -0,0 +1,22 @@ +# wchar_t.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. +dnl Test whether has the 'wchar_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WCHAR_T], +[ + AC_CACHE_CHECK([for wchar_t], gt_cv_c_wchar_t, + [AC_TRY_COMPILE([#include + wchar_t foo = (wchar_t)'\0';], , + gt_cv_c_wchar_t=yes, gt_cv_c_wchar_t=no)]) + if test $gt_cv_c_wchar_t = yes; then + AC_DEFINE(HAVE_WCHAR_T, 1, [Define if you have the 'wchar_t' type.]) + fi +]) diff --git a/ism/m4/wint_t.m4 b/ism/m4/wint_t.m4 new file mode 100755 index 0000000..3d8d215 --- /dev/null +++ b/ism/m4/wint_t.m4 @@ -0,0 +1,22 @@ +# wint_t.m4 serial 1 (gettext-0.12) +dnl Copyright (C) 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. +dnl Test whether has the 'wint_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WINT_T], +[ + AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t, + [AC_TRY_COMPILE([#include + wint_t foo = (wchar_t)'\0';], , + gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)]) + if test $gt_cv_c_wint_t = yes; then + AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.]) + fi +]) diff --git a/ism/m4/xsize.m4 b/ism/m4/xsize.m4 new file mode 100755 index 0000000..9b7cf9b --- /dev/null +++ b/ism/m4/xsize.m4 @@ -0,0 +1,14 @@ +# xsize.m4 serial 2 +dnl Copyright (C) 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +AC_DEFUN([gl_XSIZE], +[ + dnl Prerequisites of lib/xsize.h. + AC_REQUIRE([gl_SIZE_MAX]) + AC_CHECK_HEADERS(stdint.h) +]) diff --git a/ism/modules/Makefile.am b/ism/modules/Makefile.am new file mode 100644 index 0000000..36551a9 --- /dev/null +++ b/ism/modules/Makefile.am @@ -0,0 +1,21 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +SUBDIRS = frontend imengine config filter diff --git a/ism/modules/config/Makefile.am b/ism/modules/config/Makefile.am new file mode 100644 index 0000000..e7736b6 --- /dev/null +++ b/ism/modules/config/Makefile.am @@ -0,0 +1,76 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak +EXTRA_DIST = config.version-script + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" + +moduledir = @SCIM_MODULE_PATH@/$(SCIM_BINARY_VERSION)/Config + +noinst_HEADERS = scim_simple_config.h \ + scim_socket_config.h + +if SCIM_BUILD_CONFIG_SIMPLE +CONFIG_SIMPLE_MODULE = simple.la +endif + +if SCIM_BUILD_CONFIG_SOCKET +CONFIG_SOCKET_MODULE = socket.la +endif + +if SCIM_LD_VERSION_SCRIPT +LD_VERSION_SCRIPT_OPTION="-Wl,--version-script=$(srcdir)/config.version-script" +endif + +module_LTLIBRARIES = \ + $(CONFIG_SIMPLE_MODULE) \ + $(CONFIG_SOCKET_MODULE) + +simple_la_SOURCES = scim_simple_config.cpp + +simple_la_LDFLAGS = -avoid-version \ + -rpath $(moduledir) \ + -module \ + $(LD_VERSION_SCRIPT_OPTION) \ + @LIBTOOL_EXPORT_OPTIONS@ \ + @LTLIBINTL@ + +simple_la_LIBADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la + +socket_la_SOURCES = scim_socket_config.cpp + +socket_la_LDFLAGS = -avoid-version \ + -rpath $(moduledir) \ + -module \ + $(LD_VERSION_SCRIPT_OPTION) \ + @LIBTOOL_EXPORT_OPTIONS@ \ + @LTLIBINTL@ + +socket_la_LIBADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la + diff --git a/ism/modules/config/config.version-script b/ism/modules/config/config.version-script new file mode 100755 index 0000000..e1d8b00 --- /dev/null +++ b/ism/modules/config/config.version-script @@ -0,0 +1,16 @@ +SCIM_CONFIG_1.0 { + global: + extern "C" { + *scim_config_module_create_config*; + *scim_config_module_init*; + *scim_module_exit*; + *scim_module_init*; + }; + + local: + extern "C++" { + scim::*; + std::*; + __gnu_cxx::*; + }; +}; diff --git a/ism/modules/config/scim_simple_config.cpp b/ism/modules/config/scim_simple_config.cpp new file mode 100644 index 0000000..89a994c --- /dev/null +++ b/ism/modules/config/scim_simple_config.cpp @@ -0,0 +1,644 @@ +/** @file scim_simple_config.cpp + * implementation of SimpleConfig class. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_simple_config.cpp,v 1.35 2005/07/06 03:57:04 suzhe Exp $ + */ + +#define Uses_SCIM_CONFIG_BASE +#define Uses_SCIM_CONFIG_PATH +#define Uses_STL_IOSTREAM +#define Uses_STL_FSTREAM +#define Uses_C_STDIO + +#include +#include +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "scim_simple_config.h" + +#ifndef SCIM_SYSCONFDIR + #define SCIM_SYSCONFDIR "/etc" +#endif + +#define scim_module_init simple_LTX_scim_module_init +#define scim_module_exit simple_LTX_scim_module_exit +#define scim_config_module_init simple_LTX_scim_config_module_init +#define scim_config_module_create_config simple_LTX_scim_config_module_create_config + +using namespace scim; + +extern "C" { + void scim_module_init (void) + { + SCIM_DEBUG_CONFIG(1) << "Initializing Simple Config module...\n"; + } + + void scim_module_exit (void) + { + SCIM_DEBUG_CONFIG(1) << "Exiting Simple Config module...\n"; + } + + void scim_config_module_init () + { + SCIM_DEBUG_CONFIG(1) << "Initializing Simple Config module (more)...\n"; + } + + ConfigPointer scim_config_module_create_config () + { + SCIM_DEBUG_CONFIG(1) << "Creating a Simple Config instance...\n"; + return new SimpleConfig (); + } +} + +namespace scim { + +SimpleConfig::SimpleConfig () + : m_need_reload (false) +{ + m_update_timestamp.tv_sec = 0; + m_update_timestamp.tv_usec = 0; + + load_all_config (); +} + +SimpleConfig::~SimpleConfig () +{ + flush (); +} + +bool +SimpleConfig::valid () const +{ + return ConfigBase::valid(); +} + +String +SimpleConfig::get_name () const +{ + return "simple"; +} + +// String +bool +SimpleConfig::read (const String& key, String *pStr) const +{ + if (!valid () || !pStr || key.empty()) return false; + + KeyValueRepository::const_iterator i = m_new_config.find (key); + KeyValueRepository::const_iterator end = m_new_config.end (); + + if (i == end) { + i = m_config.find (key); + end = m_config.end (); + } + + if (i != end) { + *pStr = i->second; + return true; + } + + *pStr = String (""); + return false; +} + +// int +bool +SimpleConfig::read (const String& key, int *pl) const +{ + if (!valid () || !pl || key.empty()) return false; + + KeyValueRepository::const_iterator i = m_new_config.find (key); + KeyValueRepository::const_iterator end = m_new_config.end (); + + if (i == end || !i->second.length ()) { + i = m_config.find (key); + end = m_config.end (); + } + + if (i != end && i->second.length ()) { + *pl = strtol (i->second.c_str (), (char**) NULL, 10); + return true; + } + + *pl = 0; + return false; +} + +// double +bool +SimpleConfig::read (const String& key, double* val) const +{ + if (!valid () || !val || key.empty()) return false; + + KeyValueRepository::const_iterator i = m_new_config.find (key); + KeyValueRepository::const_iterator end = m_new_config.end (); + + if (i == end || !i->second.length ()) { + i = m_config.find (key); + end = m_config.end (); + } + + if (i != end && i->second.length ()) { + *val = strtod (i->second.c_str (), (char**) NULL); + return true; + } + + *val = 0; + return false; +} + +// bool +bool +SimpleConfig::read (const String& key, bool* val) const +{ + if (!valid () || !val || key.empty()) return false; + + KeyValueRepository::const_iterator i = m_new_config.find (key); + KeyValueRepository::const_iterator end = m_new_config.end (); + + if (i == end || !i->second.length ()) { + i = m_config.find (key); + end = m_config.end (); + } + + if (i != end && i->second.length ()) { + if (i->second == "true" || i->second == "TRUE" || i->second == "True" || + i->second == "1") { + *val = true; + return true; + } else if (i->second == "false" || i->second == "FALSE" || i->second == "False" || + i->second == "0") { + *val = false; + return true; + } + } + + *val = false; + return false; +} + +//String list +bool +SimpleConfig::read (const String& key, std::vector * val) const +{ + if (!valid () || !val || key.empty()) return false; + + KeyValueRepository::const_iterator i = m_new_config.find (key); + KeyValueRepository::const_iterator end = m_new_config.end (); + + if (i == end) { + i = m_config.find (key); + end = m_config.end (); + } + + val->clear (); + + if (i != end) { + scim_split_string_list (*val, i->second, ','); + return true; + } + + return false; +} + +//int list +bool +SimpleConfig::read (const String& key, std::vector * val) const +{ + if (!valid () || !val || key.empty()) return false; + + KeyValueRepository::const_iterator i = m_new_config.find (key); + KeyValueRepository::const_iterator end = m_new_config.end (); + + if (i == end) { + i = m_config.find (key); + end = m_config.end (); + } + + val->clear(); + + if (i != end) { + std::vector vec; + scim_split_string_list (vec, i->second, ','); + + for (std::vector ::iterator j = vec.begin (); j != vec.end (); ++j) { + int result = strtol (j->c_str (), (char**)NULL, 10); + val->push_back (result); + } + return true; + } + + return false; +} + +// write the value (return true on success) +bool +SimpleConfig::write (const String& key, const String& value) +{ + if (!valid () || key.empty()) return false; + + m_new_config [key] = value; + + remove_key_from_erased_list (key); + + m_need_reload = true; + + return true; +} + +bool +SimpleConfig::write (const String& key, int value) +{ + if (!valid () || key.empty()) return false; + + char buf [256]; + + snprintf (buf, 255, "%d", value); + + m_new_config [key] = String (buf); + + remove_key_from_erased_list (key); + + m_need_reload = true; + + return true; +} + +bool +SimpleConfig::write (const String& key, double value) +{ + if (!valid () || key.empty()) return false; + + char buf [256]; + + snprintf (buf, 255, "%lf", value); + + m_new_config [key] = String (buf); + + remove_key_from_erased_list (key); + + m_need_reload = true; + + return true; +} + +bool +SimpleConfig::write (const String& key, bool value) +{ + if (!valid () || key.empty()) return false; + + if (value) + m_new_config [key] = String ("true"); + else + m_new_config [key] = String ("false"); + + remove_key_from_erased_list (key); + + m_need_reload = true; + + return true; +} + +bool +SimpleConfig::write (const String& key, const std::vector & value) +{ + if (!valid () || key.empty()) return false; + + m_new_config [key] = scim_combine_string_list (value, ','); + + remove_key_from_erased_list (key); + + m_need_reload = true; + + return true; +} + +bool +SimpleConfig::write (const String& key, const std::vector & value) +{ + if (!valid () || key.empty()) return false; + + std::vector vec; + char buf [256]; + + for (std::vector ::const_iterator i = value.begin (); i != value.end (); ++i) { + snprintf (buf, 255, "%d", *i); + vec.push_back (String (buf)); + } + + m_new_config [key] = scim_combine_string_list (vec, ','); + + remove_key_from_erased_list (key); + + m_need_reload = true; + + return true; +} + +// permanently writes all changes +bool +SimpleConfig::flush() +{ + if (!valid ()) return false; + + // If no config has been modified, then just return. + if (!m_new_config.size () && !m_erased_keys.size ()) + return true; + + String userconf = get_userconf_filename (); + String userconf_dir = get_userconf_dir (); + + if (access (userconf_dir.c_str (), R_OK | W_OK) != 0) { + mkdir (userconf_dir.c_str (), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + if (access (userconf_dir.c_str (), R_OK | W_OK) != 0) + return false; + } + + if (userconf.length ()) { + // Reload config to ensure user made modification won't lost. + load_all_config (); + + std::ofstream os (userconf.c_str ()); + if (!os) return false; + + KeyValueRepository::iterator i; + std::vector::iterator j; + + // Merge new config with old ones. + for (i = m_new_config.begin (); i != m_new_config.end (); ++i) + m_config [i->first] = i->second; + + // Remove all erased keys. + for (j = m_erased_keys.begin (); j != m_erased_keys.end (); ++j) { + if ((i = m_config.find (*j)) != m_config.end ()) + m_config.erase (i); + } + + m_new_config.clear (); + m_erased_keys.clear (); + + gettimeofday (&m_update_timestamp, 0); + + char buf [128]; + snprintf (buf, 128, "%lu:%lu", m_update_timestamp.tv_sec, m_update_timestamp.tv_usec); + + m_config [String (SCIM_CONFIG_UPDATE_TIMESTAMP)] = String (buf); + + save_config (os); + return true; + } + + return false; +} + +// delete entries +bool +SimpleConfig::erase (const String& key) +{ + if (!valid ()) return false; + + KeyValueRepository::iterator i = m_new_config.find(key); + KeyValueRepository::iterator j = m_config.find(key); + bool ok = false; + + if (i != m_new_config.end ()) { + m_new_config.erase (i); + ok = true; + } + + if (j != m_config.end ()) { + m_config.erase (j); + ok = true; + } + + if (ok && std::find (m_erased_keys.begin (), m_erased_keys.end (), key) == m_erased_keys.end ()) + m_erased_keys.push_back (key); + + m_need_reload = true; + + return ok; +} + +bool +SimpleConfig::reload () +{ + if (!valid ()) return false; + + if (load_all_config ()) { + m_new_config.clear (); + m_erased_keys.clear (); + m_need_reload = true; + } + + if (m_need_reload) { + m_need_reload = false; + return ConfigBase::reload (); + } + + return false; +} + +String +SimpleConfig::get_sysconf_dir () +{ + return String (SCIM_SYSCONFDIR) + + String (SCIM_PATH_DELIM_STRING) + + String ("scim"); +} + +String +SimpleConfig::get_userconf_dir () +{ + return scim_get_user_data_dir (); +} + +String +SimpleConfig::get_sysconf_filename () +{ + return get_sysconf_dir () + + String (SCIM_PATH_DELIM_STRING) + + String ("config"); +} + +String +SimpleConfig::get_userconf_filename () +{ + return get_userconf_dir () + + String (SCIM_PATH_DELIM_STRING) + + String ("config"); +} + +String +SimpleConfig::trim_blank (const String &str) +{ + String::size_type begin, len; + + begin = str.find_first_not_of (" \t\n\v"); + + if (begin == String::npos) + return String (); + + len = str.find_last_not_of (" \t\n\v") - begin + 1; + + return str.substr (begin, len); +} + +String +SimpleConfig::get_param_portion (const String &str) +{ + String::size_type begin = str.find_first_of (" \t\n\v="); + + if (begin == String::npos) return str; + + return str.substr (0, begin); +} + +String +SimpleConfig::get_value_portion (const String &str) +{ + String::size_type begin = str.find_first_of ("="); + + if (begin == String::npos || (begin + 1) == str.length ()) return String (""); + + return trim_blank (str.substr (begin + 1, String::npos)); +} + +void +SimpleConfig::parse_config (std::istream &is, KeyValueRepository &config) +{ + char *conf_line = new char [SCIM_MAX_CONFIG_LINE_LENGTH]; + + while (!is.eof()) { + is.getline(conf_line, SCIM_MAX_CONFIG_LINE_LENGTH); + if (!is.eof()) { + String normalized_line = trim_blank(conf_line); + + if ((normalized_line.find_first_of("#") > 0) && (normalized_line.length() != 0)) { + if (normalized_line.find_first_of("=") == String::npos) { + SCIM_DEBUG_CONFIG(2) << " Invalid config line : " << normalized_line << "\n"; + continue; + } + + if (normalized_line[0] == '=') { + SCIM_DEBUG_CONFIG(2) << " Invalid config line : " << normalized_line << "\n"; + continue; + } + + String param = get_param_portion(normalized_line); + KeyValueRepository::iterator i = config.find(param); + + if (i != config.end()) { + SCIM_DEBUG_CONFIG(2) << " Config entry " << normalized_line << " has been read.\n"; + } else { + String value = get_value_portion (normalized_line); + config [param] = value; + SCIM_DEBUG_CONFIG(2) << " Config entry " << param << "=" << value << " is successfully read.\n"; + } + } + } + } + + delete [] conf_line; +} + +void +SimpleConfig::save_config (std::ostream &os) +{ + KeyValueRepository::iterator i; + for (i = m_config.begin (); i != m_config.end (); ++i) { + os << i->first << " = " << i->second << "\n"; + } +} + +bool +SimpleConfig::load_all_config () +{ + String sysconf = get_sysconf_filename (); + String userconf = get_userconf_filename (); + + KeyValueRepository config; + + if (userconf.length ()) { + std::ifstream is (userconf.c_str ()); + if (is) { + SCIM_DEBUG_CONFIG(1) << "Parsing user config file: " + << userconf << "\n"; + parse_config (is, config); + } + } + + if (sysconf.length ()) { + std::ifstream is (sysconf.c_str ()); + if (is) { + SCIM_DEBUG_CONFIG(1) << "Parsing system config file: " + << sysconf << "\n"; + parse_config (is, config); + } + } else { + std::cerr << __func__ << " Cannot open(" << sysconf << ")\n"; + } + + if (!m_config.size () || (m_update_timestamp.tv_sec == 0 && m_update_timestamp.tv_usec == 0)) { + m_config.swap (config); + gettimeofday (&m_update_timestamp, 0); + return true; + } + + KeyValueRepository::iterator it = config.find (String (SCIM_CONFIG_UPDATE_TIMESTAMP)); + + if (it != config.end ()) { + std::vector strs; + if (scim_split_string_list (strs, it->second, ':') == 2) { + time_t sec = (time_t) strtol (strs [0].c_str (), 0, 10); + suseconds_t usec = (suseconds_t) strtol (strs [1].c_str (), 0, 10); + + // The config file is newer, so load it. + if (m_update_timestamp.tv_sec < sec || (m_update_timestamp.tv_sec == sec && m_update_timestamp.tv_usec < usec)) { + m_config.swap (config); + m_update_timestamp.tv_sec = (time_t) sec; + m_update_timestamp.tv_usec = (suseconds_t) usec; + return true; + } + } + } + return false; +} + +void +SimpleConfig::remove_key_from_erased_list (const String &key) +{ + std::vector ::iterator it = std::find (m_erased_keys.begin (), m_erased_keys.end (), key); + + if (it != m_erased_keys.end ()) + m_erased_keys.erase (it); +} + +} // namespace scim + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/config/scim_simple_config.h b/ism/modules/config/scim_simple_config.h new file mode 100644 index 0000000..51126d5 --- /dev/null +++ b/ism/modules/config/scim_simple_config.h @@ -0,0 +1,123 @@ +/** @file scim_simple_config.h + * definition of SimpleConfig class. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_simple_config.h,v 1.22 2005/07/06 03:57:04 suzhe Exp $ + */ + +#if !defined (__SCIM_SIMPLE_CONFIG_H) +#define __SCIM_SIMPLE_CONFIG_H + +#include +#include "scim_stl_map.h" + +namespace scim { + +const int SCIM_MAX_CONFIG_LINE_LENGTH = 16384; + +class SimpleConfig : public ConfigBase +{ +#if SCIM_USE_STL_EXT_HASH_MAP +typedef __gnu_cxx::hash_map KeyValueRepository; +#elif SCIM_USE_STL_HASH_MAP +typedef std::hash_map KeyValueRepository; +#else +typedef std::map KeyValueRepository; +#endif + + KeyValueRepository m_config; + KeyValueRepository m_new_config; + std::vector m_erased_keys; + timeval m_update_timestamp; + bool m_need_reload; + +public: + SimpleConfig (); + + virtual ~SimpleConfig (); + + virtual bool valid () const; + + virtual String get_name () const; + + // String + virtual bool read (const String& key, String *pStr) const; + + // int + virtual bool read (const String& key, int *pl) const; + + // double + virtual bool read (const String& key, double* val) const; + + // bool + virtual bool read (const String& key, bool* val) const; + + //String list + virtual bool read (const String& key, std::vector * val) const; + + //int list + virtual bool read (const String& key, std::vector * val) const; + + // write the value (return true on success) + virtual bool write (const String& key, const String& value); + virtual bool write (const String& key, int value); + virtual bool write (const String& key, double value); + virtual bool write (const String& key, bool value); + virtual bool write (const String& key, const std::vector & value); + virtual bool write (const String& key, const std::vector & value); + + // permanently writes all changes + virtual bool flush(); + + // delete entries + virtual bool erase (const String& key ); + + // reload the configurations. + virtual bool reload (); +private: + String get_sysconf_dir (); + String get_userconf_dir (); + String get_sysconf_filename (); + String get_userconf_filename (); + + String trim_blank (const String &str); + String get_param_portion (const String &str); + String get_value_portion (const String &str); + + void parse_config (std::istream &is, KeyValueRepository &config); + + void save_config (std::ostream &os); + + bool load_all_config (); + + void remove_key_from_erased_list (const String &key); +}; + +} // namespace scim + +#endif + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/config/scim_socket_config.cpp b/ism/modules/config/scim_socket_config.cpp new file mode 100644 index 0000000..e930a00 --- /dev/null +++ b/ism/modules/config/scim_socket_config.cpp @@ -0,0 +1,670 @@ +/** @file scim_socket_config.cpp + * implementation of SocketConfig class. + */ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_socket_config.cpp,v 1.23 2005/12/16 11:12:26 suzhe Exp $ + */ + +#define Uses_SCIM_CONFIG_BASE +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_SOCKET +#define Uses_SCIM_TRANSACTION +#define Uses_C_STDIO +#define Uses_C_STDLIB + +#include "scim_private.h" +#include "scim.h" +#include "scim_socket_config.h" + +#define scim_module_init socket_LTX_scim_module_init +#define scim_module_exit socket_LTX_scim_module_exit +#define scim_config_module_init socket_LTX_scim_config_module_init +#define scim_config_module_create_config socket_LTX_scim_config_module_create_config + +using namespace scim; + +extern "C" { + void scim_module_init (void) + { + SCIM_DEBUG_CONFIG(1) << "Initializing Socket Config module...\n"; + } + + void scim_module_exit (void) + { + SCIM_DEBUG_CONFIG(1) << "Exiting Socket Config module...\n"; + } + + void scim_config_module_init () + { + SCIM_DEBUG_CONFIG(1) << "Initializing Socket Config module (more)...\n"; + } + + ConfigPointer scim_config_module_create_config () + { + SCIM_DEBUG_CONFIG(1) << "Creating a Socket Config instance...\n"; + return new SocketConfig (); + } +} + +namespace scim { + +SocketConfig::SocketConfig () + : m_socket_address (scim_get_default_socket_config_address ()), + m_socket_timeout (scim_get_default_socket_timeout ()), + m_valid (false), + m_connected (false) +{ + SCIM_DEBUG_CONFIG (2) << " Construct SocketConfig object.\n"; + + m_valid = open_connection (); +} + +SocketConfig::~SocketConfig () +{ + m_socket_client.close (); +} + +bool +SocketConfig::valid () const +{ + return ConfigBase::valid() && m_valid; +} + +String +SocketConfig::get_name () const +{ + return "socket"; +} + +// String +bool +SocketConfig::read (const String& key, String *pStr) const +{ + if (!valid () || !pStr || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_STRING); + trans.put_data (key); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (*pStr) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + return true; + + break; + } + + if (!open_connection ()) + break; + } + + *pStr = String (""); + return false; +} + +// int +bool +SocketConfig::read (const String& key, int *pl) const +{ + if (!valid () || !pl || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_INT); + trans.put_data (key); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + uint32 val; + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (val) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + *pl = val; + return true; + } + + break; + } + + if (!open_connection ()) + break; + } + + *pl = 0; + return false; +} + +// double +bool +SocketConfig::read (const String& key, double* val) const +{ + if (!valid () || !val || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_DOUBLE); + trans.put_data (key); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + String str; + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (str) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + sscanf (str.c_str (), "%lE", val); + return true; + } + + break; + } + + if (!open_connection ()) + break; + } + + *val = 0; + return false; +} + +// bool +bool +SocketConfig::read (const String& key, bool* val) const +{ + if (!valid () || !val || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_BOOL); + trans.put_data (key); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + uint32 tmp; + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (tmp) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + *val = (bool)tmp; + return true; + } + + break; + } + + if (!open_connection ()) + break; + } + + *val = false; + return false; +} + +//String list +bool +SocketConfig::read (const String& key, std::vector * val) const +{ + if (!valid () || !val || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + val->clear (); + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_VECTOR_STRING); + trans.put_data (key); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (*val) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + return true; + } + + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +//int list +bool +SocketConfig::read (const String& key, std::vector * val) const +{ + if (!valid () || !val || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + val->clear(); + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_VECTOR_INT); + trans.put_data (key); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + std::vector vec; + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (vec) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + for (uint32 i=0; ipush_back ((int) vec[i]); + return true; + } + + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +// write the value (return true on success) +bool +SocketConfig::write (const String& key, const String& value) +{ + if (!valid () || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_STRING); + trans.put_data (key); + trans.put_data (value); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + return true; + + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +bool +SocketConfig::write (const String& key, int value) +{ + if (!valid () || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_INT); + trans.put_data (key); + trans.put_data ((uint32)value); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + return true; + + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +bool +SocketConfig::write (const String& key, double value) +{ + if (!valid () || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + char buf [256]; + snprintf (buf, 255, "%lE", value); + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_DOUBLE); + trans.put_data (key); + trans.put_data (String (buf)); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + return true; + + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +bool +SocketConfig::write (const String& key, bool value) +{ + if (!valid () || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_BOOL); + trans.put_data (key); + trans.put_data ((uint32)value); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + return true; + + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +bool +SocketConfig::write (const String& key, const std::vector & value) +{ + if (!valid () || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + Transaction trans; + int cmd; + + for (int retry = 0; retry < 3; ++retry) { + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_VECTOR_STRING); + trans.put_data (key); + trans.put_data (value); + + if (trans.write_to_socket (m_socket_client) && + trans.read_from_socket (m_socket_client, m_socket_timeout)) { + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + return true; + + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +bool +SocketConfig::write (const String& key, const std::vector & value) +{ + if (!valid () || key.empty()) return false; + if (!m_connected && !open_connection ()) return false; + + std::vector vec; + + for (uint32 i=0; i strs; + if (scim_split_string_list (strs, str, ':') == 2) { + time_t sec = (time_t) strtol (strs [0].c_str (), 0, 10); + suseconds_t usec = (suseconds_t) strtol (strs [1].c_str (), 0, 10); + + // The config file is newer, so load it. + if (m_update_timestamp.tv_sec < sec || + (m_update_timestamp.tv_sec == sec && m_update_timestamp.tv_usec < usec)) { + m_update_timestamp.tv_sec = sec; + m_update_timestamp.tv_usec = usec; + return ConfigBase::reload (); + } + } + } + } + break; + } + + if (!open_connection ()) + break; + } + + return false; +} + +void +SocketConfig::init_transaction (Transaction &trans) const +{ + trans.clear (); + trans.put_command (SCIM_TRANS_CMD_REQUEST); + trans.put_data (m_socket_magic_key); +} + +bool +SocketConfig::open_connection () const +{ + SocketAddress socket_address (m_socket_address); + + m_connected = false; + + // Connect to SocketFrontEnd. + if (!m_socket_client.connect (socket_address)) { + for (int i = 0; i < 6; ++i) { + if (m_socket_client.connect (socket_address)) + break; + scim_usleep (100000); + std::cerr << " Re-connecting to ISF(scim) server. SocketConfig connect count : " << i+1 << "\n"; + ISF_LOG (" Re-connecting to ISF(scim) server. SocketConfig connect count : %d\n", i+1); + } + } + + if (!m_socket_client.is_connected ()) { + std::cerr << " Cannot connect to SocketFrontEnd (" << m_socket_address << ").\n"; + ISF_LOG (" Cannot connect to SocketFrontEnd (%s).\n", m_socket_address.c_str ()); + return false; + } + + // Init the connection, + if (!scim_socket_open_connection (m_socket_magic_key, + String ("SocketConfig"), + String ("SocketFrontEnd"), + m_socket_client, + m_socket_timeout)) { + m_socket_client.close (); + return false; + } + + ISF_LOG (" Connect to SocketFrontEnd (%s).\n", m_socket_address.c_str ()); + m_connected = true; + gettimeofday (&m_update_timestamp, 0); + return true; +} + +} // namespace scim + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/config/scim_socket_config.h b/ism/modules/config/scim_socket_config.h new file mode 100644 index 0000000..4f75134 --- /dev/null +++ b/ism/modules/config/scim_socket_config.h @@ -0,0 +1,100 @@ +/** @file scim_socket_config.h + * definition of SocketConfig class. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_socket_config.h,v 1.11 2005/07/06 03:57:04 suzhe Exp $ + */ + +#if !defined (__SCIM_SOCKET_CONFIG_H) +#define __SCIM_SOCKET_CONFIG_H + +#include + +namespace scim { + +class SocketConfig : public ConfigBase +{ + String m_socket_address; + int m_socket_timeout; + bool m_valid; + mutable SocketClient m_socket_client; + mutable uint32 m_socket_magic_key; + mutable bool m_connected; + mutable timeval m_update_timestamp; + +public: + SocketConfig (); + + virtual ~SocketConfig (); + + virtual bool valid () const; + + virtual String get_name () const; + + // String + virtual bool read (const String& key, String *pStr) const; + + // int + virtual bool read (const String& key, int *pl) const; + + // double + virtual bool read (const String& key, double* val) const; + + // bool + virtual bool read (const String& key, bool* val) const; + + //String list + virtual bool read (const String& key, std::vector * val) const; + + //int list + virtual bool read (const String& key, std::vector * val) const; + + // write the value (return true on success) + virtual bool write (const String& key, const String& value); + virtual bool write (const String& key, int value); + virtual bool write (const String& key, double value); + virtual bool write (const String& key, bool value); + virtual bool write (const String& key, const std::vector & value); + virtual bool write (const String& key, const std::vector & value); + + // permanently writes all changes + virtual bool flush(); + + // delete entries + virtual bool erase (const String& key ); + + // reload the configurations. + virtual bool reload (); +private: + void init_transaction (Transaction &trans) const; + bool open_connection () const; +}; + +} // namespace scim + +#endif + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/filter/Makefile.am b/ism/modules/filter/Makefile.am new file mode 100644 index 0000000..7ff4179 --- /dev/null +++ b/ism/modules/filter/Makefile.am @@ -0,0 +1,54 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/utils \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" + +if SCIM_BUILD_FILTER_SCTC +CONFIG_FILTER_SCTC = sctc.la +endif + +noinst_HEADERS = scim_sctc_filter.h \ + scim_sctc_filter_data.h + +moduledir = @SCIM_MODULE_PATH@/$(SCIM_BINARY_VERSION)/Filter +module_LTLIBRARIES = $(CONFIG_FILTER_SCTC) + +sctc_la_SOURCES = scim_sctc_filter.cpp + +sctc_la_LDFLAGS = -avoid-version \ + -rpath $(moduledir) \ + -module \ + @LIBTOOL_EXPORT_OPTIONS@ \ + @LTLIBINTL@ + +sctc_la_LIBADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la + diff --git a/ism/modules/filter/scim_sctc_filter.cpp b/ism/modules/filter/scim_sctc_filter.cpp new file mode 100644 index 0000000..a0b9552 --- /dev/null +++ b/ism/modules/filter/scim_sctc_filter.cpp @@ -0,0 +1,602 @@ +/** @file scim_sctc_filter.cpp + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_sctc_filter.cpp,v 1.7.2.1 2006/01/09 13:37:25 suzhe Exp $ + * + */ + +#define Uses_SCIM_FILTER +#define Uses_SCIM_FILTER_MODULE +#define Uses_SCIM_CONFIG_BASE +#include "scim_private.h" +#include "scim.h" +#include "scim_stl_map.h" +#include "scim_sctc_filter.h" +#include "scim_sctc_filter_data.h" + +#define scim_module_init sctc_LTX_scim_module_init +#define scim_module_exit sctc_LTX_scim_module_exit +#define scim_filter_module_init sctc_LTX_scim_filter_module_init +#define scim_filter_module_create_filter sctc_LTX_scim_filter_module_create_filter +#define scim_filter_module_get_filter_info sctc_LTX_scim_filter_module_get_filter_info + +using namespace scim; + +// Private datatype definition. +#if SCIM_USE_STL_EXT_HASH_MAP +typedef __gnu_cxx::hash_map > UUMap; +#elif SCIM_USE_STL_HASH_MAP +typedef std::hash_map > UUMap; +#else +typedef std::map UUMap; +#endif + +// Private data definition. +static FilterInfo __filter_info (String ("adb861a9-76da-454c-941b-1957e644a94e"), + String (_("Simplified-Traditional Chinese Conversion")), + String ("zh_CN,zh_TW,zh_SG,zh_HK"), + String (SCTC_ICON_PNG), + String (_("Convert between Simplified Chinese and Traditional Chinese"))); + +static std::vector __sc_encodings; +static std::vector __tc_encodings; + +static UUMap __sc_to_tc_map; +static UUMap __tc_to_sc_map; +static bool __sc_to_tc_initialized = false; +static bool __tc_to_sc_initialized = false; + +static Property __prop_root (String ("/Filter/SCTC"), + String (_("SC-TC")), + String (SCTC_ICON_PNG), + String (_("Simplified-Traditional Chinese conversion"))); + +static Property __prop_off (String ("/Filter/SCTC/Off"), + String (_("No Conversion")), + String (SCTC_ICON_PNG), + String (_("Simplified-Traditional Chinese conversion"))); + +static Property __prop_sc_to_tc (String ("/Filter/SCTC/SC-TC"), + String (_("Simplified to Traditional")), + String (SC_TO_TC_ICON_PNG), + String (_("Convert Simplified Chinese to Traditional Chinese"))); + +static Property __prop_tc_to_sc (String ("/Filter/SCTC/TC-SC"), + String (_("Traditional to Simplified")), + String (TC_TO_SC_ICON_PNG), + String (_("Convert Traditional Chinese to Simplified Chinese"))); + +//Private functions definition. +static void __init_sc_to_tc (); +static void __init_tc_to_sc (); + +static bool __is_sc_encoding (const String &encoding); +static bool __is_tc_encoding (const String &encoding); + +static WideString __sc_to_tc (const WideString &sc); +static WideString __tc_to_sc (const WideString &tc); + + +//Module Interface +extern "C" { + void scim_module_init (void) + { + //Initialize encoding information. + __sc_encodings.push_back ("GB2312"); + __sc_encodings.push_back ("GBK"); + __sc_encodings.push_back ("GB18030"); + __sc_encodings.push_back ("EUC-CN"); + __tc_encodings.push_back ("BIG5"); + __tc_encodings.push_back ("BIG5-HKSCS"); + __tc_encodings.push_back ("EUC-TW"); + } + + void scim_module_exit (void) + { + } + + unsigned int scim_filter_module_init (const ConfigPointer &config) + { + return 1; + } + + FilterFactoryPointer scim_filter_module_create_filter (unsigned int index) + { + if (index == 0) + return new SCTCFilterFactory (); + + return FilterFactoryPointer (0); + } + + bool scim_filter_module_get_filter_info (unsigned int index, FilterInfo &info) + { + if (index == 0) { + info = __filter_info; + return true; + } + return false; + } +} + +//Implementation of private functions +static void +__init_sc_to_tc () +{ + if (__sc_to_tc_initialized) return; + + __sc_to_tc_map.clear (); + + for (size_t i = 0; __sc_to_tc_table [i].first; ++i) + __sc_to_tc_map [__sc_to_tc_table [i].first] = __sc_to_tc_table [i].second; + + __sc_to_tc_initialized = true; +} + +static void +__init_tc_to_sc () +{ + if (__tc_to_sc_initialized) return; + + __tc_to_sc_map.clear (); + + for (size_t i = 0; __tc_to_sc_table [i].first; ++i) + __tc_to_sc_map [__tc_to_sc_table [i].first] = __tc_to_sc_table [i].second; + + __tc_to_sc_initialized = true; +} + +static WideString __sc_to_tc (const WideString &sc) +{ + WideString tc; + if (!__sc_to_tc_initialized) __init_sc_to_tc (); + + UUMap::const_iterator mapit; + WideString::const_iterator sit; + + for (sit = sc.begin (); sit != sc.end (); ++sit) { + if (*sit <= 0xFFFF) { + mapit = __sc_to_tc_map.find ((unsigned short) (*sit)); + if (mapit != __sc_to_tc_map.end ()) { + tc.push_back (static_cast (mapit->second)); + } else { + tc.push_back (*sit); + } + } else { + tc.push_back (*sit); + } + } + return tc; +} + +static WideString __tc_to_sc (const WideString &tc) +{ + WideString sc; + if (!__tc_to_sc_initialized) __init_tc_to_sc (); + + UUMap::const_iterator mapit; + WideString::const_iterator sit; + + for (sit = tc.begin (); sit != tc.end (); ++sit) { + if (*sit <= 0xFFFF) { + mapit = __tc_to_sc_map.find ((unsigned short) (*sit)); + if (mapit != __tc_to_sc_map.end ()) { + sc.push_back (static_cast (mapit->second)); + } else { + sc.push_back (*sit); + } + } else { + sc.push_back (*sit); + } + } + return sc; +} + +static bool +__is_sc_encoding (const String &encoding) +{ + return std::find (__sc_encodings.begin (), __sc_encodings.end (), encoding) != __sc_encodings.end (); +} + +static bool +__is_tc_encoding (const String &encoding) +{ + return std::find (__tc_encodings.begin (), __tc_encodings.end (), encoding) != __tc_encodings.end (); +} + +//Implementation of SCTCFilterFactory. +SCTCFilterFactory::SCTCFilterFactory () + : m_sc_ok(false), + m_tc_ok(false) +{ +} + +void +SCTCFilterFactory::attach_imengine_factory (const IMEngineFactoryPointer &orig) +{ + size_t i; + + FilterFactoryBase::attach_imengine_factory (orig); + + for (i = 0; i < __sc_encodings.size (); ++i) { + if (orig->validate_encoding (__sc_encodings [i])) { + m_sc_ok = true; + if (orig->validate_encoding ("GB18030")) + m_sc_encoding = "GB18030"; + else + m_sc_encoding = __sc_encodings [i]; + + break; + } + } + + for (i = 0; i < __tc_encodings.size (); ++i) { + if (orig->validate_encoding (__tc_encodings [i])) { + m_tc_ok = true; + if (orig->validate_encoding ("BIG5")) + m_tc_encoding = "BIG5"; + else + m_tc_encoding = __tc_encodings [i]; + + break; + } + } + + if (m_sc_ok || m_tc_ok) { + String locales = orig->get_locales (); + locales = locales + String (",") + scim_get_language_locales ("zh_CN"); + locales = locales + String (",") + scim_get_language_locales ("zh_TW"); + locales = locales + String (",") + scim_get_language_locales ("zh_SG"); + locales = locales + String (",") + scim_get_language_locales ("zh_HK"); + set_locales (locales); + } +} + +WideString +SCTCFilterFactory::get_name () const +{ + WideString name = FilterFactoryBase::get_name (); + return name.length () ? name : utf8_mbstowcs (__filter_info.name); +} + +String +SCTCFilterFactory::get_uuid () const +{ + String uuid = FilterFactoryBase::get_uuid (); + return uuid.length () ? uuid : __filter_info.uuid; +} + +String +SCTCFilterFactory::get_icon_file () const +{ + String icon = FilterFactoryBase::get_icon_file (); + return icon.length () ? icon : __filter_info.icon; +} + +WideString +SCTCFilterFactory::get_authors () const +{ + WideString authors = FilterFactoryBase::get_authors (); + return authors.length () ? authors : utf8_mbstowcs (_("James Su ")); +} + +WideString +SCTCFilterFactory::get_help () const +{ + // No help yet. + WideString help = FilterFactoryBase::get_help (); + return help; +} + +bool +SCTCFilterFactory::validate_encoding (const String& encoding) const +{ + // Bypass the original IMEngineFactory. + return IMEngineFactoryBase::validate_encoding (encoding); +} + +bool +SCTCFilterFactory::validate_locale (const String& locale) const +{ + // Bypass the original IMEngineFactory. + return IMEngineFactoryBase::validate_locale (locale); +} + +IMEngineInstancePointer +SCTCFilterFactory::create_instance (const String& encoding, int id) +{ + if (m_sc_ok || m_tc_ok) { + SCTCWorkMode mode = SCTC_MODE_OFF; + + String orig_encoding = encoding; + + // If the original IMEngineFactory doesn't support this encoding, + // then we must use another encoding to create the original IMEngineInstance. + // It means we must use a conversion mode. + if (!FilterFactoryBase::validate_encoding (encoding)) { + // The client encoding is Simplified Chinese encoding, but is not supported by the IMEngine. + // So use Traditional Chinese encoding instead. + if (__is_sc_encoding (encoding)) { + if (FilterFactoryBase::validate_encoding (m_sc_encoding)) { + orig_encoding = m_sc_encoding; + } else { + orig_encoding = m_tc_encoding; + mode = SCTC_MODE_FORCE_TC_TO_SC; + } + } else if (__is_tc_encoding (encoding)) { + if (FilterFactoryBase::validate_encoding (m_tc_encoding)) { + orig_encoding = m_tc_encoding; + } else { + orig_encoding = m_sc_encoding; + mode = SCTC_MODE_FORCE_SC_TO_TC; + } + } + } else if ((__is_sc_encoding (encoding) && !FilterFactoryBase::validate_encoding (m_tc_encoding)) || + (__is_tc_encoding (encoding) && !FilterFactoryBase::validate_encoding (m_sc_encoding))) { + mode = SCTC_MODE_FORCE_OFF; + } + + return new SCTCFilterInstance (this, mode, encoding, FilterFactoryBase::create_instance (orig_encoding, id)); + } + + return FilterFactoryBase::create_instance (encoding, id); +} + +//Implementation of SCTCFilterInstance +SCTCFilterInstance::SCTCFilterInstance (SCTCFilterFactory *factory, const SCTCWorkMode &mode, const String &client_encoding, const IMEngineInstancePointer &orig_inst) + : FilterInstanceBase (factory, orig_inst), + m_factory (factory), + m_props_registered (false), + m_work_mode (mode) +{ + IMEngineInstanceBase::set_encoding (client_encoding); +} + +bool +SCTCFilterInstance::set_encoding (const String &encoding) +{ + if (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) { + if (__is_tc_encoding (encoding)) + FilterInstanceBase::set_encoding (m_factory->m_sc_encoding); + } else if (m_work_mode == SCTC_MODE_TC_TO_SC || m_work_mode == SCTC_MODE_FORCE_TC_TO_SC) { + if (__is_sc_encoding (encoding)) + FilterInstanceBase::set_encoding (m_factory->m_tc_encoding); + } else { + FilterInstanceBase::set_encoding (encoding); + } + reset (); + return IMEngineInstanceBase::set_encoding (encoding); +} + +void +SCTCFilterInstance::focus_in () +{ + m_props_registered = false; + + FilterInstanceBase::focus_in (); + + if (!m_props_registered) { + PropertyList props; + filter_register_properties (props); + } +} + +void +SCTCFilterInstance::trigger_property (const String &property) +{ + if (property != __prop_off.get_key () && property != __prop_sc_to_tc.get_key () && property != __prop_tc_to_sc.get_key ()) { + FilterInstanceBase::trigger_property (property); + return; + } + + if (m_work_mode == SCTC_MODE_FORCE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_TC_TO_SC || m_work_mode == SCTC_MODE_FORCE_OFF) + return; + + Property prop = __prop_root; + bool changed = false; + + if (property == __prop_off.get_key () && (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_TC_TO_SC)) { + m_work_mode = SCTC_MODE_OFF; + changed = true; + } else if (property == __prop_sc_to_tc.get_key () && m_factory->m_sc_ok && !__is_sc_encoding (get_encoding ()) && + (m_work_mode == SCTC_MODE_OFF || m_work_mode == SCTC_MODE_TC_TO_SC)) { + m_work_mode = SCTC_MODE_SC_TO_TC; + prop.set_icon (__prop_sc_to_tc.get_icon ()); + prop.set_label (_("SC->TC")); + changed = true; + } else if (property == __prop_tc_to_sc.get_key () && m_factory->m_tc_ok && !__is_tc_encoding (get_encoding ()) && + (m_work_mode == SCTC_MODE_OFF || m_work_mode == SCTC_MODE_SC_TO_TC)) { + m_work_mode = SCTC_MODE_TC_TO_SC; + prop.set_icon (__prop_tc_to_sc.get_icon ()); + prop.set_label (_("TC->SC")); + changed = true; + } + + if (changed) { + set_encoding (get_encoding ()); + update_property (prop); + } +} + +void +SCTCFilterInstance::filter_update_preedit_string (const WideString &str, + const AttributeList &attrs) +{ + WideString nstr = str; + + if (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) + nstr = __sc_to_tc (str); + if (m_work_mode == SCTC_MODE_TC_TO_SC || m_work_mode == SCTC_MODE_FORCE_TC_TO_SC) + nstr = __tc_to_sc (str); + + update_preedit_string (nstr, attrs); +} + +void +SCTCFilterInstance::filter_update_aux_string (const WideString &str, + const AttributeList &attrs) +{ + WideString nstr = str; + + if (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) + nstr = __sc_to_tc (str); + if (m_work_mode == SCTC_MODE_TC_TO_SC || m_work_mode == SCTC_MODE_FORCE_TC_TO_SC) + nstr = __tc_to_sc (str); + + update_aux_string (nstr, attrs); +} + +void +SCTCFilterInstance::filter_update_lookup_table (const LookupTable &table) +{ + if (m_work_mode == SCTC_MODE_OFF) { + update_lookup_table (table); + } else { + CommonLookupTable ntable; + std::vector labels; + size_t i; + + // Can be paged up. + if (table.get_current_page_start ()) + ntable.append_candidate (0x3400); + + if (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) { + for (i = 0; i < table.get_current_page_size (); ++i) { + ntable.append_candidate (__sc_to_tc (table.get_candidate_in_current_page (i)), table.get_attributes_in_current_page (i)); + labels.push_back (__sc_to_tc (table.get_candidate_label (i))); + } + } else { + for (i = 0; i < table.get_current_page_size (); ++i) { + ntable.append_candidate (__tc_to_sc (table.get_candidate_in_current_page (i)), table.get_attributes_in_current_page (i)); + labels.push_back (__tc_to_sc (table.get_candidate_label (i))); + } + } + + if (table.get_current_page_start () + table.get_current_page_size () < table.number_of_candidates ()) + ntable.append_candidate (0x3400); + + if (table.get_current_page_start ()) { + ntable.set_page_size (1); + ntable.page_down (); + } + + ntable.set_page_size (table.get_current_page_size ()); + ntable.set_cursor_pos_in_current_page (table.get_cursor_pos_in_current_page ()); + ntable.show_cursor (table.is_cursor_visible ()); + ntable.fix_page_size (table.is_page_size_fixed ()); + ntable.set_candidate_labels (labels); + + update_lookup_table (ntable); + } +} + +void +SCTCFilterInstance::filter_commit_string (const WideString &str) +{ + WideString nstr = str; + + if (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) + nstr = __sc_to_tc (str); + if (m_work_mode == SCTC_MODE_TC_TO_SC || m_work_mode == SCTC_MODE_FORCE_TC_TO_SC) + nstr = __tc_to_sc (str); + + commit_string (nstr); +} + +void +SCTCFilterInstance::filter_register_properties (const PropertyList &properties) +{ + PropertyList props; + + if (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) { + for (size_t i = 0; i < properties.size (); ++i) { + Property prop = properties [i]; + prop.set_label (utf8_wcstombs (__sc_to_tc (utf8_mbstowcs (prop.get_label ())))); + prop.set_tip (utf8_wcstombs (__sc_to_tc (utf8_mbstowcs (prop.get_tip ())))); + props.push_back (prop); + } + } else if (m_work_mode == SCTC_MODE_TC_TO_SC || m_work_mode == SCTC_MODE_FORCE_TC_TO_SC) { + for (size_t i = 0; i < properties.size (); ++i) { + Property prop = properties [i]; + prop.set_label (utf8_wcstombs (__tc_to_sc (utf8_mbstowcs (prop.get_label ())))); + prop.set_tip (utf8_wcstombs (__tc_to_sc (utf8_mbstowcs (prop.get_tip ())))); + props.push_back (prop); + } + } else { + props = properties; + } + + if (m_work_mode == SCTC_MODE_OFF || m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_TC_TO_SC) { + Property root = __prop_root; + + if (m_work_mode == SCTC_MODE_SC_TO_TC) { + root.set_icon (__prop_sc_to_tc.get_icon ()); + root.set_tip (__prop_sc_to_tc.get_tip ()); + root.set_label (_("SC->TC")); + } else if (m_work_mode == SCTC_MODE_TC_TO_SC) { + root.set_icon (__prop_tc_to_sc.get_icon ()); + root.set_tip (__prop_tc_to_sc.get_tip ()); + root.set_label (_("TC->SC")); + } + + props.push_back (root); + props.push_back (__prop_off); + + if (!__is_sc_encoding (get_encoding ()) && m_factory->m_sc_ok) + props.push_back (__prop_sc_to_tc); + if (!__is_tc_encoding (get_encoding ()) && m_factory->m_tc_ok) + props.push_back (__prop_tc_to_sc); + } else if (m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) { + Property root = __prop_sc_to_tc; + root.set_label (_("SC->TC")); + props.push_back (root); + } else if (m_work_mode == SCTC_MODE_FORCE_TC_TO_SC) { + Property root = __prop_tc_to_sc; + root.set_label (_("TC->SC")); + props.push_back (root); + } + + register_properties (props); + + m_props_registered = true; +} + +void +SCTCFilterInstance::filter_update_property (const Property &property) +{ + Property prop = property; + + if (m_work_mode == SCTC_MODE_SC_TO_TC || m_work_mode == SCTC_MODE_FORCE_SC_TO_TC) { + prop.set_label (utf8_wcstombs (__sc_to_tc (utf8_mbstowcs (prop.get_label ())))); + prop.set_tip (utf8_wcstombs (__sc_to_tc (utf8_mbstowcs (prop.get_tip ())))); + } else if (m_work_mode == SCTC_MODE_TC_TO_SC || m_work_mode == SCTC_MODE_FORCE_TC_TO_SC) { + prop.set_label (utf8_wcstombs (__tc_to_sc (utf8_mbstowcs (prop.get_label ())))); + prop.set_tip (utf8_wcstombs (__tc_to_sc (utf8_mbstowcs (prop.get_tip ())))); + } + + update_property (prop); +} + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/filter/scim_sctc_filter.h b/ism/modules/filter/scim_sctc_filter.h new file mode 100644 index 0000000..81994c1 --- /dev/null +++ b/ism/modules/filter/scim_sctc_filter.h @@ -0,0 +1,108 @@ +/** @file scim_sctc_filter.h + * definition of SCTCFilter (Simplified Chinese <-> Traditional Chinese Filter) related classes. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_sctc_filter.h,v 1.2 2005/05/17 14:56:39 suzhe Exp $ + */ + +#if !defined (__SCIM_SCTC_FILTER_H) +#define __SCIM_SCTC_FILTER_H + +using namespace scim; + +#define SCTC_ICON_PNG (SCIM_ICONDIR "/sctc.png") +#define SC_TO_TC_ICON_PNG (SCIM_ICONDIR "/sctc-sc-to-tc.png") +#define TC_TO_SC_ICON_PNG (SCIM_ICONDIR "/sctc-tc-to-sc.png") + +enum SCTCWorkMode +{ + SCTC_MODE_OFF = 0, + SCTC_MODE_SC_TO_TC, + SCTC_MODE_TC_TO_SC, + SCTC_MODE_FORCE_OFF, + SCTC_MODE_FORCE_SC_TO_TC, + SCTC_MODE_FORCE_TC_TO_SC +}; + +class SCTCFilterFactory : public FilterFactoryBase +{ + bool m_sc_ok; + String m_sc_encoding; + + bool m_tc_ok; + String m_tc_encoding; + + friend class SCTCFilterInstance; + +public: + SCTCFilterFactory (); + + virtual void attach_imengine_factory (const IMEngineFactoryPointer &orig); + virtual WideString get_name () const; + virtual String get_uuid () const; + virtual String get_icon_file () const; + virtual WideString get_authors () const; + virtual WideString get_help () const; + virtual bool validate_encoding (const String& encoding) const; + virtual bool validate_locale (const String& locale) const; + virtual IMEngineInstancePointer create_instance (const String& encoding, int id = -1); +}; + +class SCTCFilterInstance : public FilterInstanceBase +{ + SCTCFilterFactory *m_factory; + + bool m_props_registered; + + SCTCWorkMode m_work_mode; + +public: + SCTCFilterInstance (SCTCFilterFactory *factory, + const SCTCWorkMode &mode, + const String &client_encoding, + const IMEngineInstancePointer &orig_inst); + + virtual bool set_encoding (const String &encoding); + +public: + virtual void focus_in (); + + virtual void trigger_property (const String &property); + +protected: + virtual void filter_update_preedit_string (const WideString &str, + const AttributeList &attrs = AttributeList ()); + virtual void filter_update_aux_string (const WideString &str, + const AttributeList &attrs = AttributeList ()); + virtual void filter_update_lookup_table (const LookupTable &table); + virtual void filter_commit_string (const WideString &str); + virtual void filter_register_properties (const PropertyList &properties); + virtual void filter_update_property (const Property &property); +}; + +#endif +/* +vi:ts=4:nowrap:ai:expandtab +*/ + diff --git a/ism/modules/filter/scim_sctc_filter_data.h b/ism/modules/filter/scim_sctc_filter_data.h new file mode 100644 index 0000000..599696c --- /dev/null +++ b/ism/modules/filter/scim_sctc_filter_data.h @@ -0,0 +1,1307 @@ +/** @file scim_sctc_filter_data.h + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_sctc_filter_data.h,v 1.1 2005/05/16 05:22:49 suzhe Exp $ + */ + +#if !defined (__SCIM_SCTC_FILTER_DATA_H) +#define __SCIM_SCTC_FILTER_DATA_H +struct UShortPair +{ + unsigned short first; + unsigned short second; +}; + +static UShortPair __sc_to_tc_table [] = { + { 0x00a8, 0x2025 },{ 0x2015, 0x2500 },{ 0x2016, 0x2225 },{ 0x2033, 0x301e }, + { 0x220f, 0x03a0 },{ 0x2211, 0x03a3 },{ 0x2227, 0xfe3f },{ 0x2228, 0xfe40 }, + { 0x2236, 0xfe30 },{ 0x2248, 0x2252 },{ 0x2264, 0x2266 },{ 0x2265, 0x2267 }, + { 0x2501, 0x2500 },{ 0x2503, 0x2502 },{ 0x250f, 0x250c },{ 0x2513, 0x2510 }, + { 0x2517, 0x2514 },{ 0x251b, 0x2518 },{ 0x2523, 0x251c },{ 0x252b, 0x2524 }, + { 0x2533, 0x252c },{ 0x253b, 0x2534 },{ 0x254b, 0x253c },{ 0x30fb, 0x00b7 }, + { 0x4e07, 0x842c },{ 0x4e0e, 0x8207 },{ 0x4e11, 0x919c },{ 0x4e13, 0x5c08 }, + { 0x4e1a, 0x696d },{ 0x4e1b, 0x53e2 },{ 0x4e1c, 0x6771 },{ 0x4e1d, 0x7d72 }, + { 0x4e22, 0x4e1f },{ 0x4e24, 0x5169 },{ 0x4e25, 0x56b4 },{ 0x4e27, 0x55aa }, + { 0x4e2a, 0x500b },{ 0x4e2c, 0x723f },{ 0x4e30, 0x8c50 },{ 0x4e34, 0x81e8 }, + { 0x4e3a, 0x70ba },{ 0x4e3d, 0x9e97 },{ 0x4e3e, 0x8209 },{ 0x4e48, 0x9ebc }, + { 0x4e49, 0x7fa9 },{ 0x4e4c, 0x70cf },{ 0x4e50, 0x6a02 },{ 0x4e54, 0x55ac }, + { 0x4e60, 0x7fd2 },{ 0x4e61, 0x9109 },{ 0x4e66, 0x66f8 },{ 0x4e70, 0x8cb7 }, + { 0x4e71, 0x4e82 },{ 0x4e89, 0x722d },{ 0x4e8f, 0x8667 },{ 0x4e91, 0x96f2 }, + { 0x4e98, 0x4e99 },{ 0x4e9a, 0x4e9e },{ 0x4ea7, 0x7522 },{ 0x4ea9, 0x755d }, + { 0x4eb2, 0x89aa },{ 0x4eb5, 0x893b },{ 0x4ebb, 0x4eba },{ 0x4ebf, 0x5104 }, + { 0x4ec5, 0x50c5 },{ 0x4ec6, 0x50d5 },{ 0x4ece, 0x5f9e },{ 0x4ed1, 0x4f96 }, + { 0x4ed3, 0x5009 },{ 0x4eea, 0x5100 },{ 0x4eec, 0x5011 },{ 0x4ef7, 0x50f9 }, + { 0x4f17, 0x773e },{ 0x4f18, 0x512a },{ 0x4f1a, 0x6703 },{ 0x4f1b, 0x50b4 }, + { 0x4f1e, 0x5098 },{ 0x4f1f, 0x5049 },{ 0x4f20, 0x50b3 },{ 0x4f24, 0x50b7 }, + { 0x4f25, 0x5000 },{ 0x4f26, 0x502b },{ 0x4f27, 0x5096 },{ 0x4f2a, 0x507d }, + { 0x4f2b, 0x4f47 },{ 0x4f32, 0x4f60 },{ 0x4f53, 0x9ad4 },{ 0x4f59, 0x9918 }, + { 0x4f63, 0x50ad },{ 0x4f65, 0x50c9 },{ 0x4f84, 0x59ea },{ 0x4fa0, 0x4fe0 }, + { 0x4fa3, 0x4fb6 },{ 0x4fa5, 0x50e5 },{ 0x4fa6, 0x5075 },{ 0x4fa7, 0x5074 }, + { 0x4fa8, 0x50d1 },{ 0x4fa9, 0x5108 },{ 0x4faa, 0x5115 },{ 0x4fac, 0x5102 }, + { 0x4fe3, 0x4fc1 },{ 0x4fe6, 0x5114 },{ 0x4fe8, 0x513c },{ 0x4fe9, 0x5006 }, + { 0x4fea, 0x5137 },{ 0x4fed, 0x5109 },{ 0x502e, 0x88f8 },{ 0x503a, 0x50b5 }, + { 0x503e, 0x50be },{ 0x506c, 0x50af },{ 0x507b, 0x50c2 },{ 0x507e, 0x50e8 }, + { 0x507f, 0x511f },{ 0x50a5, 0x513b },{ 0x50a7, 0x5110 },{ 0x50a8, 0x5132 }, + { 0x50a9, 0x513a },{ 0x513f, 0x5152 },{ 0x5151, 0x514c },{ 0x5156, 0x5157 }, + { 0x515a, 0x9ee8 },{ 0x5170, 0x862d },{ 0x5173, 0x95dc },{ 0x5174, 0x8208 }, + { 0x5179, 0x8332 },{ 0x517b, 0x990a },{ 0x517d, 0x7378 },{ 0x5181, 0x56c5 }, + { 0x5185, 0x5167 },{ 0x5188, 0x5ca1 },{ 0x518c, 0x518a },{ 0x5199, 0x5beb }, + { 0x519b, 0x8ecd },{ 0x519c, 0x8fb2 },{ 0x51a2, 0x585a },{ 0x51af, 0x99ae }, + { 0x51b2, 0x885d },{ 0x51b3, 0x6c7a },{ 0x51b5, 0x6cc1 },{ 0x51bb, 0x51cd }, + { 0x51c0, 0x6de8 },{ 0x51c4, 0x6dd2 },{ 0x51c6, 0x6e96 },{ 0x51c7, 0x6dde }, + { 0x51c9, 0x6dbc },{ 0x51cf, 0x6e1b },{ 0x51d1, 0x6e4a },{ 0x51db, 0x51dc }, + { 0x51e0, 0x5e7e },{ 0x51e4, 0x9cf3 },{ 0x51eb, 0x9ce7 },{ 0x51ed, 0x6191 }, + { 0x51ef, 0x51f1 },{ 0x51f6, 0x5147 },{ 0x51fb, 0x64ca },{ 0x51fc, 0x5e7d }, + { 0x51ff, 0x947f },{ 0x5202, 0x5200 },{ 0x520d, 0x82bb },{ 0x5212, 0x5283 }, + { 0x5218, 0x5289 },{ 0x5219, 0x5247 },{ 0x521a, 0x525b },{ 0x521b, 0x5275 }, + { 0x5220, 0x522a },{ 0x522b, 0x5225 },{ 0x522d, 0x5244 },{ 0x5239, 0x524e }, + { 0x523d, 0x528a },{ 0x523f, 0x528c },{ 0x5240, 0x5274 },{ 0x5242, 0x5291 }, + { 0x5250, 0x526e },{ 0x5251, 0x528d },{ 0x5265, 0x525d },{ 0x5267, 0x5287 }, + { 0x527f, 0x52e6 },{ 0x529d, 0x52f8 },{ 0x529e, 0x8fa6 },{ 0x52a1, 0x52d9 }, + { 0x52a2, 0x52f1 },{ 0x52a8, 0x52d5 },{ 0x52b1, 0x52f5 },{ 0x52b2, 0x52c1 }, + { 0x52b3, 0x52de },{ 0x52bf, 0x52e2 },{ 0x52cb, 0x52f3 },{ 0x52d6, 0x52d7 }, + { 0x5300, 0x52fb },{ 0x5326, 0x532d },{ 0x532e, 0x5331 },{ 0x533a, 0x5340 }, + { 0x533b, 0x91ab },{ 0x534e, 0x83ef },{ 0x534f, 0x5354 },{ 0x5355, 0x55ae }, + { 0x5356, 0x8ce3 },{ 0x5360, 0x4f54 },{ 0x5362, 0x76e7 },{ 0x5364, 0x6ef7 }, + { 0x5367, 0x81e5 },{ 0x5369, 0x90e8 },{ 0x536b, 0x885b },{ 0x5374, 0x537b }, + { 0x537a, 0x5df9 },{ 0x5382, 0x5ee0 },{ 0x5385, 0x5ef3 },{ 0x5386, 0x6b77 }, + { 0x5389, 0x53b2 },{ 0x538b, 0x58d3 },{ 0x538c, 0x53ad },{ 0x538d, 0x5399 }, + { 0x5395, 0x5ec1 },{ 0x5398, 0x91d0 },{ 0x53a2, 0x5ec2 },{ 0x53a3, 0x53b4 }, + { 0x53a6, 0x5ec8 },{ 0x53a8, 0x5eda },{ 0x53a9, 0x5ec4 },{ 0x53ae, 0x5edd }, + { 0x53b6, 0x79c1 },{ 0x53bf, 0x7e23 },{ 0x53c1, 0x53c3 },{ 0x53c2, 0x53c3 }, + { 0x53cc, 0x96d9 },{ 0x53d1, 0x767c },{ 0x53d8, 0x8b8a },{ 0x53d9, 0x6558 }, + { 0x53e0, 0x758a },{ 0x53f6, 0x8449 },{ 0x53f7, 0x865f },{ 0x53f9, 0x5606 }, + { 0x53fd, 0x5630 },{ 0x5401, 0x7c72 },{ 0x540e, 0x5f8c },{ 0x5413, 0x5687 }, + { 0x5415, 0x5442 },{ 0x5417, 0x55ce },{ 0x5428, 0x5678 },{ 0x542c, 0x807d }, + { 0x542f, 0x555f },{ 0x5434, 0x5433 },{ 0x5450, 0x5436 },{ 0x5452, 0x5638 }, + { 0x5453, 0x56c8 },{ 0x5455, 0x5614 },{ 0x5456, 0x56a6 },{ 0x5457, 0x5504 }, + { 0x5458, 0x54e1 },{ 0x5459, 0x54bc },{ 0x545b, 0x55c6 },{ 0x545c, 0x55da }, + { 0x5468, 0x9031 },{ 0x548f, 0x8a60 },{ 0x5499, 0x56a8 },{ 0x549b, 0x5680 }, + { 0x54b8, 0x9e79 },{ 0x54cc, 0x5471 },{ 0x54cd, 0x97ff },{ 0x54d1, 0x555e }, + { 0x54d2, 0x5660 },{ 0x54d3, 0x5635 },{ 0x54d4, 0x55f6 },{ 0x54d5, 0x5666 }, + { 0x54d7, 0x5629 },{ 0x54d9, 0x5672 },{ 0x54dc, 0x568c },{ 0x54dd, 0x5665 }, + { 0x54df, 0x55b2 },{ 0x551b, 0x561c },{ 0x5520, 0x562e },{ 0x5522, 0x55e9 }, + { 0x5524, 0x559a },{ 0x5567, 0x5616 },{ 0x556c, 0x55c7 },{ 0x556d, 0x56c0 }, + { 0x556e, 0x56d3 },{ 0x5578, 0x562f },{ 0x55b7, 0x5674 },{ 0x55bd, 0x560d }, + { 0x55be, 0x56b3 },{ 0x55eb, 0x56c1 },{ 0x55ec, 0x5475 },{ 0x55f3, 0x566f }, + { 0x5618, 0x5653 },{ 0x5624, 0x56b6 },{ 0x5631, 0x56d1 },{ 0x565c, 0x5695 }, + { 0x56a3, 0x56c2 },{ 0x56e2, 0x5718 },{ 0x56ed, 0x5712 },{ 0x56f1, 0x56ea }, + { 0x56f4, 0x570d },{ 0x56f5, 0x5707 },{ 0x56fd, 0x570b },{ 0x56fe, 0x5716 }, + { 0x5706, 0x5713 },{ 0x5723, 0x8056 },{ 0x5739, 0x58d9 },{ 0x573a, 0x5834 }, + { 0x5742, 0x962a },{ 0x574f, 0x58de },{ 0x5757, 0x584a },{ 0x575a, 0x5805 }, + { 0x575b, 0x58c7 },{ 0x575c, 0x58e2 },{ 0x575d, 0x58e9 },{ 0x575e, 0x5862 }, + { 0x575f, 0x58b3 },{ 0x5760, 0x589c },{ 0x5784, 0x58df },{ 0x5785, 0x58df }, + { 0x5786, 0x58da },{ 0x5792, 0x58d8 },{ 0x57a6, 0x58be },{ 0x57a9, 0x580a }, + { 0x57ab, 0x588a },{ 0x57ad, 0x57e1 },{ 0x57b2, 0x584f },{ 0x57d8, 0x5852 }, + { 0x57d9, 0x58ce },{ 0x57da, 0x581d },{ 0x5811, 0x5879 },{ 0x5815, 0x58ae }, + { 0x5892, 0x5891 },{ 0x5899, 0x7246 },{ 0x58ee, 0x58ef },{ 0x58f0, 0x8072 }, + { 0x58f3, 0x6bbc },{ 0x58f6, 0x58fa },{ 0x5904, 0x8655 },{ 0x5907, 0x5099 }, + { 0x590d, 0x5fa9 },{ 0x591f, 0x5920 },{ 0x5934, 0x982d },{ 0x5938, 0x8a87 }, + { 0x5939, 0x593e },{ 0x593a, 0x596a },{ 0x5941, 0x5969 },{ 0x5942, 0x5950 }, + { 0x594b, 0x596e },{ 0x5956, 0x734e },{ 0x5965, 0x5967 },{ 0x5986, 0x599d }, + { 0x5987, 0x5a66 },{ 0x5988, 0x5abd },{ 0x59a9, 0x5af5 },{ 0x59aa, 0x5ad7 }, + { 0x59ab, 0x5aaf },{ 0x59d7, 0x59cd },{ 0x5a04, 0x5a41 },{ 0x5a05, 0x5a6d }, + { 0x5a06, 0x5b08 },{ 0x5a07, 0x5b0c },{ 0x5a08, 0x5b4c },{ 0x5a31, 0x5a1b }, + { 0x5a32, 0x5aa7 },{ 0x5a34, 0x5afb },{ 0x5a74, 0x5b30 },{ 0x5a75, 0x5b0b }, + { 0x5a76, 0x5b38 },{ 0x5aaa, 0x5abc },{ 0x5ad2, 0x5b21 },{ 0x5ad4, 0x5b2a }, + { 0x5af1, 0x5b19 },{ 0x5b37, 0x5b24 },{ 0x5b59, 0x5b6b },{ 0x5b66, 0x5b78 }, + { 0x5b6a, 0x5b7f },{ 0x5b81, 0x5be7 },{ 0x5b9d, 0x5bf6 },{ 0x5b9e, 0x5be6 }, + { 0x5ba0, 0x5bf5 },{ 0x5ba1, 0x5be9 },{ 0x5baa, 0x61b2 },{ 0x5bab, 0x5bae }, + { 0x5bbd, 0x5bec },{ 0x5bbe, 0x8cd3 },{ 0x5bdd, 0x5be2 },{ 0x5bf9, 0x5c0d }, + { 0x5bfb, 0x5c0b },{ 0x5bfc, 0x5c0e },{ 0x5bff, 0x58fd },{ 0x5c06, 0x5c07 }, + { 0x5c14, 0x723e },{ 0x5c18, 0x5875 },{ 0x5c1c, 0x560e },{ 0x5c1d, 0x5617 }, + { 0x5c27, 0x582f },{ 0x5c34, 0x5c37 },{ 0x5c38, 0x5c4d },{ 0x5c3d, 0x76e1 }, + { 0x5c42, 0x5c64 },{ 0x5c49, 0x5c5c },{ 0x5c4a, 0x5c46 },{ 0x5c5e, 0x5c6c }, + { 0x5c61, 0x5c62 },{ 0x5c66, 0x5c68 },{ 0x5c7f, 0x5dbc },{ 0x5c81, 0x6b72 }, + { 0x5c82, 0x8c48 },{ 0x5c96, 0x5d87 },{ 0x5c97, 0x5d17 },{ 0x5c98, 0x5cf4 }, + { 0x5c9a, 0x5d50 },{ 0x5c9b, 0x5cf6 },{ 0x5cad, 0x5dba },{ 0x5cbd, 0x5d20 }, + { 0x5cbf, 0x5dcb },{ 0x5cc4, 0x5da7 },{ 0x5ce1, 0x5cfd },{ 0x5ce4, 0x5da0 }, + { 0x5ce5, 0x5d22 },{ 0x5ce6, 0x5dd2 },{ 0x5d02, 0x5d97 },{ 0x5d03, 0x5d0d }, + { 0x5d2d, 0x5d84 },{ 0x5d58, 0x5db8 },{ 0x5d5b, 0x5d33 },{ 0x5d5d, 0x5d81 }, + { 0x5dc5, 0x5dd4 },{ 0x5de9, 0x978f },{ 0x5def, 0x5df0 },{ 0x5e01, 0x5e63 }, + { 0x5e05, 0x5e25 },{ 0x5e08, 0x5e2b },{ 0x5e0f, 0x5e43 },{ 0x5e10, 0x5e33 }, + { 0x5e18, 0x7c3e },{ 0x5e1c, 0x5e5f },{ 0x5e26, 0x5e36 },{ 0x5e27, 0x5e40 }, + { 0x5e2e, 0x5e6b },{ 0x5e31, 0x5e6c },{ 0x5e3b, 0x5e58 },{ 0x5e3c, 0x5e57 }, + { 0x5e42, 0x51aa },{ 0x5e72, 0x5e79 },{ 0x5e76, 0x4e26 },{ 0x5e7a, 0x4e48 }, + { 0x5e7f, 0x5ee3 },{ 0x5e84, 0x838a },{ 0x5e86, 0x6176 },{ 0x5e90, 0x5eec }, + { 0x5e91, 0x5ee1 },{ 0x5e93, 0x5eab },{ 0x5e94, 0x61c9 },{ 0x5e99, 0x5edf }, + { 0x5e9e, 0x9f90 },{ 0x5e9f, 0x5ee2 },{ 0x5eea, 0x5ee9 },{ 0x5f00, 0x958b }, + { 0x5f02, 0x7570 },{ 0x5f03, 0x68c4 },{ 0x5f11, 0x5f12 },{ 0x5f20, 0x5f35 }, + { 0x5f25, 0x5f4c },{ 0x5f2a, 0x5f33 },{ 0x5f2f, 0x5f4e },{ 0x5f39, 0x5f48 }, + { 0x5f3a, 0x5f37 },{ 0x5f52, 0x6b78 },{ 0x5f53, 0x7576 },{ 0x5f55, 0x9304 }, + { 0x5f66, 0x5f65 },{ 0x5f7b, 0x5fb9 },{ 0x5f84, 0x5f91 },{ 0x5f95, 0x5fa0 }, + { 0x5fa1, 0x79a6 },{ 0x5fc4, 0x5fc3 },{ 0x5fc6, 0x61b6 },{ 0x5fcf, 0x61fa }, + { 0x5fe7, 0x6182 },{ 0x5ffe, 0x613e },{ 0x6000, 0x61f7 },{ 0x6001, 0x614b }, + { 0x6002, 0x616b },{ 0x6003, 0x61ae },{ 0x6004, 0x616a },{ 0x6005, 0x60b5 }, + { 0x6006, 0x6134 },{ 0x601c, 0x6190 },{ 0x603b, 0x7e3d },{ 0x603c, 0x61df }, + { 0x603f, 0x61cc },{ 0x604b, 0x6200 },{ 0x6052, 0x6046 },{ 0x6073, 0x61c7 }, + { 0x6076, 0x60e1 },{ 0x6078, 0x615f },{ 0x6079, 0x61e8 },{ 0x607a, 0x6137 }, + { 0x607b, 0x60fb },{ 0x607c, 0x60f1 },{ 0x607d, 0x60f2 },{ 0x60a6, 0x6085 }, + { 0x60ab, 0x6128 },{ 0x60ac, 0x61f8 },{ 0x60ad, 0x6173 },{ 0x60af, 0x61ab }, + { 0x60ca, 0x9a5a },{ 0x60e7, 0x61fc },{ 0x60e8, 0x6158 },{ 0x60e9, 0x61f2 }, + { 0x60eb, 0x618a },{ 0x60ec, 0x611c },{ 0x60ed, 0x615a },{ 0x60ee, 0x619a }, + { 0x60ef, 0x6163 },{ 0x6120, 0x614d },{ 0x6124, 0x61a4 },{ 0x6126, 0x6192 }, + { 0x613f, 0x9858 },{ 0x6151, 0x61fe },{ 0x61d1, 0x61e3 },{ 0x61d2, 0x61f6 }, + { 0x61d4, 0x61cd },{ 0x6206, 0x6207 },{ 0x620b, 0x6214 },{ 0x620f, 0x6232 }, + { 0x6217, 0x6227 },{ 0x6218, 0x6230 },{ 0x622c, 0x6229 },{ 0x6237, 0x6236 }, + { 0x624c, 0x624b },{ 0x6251, 0x64b2 },{ 0x6258, 0x8a17 },{ 0x6267, 0x57f7 }, + { 0x6269, 0x64f4 },{ 0x626a, 0x636b },{ 0x626b, 0x6383 },{ 0x626c, 0x63da }, + { 0x6270, 0x64fe },{ 0x629a, 0x64ab },{ 0x629b, 0x62cb },{ 0x629f, 0x6476 }, + { 0x62a0, 0x6473 },{ 0x62a1, 0x6384 },{ 0x62a2, 0x6436 },{ 0x62a4, 0x8b77 }, + { 0x62a5, 0x5831 },{ 0x62c5, 0x64d4 },{ 0x62df, 0x64ec },{ 0x62e2, 0x650f }, + { 0x62e3, 0x63c0 },{ 0x62e5, 0x64c1 },{ 0x62e6, 0x6514 },{ 0x62e7, 0x64f0 }, + { 0x62e8, 0x64a5 },{ 0x62e9, 0x64c7 },{ 0x6302, 0x639b },{ 0x631a, 0x646f }, + { 0x631b, 0x6523 },{ 0x631d, 0x64be },{ 0x631e, 0x64bb },{ 0x631f, 0x633e }, + { 0x6320, 0x6493 },{ 0x6321, 0x64cb },{ 0x6322, 0x649f },{ 0x6323, 0x6399 }, + { 0x6324, 0x64e0 },{ 0x6325, 0x63ee },{ 0x6342, 0x6440 },{ 0x635e, 0x6488 }, + { 0x635f, 0x640d },{ 0x6361, 0x64bf },{ 0x6362, 0x63db },{ 0x6363, 0x6417 }, + { 0x636e, 0x64da },{ 0x63b3, 0x64c4 },{ 0x63b4, 0x6451 },{ 0x63b7, 0x64f2 }, + { 0x63b8, 0x64a2 },{ 0x63ba, 0x647b },{ 0x63bc, 0x645c },{ 0x63fd, 0x652c }, + { 0x63ff, 0x64b3 },{ 0x6400, 0x6519 },{ 0x6401, 0x64f1 },{ 0x6402, 0x645f }, + { 0x6405, 0x652a },{ 0x643a, 0x651c },{ 0x6444, 0x651d },{ 0x6445, 0x6504 }, + { 0x6446, 0x64fa },{ 0x6447, 0x6416 },{ 0x6448, 0x64ef },{ 0x644a, 0x6524 }, + { 0x6484, 0x6516 },{ 0x6491, 0x6490 },{ 0x64b5, 0x6506 },{ 0x64b7, 0x64f7 }, + { 0x64b8, 0x64fc },{ 0x64ba, 0x651b },{ 0x64c0, 0x641f },{ 0x64de, 0x64fb }, + { 0x6512, 0x6522 },{ 0x6534, 0x64b2 },{ 0x654c, 0x6575 },{ 0x655b, 0x6582 }, + { 0x6570, 0x6578 },{ 0x658b, 0x9f4b },{ 0x6593, 0x6595 },{ 0x6597, 0x9b25 }, + { 0x65a9, 0x65ac },{ 0x65ad, 0x65b7 },{ 0x65e0, 0x7121 },{ 0x65e7, 0x820a }, + { 0x65f6, 0x6642 },{ 0x65f7, 0x66e0 },{ 0x6619, 0x66c7 },{ 0x6635, 0x66b1 }, + { 0x663c, 0x665d },{ 0x663e, 0x986f },{ 0x664b, 0x6649 },{ 0x6652, 0x66ec }, + { 0x6653, 0x66c9 },{ 0x6654, 0x66c4 },{ 0x6655, 0x6688 },{ 0x6656, 0x6689 }, + { 0x6682, 0x66ab },{ 0x66a7, 0x66d6 },{ 0x6710, 0x80ca },{ 0x672f, 0x8853 }, + { 0x6734, 0x6a38 },{ 0x673a, 0x6a5f },{ 0x6740, 0x6bba },{ 0x6742, 0x96dc }, + { 0x6743, 0x6b0a },{ 0x6746, 0x687f },{ 0x6760, 0x69d3 },{ 0x6761, 0x689d }, + { 0x6765, 0x4f86 },{ 0x6768, 0x694a },{ 0x6769, 0x69aa },{ 0x6770, 0x5091 }, + { 0x677e, 0x9b06 },{ 0x6781, 0x6975 },{ 0x6784, 0x69cb },{ 0x679e, 0x6a05 }, + { 0x67a2, 0x6a1e },{ 0x67a3, 0x68d7 },{ 0x67a5, 0x6aea },{ 0x67a8, 0x68d6 }, + { 0x67aa, 0x69cd },{ 0x67ab, 0x6953 },{ 0x67ad, 0x689f },{ 0x67dc, 0x6ac3 }, + { 0x67e0, 0x6ab8 },{ 0x67fd, 0x6a89 },{ 0x6800, 0x6894 },{ 0x6805, 0x67f5 }, + { 0x6807, 0x6a19 },{ 0x6808, 0x68e7 },{ 0x6809, 0x6adb },{ 0x680a, 0x6af3 }, + { 0x680b, 0x68df },{ 0x680c, 0x6ae8 },{ 0x680e, 0x6adf },{ 0x680f, 0x6b04 }, + { 0x6811, 0x6a39 },{ 0x6816, 0x68f2 },{ 0x6837, 0x6a23 },{ 0x683e, 0x6b12 }, + { 0x6860, 0x690f },{ 0x6861, 0x6a48 },{ 0x6862, 0x6968 },{ 0x6863, 0x6a94 }, + { 0x6864, 0x69bf },{ 0x6865, 0x6a4b },{ 0x6866, 0x6a3a },{ 0x6867, 0x6a9c }, + { 0x6868, 0x69f3 },{ 0x6869, 0x6a01 },{ 0x68a6, 0x5922 },{ 0x68c0, 0x6aa2 }, + { 0x68c2, 0x6afa },{ 0x68f0, 0x7ba0 },{ 0x68f1, 0x7a1c },{ 0x6901, 0x69e8 }, + { 0x691f, 0x6add },{ 0x6920, 0x69e7 },{ 0x6924, 0x6b0f },{ 0x692d, 0x6a62 }, + { 0x697c, 0x6a13 },{ 0x6984, 0x6b16 },{ 0x6987, 0x6aec },{ 0x6988, 0x6ada }, + { 0x6989, 0x6af8 },{ 0x6998, 0x77e9 },{ 0x69db, 0x6abb },{ 0x69df, 0x6ab3 }, + { 0x69e0, 0x6ae7 },{ 0x6a2a, 0x6a6b },{ 0x6a2f, 0x6aa3 },{ 0x6a31, 0x6afb }, + { 0x6a65, 0x6aeb },{ 0x6a71, 0x6ae5 },{ 0x6a79, 0x6ad3 },{ 0x6a7c, 0x6ade }, + { 0x6a90, 0x7c37 },{ 0x6aa9, 0x6a81 },{ 0x6b22, 0x6b61 },{ 0x6b24, 0x6b5f }, + { 0x6b27, 0x6b50 },{ 0x6b7c, 0x6bb2 },{ 0x6b81, 0x6b7f },{ 0x6b87, 0x6ba4 }, + { 0x6b8b, 0x6b98 },{ 0x6b92, 0x6b9e },{ 0x6b93, 0x6bae },{ 0x6b9a, 0x6bab }, + { 0x6ba1, 0x6baf },{ 0x6bb4, 0x6bc6 },{ 0x6bc1, 0x6bc0 },{ 0x6bc2, 0x8f42 }, + { 0x6bd5, 0x7562 },{ 0x6bd9, 0x6583 },{ 0x6be1, 0x6c08 },{ 0x6bf5, 0x6bff }, + { 0x6c07, 0x6c0c },{ 0x6c14, 0x6c23 },{ 0x6c22, 0x6c2b },{ 0x6c29, 0x6c2c }, + { 0x6c32, 0x6c33 },{ 0x6c35, 0x6c34 },{ 0x6c3d, 0x6c46 },{ 0x6c47, 0x532f }, + { 0x6c49, 0x6f22 },{ 0x6c64, 0x6e6f },{ 0x6c79, 0x6d36 },{ 0x6c9f, 0x6e9d }, + { 0x6ca1, 0x6c92 },{ 0x6ca3, 0x7043 },{ 0x6ca4, 0x6f1a },{ 0x6ca5, 0x701d }, + { 0x6ca6, 0x6dea },{ 0x6ca7, 0x6ec4 },{ 0x6ca9, 0x6e88 },{ 0x6caa, 0x6eec }, + { 0x6cb2, 0x6cb1 },{ 0x6cc4, 0x6d29 },{ 0x6cde, 0x6fd8 },{ 0x6cea, 0x6dda }, + { 0x6cf6, 0x6fa9 },{ 0x6cf7, 0x7027 },{ 0x6cf8, 0x7018 },{ 0x6cfa, 0x6ffc }, + { 0x6cfb, 0x7009 },{ 0x6cfc, 0x6f51 },{ 0x6cfd, 0x6fa4 },{ 0x6cfe, 0x6d87 }, + { 0x6d01, 0x6f54 },{ 0x6d12, 0x7051 },{ 0x6d3c, 0x7aaa },{ 0x6d43, 0x6d79 }, + { 0x6d45, 0x6dfa },{ 0x6d46, 0x6f3f },{ 0x6d47, 0x6f86 },{ 0x6d48, 0x6e5e }, + { 0x6d4a, 0x6fc1 },{ 0x6d4b, 0x6e2c },{ 0x6d4d, 0x6fae },{ 0x6d4e, 0x6fdf }, + { 0x6d4f, 0x700f },{ 0x6d51, 0x6e3e },{ 0x6d52, 0x6ef8 },{ 0x6d53, 0x6fc3 }, + { 0x6d54, 0x6f6f },{ 0x6d5c, 0x6ff1 },{ 0x6d82, 0x5857 },{ 0x6d8c, 0x6e67 }, + { 0x6d9b, 0x6fe4 },{ 0x6d9d, 0x6f87 },{ 0x6d9e, 0x6df6 },{ 0x6d9f, 0x6f23 }, + { 0x6da0, 0x6f7f },{ 0x6da1, 0x6e26 },{ 0x6da3, 0x6e19 },{ 0x6da4, 0x6ecc }, + { 0x6da6, 0x6f64 },{ 0x6da7, 0x6f97 },{ 0x6da8, 0x6f32 },{ 0x6da9, 0x6f80 }, + { 0x6dc0, 0x6fb1 },{ 0x6e0a, 0x6df5 },{ 0x6e0c, 0x6de5 },{ 0x6e0d, 0x6f2c }, + { 0x6e0e, 0x7006 },{ 0x6e10, 0x6f38 },{ 0x6e11, 0x6fa0 },{ 0x6e14, 0x6f01 }, + { 0x6e16, 0x700b },{ 0x6e17, 0x6ef2 },{ 0x6e29, 0x6eab },{ 0x6e38, 0x904a }, + { 0x6e7e, 0x7063 },{ 0x6e7f, 0x6fd5 },{ 0x6e83, 0x6f70 },{ 0x6e85, 0x6ffa }, + { 0x6e86, 0x6f35 },{ 0x6ed7, 0x6f77 },{ 0x6eda, 0x6efe },{ 0x6ede, 0x6eef }, + { 0x6edf, 0x7069 },{ 0x6ee0, 0x7044 },{ 0x6ee1, 0x6eff },{ 0x6ee2, 0x7005 }, + { 0x6ee4, 0x6ffe },{ 0x6ee5, 0x6feb },{ 0x6ee6, 0x7064 },{ 0x6ee8, 0x6ff1 }, + { 0x6ee9, 0x7058 },{ 0x6f46, 0x7020 },{ 0x6f47, 0x701f },{ 0x6f4b, 0x7032 }, + { 0x6f4d, 0x6ff0 },{ 0x6f5c, 0x6f5b },{ 0x6f74, 0x7026 },{ 0x6f9c, 0x703e }, + { 0x6fd1, 0x7028 },{ 0x6fd2, 0x7015 },{ 0x704f, 0x705d },{ 0x706c, 0x706b }, + { 0x706d, 0x6ec5 },{ 0x706f, 0x71c8 },{ 0x7075, 0x9748 },{ 0x707e, 0x707d }, + { 0x707f, 0x71e6 },{ 0x7080, 0x716c },{ 0x7089, 0x7210 },{ 0x7096, 0x71c9 }, + { 0x709c, 0x7152 },{ 0x709d, 0x7197 },{ 0x70ae, 0x7832 },{ 0x70b9, 0x9ede }, + { 0x70bc, 0x934a },{ 0x70bd, 0x71be },{ 0x70c1, 0x720d },{ 0x70c2, 0x721b }, + { 0x70c3, 0x70f4 },{ 0x70db, 0x71ed },{ 0x70df, 0x7159 },{ 0x70e6, 0x7169 }, + { 0x70e7, 0x71d2 },{ 0x70e8, 0x71c1 },{ 0x70e9, 0x71f4 },{ 0x70eb, 0x71d9 }, + { 0x70ec, 0x71fc },{ 0x70ed, 0x71b1 },{ 0x7115, 0x7165 },{ 0x7116, 0x71dc }, + { 0x7118, 0x71fe },{ 0x7130, 0x71c4 },{ 0x7145, 0x935b },{ 0x718f, 0x71fb }, + { 0x7231, 0x611b },{ 0x7237, 0x723a },{ 0x724d, 0x7258 },{ 0x7266, 0x729b }, + { 0x7275, 0x727d },{ 0x727a, 0x72a7 },{ 0x728a, 0x72a2 },{ 0x72ad, 0x72ac }, + { 0x72b6, 0x72c0 },{ 0x72b7, 0x7377 },{ 0x72b9, 0x7336 },{ 0x72c8, 0x72fd }, + { 0x72de, 0x7370 },{ 0x72ec, 0x7368 },{ 0x72ed, 0x72f9 },{ 0x72ee, 0x7345 }, + { 0x72ef, 0x736a },{ 0x72f0, 0x7319 },{ 0x72f1, 0x7344 },{ 0x72f2, 0x733b }, + { 0x7303, 0x736b },{ 0x730e, 0x7375 },{ 0x7315, 0x737c },{ 0x7321, 0x7380 }, + { 0x732a, 0x8c6c },{ 0x732b, 0x8c93 },{ 0x732c, 0x875f },{ 0x732e, 0x737b }, + { 0x736d, 0x737a },{ 0x7391, 0x74a3 },{ 0x739b, 0x746a },{ 0x73ae, 0x744b }, + { 0x73af, 0x74b0 },{ 0x73b0, 0x73fe },{ 0x73ba, 0x74bd },{ 0x73c9, 0x739f }, + { 0x73cf, 0x73a8 },{ 0x73d0, 0x743a },{ 0x73d1, 0x74cf },{ 0x73f2, 0x743f }, + { 0x740f, 0x7489 },{ 0x7410, 0x7463 },{ 0x743c, 0x74ca },{ 0x7476, 0x7464 }, + { 0x7477, 0x74a6 },{ 0x748e, 0x74d4 },{ 0x74d2, 0x74da },{ 0x74ee, 0x7515 }, + { 0x74ef, 0x750c },{ 0x7535, 0x96fb },{ 0x753b, 0x756b },{ 0x7545, 0x66a2 }, + { 0x7572, 0x756c },{ 0x7574, 0x7587 },{ 0x7596, 0x7664 },{ 0x7597, 0x7642 }, + { 0x759f, 0x7627 },{ 0x75a0, 0x7658 },{ 0x75a1, 0x760d },{ 0x75ae, 0x7621 }, + { 0x75af, 0x760b },{ 0x75b1, 0x76b0 },{ 0x75b4, 0x75fe },{ 0x75c8, 0x7670 }, + { 0x75c9, 0x75d9 },{ 0x75d2, 0x7662 },{ 0x75e8, 0x7646 },{ 0x75ea, 0x7613 }, + { 0x75eb, 0x7647 },{ 0x75f4, 0x7661 },{ 0x75f9, 0x75fa },{ 0x7605, 0x7649 }, + { 0x7617, 0x761e },{ 0x7618, 0x763a },{ 0x762a, 0x765f },{ 0x762b, 0x7671 }, + { 0x763e, 0x766e },{ 0x763f, 0x766d },{ 0x765e, 0x7669 },{ 0x7663, 0x766c }, + { 0x766b, 0x7672 },{ 0x7691, 0x769a },{ 0x76b1, 0x76ba },{ 0x76b2, 0x76b8 }, + { 0x76cf, 0x76de },{ 0x76d0, 0x9e7d },{ 0x76d1, 0x76e3 },{ 0x76d6, 0x84cb }, + { 0x76d7, 0x76dc },{ 0x76d8, 0x76e4 },{ 0x7726, 0x7725 },{ 0x772f, 0x7787 }, + { 0x7740, 0x8457 },{ 0x7741, 0x775c },{ 0x7750, 0x775e },{ 0x7751, 0x77bc }, + { 0x777e, 0x776a },{ 0x777f, 0x53e1 },{ 0x7792, 0x779e },{ 0x77a9, 0x77da }, + { 0x77eb, 0x77ef },{ 0x77f6, 0x78ef },{ 0x77fe, 0x792c },{ 0x77ff, 0x7926 }, + { 0x7800, 0x78ad },{ 0x7801, 0x78bc },{ 0x7816, 0x78da },{ 0x7817, 0x7868 }, + { 0x781a, 0x786f },{ 0x783a, 0x792a },{ 0x783b, 0x7931 },{ 0x783e, 0x792b }, + { 0x7840, 0x790e },{ 0x7855, 0x78a9 },{ 0x7856, 0x7864 },{ 0x7857, 0x78fd }, + { 0x786e, 0x78ba },{ 0x7877, 0x9e7c },{ 0x788d, 0x7919 },{ 0x789b, 0x78e7 }, + { 0x789c, 0x78e3 },{ 0x78b1, 0x583f },{ 0x7934, 0x7921 },{ 0x793b, 0x793a }, + { 0x793c, 0x79ae },{ 0x795b, 0x88aa },{ 0x7962, 0x79b0 },{ 0x796f, 0x798e }, + { 0x7977, 0x79b1 },{ 0x7978, 0x798d },{ 0x7980, 0x7a1f },{ 0x7984, 0x797f }, + { 0x7985, 0x79aa },{ 0x79bb, 0x96e2 },{ 0x79c3, 0x79bf },{ 0x79c6, 0x7a08 }, + { 0x79cd, 0x7a2e },{ 0x79ef, 0x7a4d },{ 0x79f0, 0x7a31 },{ 0x79fd, 0x7a62 }, + { 0x7a0e, 0x7a05 },{ 0x7a23, 0x7a4c },{ 0x7a33, 0x7a69 },{ 0x7a51, 0x7a61 }, + { 0x7a77, 0x7aae },{ 0x7a83, 0x7aca },{ 0x7a8d, 0x7ac5 },{ 0x7a91, 0x7aaf }, + { 0x7a9c, 0x7ac4 },{ 0x7a9d, 0x7aa9 },{ 0x7aa5, 0x7aba },{ 0x7aa6, 0x7ac7 }, + { 0x7aad, 0x7ab6 },{ 0x7ad6, 0x8c4e },{ 0x7ade, 0x7af6 },{ 0x7b03, 0x7be4 }, + { 0x7b0b, 0x7b4d },{ 0x7b14, 0x7b46 },{ 0x7b15, 0x7b67 },{ 0x7b3a, 0x7b8b }, + { 0x7b3c, 0x7c60 },{ 0x7b3e, 0x7c69 },{ 0x7b47, 0x7b3b },{ 0x7b51, 0x7bc9 }, + { 0x7b5a, 0x7bf3 },{ 0x7b5b, 0x7be9 },{ 0x7b5d, 0x7b8f },{ 0x7b71, 0x7be0 }, + { 0x7b79, 0x7c4c },{ 0x7b7e, 0x7c3d },{ 0x7b80, 0x7c21 },{ 0x7ba6, 0x7c00 }, + { 0x7ba7, 0x7bcb },{ 0x7ba8, 0x7c5c },{ 0x7ba9, 0x7c6e },{ 0x7baa, 0x7c1e }, + { 0x7bab, 0x7c2b },{ 0x7bd1, 0x7c23 },{ 0x7bd3, 0x7c0d },{ 0x7bee, 0x7c43 }, + { 0x7bf1, 0x7c6c },{ 0x7c16, 0x7c6a },{ 0x7c41, 0x7c5f },{ 0x7c74, 0x7cf4 }, + { 0x7c7b, 0x985e },{ 0x7c7c, 0x79c8 },{ 0x7c9c, 0x7cf6 },{ 0x7c9d, 0x7cf2 }, + { 0x7ca4, 0x7cb5 },{ 0x7caa, 0x7cde },{ 0x7cae, 0x7ce7 },{ 0x7cc1, 0x7cdd }, + { 0x7cc7, 0x9931 },{ 0x7ccd, 0x9908 },{ 0x7d27, 0x7dca },{ 0x7d77, 0x7e36 }, + { 0x7e9f, 0x7d72 },{ 0x7ea0, 0x7cfe },{ 0x7ea1, 0x7d06 },{ 0x7ea2, 0x7d05 }, + { 0x7ea3, 0x7d02 },{ 0x7ea4, 0x7e96 },{ 0x7ea5, 0x7d07 },{ 0x7ea6, 0x7d04 }, + { 0x7ea7, 0x7d1a },{ 0x7ea8, 0x7d08 },{ 0x7ea9, 0x7e8a },{ 0x7eaa, 0x7d00 }, + { 0x7eab, 0x7d09 },{ 0x7eac, 0x7def },{ 0x7ead, 0x7d1c },{ 0x7eaf, 0x7d14 }, + { 0x7eb0, 0x7d15 },{ 0x7eb1, 0x7d17 },{ 0x7eb2, 0x7db1 },{ 0x7eb3, 0x7d0d }, + { 0x7eb5, 0x7e31 },{ 0x7eb6, 0x7db8 },{ 0x7eb7, 0x7d1b },{ 0x7eb8, 0x7d19 }, + { 0x7eb9, 0x7d0b },{ 0x7eba, 0x7d21 },{ 0x7ebd, 0x7d10 },{ 0x7ebe, 0x7d13 }, + { 0x7ebf, 0x7dda },{ 0x7ec0, 0x7d3a },{ 0x7ec1, 0x7d32 },{ 0x7ec2, 0x7d31 }, + { 0x7ec3, 0x7df4 },{ 0x7ec4, 0x7d44 },{ 0x7ec5, 0x7d33 },{ 0x7ec6, 0x7d30 }, + { 0x7ec7, 0x7e54 },{ 0x7ec8, 0x7d42 },{ 0x7ec9, 0x7e10 },{ 0x7eca, 0x7d46 }, + { 0x7ecb, 0x7d3c },{ 0x7ecc, 0x7d40 },{ 0x7ecd, 0x7d39 },{ 0x7ece, 0x7e79 }, + { 0x7ecf, 0x7d93 },{ 0x7ed0, 0x7d3f },{ 0x7ed1, 0x7d81 },{ 0x7ed2, 0x7d68 }, + { 0x7ed3, 0x7d50 },{ 0x7ed4, 0x8932 },{ 0x7ed5, 0x7e5e },{ 0x7ed7, 0x7d4e }, + { 0x7ed8, 0x7e6a },{ 0x7ed9, 0x7d66 },{ 0x7eda, 0x7d62 },{ 0x7edb, 0x7d73 }, + { 0x7edc, 0x7d61 },{ 0x7edd, 0x7d55 },{ 0x7ede, 0x7d5e },{ 0x7edf, 0x7d71 }, + { 0x7ee0, 0x7d86 },{ 0x7ee1, 0x7d83 },{ 0x7ee2, 0x7d79 },{ 0x7ee3, 0x7e61 }, + { 0x7ee5, 0x7d8f },{ 0x7ee6, 0x7d5b },{ 0x7ee7, 0x7e7c },{ 0x7ee8, 0x7d88 }, + { 0x7ee9, 0x7e3e },{ 0x7eea, 0x7dd2 },{ 0x7eeb, 0x7dbe },{ 0x7eed, 0x7e8c }, + { 0x7eee, 0x7dba },{ 0x7eef, 0x7dcb },{ 0x7ef0, 0x7dbd },{ 0x7ef2, 0x7dc4 }, + { 0x7ef3, 0x7e69 },{ 0x7ef4, 0x7dad },{ 0x7ef5, 0x7dbf },{ 0x7ef6, 0x7dac }, + { 0x7ef7, 0x7e43 },{ 0x7ef8, 0x7da2 },{ 0x7efa, 0x7db9 },{ 0x7efb, 0x7da3 }, + { 0x7efc, 0x7d9c },{ 0x7efd, 0x7dbb },{ 0x7efe, 0x7db0 },{ 0x7eff, 0x7da0 }, + { 0x7f00, 0x7db4 },{ 0x7f01, 0x7dc7 },{ 0x7f02, 0x7dd9 },{ 0x7f03, 0x7dd7 }, + { 0x7f04, 0x7dd8 },{ 0x7f05, 0x7dec },{ 0x7f06, 0x7e9c },{ 0x7f07, 0x7df9 }, + { 0x7f08, 0x7df2 },{ 0x7f09, 0x7ddd },{ 0x7f0b, 0x7e62 },{ 0x7f0c, 0x7de6 }, + { 0x7f0d, 0x7d9e },{ 0x7f0e, 0x7dde },{ 0x7f0f, 0x7df6 },{ 0x7f11, 0x7df1 }, + { 0x7f12, 0x7e0b },{ 0x7f13, 0x7de9 },{ 0x7f14, 0x7de0 },{ 0x7f15, 0x7e37 }, + { 0x7f16, 0x7de8 },{ 0x7f17, 0x7de1 },{ 0x7f18, 0x7de3 },{ 0x7f19, 0x7e09 }, + { 0x7f1a, 0x7e1b },{ 0x7f1b, 0x7e1f },{ 0x7f1c, 0x7e1d },{ 0x7f1d, 0x7e2b }, + { 0x7f1f, 0x7e1e },{ 0x7f20, 0x7e8f },{ 0x7f21, 0x7e2d },{ 0x7f22, 0x7e0a }, + { 0x7f23, 0x7e11 },{ 0x7f24, 0x7e7d },{ 0x7f25, 0x7e39 },{ 0x7f26, 0x7e35 }, + { 0x7f27, 0x7e32 },{ 0x7f28, 0x7e93 },{ 0x7f29, 0x7e2e },{ 0x7f2a, 0x7e46 }, + { 0x7f2b, 0x7e45 },{ 0x7f2c, 0x7e88 },{ 0x7f2d, 0x7e5a },{ 0x7f2e, 0x7e55 }, + { 0x7f2f, 0x7e52 },{ 0x7f30, 0x97c1 },{ 0x7f31, 0x7e7e },{ 0x7f32, 0x7e70 }, + { 0x7f33, 0x7e6f },{ 0x7f34, 0x7e73 },{ 0x7f35, 0x7e98 },{ 0x7f42, 0x7f4c }, + { 0x7f51, 0x7db2 },{ 0x7f57, 0x7f85 },{ 0x7f5a, 0x7f70 },{ 0x7f62, 0x7f77 }, + { 0x7f74, 0x7f86 },{ 0x7f81, 0x7f88 },{ 0x7f9f, 0x7fa5 },{ 0x7fa1, 0x7fa8 }, + { 0x7fd8, 0x7ff9 },{ 0x8027, 0x802c },{ 0x8038, 0x8073 },{ 0x803b, 0x6065 }, + { 0x8042, 0x8076 },{ 0x804b, 0x807e },{ 0x804c, 0x8077 },{ 0x804d, 0x8079 }, + { 0x8054, 0x806f },{ 0x8069, 0x8075 },{ 0x806a, 0x8070 },{ 0x8080, 0x807f }, + { 0x8083, 0x8085 },{ 0x80a0, 0x8178 },{ 0x80a4, 0x819a },{ 0x80ae, 0x9aaf }, + { 0x80b4, 0x991a },{ 0x80be, 0x814e },{ 0x80bf, 0x816b },{ 0x80c0, 0x8139 }, + { 0x80c1, 0x8105 },{ 0x80c4, 0x5191 },{ 0x80c6, 0x81bd },{ 0x80dc, 0x52dd }, + { 0x80e7, 0x6727 },{ 0x80ea, 0x81da },{ 0x80eb, 0x811b },{ 0x80f6, 0x81a0 }, + { 0x8109, 0x8108 },{ 0x810d, 0x81be },{ 0x810f, 0x9ad2 },{ 0x8110, 0x81cd }, + { 0x8111, 0x8166 },{ 0x8113, 0x81bf },{ 0x8114, 0x81e0 },{ 0x811a, 0x8173 }, + { 0x8131, 0x812b },{ 0x8132, 0x5c3f },{ 0x8136, 0x8161 },{ 0x8138, 0x81c9 }, + { 0x814a, 0x81d8 },{ 0x814c, 0x9183 },{ 0x816d, 0x9f76 },{ 0x817b, 0x81a9 }, + { 0x817c, 0x9766 },{ 0x817d, 0x8183 },{ 0x817e, 0x9a30 },{ 0x8191, 0x81cf }, + { 0x8206, 0x8f3f },{ 0x8223, 0x8264 },{ 0x8230, 0x8266 },{ 0x8231, 0x8259 }, + { 0x823b, 0x826b },{ 0x8270, 0x8271 },{ 0x8273, 0x8c54 },{ 0x8279, 0x8278 }, + { 0x827a, 0x85dd },{ 0x8282, 0x7bc0 },{ 0x8288, 0x7f8b },{ 0x8297, 0x858c }, + { 0x829c, 0x856a },{ 0x82a6, 0x8606 },{ 0x82c1, 0x84ef },{ 0x82c7, 0x8466 }, + { 0x82c8, 0x85f6 },{ 0x82cb, 0x83a7 },{ 0x82cc, 0x8407 },{ 0x82cd, 0x84bc }, + { 0x82ce, 0x82e7 },{ 0x82cf, 0x8607 },{ 0x82f9, 0x860b },{ 0x8303, 0x7bc4 }, + { 0x830e, 0x8396 },{ 0x830f, 0x8622 },{ 0x8311, 0x8526 },{ 0x8314, 0x584b }, + { 0x8315, 0x7162 },{ 0x8327, 0x7e6d },{ 0x8346, 0x834a },{ 0x8350, 0x85a6 }, + { 0x835a, 0x83a2 },{ 0x835b, 0x8558 },{ 0x835c, 0x84fd },{ 0x835e, 0x854e }, + { 0x835f, 0x8588 },{ 0x8360, 0x85ba },{ 0x8361, 0x8569 },{ 0x8363, 0x69ae }, + { 0x8364, 0x8477 },{ 0x8365, 0x6ece },{ 0x8366, 0x7296 },{ 0x8367, 0x7192 }, + { 0x8368, 0x8541 },{ 0x8369, 0x85ce },{ 0x836a, 0x84c0 },{ 0x836b, 0x852d }, + { 0x836c, 0x85da },{ 0x836d, 0x8452 },{ 0x836f, 0x85e5 },{ 0x8385, 0x849e }, + { 0x83b1, 0x840a },{ 0x83b2, 0x84ee },{ 0x83b3, 0x8494 },{ 0x83b4, 0x8435 }, + { 0x83b6, 0x859f },{ 0x83b7, 0x7372 },{ 0x83b8, 0x8555 },{ 0x83b9, 0x7469 }, + { 0x83ba, 0x9daf },{ 0x83bc, 0x84f4 },{ 0x841d, 0x863f },{ 0x8424, 0x87a2 }, + { 0x8425, 0x71df },{ 0x8426, 0x7e08 },{ 0x8427, 0x856d },{ 0x8428, 0x85a9 }, + { 0x8471, 0x8525 },{ 0x8487, 0x8546 },{ 0x8489, 0x8562 },{ 0x848b, 0x8523 }, + { 0x848c, 0x851e },{ 0x84d1, 0x7c11 },{ 0x84dd, 0x85cd },{ 0x84df, 0x858a }, + { 0x84e0, 0x863a },{ 0x84e3, 0x8577 },{ 0x84e5, 0x93a3 },{ 0x84e6, 0x9a40 }, + { 0x8537, 0x8594 },{ 0x8539, 0x861e },{ 0x853a, 0x85fa },{ 0x853c, 0x85f9 }, + { 0x8572, 0x8604 },{ 0x8574, 0x860a },{ 0x85ae, 0x85ea },{ 0x85d3, 0x861a }, + { 0x8616, 0x8617 },{ 0x864f, 0x865c },{ 0x8651, 0x616e },{ 0x865a, 0x865b }, + { 0x866b, 0x87f2 },{ 0x866c, 0x866f },{ 0x866e, 0x87e3 },{ 0x867d, 0x96d6 }, + { 0x867e, 0x8766 },{ 0x867f, 0x8806 },{ 0x8680, 0x8755 },{ 0x8681, 0x87fb }, + { 0x8682, 0x879e },{ 0x8695, 0x8836 },{ 0x869d, 0x8814 },{ 0x86ac, 0x8706 }, + { 0x86ca, 0x8831 },{ 0x86ce, 0x8823 },{ 0x86cf, 0x87f6 },{ 0x86ee, 0x883b }, + { 0x86f0, 0x87c4 },{ 0x86f1, 0x86fa },{ 0x86f2, 0x87ef },{ 0x86f3, 0x8784 }, + { 0x86f4, 0x8810 },{ 0x8715, 0x86fb },{ 0x8717, 0x8778 },{ 0x8721, 0x881f }, + { 0x8747, 0x8805 },{ 0x8748, 0x87c8 },{ 0x8749, 0x87ec },{ 0x874e, 0x880d }, + { 0x8770, 0x867a },{ 0x877c, 0x87bb },{ 0x877e, 0x8811 },{ 0x87ee, 0x87fa }, + { 0x8845, 0x91c1 },{ 0x8854, 0x929c },{ 0x8864, 0x8863 },{ 0x8865, 0x88dc }, + { 0x886c, 0x896f },{ 0x886e, 0x889e },{ 0x8884, 0x8956 },{ 0x8885, 0x88ca }, + { 0x889c, 0x896a },{ 0x88ad, 0x8972 },{ 0x88c5, 0x88dd },{ 0x88c6, 0x8960 }, + { 0x88e2, 0x8933 },{ 0x88e3, 0x895d },{ 0x88e4, 0x8932 },{ 0x88e5, 0x8949 }, + { 0x891b, 0x8938 },{ 0x8934, 0x8964 },{ 0x89c1, 0x898b },{ 0x89c2, 0x89c0 }, + { 0x89c4, 0x898f },{ 0x89c5, 0x8993 },{ 0x89c6, 0x8996 },{ 0x89c7, 0x8998 }, + { 0x89c8, 0x89bd },{ 0x89c9, 0x89ba },{ 0x89ca, 0x89ac },{ 0x89cb, 0x89a1 }, + { 0x89cc, 0x89bf },{ 0x89ce, 0x89a6 },{ 0x89cf, 0x89af },{ 0x89d0, 0x89b2 }, + { 0x89d1, 0x89b7 },{ 0x89de, 0x89f4 },{ 0x89e6, 0x89f8 },{ 0x89ef, 0x89f6 }, + { 0x8a89, 0x8b7d },{ 0x8a8a, 0x8b04 },{ 0x8ba0, 0x8a00 },{ 0x8ba1, 0x8a08 }, + { 0x8ba2, 0x8a02 },{ 0x8ba3, 0x8a03 },{ 0x8ba4, 0x8a8d },{ 0x8ba5, 0x8b4f }, + { 0x8ba6, 0x8a10 },{ 0x8ba7, 0x8a0c },{ 0x8ba8, 0x8a0e },{ 0x8ba9, 0x8b93 }, + { 0x8baa, 0x8a15 },{ 0x8bab, 0x8a16 },{ 0x8bad, 0x8a13 },{ 0x8bae, 0x8b70 }, + { 0x8baf, 0x8a0a },{ 0x8bb0, 0x8a18 },{ 0x8bb2, 0x8b1b },{ 0x8bb3, 0x8af1 }, + { 0x8bb4, 0x8b33 },{ 0x8bb5, 0x8a4e },{ 0x8bb6, 0x8a1d },{ 0x8bb7, 0x8a25 }, + { 0x8bb8, 0x8a31 },{ 0x8bb9, 0x8a1b },{ 0x8bba, 0x8ad6 },{ 0x8bbc, 0x8a1f }, + { 0x8bbd, 0x8af7 },{ 0x8bbe, 0x8a2d },{ 0x8bbf, 0x8a2a },{ 0x8bc0, 0x8a23 }, + { 0x8bc1, 0x8b49 },{ 0x8bc2, 0x8a41 },{ 0x8bc3, 0x8a36 },{ 0x8bc4, 0x8a55 }, + { 0x8bc5, 0x8a5b },{ 0x8bc6, 0x8b58 },{ 0x8bc8, 0x8a50 },{ 0x8bc9, 0x8a34 }, + { 0x8bca, 0x8a3a },{ 0x8bcb, 0x8a46 },{ 0x8bcc, 0x8b05 },{ 0x8bcd, 0x8a5e }, + { 0x8bce, 0x8a58 },{ 0x8bcf, 0x8a54 },{ 0x8bd1, 0x8b6f },{ 0x8bd2, 0x8a52 }, + { 0x8bd3, 0x8a86 },{ 0x8bd4, 0x8a84 },{ 0x8bd5, 0x8a66 },{ 0x8bd6, 0x8a7f }, + { 0x8bd7, 0x8a69 },{ 0x8bd8, 0x8a70 },{ 0x8bd9, 0x8a7c },{ 0x8bda, 0x8aa0 }, + { 0x8bdb, 0x8a85 },{ 0x8bdc, 0x8a75 },{ 0x8bdd, 0x8a71 },{ 0x8bde, 0x8a95 }, + { 0x8bdf, 0x8a6c },{ 0x8be0, 0x8a6e },{ 0x8be1, 0x8a6d },{ 0x8be2, 0x8a62 }, + { 0x8be3, 0x8a63 },{ 0x8be4, 0x8acd },{ 0x8be5, 0x8a72 },{ 0x8be6, 0x8a73 }, + { 0x8be7, 0x8a6b },{ 0x8be8, 0x8ae2 },{ 0x8be9, 0x8a61 },{ 0x8beb, 0x8aa1 }, + { 0x8bec, 0x8aa3 },{ 0x8bed, 0x8a9e },{ 0x8bee, 0x8a9a },{ 0x8bef, 0x8aa4 }, + { 0x8bf0, 0x8aa5 },{ 0x8bf1, 0x8a98 },{ 0x8bf2, 0x8aa8 },{ 0x8bf3, 0x8a91 }, + { 0x8bf4, 0x8aaa },{ 0x8bf5, 0x8aa6 },{ 0x8bf6, 0x8a92 },{ 0x8bf7, 0x8acb }, + { 0x8bf8, 0x8af8 },{ 0x8bf9, 0x8acf },{ 0x8bfa, 0x8afe },{ 0x8bfb, 0x8b80 }, + { 0x8bfc, 0x8ad1 },{ 0x8bfd, 0x8ab9 },{ 0x8bfe, 0x8ab2 },{ 0x8bff, 0x8ac9 }, + { 0x8c00, 0x8adb },{ 0x8c01, 0x8ab0 },{ 0x8c02, 0x8ad7 },{ 0x8c03, 0x8abf }, + { 0x8c04, 0x8ac2 },{ 0x8c05, 0x8ad2 },{ 0x8c06, 0x8ac4 },{ 0x8c07, 0x8ab6 }, + { 0x8c08, 0x8ac7 },{ 0x8c0a, 0x8abc },{ 0x8c0b, 0x8b00 },{ 0x8c0c, 0x8af6 }, + { 0x8c0d, 0x8adc },{ 0x8c0e, 0x8b0a },{ 0x8c0f, 0x8aeb },{ 0x8c10, 0x8ae7 }, + { 0x8c11, 0x8b14 },{ 0x8c12, 0x8b01 },{ 0x8c13, 0x8b02 },{ 0x8c14, 0x8ae4 }, + { 0x8c15, 0x8aed },{ 0x8c16, 0x8afc },{ 0x8c17, 0x8b92 },{ 0x8c18, 0x8aee }, + { 0x8c19, 0x8af3 },{ 0x8c1a, 0x8afa },{ 0x8c1b, 0x8ae6 },{ 0x8c1c, 0x8b0e }, + { 0x8c1d, 0x8ade },{ 0x8c1f, 0x8b28 },{ 0x8c20, 0x8b9c },{ 0x8c21, 0x8b16 }, + { 0x8c22, 0x8b1d },{ 0x8c23, 0x8b20 },{ 0x8c24, 0x8b17 },{ 0x8c25, 0x8b1a }, + { 0x8c26, 0x8b19 },{ 0x8c27, 0x8b10 },{ 0x8c28, 0x8b39 },{ 0x8c29, 0x8b3e }, + { 0x8c2a, 0x8b2b },{ 0x8c2b, 0x8b7e },{ 0x8c2c, 0x8b2c },{ 0x8c2d, 0x8b5a }, + { 0x8c2e, 0x8b56 },{ 0x8c2f, 0x8b59 },{ 0x8c30, 0x8b95 },{ 0x8c31, 0x8b5c }, + { 0x8c32, 0x8b4e },{ 0x8c33, 0x8b9e },{ 0x8c34, 0x8b74 },{ 0x8c35, 0x8b6b }, + { 0x8c36, 0x8b96 },{ 0x8d1d, 0x8c9d },{ 0x8d1e, 0x8c9e },{ 0x8d1f, 0x8ca0 }, + { 0x8d21, 0x8ca2 },{ 0x8d22, 0x8ca1 },{ 0x8d23, 0x8cac },{ 0x8d24, 0x8ce2 }, + { 0x8d25, 0x6557 },{ 0x8d26, 0x8cec },{ 0x8d27, 0x8ca8 },{ 0x8d28, 0x8cea }, + { 0x8d29, 0x8ca9 },{ 0x8d2a, 0x8caa },{ 0x8d2b, 0x8ca7 },{ 0x8d2c, 0x8cb6 }, + { 0x8d2d, 0x8cfc },{ 0x8d2e, 0x8caf },{ 0x8d2f, 0x8cab },{ 0x8d30, 0x8cb3 }, + { 0x8d31, 0x8ce4 },{ 0x8d32, 0x8cc1 },{ 0x8d33, 0x8cb0 },{ 0x8d34, 0x8cbc }, + { 0x8d35, 0x8cb4 },{ 0x8d36, 0x8cba },{ 0x8d37, 0x8cb8 },{ 0x8d38, 0x8cbf }, + { 0x8d39, 0x8cbb },{ 0x8d3a, 0x8cc0 },{ 0x8d3b, 0x8cbd },{ 0x8d3c, 0x8cca }, + { 0x8d3d, 0x8d04 },{ 0x8d3e, 0x8cc8 },{ 0x8d3f, 0x8cc4 },{ 0x8d40, 0x8cb2 }, + { 0x8d41, 0x8cc3 },{ 0x8d42, 0x8cc2 },{ 0x8d43, 0x8d13 },{ 0x8d44, 0x8cc7 }, + { 0x8d45, 0x8cc5 },{ 0x8d46, 0x8d10 },{ 0x8d47, 0x8cd5 },{ 0x8d48, 0x8cd1 }, + { 0x8d49, 0x8cda },{ 0x8d4a, 0x8cd2 },{ 0x8d4b, 0x8ce6 },{ 0x8d4c, 0x8ced }, + { 0x8d4d, 0x9f4e },{ 0x8d4e, 0x8d16 },{ 0x8d4f, 0x8cde },{ 0x8d50, 0x8cdc }, + { 0x8d53, 0x8ce1 },{ 0x8d54, 0x8ce0 },{ 0x8d55, 0x8ce7 },{ 0x8d56, 0x8cf4 }, + { 0x8d58, 0x8d05 },{ 0x8d59, 0x8cfb },{ 0x8d5a, 0x8cfa },{ 0x8d5b, 0x8cfd }, + { 0x8d5c, 0x8cfe },{ 0x8d5d, 0x8d17 },{ 0x8d5e, 0x8d0a },{ 0x8d60, 0x8d08 }, + { 0x8d61, 0x8d0d },{ 0x8d62, 0x8d0f },{ 0x8d63, 0x8d1b },{ 0x8d75, 0x8d99 }, + { 0x8d76, 0x8d95 },{ 0x8d8b, 0x8da8 },{ 0x8db1, 0x8db2 },{ 0x8db8, 0x8e89 }, + { 0x8dc3, 0x8e8d },{ 0x8dc4, 0x8e4c },{ 0x8dde, 0x8e92 },{ 0x8df5, 0x8e10 }, + { 0x8df7, 0x8e7a },{ 0x8df8, 0x8e55 },{ 0x8df9, 0x8e9a },{ 0x8dfb, 0x8e8b }, + { 0x8e0a, 0x8e34 },{ 0x8e0c, 0x8e8a },{ 0x8e2a, 0x8e64 },{ 0x8e2c, 0x8e93 }, + { 0x8e2f, 0x8e91 },{ 0x8e51, 0x8ea1 },{ 0x8e52, 0x8e63 },{ 0x8e70, 0x8e95 }, + { 0x8e7f, 0x8ea5 },{ 0x8e8f, 0x8eaa },{ 0x8e9c, 0x8ea6 },{ 0x8eaf, 0x8ec0 }, + { 0x8f66, 0x8eca },{ 0x8f67, 0x8ecb },{ 0x8f68, 0x8ecc },{ 0x8f69, 0x8ed2 }, + { 0x8f6b, 0x8ed4 },{ 0x8f6c, 0x8f49 },{ 0x8f6d, 0x8edb },{ 0x8f6e, 0x8f2a }, + { 0x8f6f, 0x8edf },{ 0x8f70, 0x8f5f },{ 0x8f72, 0x8efb },{ 0x8f73, 0x8f64 }, + { 0x8f74, 0x8ef8 },{ 0x8f75, 0x8ef9 },{ 0x8f76, 0x8efc },{ 0x8f78, 0x8eeb }, + { 0x8f79, 0x8f62 },{ 0x8f7a, 0x8efa },{ 0x8f7b, 0x8f15 },{ 0x8f7c, 0x8efe }, + { 0x8f7d, 0x8f09 },{ 0x8f7e, 0x8f0a },{ 0x8f7f, 0x8f4e },{ 0x8f81, 0x8f07 }, + { 0x8f82, 0x8f05 },{ 0x8f83, 0x8f03 },{ 0x8f84, 0x8f12 },{ 0x8f85, 0x8f14 }, + { 0x8f86, 0x8f1b },{ 0x8f87, 0x8f26 },{ 0x8f88, 0x8f29 },{ 0x8f89, 0x8f1d }, + { 0x8f8a, 0x8f25 },{ 0x8f8b, 0x8f1e },{ 0x8f8d, 0x8f1f },{ 0x8f8e, 0x8f1c }, + { 0x8f8f, 0x8f33 },{ 0x8f90, 0x8f3b },{ 0x8f91, 0x8f2f },{ 0x8f93, 0x8f38 }, + { 0x8f94, 0x8f61 },{ 0x8f95, 0x8f45 },{ 0x8f96, 0x8f44 },{ 0x8f97, 0x8f3e }, + { 0x8f98, 0x8f46 },{ 0x8f99, 0x8f4d },{ 0x8f9a, 0x8f54 },{ 0x8f9e, 0x8fad }, + { 0x8f9f, 0x95e2 },{ 0x8fa9, 0x8faf },{ 0x8fab, 0x8fae },{ 0x8fb9, 0x908a }, + { 0x8fbd, 0x907c },{ 0x8fbe, 0x9054 },{ 0x8fc1, 0x9077 },{ 0x8fc7, 0x904e }, + { 0x8fc8, 0x9081 },{ 0x8fd0, 0x904b },{ 0x8fd8, 0x9084 },{ 0x8fd9, 0x9019 }, + { 0x8fdb, 0x9032 },{ 0x8fdc, 0x9060 },{ 0x8fdd, 0x9055 },{ 0x8fde, 0x9023 }, + { 0x8fdf, 0x9072 },{ 0x8fe9, 0x9087 },{ 0x8ff3, 0x9015 },{ 0x8ff9, 0x8e5f }, + { 0x9002, 0x9069 },{ 0x9009, 0x9078 },{ 0x900a, 0x905c },{ 0x9012, 0x905e }, + { 0x9026, 0x9090 },{ 0x903b, 0x908f },{ 0x9057, 0x907a },{ 0x9065, 0x9059 }, + { 0x9093, 0x9127 },{ 0x909d, 0x913a },{ 0x90ac, 0x9114 },{ 0x90ae, 0x90f5 }, + { 0x90b9, 0x9112 },{ 0x90ba, 0x9134 },{ 0x90bb, 0x9130 },{ 0x90c1, 0x9b31 }, + { 0x90c4, 0x9699 },{ 0x90cf, 0x90df },{ 0x90d0, 0x9136 },{ 0x90d1, 0x912d }, + { 0x90d3, 0x9106 },{ 0x90e6, 0x9148 },{ 0x90e7, 0x9116 },{ 0x90f8, 0x9132 }, + { 0x915d, 0x919e },{ 0x9171, 0x91ac },{ 0x917d, 0x91c5 },{ 0x917e, 0x91c3 }, + { 0x917f, 0x91c0 },{ 0x91c7, 0x63a1 },{ 0x91ca, 0x91cb },{ 0x91cc, 0x88e1 }, + { 0x9274, 0x9451 },{ 0x92ae, 0x947e },{ 0x933e, 0x93e8 },{ 0x9485, 0x91d1 }, + { 0x9486, 0x91d3 },{ 0x9487, 0x91d4 },{ 0x9488, 0x91dd },{ 0x9489, 0x91d8 }, + { 0x948a, 0x91d7 },{ 0x948b, 0x91d9 },{ 0x948c, 0x91d5 },{ 0x948d, 0x91f7 }, + { 0x948e, 0x91ec },{ 0x948f, 0x91e7 },{ 0x9490, 0x91e4 },{ 0x9492, 0x91e9 }, + { 0x9493, 0x91e3 },{ 0x9494, 0x9346 },{ 0x9495, 0x91f9 },{ 0x9497, 0x91f5 }, + { 0x9499, 0x9223 },{ 0x949b, 0x9226 },{ 0x949c, 0x9245 },{ 0x949d, 0x920d }, + { 0x949e, 0x9214 },{ 0x949f, 0x9418 },{ 0x94a0, 0x9209 },{ 0x94a1, 0x92c7 }, + { 0x94a2, 0x92fc },{ 0x94a3, 0x9211 },{ 0x94a4, 0x9210 },{ 0x94a5, 0x9470 }, + { 0x94a6, 0x6b3d },{ 0x94a7, 0x921e },{ 0x94a8, 0x93a2 },{ 0x94a9, 0x9264 }, + { 0x94aa, 0x9227 },{ 0x94ab, 0x9201 },{ 0x94ac, 0x9225 },{ 0x94ad, 0x9204 }, + { 0x94ae, 0x9215 },{ 0x94af, 0x9200 },{ 0x94b0, 0x923a },{ 0x94b1, 0x9322 }, + { 0x94b2, 0x9266 },{ 0x94b3, 0x9257 },{ 0x94b4, 0x9237 },{ 0x94b5, 0x7f3d }, + { 0x94b6, 0x9233 },{ 0x94b8, 0x923d },{ 0x94b9, 0x9238 },{ 0x94ba, 0x925e }, + { 0x94bb, 0x947d },{ 0x94bc, 0x926c },{ 0x94bd, 0x926d },{ 0x94be, 0x9240 }, + { 0x94bf, 0x923f },{ 0x94c0, 0x923e },{ 0x94c1, 0x9435 },{ 0x94c2, 0x9251 }, + { 0x94c3, 0x9234 },{ 0x94c4, 0x9460 },{ 0x94c5, 0x925b },{ 0x94c6, 0x925a }, + { 0x94c8, 0x9230 },{ 0x94c9, 0x9249 },{ 0x94ca, 0x9248 },{ 0x94cb, 0x924d }, + { 0x94cc, 0x922e },{ 0x94cd, 0x9239 },{ 0x94ce, 0x9438 },{ 0x94d0, 0x92ac }, + { 0x94d1, 0x92a0 },{ 0x94d2, 0x927a },{ 0x94d5, 0x92aa },{ 0x94d6, 0x92ee }, + { 0x94d7, 0x92cf },{ 0x94d9, 0x9403 },{ 0x94db, 0x943a },{ 0x94dc, 0x9285 }, + { 0x94dd, 0x92c1 },{ 0x94df, 0x92a6 },{ 0x94e0, 0x93a7 },{ 0x94e1, 0x9358 }, + { 0x94e2, 0x9296 },{ 0x94e3, 0x9291 },{ 0x94e4, 0x92cc },{ 0x94e5, 0x92a9 }, + { 0x94e7, 0x93f5 },{ 0x94e8, 0x9293 },{ 0x94e9, 0x93a9 },{ 0x94ea, 0x927f }, + { 0x94eb, 0x929a },{ 0x94ec, 0x927b },{ 0x94ed, 0x9298 },{ 0x94ee, 0x931a }, + { 0x94ef, 0x92ab },{ 0x94f0, 0x9278 },{ 0x94f1, 0x92a5 },{ 0x94f2, 0x93df }, + { 0x94f3, 0x9283 },{ 0x94f4, 0x940b },{ 0x94f5, 0x92a8 },{ 0x94f6, 0x9280 }, + { 0x94f7, 0x92a3 },{ 0x94f8, 0x9444 },{ 0x94f9, 0x9412 },{ 0x94fa, 0x92ea }, + { 0x94fc, 0x9338 },{ 0x94fd, 0x92f1 },{ 0x94fe, 0x93c8 },{ 0x94ff, 0x93d7 }, + { 0x9500, 0x92b7 },{ 0x9501, 0x9396 },{ 0x9502, 0x92f0 },{ 0x9504, 0x92e4 }, + { 0x9505, 0x934b },{ 0x9506, 0x92ef },{ 0x9507, 0x92e8 },{ 0x9508, 0x93fd }, + { 0x9509, 0x92bc },{ 0x950a, 0x92dd },{ 0x950b, 0x92d2 },{ 0x950c, 0x92c5 }, + { 0x9510, 0x92b3 },{ 0x9511, 0x92bb },{ 0x9512, 0x92c3 },{ 0x9513, 0x92df }, + { 0x9514, 0x92e6 },{ 0x9515, 0x9312 },{ 0x9516, 0x9306 },{ 0x9517, 0x937a }, + { 0x9519, 0x932f },{ 0x951a, 0x9328 },{ 0x951b, 0x931b },{ 0x951e, 0x9301 }, + { 0x951f, 0x9315 },{ 0x9521, 0x932b },{ 0x9522, 0x932e },{ 0x9523, 0x947c }, + { 0x9524, 0x939a },{ 0x9525, 0x9310 },{ 0x9526, 0x9326 },{ 0x9529, 0x9308 }, + { 0x952c, 0x931f },{ 0x952d, 0x9320 },{ 0x952e, 0x9375 },{ 0x952f, 0x92f8 }, + { 0x9530, 0x9333 },{ 0x9531, 0x9319 },{ 0x9532, 0x9365 },{ 0x9534, 0x9347 }, + { 0x9535, 0x93d8 },{ 0x9536, 0x9376 },{ 0x9537, 0x9354 },{ 0x9538, 0x9364 }, + { 0x9539, 0x936c },{ 0x953a, 0x937e },{ 0x953b, 0x935b },{ 0x953c, 0x93aa }, + { 0x953e, 0x9370 },{ 0x9540, 0x934d },{ 0x9541, 0x9382 },{ 0x9542, 0x93e4 }, + { 0x9544, 0x9428 },{ 0x9546, 0x93cc },{ 0x9547, 0x93ae },{ 0x9549, 0x9398 }, + { 0x954a, 0x9477 },{ 0x954c, 0x942b },{ 0x954d, 0x93b3 },{ 0x954f, 0x93a6 }, + { 0x9550, 0x93ac },{ 0x9551, 0x938a },{ 0x9552, 0x93b0 },{ 0x9553, 0x93b5 }, + { 0x9554, 0x944c },{ 0x9556, 0x93e2 },{ 0x9557, 0x93dc },{ 0x9558, 0x93dd }, + { 0x9559, 0x93cd },{ 0x955b, 0x93de },{ 0x955c, 0x93e1 },{ 0x955d, 0x93d1 }, + { 0x955e, 0x93c3 },{ 0x955f, 0x93c7 },{ 0x9561, 0x9414 },{ 0x9563, 0x9410 }, + { 0x9564, 0x93f7 },{ 0x9566, 0x9413 },{ 0x9567, 0x946d },{ 0x9568, 0x9420 }, + { 0x956a, 0x93f9 },{ 0x956b, 0x9419 },{ 0x956c, 0x944a },{ 0x956d, 0x9433 }, + { 0x956f, 0x9432 },{ 0x9570, 0x942e },{ 0x9571, 0x943f },{ 0x9573, 0x9463 }, + { 0x9576, 0x9472 },{ 0x957f, 0x9577 },{ 0x95e8, 0x9580 },{ 0x95e9, 0x9582 }, + { 0x95ea, 0x9583 },{ 0x95eb, 0x9586 },{ 0x95ed, 0x9589 },{ 0x95ee, 0x554f }, + { 0x95ef, 0x95d6 },{ 0x95f0, 0x958f },{ 0x95f1, 0x95c8 },{ 0x95f2, 0x9592 }, + { 0x95f3, 0x958e },{ 0x95f4, 0x9593 },{ 0x95f5, 0x9594 },{ 0x95f6, 0x958c }, + { 0x95f7, 0x60b6 },{ 0x95f8, 0x9598 },{ 0x95f9, 0x9b27 },{ 0x95fa, 0x95a8 }, + { 0x95fb, 0x805e },{ 0x95fc, 0x95e5 },{ 0x95fd, 0x95a9 },{ 0x95fe, 0x95ad }, + { 0x9600, 0x95a5 },{ 0x9601, 0x95a3 },{ 0x9602, 0x95a1 },{ 0x9603, 0x95ab }, + { 0x9604, 0x9b2e },{ 0x9605, 0x95b1 },{ 0x9606, 0x95ac },{ 0x9608, 0x95be }, + { 0x9609, 0x95b9 },{ 0x960a, 0x95b6 },{ 0x960b, 0x9b29 },{ 0x960c, 0x95bf }, + { 0x960d, 0x95bd },{ 0x960e, 0x95bb },{ 0x960f, 0x95bc },{ 0x9610, 0x95e1 }, + { 0x9611, 0x95cc },{ 0x9612, 0x95c3 },{ 0x9614, 0x95ca },{ 0x9615, 0x95cb }, + { 0x9616, 0x95d4 },{ 0x9617, 0x95d0 },{ 0x9619, 0x95d5 },{ 0x961a, 0x95de }, + { 0x961d, 0x961c },{ 0x961f, 0x968a },{ 0x9633, 0x967d },{ 0x9634, 0x9670 }, + { 0x9635, 0x9663 },{ 0x9636, 0x968e },{ 0x9645, 0x969b },{ 0x9646, 0x9678 }, + { 0x9647, 0x96b4 },{ 0x9648, 0x9673 },{ 0x9649, 0x9658 },{ 0x9655, 0x965d }, + { 0x9667, 0x9689 },{ 0x9668, 0x9695 },{ 0x9669, 0x96aa },{ 0x968f, 0x96a8 }, + { 0x9690, 0x96b1 },{ 0x96b6, 0x96b8 },{ 0x96bd, 0x96cb },{ 0x96be, 0x96e3 }, + { 0x96cf, 0x96db },{ 0x96e0, 0x8b8e },{ 0x96f3, 0x9742 },{ 0x96fe, 0x9727 }, + { 0x9701, 0x973d },{ 0x972d, 0x9744 },{ 0x9753, 0x975a },{ 0x9759, 0x975c }, + { 0x9765, 0x9768 },{ 0x9791, 0x97c3 },{ 0x9792, 0x6a47 },{ 0x97af, 0x97c9 }, + { 0x97e6, 0x97cb },{ 0x97e7, 0x97cc },{ 0x97e9, 0x97d3 },{ 0x97ea, 0x97d9 }, + { 0x97eb, 0x97de },{ 0x97ec, 0x97dc },{ 0x97f5, 0x97fb },{ 0x9875, 0x9801 }, + { 0x9876, 0x9802 },{ 0x9877, 0x9803 },{ 0x9878, 0x9807 },{ 0x9879, 0x9805 }, + { 0x987a, 0x9806 },{ 0x987b, 0x9808 },{ 0x987c, 0x980a },{ 0x987d, 0x9811 }, + { 0x987e, 0x9867 },{ 0x987f, 0x9813 },{ 0x9880, 0x980e },{ 0x9881, 0x9812 }, + { 0x9882, 0x980c },{ 0x9883, 0x980f },{ 0x9884, 0x9810 },{ 0x9885, 0x9871 }, + { 0x9886, 0x9818 },{ 0x9887, 0x9817 },{ 0x9888, 0x9838 },{ 0x9889, 0x9821 }, + { 0x988a, 0x9830 },{ 0x988c, 0x981c },{ 0x988d, 0x6f41 },{ 0x988f, 0x9826 }, + { 0x9890, 0x9824 },{ 0x9891, 0x983b },{ 0x9893, 0x9839 },{ 0x9894, 0x9837 }, + { 0x9896, 0x7a4e },{ 0x9897, 0x9846 },{ 0x9898, 0x984c },{ 0x989a, 0x984e }, + { 0x989b, 0x9853 },{ 0x989c, 0x984f },{ 0x989d, 0x984d },{ 0x989e, 0x9873 }, + { 0x989f, 0x9862 },{ 0x98a0, 0x985b },{ 0x98a1, 0x9859 },{ 0x98a2, 0x9865 }, + { 0x98a4, 0x986b },{ 0x98a6, 0x9870 },{ 0x98a7, 0x9874 },{ 0x98ce, 0x98a8 }, + { 0x98d1, 0x98ae },{ 0x98d2, 0x98af },{ 0x98d3, 0x98b6 },{ 0x98d5, 0x98bc }, + { 0x98d8, 0x98c4 },{ 0x98d9, 0x98c6 },{ 0x98de, 0x98db },{ 0x98e8, 0x9957 }, + { 0x990d, 0x995c },{ 0x9963, 0x98df },{ 0x9965, 0x98e2 },{ 0x9967, 0x9933 }, + { 0x9968, 0x98e9 },{ 0x9969, 0x993c },{ 0x996a, 0x98ea },{ 0x996b, 0x98eb }, + { 0x996c, 0x98ed },{ 0x996d, 0x98ef },{ 0x996e, 0x98f2 },{ 0x996f, 0x991e }, + { 0x9970, 0x98fe },{ 0x9971, 0x98fd },{ 0x9972, 0x98fc },{ 0x9974, 0x98f4 }, + { 0x9975, 0x990c },{ 0x9976, 0x9952 },{ 0x9977, 0x9909 },{ 0x997a, 0x9903 }, + { 0x997c, 0x9905 },{ 0x997d, 0x9911 },{ 0x997f, 0x9913 },{ 0x9980, 0x9918 }, + { 0x9981, 0x9912 },{ 0x9984, 0x991b },{ 0x9985, 0x9921 },{ 0x9986, 0x9928 }, + { 0x9988, 0x994b },{ 0x998a, 0x993f },{ 0x998b, 0x995e },{ 0x998d, 0x7ce2 }, + { 0x998f, 0x993e },{ 0x9990, 0x9948 },{ 0x9991, 0x9949 },{ 0x9992, 0x9945 }, + { 0x9994, 0x994c },{ 0x9a6c, 0x99ac },{ 0x9a6d, 0x99ad },{ 0x9a6e, 0x99b1 }, + { 0x9a6f, 0x99b4 },{ 0x9a70, 0x99b3 },{ 0x9a71, 0x9a45 },{ 0x9a73, 0x99c1 }, + { 0x9a74, 0x9a62 },{ 0x9a75, 0x99d4 },{ 0x9a76, 0x99db },{ 0x9a77, 0x99df }, + { 0x9a78, 0x99d9 },{ 0x9a79, 0x99d2 },{ 0x9a7a, 0x9a36 },{ 0x9a7b, 0x99d0 }, + { 0x9a7c, 0x99dd },{ 0x9a7d, 0x99d1 },{ 0x9a7e, 0x99d5 },{ 0x9a7f, 0x9a5b }, + { 0x9a80, 0x99d8 },{ 0x9a81, 0x9a4d },{ 0x9a82, 0x7f75 },{ 0x9a84, 0x9a55 }, + { 0x9a85, 0x9a4a },{ 0x9a86, 0x99f1 },{ 0x9a87, 0x99ed },{ 0x9a88, 0x99e2 }, + { 0x9a8a, 0x9a6a },{ 0x9a8b, 0x9a01 },{ 0x9a8c, 0x9a57 },{ 0x9a8f, 0x99ff }, + { 0x9a90, 0x9a0f },{ 0x9a91, 0x9a0e },{ 0x9a92, 0x9a0d },{ 0x9a93, 0x9a05 }, + { 0x9a96, 0x9a42 },{ 0x9a97, 0x9a19 },{ 0x9a98, 0x9a2d },{ 0x9a9a, 0x9a37 }, + { 0x9a9b, 0x9a16 },{ 0x9a9c, 0x9a41 },{ 0x9a9d, 0x9a2e },{ 0x9a9e, 0x9a2b }, + { 0x9a9f, 0x9a38 },{ 0x9aa0, 0x9a43 },{ 0x9aa1, 0x9a3e },{ 0x9aa2, 0x9a44 }, + { 0x9aa3, 0x9a4f },{ 0x9aa4, 0x9a5f },{ 0x9aa5, 0x9a65 },{ 0x9aa7, 0x9a64 }, + { 0x9ac5, 0x9acf },{ 0x9acb, 0x9ad6 },{ 0x9acc, 0x9ad5 },{ 0x9b13, 0x9b22 }, + { 0x9b47, 0x9b58 },{ 0x9b49, 0x9b4e },{ 0x9c7c, 0x9b5a },{ 0x9c7f, 0x9b77 }, + { 0x9c81, 0x9b6f },{ 0x9c82, 0x9b74 },{ 0x9c87, 0x9bf0 },{ 0x9c88, 0x9c78 }, + { 0x9c8b, 0x9b92 },{ 0x9c8d, 0x9b91 },{ 0x9c8e, 0x9c5f },{ 0x9c90, 0x9b90 }, + { 0x9c91, 0x9bad },{ 0x9c92, 0x9b9a },{ 0x9c94, 0x9baa },{ 0x9c95, 0x9b9e }, + { 0x9c9a, 0x9c6d },{ 0x9c9b, 0x9bab },{ 0x9c9c, 0x9bae },{ 0x9c9e, 0x9bd7 }, + { 0x9c9f, 0x9c58 },{ 0x9ca0, 0x9bc1 },{ 0x9ca1, 0x9c7a },{ 0x9ca2, 0x9c31 }, + { 0x9ca3, 0x9c39 },{ 0x9ca4, 0x9bc9 },{ 0x9ca5, 0x9c23 },{ 0x9ca6, 0x9c37 }, + { 0x9ca7, 0x9bc0 },{ 0x9ca8, 0x9bca },{ 0x9ca9, 0x9bc7 },{ 0x9cab, 0x9bfd }, + { 0x9cad, 0x9bd6 },{ 0x9cae, 0x9bea },{ 0x9cb0, 0x9beb },{ 0x9cb1, 0x9be1 }, + { 0x9cb2, 0x9be4 },{ 0x9cb3, 0x9be7 },{ 0x9cb5, 0x9be2 },{ 0x9cb6, 0x9bf0 }, + { 0x9cb7, 0x9bdb },{ 0x9cb8, 0x9be8 },{ 0x9cbb, 0x9bd4 },{ 0x9cbd, 0x9c08 }, + { 0x9cc3, 0x9c13 },{ 0x9cc4, 0x9c77 },{ 0x9cc5, 0x9c0d },{ 0x9cc6, 0x9c12 }, + { 0x9cc7, 0x9c09 },{ 0x9ccc, 0x9c32 },{ 0x9ccd, 0x9c2d },{ 0x9cce, 0x9c28 }, + { 0x9ccf, 0x9c25 },{ 0x9cd0, 0x9c29 },{ 0x9cd3, 0x9c33 },{ 0x9cd4, 0x9c3e }, + { 0x9cd5, 0x9c48 },{ 0x9cd6, 0x9c49 },{ 0x9cd7, 0x9c3b },{ 0x9cdc, 0x9c56 }, + { 0x9cdd, 0x9c54 },{ 0x9cde, 0x9c57 },{ 0x9cdf, 0x9c52 },{ 0x9ce2, 0x9c67 }, + { 0x9e1f, 0x9ce5 },{ 0x9e20, 0x9ce9 },{ 0x9e21, 0x96de },{ 0x9e22, 0x9cf6 }, + { 0x9e23, 0x9cf4 },{ 0x9e25, 0x9dd7 },{ 0x9e26, 0x9d09 },{ 0x9e28, 0x9d07 }, + { 0x9e29, 0x9d06 },{ 0x9e2a, 0x9d23 },{ 0x9e2b, 0x9d87 },{ 0x9e2c, 0x9e15 }, + { 0x9e2d, 0x9d28 },{ 0x9e2f, 0x9d26 },{ 0x9e31, 0x9d1f },{ 0x9e32, 0x9d1d }, + { 0x9e33, 0x9d1b },{ 0x9e35, 0x9d15 },{ 0x9e36, 0x9de5 },{ 0x9e37, 0x9dd9 }, + { 0x9e38, 0x9d2f },{ 0x9e39, 0x9d30 },{ 0x9e3a, 0x9d42 },{ 0x9e3d, 0x9d3f }, + { 0x9e3e, 0x9e1e },{ 0x9e3f, 0x9d3b },{ 0x9e41, 0x9d53 },{ 0x9e42, 0x9e1d }, + { 0x9e43, 0x9d51 },{ 0x9e44, 0x9d60 },{ 0x9e45, 0x9d5d },{ 0x9e46, 0x9d52 }, + { 0x9e47, 0x9df4 },{ 0x9e48, 0x9d5c },{ 0x9e49, 0x9d61 },{ 0x9e4a, 0x9d72 }, + { 0x9e4c, 0x9d6a },{ 0x9e4e, 0x9d6f },{ 0x9e4f, 0x9d6c },{ 0x9e51, 0x9d89 }, + { 0x9e55, 0x9d98 },{ 0x9e57, 0x9d9a },{ 0x9e58, 0x9dbb },{ 0x9e5a, 0x9dbf }, + { 0x9e5c, 0x9da9 },{ 0x9e5e, 0x9dc2 },{ 0x9e63, 0x9dbc },{ 0x9e64, 0x9db4 }, + { 0x9e66, 0x9e1a },{ 0x9e67, 0x9dd3 },{ 0x9e68, 0x9dda },{ 0x9e69, 0x9def }, + { 0x9e6a, 0x9de6 },{ 0x9e6b, 0x9df2 },{ 0x9e6c, 0x9df8 },{ 0x9e6d, 0x9dfa }, + { 0x9e70, 0x9df9 },{ 0x9e73, 0x9e1b },{ 0x9e7e, 0x9e7a },{ 0x9ea6, 0x9ea5 }, + { 0x9eb8, 0x9ea9 },{ 0x9ebd, 0x9ebc },{ 0x9ec4, 0x9ec3 },{ 0x9ec9, 0x9ecc }, + { 0x9ee9, 0x9ef7 },{ 0x9eea, 0x9ef2 },{ 0x9efe, 0x9efd },{ 0x9f0b, 0x9eff }, + { 0x9f0d, 0x9f09 },{ 0x9f39, 0x9f34 },{ 0x9f50, 0x9f4a },{ 0x9f51, 0x9f4f }, + { 0x9f7f, 0x9f52 },{ 0x9f80, 0x9f54 },{ 0x9f83, 0x9f5f },{ 0x9f84, 0x9f61 }, + { 0x9f85, 0x9f59 },{ 0x9f86, 0x9f60 },{ 0x9f87, 0x9f5c },{ 0x9f88, 0x9f66 }, + { 0x9f89, 0x9f6c },{ 0x9f8a, 0x9f6a },{ 0x9f8b, 0x9f72 },{ 0x9f8c, 0x9f77 }, + { 0x9f99, 0x9f8d },{ 0x9f9a, 0x9f94 },{ 0x9f9b, 0x9f95 },{ 0x9f9f, 0x9f9c }, + { 0xff02, 0x301e },{ 0xff3b, 0xfe5d },{ 0xff3d, 0xfe5e },{ 0xff40, 0x2035 }, + { 0, 0 } +}; + +static UShortPair __tc_to_sc_table [] = { + { 0x00af, 0x02c9 },{ 0x00b7, 0x30fb },{ 0x03a0, 0x220f },{ 0x03a3, 0x2211 }, + { 0x2025, 0x00a8 },{ 0x2027, 0x30fb },{ 0x2035, 0xff40 },{ 0x2225, 0x2016 }, + { 0x2252, 0x2248 },{ 0x2266, 0x2264 },{ 0x2267, 0x2265 },{ 0x2500, 0x2015 }, + { 0x2571, 0xff0f },{ 0x2572, 0xff3c },{ 0x2574, 0xff3f },{ 0x301d, 0xff02 }, + { 0x301e, 0x2033 },{ 0x4e1f, 0x4e22 },{ 0x4e26, 0x5e76 },{ 0x4e3c, 0x4e95 }, + { 0x4e7e, 0x5e72 },{ 0x4e82, 0x4e71 },{ 0x4e99, 0x4e98 },{ 0x4e9e, 0x4e9a }, + { 0x4f15, 0x592b },{ 0x4f47, 0x4f2b },{ 0x4f48, 0x5e03 },{ 0x4f54, 0x5360 }, + { 0x4f6a, 0x5f8a },{ 0x4f75, 0x5e76 },{ 0x4f86, 0x6765 },{ 0x4f96, 0x4ed1 }, + { 0x4f9a, 0x5f87 },{ 0x4fb6, 0x4fa3 },{ 0x4fb7, 0x5c40 },{ 0x4fc1, 0x4fe3 }, + { 0x4fc2, 0x7cfb },{ 0x4fe0, 0x4fa0 },{ 0x5000, 0x4f25 },{ 0x5006, 0x4fe9 }, + { 0x5009, 0x4ed3 },{ 0x500b, 0x4e2a },{ 0x5011, 0x4eec },{ 0x5016, 0x5e78 }, + { 0x5023, 0x4eff },{ 0x502b, 0x4f26 },{ 0x5049, 0x4f1f },{ 0x506a, 0x903c }, + { 0x5074, 0x4fa7 },{ 0x5075, 0x4fa6 },{ 0x507a, 0x54b1 },{ 0x507d, 0x4f2a }, + { 0x5091, 0x6770 },{ 0x5096, 0x4f27 },{ 0x5098, 0x4f1e },{ 0x5099, 0x5907 }, + { 0x509a, 0x6548 },{ 0x50a2, 0x5bb6 },{ 0x50ad, 0x4f63 },{ 0x50af, 0x506c }, + { 0x50b3, 0x4f20 },{ 0x50b4, 0x4f1b },{ 0x50b5, 0x503a },{ 0x50b7, 0x4f24 }, + { 0x50be, 0x503e },{ 0x50c2, 0x507b },{ 0x50c5, 0x4ec5 },{ 0x50c9, 0x4f65 }, + { 0x50ca, 0x4ed9 },{ 0x50d1, 0x4fa8 },{ 0x50d5, 0x4ec6 },{ 0x50e3, 0x50ed }, + { 0x50e5, 0x4fa5 },{ 0x50e8, 0x507e },{ 0x50f1, 0x96c7 },{ 0x50f9, 0x4ef7 }, + { 0x5100, 0x4eea },{ 0x5102, 0x4fac },{ 0x5104, 0x4ebf },{ 0x5105, 0x5f53 }, + { 0x5108, 0x4fa9 },{ 0x5109, 0x4fed },{ 0x5110, 0x50a7 },{ 0x5114, 0x4fe6 }, + { 0x5115, 0x4faa },{ 0x5118, 0x5c3d },{ 0x511f, 0x507f },{ 0x512a, 0x4f18 }, + { 0x5132, 0x50a8 },{ 0x5137, 0x4fea },{ 0x5138, 0x7f57 },{ 0x513a, 0x50a9 }, + { 0x513b, 0x50a5 },{ 0x513c, 0x4fe8 },{ 0x5147, 0x51f6 },{ 0x514c, 0x5151 }, + { 0x5152, 0x513f },{ 0x5157, 0x5156 },{ 0x5167, 0x5185 },{ 0x5169, 0x4e24 }, + { 0x518a, 0x518c },{ 0x5191, 0x80c4 },{ 0x51aa, 0x5e42 },{ 0x51c5, 0x6db8 }, + { 0x51c8, 0x51c0 },{ 0x51cd, 0x51bb },{ 0x51dc, 0x51db },{ 0x51f1, 0x51ef }, + { 0x5225, 0x522b },{ 0x522a, 0x5220 },{ 0x5244, 0x522d },{ 0x5247, 0x5219 }, + { 0x5249, 0x9509 },{ 0x524b, 0x514b },{ 0x524e, 0x5239 },{ 0x525b, 0x521a }, + { 0x525d, 0x5265 },{ 0x526e, 0x5250 },{ 0x5274, 0x5240 },{ 0x5275, 0x521b }, + { 0x5277, 0x94f2 },{ 0x5283, 0x5212 },{ 0x5284, 0x672d },{ 0x5287, 0x5267 }, + { 0x5289, 0x5218 },{ 0x528a, 0x523d },{ 0x528c, 0x523f },{ 0x528d, 0x5251 }, + { 0x5291, 0x5242 },{ 0x52bb, 0x5321 },{ 0x52c1, 0x52b2 },{ 0x52d5, 0x52a8 }, + { 0x52d7, 0x52d6 },{ 0x52d9, 0x52a1 },{ 0x52db, 0x52cb },{ 0x52dd, 0x80dc }, + { 0x52de, 0x52b3 },{ 0x52e2, 0x52bf },{ 0x52e3, 0x7ee9 },{ 0x52e6, 0x527f }, + { 0x52f1, 0x52a2 },{ 0x52f3, 0x52cb },{ 0x52f5, 0x52b1 },{ 0x52f8, 0x529d }, + { 0x52fb, 0x5300 },{ 0x530b, 0x9676 },{ 0x532d, 0x5326 },{ 0x532f, 0x6c47 }, + { 0x5331, 0x532e },{ 0x5340, 0x533a },{ 0x5344, 0x5eff },{ 0x5354, 0x534f }, + { 0x536c, 0x6602 },{ 0x5379, 0x6064 },{ 0x537b, 0x5374 },{ 0x5399, 0x538d }, + { 0x53ad, 0x538c },{ 0x53b2, 0x5389 },{ 0x53b4, 0x53a3 },{ 0x53c3, 0x53c2 }, + { 0x53e1, 0x777f },{ 0x53e2, 0x4e1b },{ 0x540b, 0x5bf8 },{ 0x5433, 0x5434 }, + { 0x5436, 0x5450 },{ 0x5442, 0x5415 },{ 0x544e, 0x5c3a },{ 0x54b7, 0x5555 }, + { 0x54bc, 0x5459 },{ 0x54e1, 0x5458 },{ 0x5504, 0x5457 },{ 0x5538, 0x5ff5 }, + { 0x554f, 0x95ee },{ 0x5557, 0x5556 },{ 0x555e, 0x54d1 },{ 0x555f, 0x542f }, + { 0x5563, 0x8854 },{ 0x559a, 0x5524 },{ 0x55aa, 0x4e27 },{ 0x55ab, 0x5403 }, + { 0x55ac, 0x4e54 },{ 0x55ae, 0x5355 },{ 0x55b2, 0x54df },{ 0x55c6, 0x545b }, + { 0x55c7, 0x556c },{ 0x55ce, 0x5417 },{ 0x55da, 0x545c },{ 0x55e9, 0x5522 }, + { 0x55f6, 0x54d4 },{ 0x5606, 0x53f9 },{ 0x560d, 0x55bd },{ 0x5614, 0x5455 }, + { 0x5616, 0x5567 },{ 0x5617, 0x5c1d },{ 0x561c, 0x551b },{ 0x5629, 0x54d7 }, + { 0x562e, 0x5520 },{ 0x562f, 0x5578 },{ 0x5630, 0x53fd },{ 0x5635, 0x54d3 }, + { 0x5638, 0x5452 },{ 0x5641, 0x6076 },{ 0x5653, 0x5618 },{ 0x5660, 0x54d2 }, + { 0x5665, 0x54dd },{ 0x5666, 0x54d5 },{ 0x566f, 0x55f3 },{ 0x5672, 0x54d9 }, + { 0x5674, 0x55b7 },{ 0x5678, 0x5428 },{ 0x5679, 0x5f53 },{ 0x5680, 0x549b }, + { 0x5687, 0x5413 },{ 0x568c, 0x54dc },{ 0x5690, 0x5c1d },{ 0x5695, 0x565c }, + { 0x5699, 0x556e },{ 0x56a5, 0x54bd },{ 0x56a6, 0x5456 },{ 0x56a8, 0x5499 }, + { 0x56ae, 0x5411 },{ 0x56b3, 0x55be },{ 0x56b4, 0x4e25 },{ 0x56b6, 0x5624 }, + { 0x56c0, 0x556d },{ 0x56c1, 0x55eb },{ 0x56c2, 0x56a3 },{ 0x56c5, 0x5181 }, + { 0x56c8, 0x5453 },{ 0x56c9, 0x7f57 },{ 0x56cc, 0x82cf },{ 0x56d1, 0x5631 }, + { 0x56d3, 0x556e },{ 0x56ea, 0x56f1 },{ 0x5707, 0x56f5 },{ 0x570b, 0x56fd }, + { 0x570d, 0x56f4 },{ 0x5712, 0x56ed },{ 0x5713, 0x5706 },{ 0x5716, 0x56fe }, + { 0x5718, 0x56e2 },{ 0x5775, 0x4e18 },{ 0x57dc, 0x91ce },{ 0x57e1, 0x57ad }, + { 0x57f7, 0x6267 },{ 0x57fc, 0x5d0e },{ 0x5805, 0x575a },{ 0x580a, 0x57a9 }, + { 0x581d, 0x57da },{ 0x582f, 0x5c27 },{ 0x5831, 0x62a5 },{ 0x5834, 0x573a }, + { 0x583f, 0x78b1 },{ 0x584a, 0x5757 },{ 0x584b, 0x8314 },{ 0x584f, 0x57b2 }, + { 0x5852, 0x57d8 },{ 0x5857, 0x6d82 },{ 0x585a, 0x51a2 },{ 0x5862, 0x575e }, + { 0x5864, 0x57d9 },{ 0x5875, 0x5c18 },{ 0x5879, 0x5811 },{ 0x588a, 0x57ab }, + { 0x5891, 0x5892 },{ 0x589c, 0x5760 },{ 0x58ab, 0x6a3d },{ 0x58ae, 0x5815 }, + { 0x58b3, 0x575f },{ 0x58bb, 0x5899 },{ 0x58be, 0x57a6 },{ 0x58c7, 0x575b }, + { 0x58ce, 0x57d9 },{ 0x58d3, 0x538b },{ 0x58d8, 0x5792 },{ 0x58d9, 0x5739 }, + { 0x58da, 0x5786 },{ 0x58de, 0x574f },{ 0x58df, 0x5784 },{ 0x58e2, 0x575c }, + { 0x58e9, 0x575d },{ 0x58ef, 0x58ee },{ 0x58fa, 0x58f6 },{ 0x58fd, 0x5bff }, + { 0x5920, 0x591f },{ 0x5922, 0x68a6 },{ 0x5925, 0x4f19 },{ 0x593e, 0x5939 }, + { 0x5950, 0x5942 },{ 0x5967, 0x5965 },{ 0x5969, 0x5941 },{ 0x596a, 0x593a }, + { 0x596e, 0x594b },{ 0x599d, 0x5986 },{ 0x59b3, 0x4f60 },{ 0x59cd, 0x59d7 }, + { 0x59e6, 0x5978 },{ 0x59ea, 0x4f84 },{ 0x5a1b, 0x5a31 },{ 0x5a41, 0x5a04 }, + { 0x5a66, 0x5987 },{ 0x5a6c, 0x6deb },{ 0x5a6d, 0x5a05 },{ 0x5aa7, 0x5a32 }, + { 0x5aae, 0x5077 },{ 0x5aaf, 0x59ab },{ 0x5abc, 0x5aaa },{ 0x5abd, 0x5988 }, + { 0x5abf, 0x6127 },{ 0x5acb, 0x8885 },{ 0x5ad7, 0x59aa },{ 0x5af5, 0x59a9 }, + { 0x5afb, 0x5a34 },{ 0x5b08, 0x5a06 },{ 0x5b0b, 0x5a75 },{ 0x5b0c, 0x5a07 }, + { 0x5b19, 0x5af1 },{ 0x5b1d, 0x8885 },{ 0x5b21, 0x5ad2 },{ 0x5b24, 0x5b37 }, + { 0x5b2a, 0x5ad4 },{ 0x5b2d, 0x5976 },{ 0x5b30, 0x5a74 },{ 0x5b38, 0x5a76 }, + { 0x5b43, 0x5a18 },{ 0x5b4c, 0x5a08 },{ 0x5b6b, 0x5b59 },{ 0x5b78, 0x5b66 }, + { 0x5b7f, 0x5b6a },{ 0x5bae, 0x5bab },{ 0x5bd8, 0x7f6e },{ 0x5be2, 0x5bdd }, + { 0x5be6, 0x5b9e },{ 0x5be7, 0x5b81 },{ 0x5be9, 0x5ba1 },{ 0x5beb, 0x5199 }, + { 0x5bec, 0x5bbd },{ 0x5bf5, 0x5ba0 },{ 0x5bf6, 0x5b9d },{ 0x5c07, 0x5c06 }, + { 0x5c08, 0x4e13 },{ 0x5c0b, 0x5bfb },{ 0x5c0d, 0x5bf9 },{ 0x5c0e, 0x5bfc }, + { 0x5c37, 0x5c34 },{ 0x5c46, 0x5c4a },{ 0x5c4d, 0x5c38 },{ 0x5c5c, 0x5c49 }, + { 0x5c5d, 0x6249 },{ 0x5c62, 0x5c61 },{ 0x5c64, 0x5c42 },{ 0x5c68, 0x5c66 }, + { 0x5c6c, 0x5c5e },{ 0x5ca1, 0x5188 },{ 0x5cf4, 0x5c98 },{ 0x5cf6, 0x5c9b }, + { 0x5cfd, 0x5ce1 },{ 0x5d0d, 0x5d03 },{ 0x5d11, 0x6606 },{ 0x5d17, 0x5c97 }, + { 0x5d19, 0x4ed1 },{ 0x5d20, 0x5cbd },{ 0x5d22, 0x5ce5 },{ 0x5d33, 0x5d5b }, + { 0x5d50, 0x5c9a },{ 0x5d52, 0x5ca9 },{ 0x5d81, 0x5d5d },{ 0x5d84, 0x5d2d }, + { 0x5d87, 0x5c96 },{ 0x5d97, 0x5d02 },{ 0x5da0, 0x5ce4 },{ 0x5da7, 0x5cc4 }, + { 0x5db8, 0x5d58 },{ 0x5dba, 0x5cad },{ 0x5dbc, 0x5c7f },{ 0x5dbd, 0x5cb3 }, + { 0x5dcb, 0x5cbf },{ 0x5dd2, 0x5ce6 },{ 0x5dd4, 0x5dc5 },{ 0x5dd6, 0x5ca9 }, + { 0x5df0, 0x5def },{ 0x5df9, 0x537a },{ 0x5e25, 0x5e05 },{ 0x5e2b, 0x5e08 }, + { 0x5e33, 0x5e10 },{ 0x5e36, 0x5e26 },{ 0x5e40, 0x5e27 },{ 0x5e43, 0x5e0f }, + { 0x5e57, 0x5e3c },{ 0x5e58, 0x5e3b },{ 0x5e5f, 0x5e1c },{ 0x5e63, 0x5e01 }, + { 0x5e6b, 0x5e2e },{ 0x5e6c, 0x5e31 },{ 0x5e75, 0x5f00 },{ 0x5e79, 0x5e72 }, + { 0x5e7e, 0x51e0 },{ 0x5e82, 0x4ec4 },{ 0x5eab, 0x5e93 },{ 0x5ec1, 0x5395 }, + { 0x5ec2, 0x53a2 },{ 0x5ec4, 0x53a9 },{ 0x5ec8, 0x53a6 },{ 0x5eda, 0x53a8 }, + { 0x5edd, 0x53ae },{ 0x5edf, 0x5e99 },{ 0x5ee0, 0x5382 },{ 0x5ee1, 0x5e91 }, + { 0x5ee2, 0x5e9f },{ 0x5ee3, 0x5e7f },{ 0x5ee9, 0x5eea },{ 0x5eec, 0x5e90 }, + { 0x5ef1, 0x75c8 },{ 0x5ef3, 0x5385 },{ 0x5f12, 0x5f11 },{ 0x5f14, 0x540a }, + { 0x5f33, 0x5f2a },{ 0x5f35, 0x5f20 },{ 0x5f37, 0x5f3a },{ 0x5f46, 0x522b }, + { 0x5f48, 0x5f39 },{ 0x5f4a, 0x5f3a },{ 0x5f4c, 0x5f25 },{ 0x5f4e, 0x5f2f }, + { 0x5f59, 0x6c47 },{ 0x5f65, 0x5f66 },{ 0x5f6b, 0x96d5 },{ 0x5f7f, 0x4f5b }, + { 0x5f8c, 0x540e },{ 0x5f91, 0x5f84 },{ 0x5f9e, 0x4ece },{ 0x5fa0, 0x5f95 }, + { 0x5fa9, 0x590d },{ 0x5fac, 0x65c1 },{ 0x5fb9, 0x5f7b },{ 0x6046, 0x6052 }, + { 0x6065, 0x803b },{ 0x6085, 0x60a6 },{ 0x60b5, 0x6005 },{ 0x60b6, 0x95f7 }, + { 0x60bd, 0x51c4 },{ 0x60c7, 0x6566 },{ 0x60e1, 0x6076 },{ 0x60f1, 0x607c }, + { 0x60f2, 0x607d },{ 0x60f7, 0x8822 },{ 0x60fb, 0x607b },{ 0x611b, 0x7231 }, + { 0x611c, 0x60ec },{ 0x6128, 0x60ab },{ 0x6134, 0x6006 },{ 0x6137, 0x607a }, + { 0x613e, 0x5ffe },{ 0x6144, 0x6817 },{ 0x6147, 0x6bb7 },{ 0x614b, 0x6001 }, + { 0x614d, 0x6120 },{ 0x6158, 0x60e8 },{ 0x615a, 0x60ed },{ 0x615f, 0x6078 }, + { 0x6163, 0x60ef },{ 0x616a, 0x6004 },{ 0x616b, 0x6002 },{ 0x616e, 0x8651 }, + { 0x6173, 0x60ad },{ 0x6176, 0x5e86 },{ 0x617c, 0x621a },{ 0x617e, 0x6b32 }, + { 0x6182, 0x5fe7 },{ 0x618a, 0x60eb },{ 0x6190, 0x601c },{ 0x6191, 0x51ed }, + { 0x6192, 0x6126 },{ 0x619a, 0x60ee },{ 0x61a4, 0x6124 },{ 0x61ab, 0x60af }, + { 0x61ae, 0x6003 },{ 0x61b2, 0x5baa },{ 0x61b6, 0x5fc6 },{ 0x61c3, 0x52e4 }, + { 0x61c7, 0x6073 },{ 0x61c9, 0x5e94 },{ 0x61cc, 0x603f },{ 0x61cd, 0x61d4 }, + { 0x61de, 0x8499 },{ 0x61df, 0x603c },{ 0x61e3, 0x61d1 },{ 0x61e8, 0x6079 }, + { 0x61f2, 0x60e9 },{ 0x61f6, 0x61d2 },{ 0x61f7, 0x6000 },{ 0x61f8, 0x60ac }, + { 0x61fa, 0x5fcf },{ 0x61fc, 0x60e7 },{ 0x61fe, 0x6151 },{ 0x6200, 0x604b }, + { 0x6207, 0x6206 },{ 0x6209, 0x94ba },{ 0x6214, 0x620b },{ 0x6227, 0x6217 }, + { 0x6229, 0x622c },{ 0x6230, 0x6218 },{ 0x6232, 0x620f },{ 0x6236, 0x6237 }, + { 0x6250, 0x4ec2 },{ 0x625e, 0x634d },{ 0x6271, 0x63d2 },{ 0x627a, 0x62b5 }, + { 0x6283, 0x62da },{ 0x6294, 0x62b1 },{ 0x62b4, 0x66f3 },{ 0x62cb, 0x629b }, + { 0x62d1, 0x94b3 },{ 0x630c, 0x683c },{ 0x6336, 0x5c40 },{ 0x633e, 0x631f }, + { 0x6368, 0x820d },{ 0x636b, 0x626a },{ 0x6372, 0x5377 },{ 0x6383, 0x626b }, + { 0x6384, 0x62a1 },{ 0x6399, 0x6323 },{ 0x639b, 0x6302 },{ 0x63a1, 0x91c7 }, + { 0x63c0, 0x62e3 },{ 0x63da, 0x626c },{ 0x63db, 0x6362 },{ 0x63ee, 0x6325 }, + { 0x63f9, 0x80cc },{ 0x6406, 0x6784 },{ 0x640d, 0x635f },{ 0x6416, 0x6447 }, + { 0x6417, 0x6363 },{ 0x641f, 0x64c0 },{ 0x6425, 0x6376 },{ 0x6428, 0x6253 }, + { 0x642f, 0x638f },{ 0x6436, 0x62a2 },{ 0x643e, 0x69a8 },{ 0x6440, 0x6342 }, + { 0x6443, 0x625b },{ 0x6451, 0x63b4 },{ 0x645c, 0x63bc },{ 0x645f, 0x6402 }, + { 0x646f, 0x631a },{ 0x6473, 0x62a0 },{ 0x6476, 0x629f },{ 0x647b, 0x63ba }, + { 0x6488, 0x635e },{ 0x6490, 0x6491 },{ 0x6493, 0x6320 },{ 0x649a, 0x637b }, + { 0x649f, 0x6322 },{ 0x64a2, 0x63b8 },{ 0x64a3, 0x63b8 },{ 0x64a5, 0x62e8 }, + { 0x64a6, 0x626f },{ 0x64ab, 0x629a },{ 0x64b2, 0x6251 },{ 0x64b3, 0x63ff }, + { 0x64bb, 0x631e },{ 0x64be, 0x631d },{ 0x64bf, 0x6361 },{ 0x64c1, 0x62e5 }, + { 0x64c4, 0x63b3 },{ 0x64c7, 0x62e9 },{ 0x64ca, 0x51fb },{ 0x64cb, 0x6321 }, + { 0x64d4, 0x62c5 },{ 0x64da, 0x636e },{ 0x64e0, 0x6324 },{ 0x64e3, 0x6363 }, + { 0x64ec, 0x62df },{ 0x64ef, 0x6448 },{ 0x64f0, 0x62e7 },{ 0x64f1, 0x6401 }, + { 0x64f2, 0x63b7 },{ 0x64f4, 0x6269 },{ 0x64f7, 0x64b7 },{ 0x64fa, 0x6446 }, + { 0x64fb, 0x64de },{ 0x64fc, 0x64b8 },{ 0x64fe, 0x6270 },{ 0x6504, 0x6445 }, + { 0x6506, 0x64b5 },{ 0x650f, 0x62e2 },{ 0x6514, 0x62e6 },{ 0x6516, 0x6484 }, + { 0x6519, 0x6400 },{ 0x651b, 0x64ba },{ 0x651c, 0x643a },{ 0x651d, 0x6444 }, + { 0x6522, 0x6512 },{ 0x6523, 0x631b },{ 0x6524, 0x644a },{ 0x652a, 0x6405 }, + { 0x652c, 0x63fd },{ 0x6537, 0x8003 },{ 0x6557, 0x8d25 },{ 0x6558, 0x53d9 }, + { 0x6575, 0x654c },{ 0x6578, 0x6570 },{ 0x6582, 0x655b },{ 0x6583, 0x6bd9 }, + { 0x6595, 0x6593 },{ 0x65ac, 0x65a9 },{ 0x65b7, 0x65ad },{ 0x65c2, 0x65d7 }, + { 0x65db, 0x5e61 },{ 0x6607, 0x5347 },{ 0x6642, 0x65f6 },{ 0x6649, 0x664b }, + { 0x665d, 0x663c },{ 0x665e, 0x66e6 },{ 0x6662, 0x6670 },{ 0x667b, 0x6697 }, + { 0x6688, 0x6655 },{ 0x6689, 0x6656 },{ 0x6698, 0x9633 },{ 0x66a2, 0x7545 }, + { 0x66ab, 0x6682 },{ 0x66b1, 0x6635 },{ 0x66b8, 0x4e86 },{ 0x66c4, 0x6654 }, + { 0x66c6, 0x5386 },{ 0x66c7, 0x6619 },{ 0x66c9, 0x6653 },{ 0x66cf, 0x5411 }, + { 0x66d6, 0x66a7 },{ 0x66e0, 0x65f7 },{ 0x66ec, 0x6652 },{ 0x66f8, 0x4e66 }, + { 0x6703, 0x4f1a },{ 0x6722, 0x671b },{ 0x6727, 0x80e7 },{ 0x672e, 0x672f }, + { 0x6747, 0x572c },{ 0x6771, 0x4e1c },{ 0x67b4, 0x62d0 },{ 0x67f5, 0x6805 }, + { 0x67fa, 0x62d0 },{ 0x6812, 0x65ec },{ 0x686e, 0x676f },{ 0x687f, 0x6746 }, + { 0x6894, 0x6800 },{ 0x689d, 0x6761 },{ 0x689f, 0x67ad },{ 0x68b1, 0x6346 }, + { 0x68c4, 0x5f03 },{ 0x68d6, 0x67a8 },{ 0x68d7, 0x67a3 },{ 0x68df, 0x680b }, + { 0x68e7, 0x6808 },{ 0x68f2, 0x6816 },{ 0x690f, 0x6860 },{ 0x6944, 0x533e }, + { 0x694a, 0x6768 },{ 0x6953, 0x67ab },{ 0x6959, 0x8302 },{ 0x695c, 0x80e1 }, + { 0x6968, 0x6862 },{ 0x696d, 0x4e1a },{ 0x6975, 0x6781 },{ 0x69a6, 0x5e72 }, + { 0x69aa, 0x6769 },{ 0x69ae, 0x8363 },{ 0x69bf, 0x6864 },{ 0x69c3, 0x76d8 }, + { 0x69cb, 0x6784 },{ 0x69cd, 0x67aa },{ 0x69d3, 0x6760 },{ 0x69e7, 0x6920 }, + { 0x69e8, 0x6901 },{ 0x69f3, 0x6868 },{ 0x6a01, 0x6869 },{ 0x6a02, 0x4e50 }, + { 0x6a05, 0x679e },{ 0x6a11, 0x6881 },{ 0x6a13, 0x697c },{ 0x6a19, 0x6807 }, + { 0x6a1e, 0x67a2 },{ 0x6a23, 0x6837 },{ 0x6a38, 0x6734 },{ 0x6a39, 0x6811 }, + { 0x6a3a, 0x6866 },{ 0x6a48, 0x6861 },{ 0x6a4b, 0x6865 },{ 0x6a5f, 0x673a }, + { 0x6a62, 0x692d },{ 0x6a66, 0x5e62 },{ 0x6a6b, 0x6a2a },{ 0x6a81, 0x6aa9 }, + { 0x6a89, 0x67fd },{ 0x6a94, 0x6863 },{ 0x6a9c, 0x6867 },{ 0x6aa2, 0x68c0 }, + { 0x6aa3, 0x6a2f },{ 0x6aaf, 0x53f0 },{ 0x6ab3, 0x69df },{ 0x6ab8, 0x67e0 }, + { 0x6abb, 0x69db },{ 0x6ac2, 0x68f9 },{ 0x6ac3, 0x67dc },{ 0x6ad0, 0x7d2f }, + { 0x6ad3, 0x6a79 },{ 0x6ada, 0x6988 },{ 0x6adb, 0x6809 },{ 0x6add, 0x691f }, + { 0x6ade, 0x6a7c },{ 0x6adf, 0x680e },{ 0x6ae5, 0x6a71 },{ 0x6ae7, 0x69e0 }, + { 0x6ae8, 0x680c },{ 0x6aea, 0x67a5 },{ 0x6aeb, 0x6a65 },{ 0x6aec, 0x6987 }, + { 0x6af3, 0x680a },{ 0x6af8, 0x6989 },{ 0x6afa, 0x68c2 },{ 0x6afb, 0x6a31 }, + { 0x6b04, 0x680f },{ 0x6b0a, 0x6743 },{ 0x6b0f, 0x6924 },{ 0x6b12, 0x683e }, + { 0x6b16, 0x6984 },{ 0x6b1e, 0x68c2 },{ 0x6b38, 0x5509 },{ 0x6b3d, 0x94a6 }, + { 0x6b4e, 0x53f9 },{ 0x6b50, 0x6b27 },{ 0x6b5f, 0x6b24 },{ 0x6b61, 0x6b22 }, + { 0x6b72, 0x5c81 },{ 0x6b77, 0x5386 },{ 0x6b78, 0x5f52 },{ 0x6b7f, 0x6b81 }, + { 0x6b80, 0x592d },{ 0x6b98, 0x6b8b },{ 0x6b9e, 0x6b92 },{ 0x6ba4, 0x6b87 }, + { 0x6bab, 0x6b9a },{ 0x6bad, 0x50f5 },{ 0x6bae, 0x6b93 },{ 0x6baf, 0x6ba1 }, + { 0x6bb2, 0x6b7c },{ 0x6bba, 0x6740 },{ 0x6bbc, 0x58f3 },{ 0x6bbd, 0x80b4 }, + { 0x6bc0, 0x6bc1 },{ 0x6bc6, 0x6bb4 },{ 0x6bcc, 0x6bcb },{ 0x6bd8, 0x6bd7 }, + { 0x6bec, 0x7403 },{ 0x6bff, 0x6bf5 },{ 0x6c08, 0x6be1 },{ 0x6c0c, 0x6c07 }, + { 0x6c23, 0x6c14 },{ 0x6c2b, 0x6c22 },{ 0x6c2c, 0x6c29 },{ 0x6c33, 0x6c32 }, + { 0x6c3e, 0x6cdb },{ 0x6c46, 0x6c3d },{ 0x6c4d, 0x4e38 },{ 0x6c4e, 0x6cdb }, + { 0x6c59, 0x6c61 },{ 0x6c7a, 0x51b3 },{ 0x6c8d, 0x51b1 },{ 0x6c92, 0x6ca1 }, + { 0x6c96, 0x51b2 },{ 0x6cc1, 0x51b5 },{ 0x6cdd, 0x6eaf },{ 0x6d1f, 0x6d95 }, + { 0x6d29, 0x6cc4 },{ 0x6d36, 0x6c79 },{ 0x6d6c, 0x91cc },{ 0x6d79, 0x6d43 }, + { 0x6d87, 0x6cfe },{ 0x6dbc, 0x51c9 },{ 0x6dd2, 0x51c4 },{ 0x6dda, 0x6cea }, + { 0x6de5, 0x6e0c },{ 0x6de8, 0x51c0 },{ 0x6dea, 0x6ca6 },{ 0x6df5, 0x6e0a }, + { 0x6df6, 0x6d9e },{ 0x6dfa, 0x6d45 },{ 0x6e19, 0x6da3 },{ 0x6e1b, 0x51cf }, + { 0x6e26, 0x6da1 },{ 0x6e2c, 0x6d4b },{ 0x6e3e, 0x6d51 },{ 0x6e4a, 0x51d1 }, + { 0x6e5e, 0x6d48 },{ 0x6e63, 0x95f5 },{ 0x6e67, 0x6d8c },{ 0x6e6f, 0x6c64 }, + { 0x6e88, 0x6ca9 },{ 0x6e96, 0x51c6 },{ 0x6e9d, 0x6c9f },{ 0x6eab, 0x6e29 }, + { 0x6ebc, 0x6e7f },{ 0x6ec4, 0x6ca7 },{ 0x6ec5, 0x706d },{ 0x6ecc, 0x6da4 }, + { 0x6ece, 0x8365 },{ 0x6eec, 0x6caa },{ 0x6eef, 0x6ede },{ 0x6ef2, 0x6e17 }, + { 0x6ef7, 0x5364 },{ 0x6ef8, 0x6d52 },{ 0x6efe, 0x6eda },{ 0x6eff, 0x6ee1 }, + { 0x6f01, 0x6e14 },{ 0x6f1a, 0x6ca4 },{ 0x6f22, 0x6c49 },{ 0x6f23, 0x6d9f }, + { 0x6f2c, 0x6e0d },{ 0x6f32, 0x6da8 },{ 0x6f35, 0x6e86 },{ 0x6f38, 0x6e10 }, + { 0x6f3f, 0x6d46 },{ 0x6f41, 0x988d },{ 0x6f51, 0x6cfc },{ 0x6f54, 0x6d01 }, + { 0x6f5b, 0x6f5c },{ 0x6f5f, 0x8204 },{ 0x6f64, 0x6da6 },{ 0x6f6f, 0x6d54 }, + { 0x6f70, 0x6e83 },{ 0x6f77, 0x6ed7 },{ 0x6f7f, 0x6da0 },{ 0x6f80, 0x6da9 }, + { 0x6f82, 0x6f84 },{ 0x6f86, 0x6d47 },{ 0x6f87, 0x6d9d },{ 0x6f94, 0x6d69 }, + { 0x6f97, 0x6da7 },{ 0x6fa0, 0x6e11 },{ 0x6fa4, 0x6cfd },{ 0x6fa9, 0x6cf6 }, + { 0x6fae, 0x6d4d },{ 0x6fb1, 0x6dc0 },{ 0x6fc1, 0x6d4a },{ 0x6fc3, 0x6d53 }, + { 0x6fd5, 0x6e7f },{ 0x6fd8, 0x6cde },{ 0x6fdb, 0x8499 },{ 0x6fdf, 0x6d4e }, + { 0x6fe4, 0x6d9b },{ 0x6feb, 0x6ee5 },{ 0x6fec, 0x6d5a },{ 0x6ff0, 0x6f4d }, + { 0x6ff1, 0x6ee8 },{ 0x6ffa, 0x6e85 },{ 0x6ffc, 0x6cfa },{ 0x6ffe, 0x6ee4 }, + { 0x7001, 0x6f3e },{ 0x7005, 0x6ee2 },{ 0x7006, 0x6e0e },{ 0x7009, 0x6cfb }, + { 0x700b, 0x6c88 },{ 0x700f, 0x6d4f },{ 0x7015, 0x6fd2 },{ 0x7018, 0x6cf8 }, + { 0x701d, 0x6ca5 },{ 0x701f, 0x6f47 },{ 0x7020, 0x6f46 },{ 0x7026, 0x6f74 }, + { 0x7027, 0x6cf7 },{ 0x7028, 0x6fd1 },{ 0x7030, 0x5f25 },{ 0x7032, 0x6f4b }, + { 0x703e, 0x6f9c },{ 0x7043, 0x6ca3 },{ 0x7044, 0x6ee0 },{ 0x7051, 0x6d12 }, + { 0x7055, 0x6f13 },{ 0x7058, 0x6ee9 },{ 0x705d, 0x704f },{ 0x7063, 0x6e7e }, + { 0x7064, 0x6ee6 },{ 0x7069, 0x6edf },{ 0x707d, 0x707e },{ 0x70a4, 0x7167 }, + { 0x70b0, 0x70ae },{ 0x70ba, 0x4e3a },{ 0x70cf, 0x4e4c },{ 0x70f4, 0x70c3 }, + { 0x7121, 0x65e0 },{ 0x7149, 0x70bc },{ 0x7152, 0x709c },{ 0x7156, 0x6696 }, + { 0x7159, 0x70df },{ 0x7162, 0x8315 },{ 0x7165, 0x7115 },{ 0x7169, 0x70e6 }, + { 0x716c, 0x7080 },{ 0x7192, 0x8367 },{ 0x7197, 0x709d },{ 0x71b1, 0x70ed }, + { 0x71be, 0x70bd },{ 0x71c1, 0x70e8 },{ 0x71c4, 0x7130 },{ 0x71c8, 0x706f }, + { 0x71c9, 0x7096 },{ 0x71d0, 0x78f7 },{ 0x71d2, 0x70e7 },{ 0x71d9, 0x70eb }, + { 0x71dc, 0x7116 },{ 0x71df, 0x8425 },{ 0x71e6, 0x707f },{ 0x71ec, 0x6bc1 }, + { 0x71ed, 0x70db },{ 0x71f4, 0x70e9 },{ 0x71fb, 0x718f },{ 0x71fc, 0x70ec }, + { 0x71fe, 0x7118 },{ 0x71ff, 0x8000 },{ 0x720d, 0x70c1 },{ 0x7210, 0x7089 }, + { 0x721b, 0x70c2 },{ 0x722d, 0x4e89 },{ 0x723a, 0x7237 },{ 0x723e, 0x5c14 }, + { 0x7246, 0x5899 },{ 0x7258, 0x724d },{ 0x7260, 0x5b83 },{ 0x7274, 0x62b5 }, + { 0x727d, 0x7275 },{ 0x7296, 0x8366 },{ 0x729b, 0x7266 },{ 0x72a2, 0x728a }, + { 0x72a7, 0x727a },{ 0x72c0, 0x72b6 },{ 0x72da, 0x65e6 },{ 0x72f9, 0x72ed }, + { 0x72fd, 0x72c8 },{ 0x7319, 0x72f0 },{ 0x7336, 0x72b9 },{ 0x733b, 0x72f2 }, + { 0x7343, 0x5446 },{ 0x7344, 0x72f1 },{ 0x7345, 0x72ee },{ 0x734e, 0x5956 }, + { 0x7368, 0x72ec },{ 0x736a, 0x72ef },{ 0x736b, 0x7303 },{ 0x7370, 0x72de }, + { 0x7372, 0x83b7 },{ 0x7375, 0x730e },{ 0x7377, 0x72b7 },{ 0x7378, 0x517d }, + { 0x737a, 0x736d },{ 0x737b, 0x732e },{ 0x737c, 0x7315 },{ 0x7380, 0x7321 }, + { 0x7385, 0x5999 },{ 0x7386, 0x5179 },{ 0x73a8, 0x73cf },{ 0x73ea, 0x572d }, + { 0x73ee, 0x4f69 },{ 0x73fe, 0x73b0 },{ 0x7431, 0x96d5 },{ 0x743a, 0x73d0 }, + { 0x743f, 0x73f2 },{ 0x744b, 0x73ae },{ 0x7463, 0x7410 },{ 0x7464, 0x7476 }, + { 0x7469, 0x83b9 },{ 0x746a, 0x739b },{ 0x746f, 0x7405 },{ 0x7489, 0x740f }, + { 0x74a3, 0x7391 },{ 0x74a6, 0x7477 },{ 0x74b0, 0x73af },{ 0x74bd, 0x73ba }, + { 0x74bf, 0x7487 },{ 0x74ca, 0x743c },{ 0x74cf, 0x73d1 },{ 0x74d4, 0x748e }, + { 0x74d6, 0x9576 },{ 0x74da, 0x74d2 },{ 0x750c, 0x74ef },{ 0x7515, 0x74ee }, + { 0x7522, 0x4ea7 },{ 0x7526, 0x82cf },{ 0x752a, 0x89d2 },{ 0x752f, 0x5b81 }, + { 0x755d, 0x4ea9 },{ 0x7562, 0x6bd5 },{ 0x756b, 0x753b },{ 0x756c, 0x7572 }, + { 0x7570, 0x5f02 },{ 0x7576, 0x5f53 },{ 0x7587, 0x7574 },{ 0x758a, 0x53e0 }, + { 0x75bf, 0x75f1 },{ 0x75d9, 0x75c9 },{ 0x75e0, 0x9178 },{ 0x75f2, 0x9ebb }, + { 0x75f3, 0x9ebb },{ 0x75fa, 0x75f9 },{ 0x75fe, 0x75b4 },{ 0x7609, 0x6108 }, + { 0x760b, 0x75af },{ 0x760d, 0x75a1 },{ 0x7613, 0x75ea },{ 0x761e, 0x7617 }, + { 0x7621, 0x75ae },{ 0x7627, 0x759f },{ 0x763a, 0x7618 },{ 0x7642, 0x7597 }, + { 0x7646, 0x75e8 },{ 0x7647, 0x75eb },{ 0x7649, 0x7605 },{ 0x7652, 0x6108 }, + { 0x7658, 0x75a0 },{ 0x765f, 0x762a },{ 0x7661, 0x75f4 },{ 0x7662, 0x75d2 }, + { 0x7664, 0x7596 },{ 0x7665, 0x75c7 },{ 0x7669, 0x765e },{ 0x766c, 0x7663 }, + { 0x766d, 0x763f },{ 0x766e, 0x763e },{ 0x7670, 0x75c8 },{ 0x7671, 0x762b }, + { 0x7672, 0x766b },{ 0x767c, 0x53d1 },{ 0x7681, 0x7682 },{ 0x769a, 0x7691 }, + { 0x76b0, 0x75b1 },{ 0x76b8, 0x76b2 },{ 0x76ba, 0x76b1 },{ 0x76c3, 0x676f }, + { 0x76dc, 0x76d7 },{ 0x76de, 0x76cf },{ 0x76e1, 0x5c3d },{ 0x76e3, 0x76d1 }, + { 0x76e4, 0x76d8 },{ 0x76e7, 0x5362 },{ 0x76ea, 0x8361 },{ 0x7725, 0x7726 }, + { 0x773e, 0x4f17 },{ 0x774f, 0x56f0 },{ 0x775c, 0x7741 },{ 0x775e, 0x7750 }, + { 0x776a, 0x777e },{ 0x7787, 0x772f },{ 0x779e, 0x7792 },{ 0x77ad, 0x4e86 }, + { 0x77bc, 0x7751 },{ 0x77c7, 0x8499 },{ 0x77d3, 0x80e7 },{ 0x77da, 0x77a9 }, + { 0x77ef, 0x77eb },{ 0x7832, 0x70ae },{ 0x7843, 0x6731 },{ 0x7864, 0x7856 }, + { 0x7868, 0x7817 },{ 0x786f, 0x781a },{ 0x7881, 0x68cb },{ 0x7895, 0x5d0e }, + { 0x78a9, 0x7855 },{ 0x78aa, 0x7827 },{ 0x78ad, 0x7800 },{ 0x78ba, 0x786e }, + { 0x78bc, 0x7801 },{ 0x78da, 0x7816 },{ 0x78e3, 0x789c },{ 0x78e7, 0x789b }, + { 0x78ef, 0x77f6 },{ 0x78fd, 0x7857 },{ 0x790e, 0x7840 },{ 0x7919, 0x788d }, + { 0x7921, 0x7934 },{ 0x7926, 0x77ff },{ 0x792a, 0x783a },{ 0x792b, 0x783e }, + { 0x792c, 0x77fe },{ 0x7931, 0x783b },{ 0x7942, 0x4ed6 },{ 0x7945, 0x7946 }, + { 0x7947, 0x53ea },{ 0x7950, 0x4f51 },{ 0x7955, 0x79d8 },{ 0x797c, 0x88f8 }, + { 0x797f, 0x7984 },{ 0x798d, 0x7978 },{ 0x798e, 0x796f },{ 0x79a6, 0x5fa1 }, + { 0x79aa, 0x7985 },{ 0x79ae, 0x793c },{ 0x79b0, 0x7962 },{ 0x79b1, 0x7977 }, + { 0x79bf, 0x79c3 },{ 0x79c8, 0x7c7c },{ 0x79cf, 0x8017 },{ 0x7a05, 0x7a0e }, + { 0x7a08, 0x79c6 },{ 0x7a1c, 0x68f1 },{ 0x7a1f, 0x7980 },{ 0x7a28, 0x6241 }, + { 0x7a2e, 0x79cd },{ 0x7a31, 0x79f0 },{ 0x7a40, 0x8c37 },{ 0x7a4c, 0x7a23 }, + { 0x7a4d, 0x79ef },{ 0x7a4e, 0x9896 },{ 0x7a61, 0x7a51 },{ 0x7a62, 0x79fd }, + { 0x7a68, 0x9893 },{ 0x7a69, 0x7a33 },{ 0x7a6b, 0x83b7 },{ 0x7aa9, 0x7a9d }, + { 0x7aaa, 0x6d3c },{ 0x7aae, 0x7a77 },{ 0x7aaf, 0x7a91 },{ 0x7ab6, 0x7aad }, + { 0x7aba, 0x7aa5 },{ 0x7ac4, 0x7a9c },{ 0x7ac5, 0x7a8d },{ 0x7ac7, 0x7aa6 }, + { 0x7aca, 0x7a83 },{ 0x7af6, 0x7ade },{ 0x7b3b, 0x7b47 },{ 0x7b46, 0x7b14 }, + { 0x7b4d, 0x7b0b },{ 0x7b67, 0x7b15 },{ 0x7b74, 0x7b56 },{ 0x7b84, 0x7b85 }, + { 0x7b87, 0x4e2a },{ 0x7b8b, 0x7b3a },{ 0x7b8f, 0x7b5d },{ 0x7ba0, 0x68f0 }, + { 0x7bc0, 0x8282 },{ 0x7bc4, 0x8303 },{ 0x7bc9, 0x7b51 },{ 0x7bcb, 0x7ba7 }, + { 0x7bdb, 0x7bac },{ 0x7be0, 0x7b71 },{ 0x7be4, 0x7b03 },{ 0x7be9, 0x7b5b }, + { 0x7bf2, 0x5f57 },{ 0x7bf3, 0x7b5a },{ 0x7c00, 0x7ba6 },{ 0x7c0d, 0x7bd3 }, + { 0x7c11, 0x84d1 },{ 0x7c1e, 0x7baa },{ 0x7c21, 0x7b80 },{ 0x7c23, 0x7bd1 }, + { 0x7c2b, 0x7bab },{ 0x7c37, 0x6a90 },{ 0x7c3d, 0x7b7e },{ 0x7c3e, 0x5e18 }, + { 0x7c43, 0x7bee },{ 0x7c4c, 0x7b79 },{ 0x7c50, 0x85e4 },{ 0x7c5c, 0x7ba8 }, + { 0x7c5f, 0x7c41 },{ 0x7c60, 0x7b3c },{ 0x7c64, 0x7b7e },{ 0x7c65, 0x9fa0 }, + { 0x7c69, 0x7b3e },{ 0x7c6a, 0x7c16 },{ 0x7c6c, 0x7bf1 },{ 0x7c6e, 0x7ba9 }, + { 0x7c72, 0x5401 },{ 0x7ca7, 0x5986 },{ 0x7cb5, 0x7ca4 },{ 0x7cdd, 0x7cc1 }, + { 0x7cde, 0x7caa },{ 0x7ce2, 0x998d },{ 0x7ce7, 0x7cae },{ 0x7cf0, 0x56e2 }, + { 0x7cf2, 0x7c9d },{ 0x7cf4, 0x7c74 },{ 0x7cf6, 0x7c9c },{ 0x7cfe, 0x7ea0 }, + { 0x7d00, 0x7eaa },{ 0x7d02, 0x7ea3 },{ 0x7d04, 0x7ea6 },{ 0x7d05, 0x7ea2 }, + { 0x7d06, 0x7ea1 },{ 0x7d07, 0x7ea5 },{ 0x7d08, 0x7ea8 },{ 0x7d09, 0x7eab }, + { 0x7d0b, 0x7eb9 },{ 0x7d0d, 0x7eb3 },{ 0x7d10, 0x7ebd },{ 0x7d13, 0x7ebe }, + { 0x7d14, 0x7eaf },{ 0x7d15, 0x7eb0 },{ 0x7d17, 0x7eb1 },{ 0x7d19, 0x7eb8 }, + { 0x7d1a, 0x7ea7 },{ 0x7d1b, 0x7eb7 },{ 0x7d1c, 0x7ead },{ 0x7d21, 0x7eba }, + { 0x7d2e, 0x624e },{ 0x7d30, 0x7ec6 },{ 0x7d31, 0x7ec2 },{ 0x7d32, 0x7ec1 }, + { 0x7d33, 0x7ec5 },{ 0x7d39, 0x7ecd },{ 0x7d3a, 0x7ec0 },{ 0x7d3c, 0x7ecb }, + { 0x7d3f, 0x7ed0 },{ 0x7d40, 0x7ecc },{ 0x7d42, 0x7ec8 },{ 0x7d43, 0x5f26 }, + { 0x7d44, 0x7ec4 },{ 0x7d46, 0x7eca },{ 0x7d4e, 0x7ed7 },{ 0x7d50, 0x7ed3 }, + { 0x7d55, 0x7edd },{ 0x7d5b, 0x7ee6 },{ 0x7d5e, 0x7ede },{ 0x7d61, 0x7edc }, + { 0x7d62, 0x7eda },{ 0x7d66, 0x7ed9 },{ 0x7d68, 0x7ed2 },{ 0x7d71, 0x7edf }, + { 0x7d72, 0x4e1d },{ 0x7d73, 0x7edb },{ 0x7d79, 0x7ee2 },{ 0x7d81, 0x7ed1 }, + { 0x7d83, 0x7ee1 },{ 0x7d86, 0x7ee0 },{ 0x7d88, 0x7ee8 },{ 0x7d8f, 0x7ee5 }, + { 0x7d91, 0x6346 },{ 0x7d93, 0x7ecf },{ 0x7d9c, 0x7efc },{ 0x7d9e, 0x7f0d }, + { 0x7da0, 0x7eff },{ 0x7da2, 0x7ef8 },{ 0x7da3, 0x7efb },{ 0x7dac, 0x7ef6 }, + { 0x7dad, 0x7ef4 },{ 0x7db0, 0x7efe },{ 0x7db1, 0x7eb2 },{ 0x7db2, 0x7f51 }, + { 0x7db4, 0x7f00 },{ 0x7db5, 0x5f69 },{ 0x7db8, 0x7eb6 },{ 0x7db9, 0x7efa }, + { 0x7dba, 0x7eee },{ 0x7dbb, 0x7efd },{ 0x7dbd, 0x7ef0 },{ 0x7dbe, 0x7eeb }, + { 0x7dbf, 0x7ef5 },{ 0x7dc4, 0x7ef2 },{ 0x7dc7, 0x7f01 },{ 0x7dca, 0x7d27 }, + { 0x7dcb, 0x7eef },{ 0x7dd2, 0x7eea },{ 0x7dd7, 0x7f03 },{ 0x7dd8, 0x7f04 }, + { 0x7dd9, 0x7f02 },{ 0x7dda, 0x7ebf },{ 0x7ddd, 0x7f09 },{ 0x7dde, 0x7f0e }, + { 0x7de0, 0x7f14 },{ 0x7de1, 0x7f17 },{ 0x7de3, 0x7f18 },{ 0x7de6, 0x7f0c }, + { 0x7de8, 0x7f16 },{ 0x7de9, 0x7f13 },{ 0x7dec, 0x7f05 },{ 0x7def, 0x7eac }, + { 0x7df1, 0x7f11 },{ 0x7df2, 0x7f08 },{ 0x7df4, 0x7ec3 },{ 0x7df6, 0x7f0f }, + { 0x7df9, 0x7f07 },{ 0x7dfb, 0x81f4 },{ 0x7e08, 0x8426 },{ 0x7e09, 0x7f19 }, + { 0x7e0a, 0x7f22 },{ 0x7e0b, 0x7f12 },{ 0x7e10, 0x7ec9 },{ 0x7e11, 0x7f23 }, + { 0x7e1a, 0x7ee6 },{ 0x7e1b, 0x7f1a },{ 0x7e1d, 0x7f1c },{ 0x7e1e, 0x7f1f }, + { 0x7e1f, 0x7f1b },{ 0x7e23, 0x53bf },{ 0x7e2b, 0x7f1d },{ 0x7e2d, 0x7f21 }, + { 0x7e2e, 0x7f29 },{ 0x7e2f, 0x6f14 },{ 0x7e31, 0x7eb5 },{ 0x7e32, 0x7f27 }, + { 0x7e33, 0x7f1a },{ 0x7e34, 0x7ea4 },{ 0x7e35, 0x7f26 },{ 0x7e36, 0x7d77 }, + { 0x7e37, 0x7f15 },{ 0x7e39, 0x7f25 },{ 0x7e3d, 0x603b },{ 0x7e3e, 0x7ee9 }, + { 0x7e43, 0x7ef7 },{ 0x7e45, 0x7f2b },{ 0x7e46, 0x7f2a },{ 0x7e48, 0x8941 }, + { 0x7e52, 0x7f2f },{ 0x7e54, 0x7ec7 },{ 0x7e55, 0x7f2e },{ 0x7e59, 0x7ffb }, + { 0x7e5a, 0x7f2d },{ 0x7e5e, 0x7ed5 },{ 0x7e61, 0x7ee3 },{ 0x7e62, 0x7f0b }, + { 0x7e69, 0x7ef3 },{ 0x7e6a, 0x7ed8 },{ 0x7e6b, 0x7cfb },{ 0x7e6d, 0x8327 }, + { 0x7e6f, 0x7f33 },{ 0x7e70, 0x7f32 },{ 0x7e73, 0x7f34 },{ 0x7e79, 0x7ece }, + { 0x7e7c, 0x7ee7 },{ 0x7e7d, 0x7f24 },{ 0x7e7e, 0x7f31 },{ 0x7e88, 0x7f2c }, + { 0x7e8a, 0x7ea9 },{ 0x7e8c, 0x7eed },{ 0x7e8d, 0x7d2f },{ 0x7e8f, 0x7f20 }, + { 0x7e93, 0x7f28 },{ 0x7e94, 0x624d },{ 0x7e96, 0x7ea4 },{ 0x7e98, 0x7f35 }, + { 0x7e9c, 0x7f06 },{ 0x7f3d, 0x94b5 },{ 0x7f3e, 0x74f6 },{ 0x7f48, 0x575b }, + { 0x7f4c, 0x7f42 },{ 0x7f66, 0x7f58 },{ 0x7f70, 0x7f5a },{ 0x7f75, 0x9a82 }, + { 0x7f77, 0x7f62 },{ 0x7f85, 0x7f57 },{ 0x7f86, 0x7f74 },{ 0x7f88, 0x7f81 }, + { 0x7f8b, 0x8288 },{ 0x7fa5, 0x7f9f },{ 0x7fa8, 0x7fa1 },{ 0x7fa9, 0x4e49 }, + { 0x7fb6, 0x81bb },{ 0x7fd2, 0x4e60 },{ 0x7ff9, 0x7fd8 },{ 0x8011, 0x7aef }, + { 0x8021, 0x52a9 },{ 0x8024, 0x85c9 },{ 0x802c, 0x8027 },{ 0x8056, 0x5723 }, + { 0x805e, 0x95fb },{ 0x806f, 0x8054 },{ 0x8070, 0x806a },{ 0x8072, 0x58f0 }, + { 0x8073, 0x8038 },{ 0x8075, 0x8069 },{ 0x8076, 0x8042 },{ 0x8077, 0x804c }, + { 0x8079, 0x804d },{ 0x807d, 0x542c },{ 0x807e, 0x804b },{ 0x8085, 0x8083 }, + { 0x808f, 0x64cd },{ 0x8090, 0x80f3 },{ 0x80c7, 0x80ba },{ 0x80ca, 0x6710 }, + { 0x8105, 0x80c1 },{ 0x8108, 0x8109 },{ 0x811b, 0x80eb },{ 0x8123, 0x5507 }, + { 0x8129, 0x4fee },{ 0x812b, 0x8131 },{ 0x8139, 0x80c0 },{ 0x814e, 0x80be }, + { 0x8161, 0x8136 },{ 0x8166, 0x8111 },{ 0x816b, 0x80bf },{ 0x8173, 0x811a }, + { 0x8178, 0x80a0 },{ 0x8183, 0x817d },{ 0x8186, 0x55c9 },{ 0x819a, 0x80a4 }, + { 0x81a0, 0x80f6 },{ 0x81a9, 0x817b },{ 0x81bd, 0x80c6 },{ 0x81be, 0x810d }, + { 0x81bf, 0x8113 },{ 0x81c9, 0x8138 },{ 0x81cd, 0x8110 },{ 0x81cf, 0x8191 }, + { 0x81d5, 0x8198 },{ 0x81d8, 0x814a },{ 0x81d9, 0x80ed },{ 0x81da, 0x80ea }, + { 0x81df, 0x810f },{ 0x81e0, 0x8114 },{ 0x81e5, 0x5367 },{ 0x81e8, 0x4e34 }, + { 0x81fa, 0x53f0 },{ 0x8207, 0x4e0e },{ 0x8208, 0x5174 },{ 0x8209, 0x4e3e }, + { 0x820a, 0x65e7 },{ 0x820b, 0x8845 },{ 0x8216, 0x94fa },{ 0x8259, 0x8231 }, + { 0x8263, 0x6a79 },{ 0x8264, 0x8223 },{ 0x8266, 0x8230 },{ 0x826b, 0x823b }, + { 0x8271, 0x8270 },{ 0x8277, 0x8273 },{ 0x8278, 0x8279 },{ 0x82bb, 0x520d }, + { 0x82e7, 0x82ce },{ 0x82fa, 0x8393 },{ 0x830d, 0x82df },{ 0x8332, 0x5179 }, + { 0x8345, 0x7b54 },{ 0x834a, 0x8346 },{ 0x8373, 0x8c46 },{ 0x838a, 0x5e84 }, + { 0x8396, 0x830e },{ 0x83a2, 0x835a },{ 0x83a7, 0x82cb },{ 0x83eb, 0x5807 }, + { 0x83ef, 0x534e },{ 0x83f4, 0x5eb5 },{ 0x8407, 0x82cc },{ 0x840a, 0x83b1 }, + { 0x842c, 0x4e07 },{ 0x8435, 0x83b4 },{ 0x8449, 0x53f6 },{ 0x8452, 0x836d }, + { 0x8466, 0x82c7 },{ 0x846f, 0x836f },{ 0x8477, 0x8364 },{ 0x8490, 0x641c }, + { 0x8494, 0x83b3 },{ 0x849e, 0x8385 },{ 0x84bc, 0x82cd },{ 0x84c0, 0x836a }, + { 0x84c6, 0x5e2d },{ 0x84cb, 0x76d6 },{ 0x84ee, 0x83b2 },{ 0x84ef, 0x82c1 }, + { 0x84f4, 0x83bc },{ 0x84fd, 0x835c },{ 0x8506, 0x83f1 },{ 0x8514, 0x535c }, + { 0x851e, 0x848c },{ 0x8523, 0x848b },{ 0x8525, 0x8471 },{ 0x8526, 0x8311 }, + { 0x852d, 0x836b },{ 0x8541, 0x8368 },{ 0x8546, 0x8487 },{ 0x854e, 0x835e }, + { 0x8553, 0x82b8 },{ 0x8555, 0x83b8 },{ 0x8558, 0x835b },{ 0x8562, 0x8489 }, + { 0x8569, 0x8361 },{ 0x856a, 0x829c },{ 0x856d, 0x8427 },{ 0x8577, 0x84e3 }, + { 0x8588, 0x835f },{ 0x858a, 0x84df },{ 0x858c, 0x8297 },{ 0x8591, 0x59dc }, + { 0x8594, 0x8537 },{ 0x8599, 0x5243 },{ 0x859f, 0x83b6 },{ 0x85a6, 0x8350 }, + { 0x85a9, 0x8428 },{ 0x85ba, 0x8360 },{ 0x85cd, 0x84dd },{ 0x85ce, 0x8369 }, + { 0x85da, 0x836c },{ 0x85dd, 0x827a },{ 0x85e5, 0x836f },{ 0x85ea, 0x85ae }, + { 0x85f6, 0x82c8 },{ 0x85f7, 0x85af },{ 0x85f9, 0x853c },{ 0x85fa, 0x853a }, + { 0x8604, 0x8572 },{ 0x8606, 0x82a6 },{ 0x8607, 0x82cf },{ 0x860a, 0x8574 }, + { 0x860b, 0x82f9 },{ 0x8617, 0x8616 },{ 0x861a, 0x85d3 },{ 0x861e, 0x8539 }, + { 0x8622, 0x830f },{ 0x862d, 0x5170 },{ 0x863a, 0x84e0 },{ 0x863f, 0x841d }, + { 0x8655, 0x5904 },{ 0x8656, 0x547c },{ 0x865b, 0x865a },{ 0x865c, 0x864f }, + { 0x865f, 0x53f7 },{ 0x8667, 0x4e8f },{ 0x866f, 0x866c },{ 0x86fa, 0x86f1 }, + { 0x86fb, 0x8715 },{ 0x8706, 0x86ac },{ 0x873a, 0x9713 },{ 0x8755, 0x8680 }, + { 0x875f, 0x732c },{ 0x8766, 0x867e },{ 0x8768, 0x8671 },{ 0x8778, 0x8717 }, + { 0x8784, 0x86f3 },{ 0x879e, 0x8682 },{ 0x87a2, 0x8424 },{ 0x87bb, 0x877c }, + { 0x87c4, 0x86f0 },{ 0x87c8, 0x8748 },{ 0x87e3, 0x866e },{ 0x87ec, 0x8749 }, + { 0x87ef, 0x86f2 },{ 0x87f2, 0x866b },{ 0x87f6, 0x86cf },{ 0x87fa, 0x87ee }, + { 0x87fb, 0x8681 },{ 0x8805, 0x8747 },{ 0x8806, 0x867f },{ 0x880d, 0x874e }, + { 0x8810, 0x86f4 },{ 0x8811, 0x877e },{ 0x8814, 0x869d },{ 0x881f, 0x8721 }, + { 0x8823, 0x86ce },{ 0x8831, 0x86ca },{ 0x8836, 0x8695 },{ 0x8837, 0x883c }, + { 0x883b, 0x86ee },{ 0x884a, 0x8511 },{ 0x8852, 0x70ab },{ 0x8853, 0x672f }, + { 0x885a, 0x80e1 },{ 0x885b, 0x536b },{ 0x885d, 0x51b2 },{ 0x8879, 0x53ea }, + { 0x889e, 0x886e },{ 0x88aa, 0x795b },{ 0x88ca, 0x8885 },{ 0x88cf, 0x91cc }, + { 0x88dc, 0x8865 },{ 0x88dd, 0x88c5 },{ 0x88e1, 0x91cc },{ 0x88fd, 0x5236 }, + { 0x8907, 0x590d },{ 0x890e, 0x8896 },{ 0x8932, 0x88e4 },{ 0x8933, 0x88e2 }, + { 0x8938, 0x891b },{ 0x893b, 0x4eb5 },{ 0x8949, 0x88e5 },{ 0x8956, 0x8884 }, + { 0x895d, 0x88e3 },{ 0x8960, 0x88c6 },{ 0x8964, 0x8934 },{ 0x896a, 0x889c }, + { 0x896c, 0x6446 },{ 0x896f, 0x886c },{ 0x8972, 0x88ad },{ 0x897e, 0x897f }, + { 0x8988, 0x6838 },{ 0x898b, 0x89c1 },{ 0x898f, 0x89c4 },{ 0x8993, 0x89c5 }, + { 0x8996, 0x89c6 },{ 0x8998, 0x89c7 },{ 0x899c, 0x773a },{ 0x89a1, 0x89cb }, + { 0x89a6, 0x89ce },{ 0x89aa, 0x4eb2 },{ 0x89ac, 0x89ca },{ 0x89af, 0x89cf }, + { 0x89b2, 0x89d0 },{ 0x89b7, 0x89d1 },{ 0x89ba, 0x89c9 },{ 0x89bd, 0x89c8 }, + { 0x89bf, 0x89cc },{ 0x89c0, 0x89c2 },{ 0x89d4, 0x7b4b },{ 0x89dd, 0x62b5 }, + { 0x89f4, 0x89de },{ 0x89f6, 0x89ef },{ 0x89f8, 0x89e6 },{ 0x8a02, 0x8ba2 }, + { 0x8a03, 0x8ba3 },{ 0x8a08, 0x8ba1 },{ 0x8a0a, 0x8baf },{ 0x8a0c, 0x8ba7 }, + { 0x8a0e, 0x8ba8 },{ 0x8a10, 0x8ba6 },{ 0x8a13, 0x8bad },{ 0x8a15, 0x8baa }, + { 0x8a16, 0x8bab },{ 0x8a17, 0x6258 },{ 0x8a18, 0x8bb0 },{ 0x8a1b, 0x8bb9 }, + { 0x8a1d, 0x8bb6 },{ 0x8a1f, 0x8bbc },{ 0x8a22, 0x6b23 },{ 0x8a23, 0x8bc0 }, + { 0x8a25, 0x8bb7 },{ 0x8a2a, 0x8bbf },{ 0x8a2d, 0x8bbe },{ 0x8a31, 0x8bb8 }, + { 0x8a34, 0x8bc9 },{ 0x8a36, 0x8bc3 },{ 0x8a3a, 0x8bca },{ 0x8a3b, 0x6ce8 }, + { 0x8a3c, 0x8bc1 },{ 0x8a41, 0x8bc2 },{ 0x8a46, 0x8bcb },{ 0x8a4e, 0x8bb5 }, + { 0x8a50, 0x8bc8 },{ 0x8a52, 0x8bd2 },{ 0x8a54, 0x8bcf },{ 0x8a55, 0x8bc4 }, + { 0x8a58, 0x8bce },{ 0x8a5b, 0x8bc5 },{ 0x8a5e, 0x8bcd },{ 0x8a60, 0x548f }, + { 0x8a61, 0x8be9 },{ 0x8a62, 0x8be2 },{ 0x8a63, 0x8be3 },{ 0x8a66, 0x8bd5 }, + { 0x8a69, 0x8bd7 },{ 0x8a6b, 0x8be7 },{ 0x8a6c, 0x8bdf },{ 0x8a6d, 0x8be1 }, + { 0x8a6e, 0x8be0 },{ 0x8a70, 0x8bd8 },{ 0x8a71, 0x8bdd },{ 0x8a72, 0x8be5 }, + { 0x8a73, 0x8be6 },{ 0x8a75, 0x8bdc },{ 0x8a76, 0x916c },{ 0x8a7b, 0x54af }, + { 0x8a7c, 0x8bd9 },{ 0x8a7f, 0x8bd6 },{ 0x8a84, 0x8bd4 },{ 0x8a85, 0x8bdb }, + { 0x8a86, 0x8bd3 },{ 0x8a87, 0x5938 },{ 0x8a8c, 0x5fd7 },{ 0x8a8d, 0x8ba4 }, + { 0x8a91, 0x8bf3 },{ 0x8a92, 0x8bf6 },{ 0x8a95, 0x8bde },{ 0x8a98, 0x8bf1 }, + { 0x8a9a, 0x8bee },{ 0x8a9e, 0x8bed },{ 0x8aa0, 0x8bda },{ 0x8aa1, 0x8beb }, + { 0x8aa3, 0x8bec },{ 0x8aa4, 0x8bef },{ 0x8aa5, 0x8bf0 },{ 0x8aa6, 0x8bf5 }, + { 0x8aa8, 0x8bf2 },{ 0x8aaa, 0x8bf4 },{ 0x8ab0, 0x8c01 },{ 0x8ab2, 0x8bfe }, + { 0x8ab6, 0x8c07 },{ 0x8ab9, 0x8bfd },{ 0x8abc, 0x8c0a },{ 0x8abf, 0x8c03 }, + { 0x8ac2, 0x8c04 },{ 0x8ac4, 0x8c06 },{ 0x8ac7, 0x8c08 },{ 0x8ac9, 0x8bff }, + { 0x8acb, 0x8bf7 },{ 0x8acd, 0x8be4 },{ 0x8acf, 0x8bf9 },{ 0x8ad1, 0x8bfc }, + { 0x8ad2, 0x8c05 },{ 0x8ad6, 0x8bba },{ 0x8ad7, 0x8c02 },{ 0x8adb, 0x8c00 }, + { 0x8adc, 0x8c0d },{ 0x8ade, 0x8c1d },{ 0x8ae0, 0x55a7 },{ 0x8ae2, 0x8be8 }, + { 0x8ae4, 0x8c14 },{ 0x8ae6, 0x8c1b },{ 0x8ae7, 0x8c10 },{ 0x8aeb, 0x8c0f }, + { 0x8aed, 0x8c15 },{ 0x8aee, 0x8c18 },{ 0x8af1, 0x8bb3 },{ 0x8af3, 0x8c19 }, + { 0x8af6, 0x8c0c },{ 0x8af7, 0x8bbd },{ 0x8af8, 0x8bf8 },{ 0x8afa, 0x8c1a }, + { 0x8afc, 0x8c16 },{ 0x8afe, 0x8bfa },{ 0x8b00, 0x8c0b },{ 0x8b01, 0x8c12 }, + { 0x8b02, 0x8c13 },{ 0x8b04, 0x8a8a },{ 0x8b05, 0x8bcc },{ 0x8b0a, 0x8c0e }, + { 0x8b0e, 0x8c1c },{ 0x8b10, 0x8c27 },{ 0x8b14, 0x8c11 },{ 0x8b16, 0x8c21 }, + { 0x8b17, 0x8c24 },{ 0x8b19, 0x8c26 },{ 0x8b1a, 0x8c25 },{ 0x8b1b, 0x8bb2 }, + { 0x8b1d, 0x8c22 },{ 0x8b20, 0x8c23 },{ 0x8b28, 0x8c1f },{ 0x8b2b, 0x8c2a }, + { 0x8b2c, 0x8c2c },{ 0x8b33, 0x8bb4 },{ 0x8b39, 0x8c28 },{ 0x8b3c, 0x547c }, + { 0x8b3e, 0x8c29 },{ 0x8b41, 0x54d7 },{ 0x8b46, 0x563b },{ 0x8b49, 0x8bc1 }, + { 0x8b4e, 0x8c32 },{ 0x8b4f, 0x8ba5 },{ 0x8b54, 0x64b0 },{ 0x8b56, 0x8c2e }, + { 0x8b58, 0x8bc6 },{ 0x8b59, 0x8c2f },{ 0x8b5a, 0x8c2d },{ 0x8b5c, 0x8c31 }, + { 0x8b5f, 0x566a },{ 0x8b6b, 0x8c35 },{ 0x8b6d, 0x6bc1 },{ 0x8b6f, 0x8bd1 }, + { 0x8b70, 0x8bae },{ 0x8b74, 0x8c34 },{ 0x8b77, 0x62a4 },{ 0x8b7d, 0x8a89 }, + { 0x8b7e, 0x8c2b },{ 0x8b80, 0x8bfb },{ 0x8b8a, 0x53d8 },{ 0x8b8c, 0x5bb4 }, + { 0x8b8e, 0x96e0 },{ 0x8b92, 0x8c17 },{ 0x8b93, 0x8ba9 },{ 0x8b95, 0x8c30 }, + { 0x8b96, 0x8c36 },{ 0x8b9a, 0x8d5e },{ 0x8b9c, 0x8c20 },{ 0x8b9e, 0x8c33 }, + { 0x8c3f, 0x6eaa },{ 0x8c48, 0x5c82 },{ 0x8c4e, 0x7ad6 },{ 0x8c50, 0x4e30 }, + { 0x8c54, 0x8273 },{ 0x8c56, 0x4e8d },{ 0x8c6c, 0x732a },{ 0x8c8d, 0x72f8 }, + { 0x8c93, 0x732b },{ 0x8c9d, 0x8d1d },{ 0x8c9e, 0x8d1e },{ 0x8ca0, 0x8d1f }, + { 0x8ca1, 0x8d22 },{ 0x8ca2, 0x8d21 },{ 0x8ca7, 0x8d2b },{ 0x8ca8, 0x8d27 }, + { 0x8ca9, 0x8d29 },{ 0x8caa, 0x8d2a },{ 0x8cab, 0x8d2f },{ 0x8cac, 0x8d23 }, + { 0x8caf, 0x8d2e },{ 0x8cb0, 0x8d33 },{ 0x8cb2, 0x8d40 },{ 0x8cb3, 0x8d30 }, + { 0x8cb4, 0x8d35 },{ 0x8cb6, 0x8d2c },{ 0x8cb7, 0x4e70 },{ 0x8cb8, 0x8d37 }, + { 0x8cba, 0x8d36 },{ 0x8cbb, 0x8d39 },{ 0x8cbc, 0x8d34 },{ 0x8cbd, 0x8d3b }, + { 0x8cbf, 0x8d38 },{ 0x8cc0, 0x8d3a },{ 0x8cc1, 0x8d32 },{ 0x8cc2, 0x8d42 }, + { 0x8cc3, 0x8d41 },{ 0x8cc4, 0x8d3f },{ 0x8cc5, 0x8d45 },{ 0x8cc7, 0x8d44 }, + { 0x8cc8, 0x8d3e },{ 0x8cca, 0x8d3c },{ 0x8cd1, 0x8d48 },{ 0x8cd2, 0x8d4a }, + { 0x8cd3, 0x5bbe },{ 0x8cd5, 0x8d47 },{ 0x8cd9, 0x5468 },{ 0x8cda, 0x8d49 }, + { 0x8cdc, 0x8d50 },{ 0x8cde, 0x8d4f },{ 0x8ce0, 0x8d54 },{ 0x8ce1, 0x8d53 }, + { 0x8ce2, 0x8d24 },{ 0x8ce3, 0x5356 },{ 0x8ce4, 0x8d31 },{ 0x8ce6, 0x8d4b }, + { 0x8ce7, 0x8d55 },{ 0x8cea, 0x8d28 },{ 0x8cec, 0x8d26 },{ 0x8ced, 0x8d4c }, + { 0x8cf4, 0x8d56 },{ 0x8cf8, 0x5269 },{ 0x8cfa, 0x8d5a },{ 0x8cfb, 0x8d59 }, + { 0x8cfc, 0x8d2d },{ 0x8cfd, 0x8d5b },{ 0x8cfe, 0x8d5c },{ 0x8d04, 0x8d3d }, + { 0x8d05, 0x8d58 },{ 0x8d08, 0x8d60 },{ 0x8d0a, 0x8d5e },{ 0x8d0d, 0x8d61 }, + { 0x8d0f, 0x8d62 },{ 0x8d10, 0x8d46 },{ 0x8d13, 0x8d43 },{ 0x8d16, 0x8d4e }, + { 0x8d17, 0x8d5d },{ 0x8d1b, 0x8d63 },{ 0x8d95, 0x8d76 },{ 0x8d99, 0x8d75 }, + { 0x8da8, 0x8d8b },{ 0x8db2, 0x8db1 },{ 0x8de1, 0x8ff9 },{ 0x8dfc, 0x5c40 }, + { 0x8e10, 0x8df5 },{ 0x8e21, 0x8737 },{ 0x8e2b, 0x78b0 },{ 0x8e30, 0x903e }, + { 0x8e34, 0x8e0a },{ 0x8e4c, 0x8dc4 },{ 0x8e55, 0x8df8 },{ 0x8e5f, 0x8ff9 }, + { 0x8e60, 0x8dd6 },{ 0x8e63, 0x8e52 },{ 0x8e64, 0x8e2a },{ 0x8e67, 0x7cdf }, + { 0x8e7a, 0x8df7 },{ 0x8e89, 0x8db8 },{ 0x8e8a, 0x8e0c },{ 0x8e8b, 0x8dfb }, + { 0x8e8d, 0x8dc3 },{ 0x8e91, 0x8e2f },{ 0x8e92, 0x8dde },{ 0x8e93, 0x8e2c }, + { 0x8e95, 0x8e70 },{ 0x8e9a, 0x8df9 },{ 0x8ea1, 0x8e51 },{ 0x8ea5, 0x8e7f }, + { 0x8ea6, 0x8e9c },{ 0x8eaa, 0x8e8f },{ 0x8ec0, 0x8eaf },{ 0x8eca, 0x8f66 }, + { 0x8ecb, 0x8f67 },{ 0x8ecc, 0x8f68 },{ 0x8ecd, 0x519b },{ 0x8ed2, 0x8f69 }, + { 0x8ed4, 0x8f6b },{ 0x8edb, 0x8f6d },{ 0x8edf, 0x8f6f },{ 0x8eeb, 0x8f78 }, + { 0x8ef8, 0x8f74 },{ 0x8ef9, 0x8f75 },{ 0x8efa, 0x8f7a },{ 0x8efb, 0x8f72 }, + { 0x8efc, 0x8f76 },{ 0x8efe, 0x8f7c },{ 0x8f03, 0x8f83 },{ 0x8f05, 0x8f82 }, + { 0x8f07, 0x8f81 },{ 0x8f09, 0x8f7d },{ 0x8f0a, 0x8f7e },{ 0x8f12, 0x8f84 }, + { 0x8f13, 0x633d },{ 0x8f14, 0x8f85 },{ 0x8f15, 0x8f7b },{ 0x8f1b, 0x8f86 }, + { 0x8f1c, 0x8f8e },{ 0x8f1d, 0x8f89 },{ 0x8f1e, 0x8f8b },{ 0x8f1f, 0x8f8d }, + { 0x8f25, 0x8f8a },{ 0x8f26, 0x8f87 },{ 0x8f29, 0x8f88 },{ 0x8f2a, 0x8f6e }, + { 0x8f2f, 0x8f91 },{ 0x8f33, 0x8f8f },{ 0x8f38, 0x8f93 },{ 0x8f3b, 0x8f90 }, + { 0x8f3e, 0x8f97 },{ 0x8f3f, 0x8206 },{ 0x8f42, 0x6bc2 },{ 0x8f44, 0x8f96 }, + { 0x8f45, 0x8f95 },{ 0x8f46, 0x8f98 },{ 0x8f49, 0x8f6c },{ 0x8f4d, 0x8f99 }, + { 0x8f4e, 0x8f7f },{ 0x8f54, 0x8f9a },{ 0x8f5f, 0x8f70 },{ 0x8f61, 0x8f94 }, + { 0x8f62, 0x8f79 },{ 0x8f64, 0x8f73 },{ 0x8fa6, 0x529e },{ 0x8fad, 0x8f9e }, + { 0x8fae, 0x8fab },{ 0x8faf, 0x8fa9 },{ 0x8fb2, 0x519c },{ 0x8fc6, 0x8fe4 }, + { 0x8ff4, 0x56de },{ 0x8ffa, 0x4e43 },{ 0x9015, 0x8ff3 },{ 0x9019, 0x8fd9 }, + { 0x9023, 0x8fde },{ 0x9031, 0x5468 },{ 0x9032, 0x8fdb },{ 0x904a, 0x6e38 }, + { 0x904b, 0x8fd0 },{ 0x904e, 0x8fc7 },{ 0x9054, 0x8fbe },{ 0x9055, 0x8fdd }, + { 0x9059, 0x9065 },{ 0x905c, 0x900a },{ 0x905e, 0x9012 },{ 0x9060, 0x8fdc }, + { 0x9069, 0x9002 },{ 0x9072, 0x8fdf },{ 0x9077, 0x8fc1 },{ 0x9078, 0x9009 }, + { 0x907a, 0x9057 },{ 0x907c, 0x8fbd },{ 0x9081, 0x8fc8 },{ 0x9084, 0x8fd8 }, + { 0x9087, 0x8fe9 },{ 0x908a, 0x8fb9 },{ 0x908f, 0x903b },{ 0x9090, 0x9026 }, + { 0x90df, 0x90cf },{ 0x90f5, 0x90ae },{ 0x9106, 0x90d3 },{ 0x9109, 0x4e61 }, + { 0x9112, 0x90b9 },{ 0x9114, 0x90ac },{ 0x9116, 0x90e7 },{ 0x9127, 0x9093 }, + { 0x912d, 0x90d1 },{ 0x9130, 0x90bb },{ 0x9132, 0x90f8 },{ 0x9134, 0x90ba }, + { 0x9136, 0x90d0 },{ 0x913a, 0x909d },{ 0x9148, 0x90e6 },{ 0x9156, 0x9e29 }, + { 0x9183, 0x814c },{ 0x9186, 0x76cf },{ 0x919c, 0x4e11 },{ 0x919e, 0x915d }, + { 0x91ab, 0x533b },{ 0x91ac, 0x9171 },{ 0x91b1, 0x53d1 },{ 0x91bc, 0x5bb4 }, + { 0x91c0, 0x917f },{ 0x91c1, 0x8845 },{ 0x91c3, 0x917e },{ 0x91c5, 0x917d }, + { 0x91c6, 0x91c7 },{ 0x91cb, 0x91ca },{ 0x91d0, 0x5398 },{ 0x91d3, 0x9486 }, + { 0x91d4, 0x9487 },{ 0x91d5, 0x948c },{ 0x91d7, 0x948a },{ 0x91d8, 0x9489 }, + { 0x91d9, 0x948b },{ 0x91dd, 0x9488 },{ 0x91e3, 0x9493 },{ 0x91e4, 0x9490 }, + { 0x91e6, 0x6263 },{ 0x91e7, 0x948f },{ 0x91e9, 0x9492 },{ 0x91ec, 0x948e }, + { 0x91f5, 0x9497 },{ 0x91f7, 0x948d },{ 0x91f9, 0x9495 },{ 0x9200, 0x94af }, + { 0x9201, 0x94ab },{ 0x9204, 0x94ad },{ 0x9209, 0x94a0 },{ 0x920d, 0x949d }, + { 0x9210, 0x94a4 },{ 0x9211, 0x94a3 },{ 0x9214, 0x949e },{ 0x9215, 0x94ae }, + { 0x921e, 0x94a7 },{ 0x9223, 0x9499 },{ 0x9225, 0x94ac },{ 0x9226, 0x949b }, + { 0x9227, 0x94aa },{ 0x922e, 0x94cc },{ 0x9230, 0x94c8 },{ 0x9233, 0x94b6 }, + { 0x9234, 0x94c3 },{ 0x9237, 0x94b4 },{ 0x9238, 0x94b9 },{ 0x9239, 0x94cd }, + { 0x923a, 0x94b0 },{ 0x923d, 0x94b8 },{ 0x923e, 0x94c0 },{ 0x923f, 0x94bf }, + { 0x9240, 0x94be },{ 0x9245, 0x5de8 },{ 0x9246, 0x94bb },{ 0x9248, 0x94ca }, + { 0x9249, 0x94c9 },{ 0x924b, 0x5228 },{ 0x924d, 0x94cb },{ 0x9251, 0x94c2 }, + { 0x9257, 0x94b3 },{ 0x925a, 0x94c6 },{ 0x925b, 0x94c5 },{ 0x925e, 0x94ba }, + { 0x9264, 0x94a9 },{ 0x9266, 0x94b2 },{ 0x926c, 0x94bc },{ 0x926d, 0x94bd }, + { 0x9278, 0x94f0 },{ 0x927a, 0x94d2 },{ 0x927b, 0x94ec },{ 0x927f, 0x94ea }, + { 0x9280, 0x94f6 },{ 0x9283, 0x94f3 },{ 0x9285, 0x94dc },{ 0x9291, 0x94e3 }, + { 0x9293, 0x94e8 },{ 0x9296, 0x94e2 },{ 0x9298, 0x94ed },{ 0x929a, 0x94eb }, + { 0x929c, 0x8854 },{ 0x92a0, 0x94d1 },{ 0x92a3, 0x94f7 },{ 0x92a5, 0x94f1 }, + { 0x92a6, 0x94df },{ 0x92a8, 0x94f5 },{ 0x92a9, 0x94e5 },{ 0x92aa, 0x94d5 }, + { 0x92ab, 0x94ef },{ 0x92ac, 0x94d0 },{ 0x92b2, 0x710a },{ 0x92b3, 0x9510 }, + { 0x92b7, 0x9500 },{ 0x92b9, 0x9508 },{ 0x92bb, 0x9511 },{ 0x92bc, 0x9509 }, + { 0x92c1, 0x94dd },{ 0x92c3, 0x9512 },{ 0x92c5, 0x950c },{ 0x92c7, 0x94a1 }, + { 0x92cc, 0x94e4 },{ 0x92cf, 0x94d7 },{ 0x92d2, 0x950b },{ 0x92dd, 0x950a }, + { 0x92df, 0x9513 },{ 0x92e4, 0x9504 },{ 0x92e6, 0x9514 },{ 0x92e8, 0x9507 }, + { 0x92ea, 0x94fa },{ 0x92ee, 0x94d6 },{ 0x92ef, 0x9506 },{ 0x92f0, 0x9502 }, + { 0x92f1, 0x94fd },{ 0x92f8, 0x952f },{ 0x92fb, 0x9274 },{ 0x92fc, 0x94a2 }, + { 0x9301, 0x951e },{ 0x9304, 0x5f55 },{ 0x9306, 0x9516 },{ 0x9308, 0x9529 }, + { 0x9310, 0x9525 },{ 0x9312, 0x9515 },{ 0x9315, 0x951f },{ 0x9318, 0x9524 }, + { 0x9319, 0x9531 },{ 0x931a, 0x94ee },{ 0x931b, 0x951b },{ 0x931f, 0x952c }, + { 0x9320, 0x952d },{ 0x9322, 0x94b1 },{ 0x9326, 0x9526 },{ 0x9328, 0x951a }, + { 0x932b, 0x9521 },{ 0x932e, 0x9522 },{ 0x932f, 0x9519 },{ 0x9333, 0x9530 }, + { 0x9336, 0x8868 },{ 0x9338, 0x94fc },{ 0x9346, 0x9494 },{ 0x9347, 0x9534 }, + { 0x934a, 0x70bc },{ 0x934b, 0x9505 },{ 0x934d, 0x9540 },{ 0x9354, 0x9537 }, + { 0x9358, 0x94e1 },{ 0x935b, 0x953b },{ 0x9364, 0x9538 },{ 0x9365, 0x9532 }, + { 0x936c, 0x9539 },{ 0x9370, 0x953e },{ 0x9375, 0x952e },{ 0x9376, 0x9536 }, + { 0x937a, 0x9517 },{ 0x937c, 0x9488 },{ 0x937e, 0x949f },{ 0x9382, 0x9541 }, + { 0x938a, 0x9551 },{ 0x938c, 0x9570 },{ 0x9394, 0x7194 },{ 0x9396, 0x9501 }, + { 0x9397, 0x67aa },{ 0x9398, 0x9549 },{ 0x939a, 0x9524 },{ 0x93a2, 0x94a8 }, + { 0x93a3, 0x84e5 },{ 0x93a6, 0x954f },{ 0x93a7, 0x94e0 },{ 0x93a9, 0x94e9 }, + { 0x93aa, 0x953c },{ 0x93ac, 0x9550 },{ 0x93ae, 0x9547 },{ 0x93b0, 0x9552 }, + { 0x93b3, 0x954d },{ 0x93b5, 0x9553 },{ 0x93c3, 0x955e },{ 0x93c7, 0x955f }, + { 0x93c8, 0x94fe },{ 0x93cc, 0x9546 },{ 0x93cd, 0x9559 },{ 0x93d1, 0x955d }, + { 0x93d7, 0x94ff },{ 0x93d8, 0x9535 },{ 0x93dc, 0x9557 },{ 0x93dd, 0x9558 }, + { 0x93de, 0x955b },{ 0x93df, 0x94f2 },{ 0x93e1, 0x955c },{ 0x93e2, 0x9556 }, + { 0x93e4, 0x9542 },{ 0x93e8, 0x933e },{ 0x93f5, 0x94e7 },{ 0x93f7, 0x9564 }, + { 0x93f9, 0x956a },{ 0x93fd, 0x9508 },{ 0x9403, 0x94d9 },{ 0x9409, 0x94e3 }, + { 0x940b, 0x94f4 },{ 0x9410, 0x9563 },{ 0x9412, 0x94f9 },{ 0x9413, 0x9566 }, + { 0x9414, 0x9561 },{ 0x9418, 0x949f },{ 0x9419, 0x956b },{ 0x9420, 0x9568 }, + { 0x9428, 0x9544 },{ 0x942b, 0x954c },{ 0x942e, 0x9570 },{ 0x9432, 0x956f }, + { 0x9433, 0x956d },{ 0x9435, 0x94c1 },{ 0x9436, 0x73af },{ 0x9438, 0x94ce }, + { 0x943a, 0x94db },{ 0x943f, 0x9571 },{ 0x9444, 0x94f8 },{ 0x944a, 0x956c }, + { 0x944c, 0x9554 },{ 0x9451, 0x9274 },{ 0x9452, 0x9274 },{ 0x9460, 0x94c4 }, + { 0x9463, 0x9573 },{ 0x9464, 0x5228 },{ 0x946a, 0x7089 },{ 0x946d, 0x9567 }, + { 0x9470, 0x94a5 },{ 0x9472, 0x9576 },{ 0x9475, 0x7f50 },{ 0x9477, 0x954a }, + { 0x947c, 0x9523 },{ 0x947d, 0x94bb },{ 0x947e, 0x92ae },{ 0x947f, 0x51ff }, + { 0x9577, 0x957f },{ 0x9580, 0x95e8 },{ 0x9582, 0x95e9 },{ 0x9583, 0x95ea }, + { 0x9586, 0x95eb },{ 0x9589, 0x95ed },{ 0x958b, 0x5f00 },{ 0x958c, 0x95f6 }, + { 0x958e, 0x95f3 },{ 0x958f, 0x95f0 },{ 0x9591, 0x95f2 },{ 0x9592, 0x95f2 }, + { 0x9593, 0x95f4 },{ 0x9594, 0x95f5 },{ 0x9598, 0x95f8 },{ 0x95a1, 0x9602 }, + { 0x95a3, 0x9601 },{ 0x95a4, 0x5408 },{ 0x95a5, 0x9600 },{ 0x95a8, 0x95fa }, + { 0x95a9, 0x95fd },{ 0x95ab, 0x9603 },{ 0x95ac, 0x9606 },{ 0x95ad, 0x95fe }, + { 0x95b1, 0x9605 },{ 0x95b6, 0x960a },{ 0x95b9, 0x9609 },{ 0x95bb, 0x960e }, + { 0x95bc, 0x960f },{ 0x95bd, 0x960d },{ 0x95be, 0x9608 },{ 0x95bf, 0x960c }, + { 0x95c3, 0x9612 },{ 0x95c6, 0x677f },{ 0x95c7, 0x6697 },{ 0x95c8, 0x95f1 }, + { 0x95ca, 0x9614 },{ 0x95cb, 0x9615 },{ 0x95cc, 0x9611 },{ 0x95d0, 0x9617 }, + { 0x95d4, 0x9616 },{ 0x95d5, 0x9619 },{ 0x95d6, 0x95ef },{ 0x95dc, 0x5173 }, + { 0x95de, 0x961a },{ 0x95e1, 0x9610 },{ 0x95e2, 0x8f9f },{ 0x95e5, 0x95fc }, + { 0x9628, 0x5384 },{ 0x962c, 0x5751 },{ 0x962f, 0x5740 },{ 0x964f, 0x968b }, + { 0x9658, 0x9649 },{ 0x965d, 0x9655 },{ 0x965e, 0x5347 },{ 0x9663, 0x9635 }, + { 0x9670, 0x9634 },{ 0x9673, 0x9648 },{ 0x9678, 0x9646 },{ 0x967d, 0x9633 }, + { 0x9684, 0x5824 },{ 0x9689, 0x9667 },{ 0x968a, 0x961f },{ 0x968e, 0x9636 }, + { 0x9695, 0x9668 },{ 0x969b, 0x9645 },{ 0x96a4, 0x9893 },{ 0x96a8, 0x968f }, + { 0x96aa, 0x9669 },{ 0x96b1, 0x9690 },{ 0x96b4, 0x9647 },{ 0x96b8, 0x96b6 }, + { 0x96bb, 0x53ea },{ 0x96cb, 0x96bd },{ 0x96d6, 0x867d },{ 0x96d9, 0x53cc }, + { 0x96db, 0x96cf },{ 0x96dc, 0x6742 },{ 0x96de, 0x9e21 },{ 0x96e2, 0x79bb }, + { 0x96e3, 0x96be },{ 0x96f2, 0x4e91 },{ 0x96fb, 0x7535 },{ 0x9711, 0x6cbe }, + { 0x9724, 0x6e9c },{ 0x9727, 0x96fe },{ 0x973d, 0x9701 },{ 0x9742, 0x96f3 }, + { 0x9744, 0x972d },{ 0x9748, 0x7075 },{ 0x975a, 0x9753 },{ 0x975c, 0x9759 }, + { 0x9766, 0x817c },{ 0x9768, 0x9765 },{ 0x978f, 0x5de9 },{ 0x97a6, 0x79cb }, + { 0x97c1, 0x7f30 },{ 0x97c3, 0x9791 },{ 0x97c6, 0x5343 },{ 0x97c9, 0x97af }, + { 0x97cb, 0x97e6 },{ 0x97cc, 0x97e7 },{ 0x97d3, 0x97e9 },{ 0x97d9, 0x97ea }, + { 0x97dc, 0x97ec },{ 0x97de, 0x97eb },{ 0x97fb, 0x97f5 },{ 0x97ff, 0x54cd }, + { 0x9801, 0x9875 },{ 0x9802, 0x9876 },{ 0x9803, 0x9877 },{ 0x9805, 0x9879 }, + { 0x9806, 0x987a },{ 0x9807, 0x9878 },{ 0x9808, 0x987b },{ 0x980a, 0x987c }, + { 0x980c, 0x9882 },{ 0x980e, 0x9880 },{ 0x980f, 0x9883 },{ 0x9810, 0x9884 }, + { 0x9811, 0x987d },{ 0x9812, 0x9881 },{ 0x9813, 0x987f },{ 0x9817, 0x9887 }, + { 0x9818, 0x9886 },{ 0x981c, 0x988c },{ 0x9821, 0x9889 },{ 0x9824, 0x9890 }, + { 0x9826, 0x988f },{ 0x982b, 0x4fef },{ 0x982d, 0x5934 },{ 0x9830, 0x988a }, + { 0x9837, 0x9894 },{ 0x9838, 0x9888 },{ 0x9839, 0x9893 },{ 0x983b, 0x9891 }, + { 0x9846, 0x9897 },{ 0x984c, 0x9898 },{ 0x984d, 0x989d },{ 0x984e, 0x989a }, + { 0x984f, 0x989c },{ 0x9853, 0x989b },{ 0x9858, 0x613f },{ 0x9859, 0x98a1 }, + { 0x985b, 0x98a0 },{ 0x985e, 0x7c7b },{ 0x9862, 0x989f },{ 0x9865, 0x98a2 }, + { 0x9867, 0x987e },{ 0x986b, 0x98a4 },{ 0x986f, 0x663e },{ 0x9870, 0x98a6 }, + { 0x9871, 0x9885 },{ 0x9873, 0x989e },{ 0x9874, 0x98a7 },{ 0x98a8, 0x98ce }, + { 0x98ae, 0x98d1 },{ 0x98af, 0x98d2 },{ 0x98b1, 0x53f0 },{ 0x98b3, 0x522e }, + { 0x98b6, 0x98d3 },{ 0x98ba, 0x626c },{ 0x98bc, 0x98d5 },{ 0x98c4, 0x98d8 }, + { 0x98c6, 0x98d9 },{ 0x98db, 0x98de },{ 0x98e2, 0x9965 },{ 0x98e9, 0x9968 }, + { 0x98ea, 0x996a },{ 0x98eb, 0x996b },{ 0x98ed, 0x996c },{ 0x98ef, 0x996d }, + { 0x98f2, 0x996e },{ 0x98f4, 0x9974 },{ 0x98fc, 0x9972 },{ 0x98fd, 0x9971 }, + { 0x98fe, 0x9970 },{ 0x9903, 0x997a },{ 0x9905, 0x997c },{ 0x9908, 0x7ccd }, + { 0x9909, 0x9977 },{ 0x990a, 0x517b },{ 0x990c, 0x9975 },{ 0x9911, 0x997d }, + { 0x9912, 0x9981 },{ 0x9913, 0x997f },{ 0x9914, 0x54fa },{ 0x9918, 0x4f59 }, + { 0x991a, 0x80b4 },{ 0x991b, 0x9984 },{ 0x991e, 0x996f },{ 0x9921, 0x9985 }, + { 0x9928, 0x9986 },{ 0x992c, 0x7cca },{ 0x9931, 0x7cc7 },{ 0x9933, 0x9967 }, + { 0x9935, 0x5582 },{ 0x993c, 0x9969 },{ 0x993d, 0x9988 },{ 0x993e, 0x998f }, + { 0x993f, 0x998a },{ 0x9943, 0x998d },{ 0x9945, 0x9992 },{ 0x9948, 0x9990 }, + { 0x9949, 0x9991 },{ 0x994b, 0x9988 },{ 0x994c, 0x9994 },{ 0x9951, 0x9965 }, + { 0x9952, 0x9976 },{ 0x9957, 0x98e8 },{ 0x995c, 0x990d },{ 0x995e, 0x998b }, + { 0x995f, 0x9977 },{ 0x99ac, 0x9a6c },{ 0x99ad, 0x9a6d },{ 0x99ae, 0x51af }, + { 0x99b1, 0x9a6e },{ 0x99b3, 0x9a70 },{ 0x99b4, 0x9a6f },{ 0x99c1, 0x9a73 }, + { 0x99d0, 0x9a7b },{ 0x99d1, 0x9a7d },{ 0x99d2, 0x9a79 },{ 0x99d4, 0x9a75 }, + { 0x99d5, 0x9a7e },{ 0x99d8, 0x9a80 },{ 0x99d9, 0x9a78 },{ 0x99db, 0x9a76 }, + { 0x99dd, 0x9a7c },{ 0x99df, 0x9a77 },{ 0x99e2, 0x9a88 },{ 0x99ed, 0x9a87 }, + { 0x99ee, 0x9a73 },{ 0x99f1, 0x9a86 },{ 0x99ff, 0x9a8f },{ 0x9a01, 0x9a8b }, + { 0x9a03, 0x5446 },{ 0x9a05, 0x9a93 },{ 0x9a0d, 0x9a92 },{ 0x9a0e, 0x9a91 }, + { 0x9a0f, 0x9a90 },{ 0x9a16, 0x9a9b },{ 0x9a19, 0x9a97 },{ 0x9a23, 0x9b03 }, + { 0x9a2b, 0x9a9e },{ 0x9a2d, 0x9a98 },{ 0x9a2e, 0x9a9d },{ 0x9a30, 0x817e }, + { 0x9a36, 0x9a7a },{ 0x9a37, 0x9a9a },{ 0x9a38, 0x9a9f },{ 0x9a3e, 0x9aa1 }, + { 0x9a40, 0x84e6 },{ 0x9a41, 0x9a9c },{ 0x9a42, 0x9a96 },{ 0x9a43, 0x9aa0 }, + { 0x9a44, 0x9aa2 },{ 0x9a45, 0x9a71 },{ 0x9a4a, 0x9a85 },{ 0x9a4d, 0x9a81 }, + { 0x9a4f, 0x9aa3 },{ 0x9a55, 0x9a84 },{ 0x9a57, 0x9a8c },{ 0x9a5a, 0x60ca }, + { 0x9a5b, 0x9a7f },{ 0x9a5f, 0x9aa4 },{ 0x9a62, 0x9a74 },{ 0x9a64, 0x9aa7 }, + { 0x9a65, 0x9aa5 },{ 0x9a6a, 0x9a8a },{ 0x9aaf, 0x80ae },{ 0x9acf, 0x9ac5 }, + { 0x9ad2, 0x810f },{ 0x9ad4, 0x4f53 },{ 0x9ad5, 0x9acc },{ 0x9ad6, 0x9acb }, + { 0x9ae3, 0x4eff },{ 0x9aee, 0x53d1 },{ 0x9b06, 0x677e },{ 0x9b0d, 0x80e1 }, + { 0x9b1a, 0x987b },{ 0x9b22, 0x9b13 },{ 0x9b25, 0x6597 },{ 0x9b27, 0x95f9 }, + { 0x9b28, 0x54c4 },{ 0x9b29, 0x960b },{ 0x9b2e, 0x9604 },{ 0x9b31, 0x90c1 }, + { 0x9b4e, 0x9b49 },{ 0x9b58, 0x9b47 },{ 0x9b5a, 0x9c7c },{ 0x9b68, 0x8c5a }, + { 0x9b6f, 0x9c81 },{ 0x9b74, 0x9c82 },{ 0x9b77, 0x9c7f },{ 0x9b90, 0x9c90 }, + { 0x9b91, 0x9c8d },{ 0x9b92, 0x9c8b },{ 0x9b9a, 0x9c92 },{ 0x9b9e, 0x9c95 }, + { 0x9baa, 0x9c94 },{ 0x9bab, 0x9c9b },{ 0x9bad, 0x9c91 },{ 0x9bae, 0x9c9c }, + { 0x9bc0, 0x9ca7 },{ 0x9bc1, 0x9ca0 },{ 0x9bc7, 0x9ca9 },{ 0x9bc9, 0x9ca4 }, + { 0x9bca, 0x9ca8 },{ 0x9bd4, 0x9cbb },{ 0x9bd6, 0x9cad },{ 0x9bd7, 0x9c9e }, + { 0x9bdb, 0x9cb7 },{ 0x9be1, 0x9cb1 },{ 0x9be2, 0x9cb5 },{ 0x9be4, 0x9cb2 }, + { 0x9be7, 0x9cb3 },{ 0x9be8, 0x9cb8 },{ 0x9bea, 0x9cae },{ 0x9beb, 0x9cb0 }, + { 0x9bf0, 0x9c87 },{ 0x9bfd, 0x9cab },{ 0x9c08, 0x9cbd },{ 0x9c09, 0x9cc7 }, + { 0x9c0d, 0x9cc5 },{ 0x9c12, 0x9cc6 },{ 0x9c13, 0x9cc3 },{ 0x9c23, 0x9ca5 }, + { 0x9c25, 0x9ccf },{ 0x9c28, 0x9cce },{ 0x9c29, 0x9cd0 },{ 0x9c2d, 0x9ccd }, + { 0x9c31, 0x9ca2 },{ 0x9c32, 0x9ccc },{ 0x9c33, 0x9cd3 },{ 0x9c37, 0x9ca6 }, + { 0x9c39, 0x9ca3 },{ 0x9c3b, 0x9cd7 },{ 0x9c3e, 0x9cd4 },{ 0x9c48, 0x9cd5 }, + { 0x9c49, 0x9cd6 },{ 0x9c52, 0x9cdf },{ 0x9c54, 0x9cdd },{ 0x9c56, 0x9cdc }, + { 0x9c57, 0x9cde },{ 0x9c58, 0x9c9f },{ 0x9c5f, 0x9c8e },{ 0x9c67, 0x9ce2 }, + { 0x9c6d, 0x9c9a },{ 0x9c77, 0x9cc4 },{ 0x9c78, 0x9c88 },{ 0x9c7a, 0x9ca1 }, + { 0x9ce5, 0x9e1f },{ 0x9ce7, 0x51eb },{ 0x9ce9, 0x9e20 },{ 0x9cf3, 0x51e4 }, + { 0x9cf4, 0x9e23 },{ 0x9cf6, 0x9e22 },{ 0x9d06, 0x9e29 },{ 0x9d07, 0x9e28 }, + { 0x9d08, 0x96c1 },{ 0x9d09, 0x9e26 },{ 0x9d15, 0x9e35 },{ 0x9d1b, 0x9e33 }, + { 0x9d1d, 0x9e32 },{ 0x9d1f, 0x9e31 },{ 0x9d23, 0x9e2a },{ 0x9d26, 0x9e2f }, + { 0x9d28, 0x9e2d },{ 0x9d2f, 0x9e38 },{ 0x9d30, 0x9e39 },{ 0x9d3b, 0x9e3f }, + { 0x9d3f, 0x9e3d },{ 0x9d42, 0x9e3a },{ 0x9d51, 0x9e43 },{ 0x9d52, 0x9e46 }, + { 0x9d53, 0x9e41 },{ 0x9d5c, 0x9e48 },{ 0x9d5d, 0x9e45 },{ 0x9d60, 0x9e44 }, + { 0x9d61, 0x9e49 },{ 0x9d6a, 0x9e4c },{ 0x9d6c, 0x9e4f },{ 0x9d6f, 0x9e4e }, + { 0x9d70, 0x96d5 },{ 0x9d72, 0x9e4a },{ 0x9d87, 0x9e2b },{ 0x9d89, 0x9e51 }, + { 0x9d98, 0x9e55 },{ 0x9d9a, 0x9e57 },{ 0x9da9, 0x9e5c },{ 0x9daf, 0x83ba }, + { 0x9db1, 0x9a9e },{ 0x9db4, 0x9e64 },{ 0x9dbb, 0x9e58 },{ 0x9dbc, 0x9e63 }, + { 0x9dbf, 0x9e5a },{ 0x9dc2, 0x9e5e },{ 0x9dd3, 0x9e67 },{ 0x9dd7, 0x9e25 }, + { 0x9dd9, 0x9e37 },{ 0x9dda, 0x9e68 },{ 0x9de5, 0x9e36 },{ 0x9de6, 0x9e6a }, + { 0x9def, 0x9e69 },{ 0x9df0, 0x71d5 },{ 0x9df2, 0x9e6b },{ 0x9df3, 0x9e47 }, + { 0x9df4, 0x9e47 },{ 0x9df8, 0x9e6c },{ 0x9df9, 0x9e70 },{ 0x9dfa, 0x9e6d }, + { 0x9e15, 0x9e2c },{ 0x9e1a, 0x9e66 },{ 0x9e1b, 0x9e73 },{ 0x9e1d, 0x9e42 }, + { 0x9e1e, 0x9e3e },{ 0x9e75, 0x5364 },{ 0x9e79, 0x54b8 },{ 0x9e7a, 0x9e7e }, + { 0x9e7c, 0x7877 },{ 0x9e7d, 0x76d0 },{ 0x9e97, 0x4e3d },{ 0x9ea5, 0x9ea6 }, + { 0x9ea9, 0x9eb8 },{ 0x9eb5, 0x9762 },{ 0x9ebc, 0x4e48 },{ 0x9ec3, 0x9ec4 }, + { 0x9ecc, 0x9ec9 },{ 0x9ede, 0x70b9 },{ 0x9ee8, 0x515a },{ 0x9ef2, 0x9eea }, + { 0x9ef4, 0x9709 },{ 0x9ef7, 0x9ee9 },{ 0x9efd, 0x9efe },{ 0x9eff, 0x9f0b }, + { 0x9f07, 0x9ccc },{ 0x9f09, 0x9f0d },{ 0x9f15, 0x51ac },{ 0x9f34, 0x9f39 }, + { 0x9f4a, 0x9f50 },{ 0x9f4b, 0x658b },{ 0x9f4e, 0x8d4d },{ 0x9f4f, 0x9f51 }, + { 0x9f52, 0x9f7f },{ 0x9f54, 0x9f80 },{ 0x9f59, 0x9f85 },{ 0x9f5c, 0x9f87 }, + { 0x9f5f, 0x9f83 },{ 0x9f60, 0x9f86 },{ 0x9f61, 0x9f84 },{ 0x9f63, 0x51fa }, + { 0x9f66, 0x9f88 },{ 0x9f67, 0x556e },{ 0x9f6a, 0x9f8a },{ 0x9f6c, 0x9f89 }, + { 0x9f72, 0x9f8b },{ 0x9f76, 0x816d },{ 0x9f77, 0x9f8c },{ 0x9f8d, 0x9f99 }, + { 0x9f90, 0x5e9e },{ 0x9f94, 0x9f9a },{ 0x9f95, 0x9f9b },{ 0x9f9c, 0x9f9f }, + { 0x9fa2, 0x548c },{ 0xfa0c, 0x5140 },{ 0xfe30, 0x2236 },{ 0xfe31, 0xff5c }, + { 0xfe33, 0xff5c },{ 0xfe3f, 0x2227 },{ 0xfe40, 0x2228 },{ 0xfe50, 0xff0c }, + { 0xfe51, 0x3001 },{ 0xfe52, 0xff0e },{ 0xfe54, 0xff1b },{ 0xfe55, 0xff1a }, + { 0xfe56, 0xff1f },{ 0xfe57, 0xff01 },{ 0xfe59, 0xff08 },{ 0xfe5a, 0xff09 }, + { 0xfe5b, 0xff5b },{ 0xfe5c, 0xff5d },{ 0xfe5d, 0xff3b },{ 0xfe5e, 0xff3d }, + { 0xfe5f, 0xff03 },{ 0xfe60, 0xff06 },{ 0xfe61, 0xff0a },{ 0xfe62, 0xff0b }, + { 0xfe63, 0xff0d },{ 0xfe64, 0xff1c },{ 0xfe65, 0xff1e },{ 0xfe66, 0xff1d }, + { 0xfe69, 0xff04 },{ 0xfe6a, 0xff05 },{ 0xfe6b, 0xff20 },{ 0, 0} +}; + +#endif +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/frontend/Makefile.am b/ism/modules/frontend/Makefile.am new file mode 100644 index 0000000..885d6c4 --- /dev/null +++ b/ism/modules/frontend/Makefile.am @@ -0,0 +1,82 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/data \ + -I$(top_srcdir)/ism/utils \ + -I$(top_srcdir)/ism/extras/panel \ + -I$(top_srcdir)/idm/src \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" + +if SCIM_BUILD_FRONTEND_X11 +CONFIG_FRONTEND_X11_MODULE = x11.la +SUBDIRS = imdkit +endif + +if SCIM_BUILD_FRONTEND_SOCKET +CONFIG_FRONTEND_SOCKET_MODULE = socket.la +endif + +noinst_HEADERS = scim_x11_ic.h \ + scim_x11_frontend.h \ + scim_socket_frontend.h + +moduledir = @SCIM_MODULE_PATH@/$(SCIM_BINARY_VERSION)/FrontEnd + +module_LTLIBRARIES = $(CONFIG_FRONTEND_X11_MODULE) $(CONFIG_FRONTEND_SOCKET_MODULE) + +x11_la_SOURCES = scim_x11_frontend.cpp \ + scim_x11_ic.cpp + +x11_la_CFLAGS = @X_CFLAGS@ + +x11_la_CXXFLAGS = @X_CFLAGS@ + +x11_la_LDFLAGS = -avoid-version \ + -rpath $(moduledir) \ + -module \ + @LIBTOOL_EXPORT_OPTIONS@ \ + @X_LIBS@ \ + @LTLIBINTL@ + +x11_la_LIBADD = imdkit/libXimd.la \ + $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la \ + $(top_builddir)/ism/utils/libscim-x11utils@SCIM_EPOCH@.la + +socket_la_SOURCES = scim_socket_frontend.cpp + +socket_la_CXXFLAGS = @GTK2_CFLAGS@ + +socket_la_LDFLAGS = -avoid-version \ + -rpath $(moduledir) \ + -module \ + @LIBTOOL_EXPORT_OPTIONS@ + +socket_la_LIBADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la + diff --git a/ism/modules/frontend/imdkit/FrameMgr.c b/ism/modules/frontend/imdkit/FrameMgr.c new file mode 100755 index 0000000..9b49794 --- /dev/null +++ b/ism/modules/frontend/imdkit/FrameMgr.c @@ -0,0 +1,2466 @@ +/****************************************************************** +Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts, + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + Author: Hiroyuki Miyamoto Digital Equipment Corporation + miyamoto@jrd.dec.com + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include "FrameMgr.h" + +/* Convenient macro */ + +#define _UNIT(n) ((int)(n) & 0xFF) +#define _NUMBER(n) (((int)(n) >> 8) & 0xFF) + +/* For byte swapping */ + +#define Swap16(p, n) ((p)->byte_swap ? \ +(((n) << 8 & 0xFF00) | \ + ((n) >> 8 & 0xFF) \ +) : n) +#define Swap32(p, n) ((p)->byte_swap ? \ + (((n) << 24 & 0xFF000000) | \ + ((n) << 8 & 0xFF0000) | \ + ((n) >> 8 & 0xFF00) | \ + ((n) >> 24 & 0xFF) \ + ) : n) +#define Swap64(p, n) ((p)->byte_swap ? \ + (((n) << 56 & 0xFF00000000000000) | \ + ((n) << 40 & 0xFF000000000000) | \ + ((n) << 24 & 0xFF0000000000) | \ + ((n) << 8 & 0xFF00000000) | \ + ((n) >> 8 & 0xFF000000) | \ + ((n) >> 24 & 0xFF0000) | \ + ((n) >> 40 & 0xFF00) | \ + ((n) >> 56 & 0xFF) \ + ) : n) + +/* Type definition */ + +typedef struct _Iter *Iter; + +typedef struct _FrameInst *FrameInst; + +typedef union +{ + int num; /* For BARRAY */ + FrameInst fi; /* For POINTER */ + Iter iter; /* For ITER */ +} ExtraDataRec, *ExtraData; + +typedef struct _Chain +{ + ExtraDataRec d; + int frame_no; + struct _Chain *next; +} ChainRec, *Chain; + +typedef struct _ChainMgr +{ + Chain top; + Chain tail; +} ChainMgrRec, *ChainMgr; + +typedef struct _ChainIter +{ + Chain cur; +} ChainIterRec, *ChainIter; + +typedef struct _FrameIter +{ + Iter iter; + Bool counting; + unsigned int counter; + int end; + struct _FrameIter* next; +} FrameIterRec, *FrameIter; + +typedef struct _FrameInst +{ + XimFrame template; + ChainMgrRec cm; + int cur_no; +} FrameInstRec; + +typedef void (*IterStartWatchProc) (Iter it, void *client_data); + +typedef struct _Iter +{ + XimFrame template; + int max_count; + Bool allow_expansion; + ChainMgrRec cm; + int cur_no; + IterStartWatchProc start_watch_proc; + void *client_data; + Bool start_counter; +} IterRec; + +typedef struct _FrameMgr +{ + XimFrame frame; + FrameInst fi; + char *area; + int idx; + Bool byte_swap; + int total_size; + FrameIter iters; +} FrameMgrRec; + +typedef union +{ + int num; /* For BARRAY and PAD */ + struct + { /* For COUNTER_* */ + Iter iter; + Bool is_byte_len; + } counter; +} XimFrameTypeInfoRec, *XimFrameTypeInfo; + +/* Special values */ +#define NO_VALUE -1 +#define NO_VALID_FIELD -2 + +static FrameInst FrameInstInit(XimFrame frame); +static void FrameInstFree(FrameInst fi); +static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info); +static XimFrameType FrameInstPeekNextType(FrameInst fi, XimFrameTypeInfo info); +static FmStatus FrameInstSetSize(FrameInst fi, int num); +static FmStatus FrameInstSetIterCount(FrameInst fi, int num); +static int FrameInstGetTotalSize(FrameInst fi); +static void FrameInstReset(FrameInst fi); + +static Iter IterInit(XimFrame frame, int count); +static void IterFree(Iter it); +static int FrameInstGetSize(FrameInst fi); +static int IterGetSize(Iter it); +static XimFrameType IterGetNextType(Iter it, XimFrameTypeInfo info); +static XimFrameType IterPeekNextType(Iter it, XimFrameTypeInfo info); +static FmStatus IterSetSize(Iter it, int num); +static FmStatus IterSetIterCount(Iter it, int num); +static int IterGetTotalSize(Iter it); +static void IterReset(Iter it); +static Bool IterIsLoopEnd(Iter it, Bool* myself); +static void IterSetStartWatch(Iter it, IterStartWatchProc proc, void* client_data); +static void _IterStartWatch(Iter it, void* client_data); + +static ExtraData ChainMgrGetExtraData(ChainMgr cm, int frame_no); +static ExtraData ChainMgrSetData(ChainMgr cm, int frame_no, + ExtraDataRec data); +static Bool ChainIterGetNext(ChainIter ci, int* frame_no, ExtraData d); +static int _FrameInstIncrement(XimFrame frame, int count); +static int _FrameInstDecrement(XimFrame frame, int count); +static int _FrameInstGetItemSize(FrameInst fi, int cur_no); +static Bool FrameInstIsIterLoopEnd(FrameInst fi); + +static FrameIter _FrameMgrAppendIter(FrameMgr fm, Iter it, int end); +static FrameIter _FrameIterCounterIncr(FrameIter fitr, int i); +static void _FrameMgrRemoveIter(FrameMgr fm, FrameIter it); +static Bool _FrameMgrIsIterLoopEnd(FrameMgr fm); +static Bool _FrameMgrProcessPadding(FrameMgr fm, FmStatus* status); + +#define IterGetIterCount(it) ((it)->allow_expansion ? \ +NO_VALUE : (it)->max_count) + +#define IterFixIteration(it) ((it)->allow_expansion = False) + +#define IterSetStarter(it) ((it)->start_counter = True) + +#define ChainMgrInit(cm) (cm)->top = (cm)->tail = NULL +#define ChainMgrFree(cm) \ +{ \ + Chain tmp; \ + Chain cur = (cm)->top; \ + \ + while (cur) \ + { \ + tmp = cur->next; \ + Xfree (cur); \ + cur = tmp; \ + } \ +} + +#define ChainIterInit(ci, cm) \ +{ \ + (ci)->cur = (cm)->top; \ +} + +/* ChainIterFree has nothing to do. */ +#define ChainIterFree(ci) + +#define FrameInstIsEnd(fi) ((fi)->template[(fi)->cur_no].type == EOL) + +FrameMgr FrameMgrInit (XimFrame frame, char* area, Bool byte_swap) +{ + FrameMgr fm; + + fm = (FrameMgr) Xmalloc (sizeof (FrameMgrRec)); + + fm->frame = frame; + fm->fi = FrameInstInit (frame); + fm->area = (char *) area; + fm->idx = 0; + fm->byte_swap = byte_swap; + fm->total_size = NO_VALUE; + fm->iters = NULL; + + return fm; +} + +void FrameMgrInitWithData (FrameMgr fm, + XimFrame frame, + void * area, + Bool byte_swap) +{ + fm->frame = frame; + fm->fi = FrameInstInit (frame); + fm->area = (char *) area; + fm->idx = 0; + fm->byte_swap = byte_swap; + fm->total_size = NO_VALUE; +} + +void FrameMgrFree (FrameMgr fm) +{ + FrameIter p, cur; + + p = fm->iters; + cur = p; + + while (p) + { + p = p->next; + Xfree (cur); + cur = p; + } + /*endwhile*/ + + FrameInstFree (fm->fi); + Xfree (fm); +} + +FmStatus FrameMgrSetBuffer (FrameMgr fm, void* area) +{ + if (fm->area) + return FmBufExist; + fm->area = (char *) area; + return FmSuccess; +} + +FmStatus _FrameMgrPutToken (FrameMgr fm, void *data, int data_size) +{ + XimFrameType type; + XimFrameTypeInfoRec info; + + if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size) + return FmNoMoreData; + /*endif*/ + + type = FrameInstGetNextType(fm->fi, &info); + + if (type & COUNTER_MASK) + { + unsigned long input_length; + + if (info.counter.is_byte_len) + { + if ((input_length = IterGetTotalSize (info.counter.iter)) + == NO_VALUE) + { + return FmCannotCalc; + } + /*endif*/ + } + else + { + if ((input_length = IterGetIterCount (info.counter.iter)) + == NO_VALUE) + { + return FmCannotCalc; + } + /*endif*/ + } + /*endif*/ + switch (type) + { + case COUNTER_BIT8: + *(CARD8 *) (fm->area + fm->idx) = input_length; + fm->idx++; + break; + + case COUNTER_BIT16: + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, input_length); + fm->idx += 2; + break; + + case COUNTER_BIT32: + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, input_length); + fm->idx += 4; + break; + +#if defined(_NEED64BIT) + case COUNTER_BIT64: + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, input_length); + fm->idx += 8; + break; +#endif + default: + break; + } + /*endswitch*/ + _FrameMgrPutToken(fm, data, data_size); + return FmSuccess; + } + /*endif*/ + + switch (type) + { + case BIT8: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else + { + ; /* Should never be reached */ + } + /*endif*/ + fm->idx++; + return FmSuccess; + + case BIT16: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD16*)(fm->area + fm->idx) = Swap16 (fm, num); + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num); + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num); + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 2; + return FmSuccess; + + case BIT32: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 4; + return FmSuccess; + +#if defined(_NEED64BIT) + case BIT64: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 4; + return FmSuccess; +#endif + + case BARRAY: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + if (info.num > 0) + { + bcopy (*(char **) data, fm->area + fm->idx, info.num); + fm->idx += info.num; + } + /*endif*/ + return FmSuccess; + + case PADDING: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + return _FrameMgrPutToken(fm, data, data_size); + + case ITER: + return FmInvalidCall; + + case EOL: + return FmEOD; + default: + break; + } + /*endswitch*/ + return (FmStatus) NULL; /* Should never be reached */ +} + +FmStatus _FrameMgrGetToken (FrameMgr fm , void* data, int data_size) +{ + XimFrameType type; + static XimFrameTypeInfoRec info; /* memory */ + FrameIter fitr; + + if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size) + return FmNoMoreData; + /*endif*/ + + type = FrameInstGetNextType(fm->fi, &info); + + if (type & COUNTER_MASK) + { + int end=0; + FrameIter client_data; + + type &= ~COUNTER_MASK; + switch (type) + { + case BIT8: + end = *(CARD8 *) (fm->area + fm->idx); + break; + + case BIT16: + end = Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + break; + + case BIT32: + end = Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + break; + +#if defined(_NEED64BIT) + case BIT64: + end = Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + break; +#endif + default: + break; + } + /*endswitch*/ + + if ((client_data = _FrameMgrAppendIter (fm, info.counter.iter, end))) + { + IterSetStarter (info.counter.iter); + IterSetStartWatch (info.counter.iter, + _IterStartWatch, + (void *) client_data); + } + /*endif*/ + } + /*endif*/ + + type &= ~COUNTER_MASK; + switch (type) + { + case BIT8: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char*) data = *(CARD8 *) (fm->area + fm->idx); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = *(CARD8 *) (fm->area + fm->idx); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = *(CARD8 *) (fm->area + fm->idx); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = *(CARD8 *) (fm->area + fm->idx); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx++; + if ((fitr = _FrameIterCounterIncr (fm->iters, 1/*BIT8*/))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return FmSuccess; + + case BIT16: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 2; + if ((fitr = _FrameIterCounterIncr (fm->iters, 2/*BIT16*/))) + _FrameMgrRemoveIter(fm, fitr); + /*endif*/ + return FmSuccess; + + case BIT32: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 4; + if ((fitr = _FrameIterCounterIncr (fm->iters, 4/*BIT32*/))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return FmSuccess; + +#if defined(_NEED64BIT) + case BIT64: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 8; + if ((fitr = _FrameIterCounterIncr (fm->iters, 8/*BIT64*/))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return FmSuccess; +#endif + + case BARRAY: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + if (info.num > 0) + { + *(char **) data = fm->area + fm->idx; + + fm->idx += info.num; + if ((fitr = _FrameIterCounterIncr (fm->iters, info.num))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + } + else + { + *(char **) data = NULL; + } + /*endif*/ + return FmSuccess; + + case PADDING: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + if ((fitr = _FrameIterCounterIncr (fm->iters, info.num))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return _FrameMgrGetToken (fm, data, data_size); + + case ITER: + return FmInvalidCall; /* if comes here, it's a bug! */ + + case EOL: + return FmEOD; + default: + break; + } + /*endswitch*/ + return (FmStatus) NULL; /* Should never be reached */ +} + +FmStatus FrameMgrSetSize (FrameMgr fm, int barray_size) +{ + if (FrameInstSetSize (fm->fi, barray_size) == FmSuccess) + return FmSuccess; + /*endif*/ + return FmNoMoreData; +} + +FmStatus FrameMgrSetIterCount (FrameMgr fm, int count) +{ + if (FrameInstSetIterCount (fm->fi, count) == FmSuccess) + return FmSuccess; + /*endif*/ + return FmNoMoreData; +} + +FmStatus FrameMgrSetTotalSize (FrameMgr fm, int total_size) +{ + fm->total_size = total_size; + return FmSuccess; +} + +int FrameMgrGetTotalSize (FrameMgr fm) +{ + return FrameInstGetTotalSize (fm->fi); +} + +int FrameMgrGetSize (FrameMgr fm) +{ + register int ret_size; + + ret_size = FrameInstGetSize (fm->fi); + if (ret_size == NO_VALID_FIELD) + return NO_VALUE; + /*endif*/ + return ret_size; +} + +FmStatus FrameMgrSkipToken (FrameMgr fm, int skip_count) +{ + XimFrameType type; + XimFrameTypeInfoRec info; + register int i; + + if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size) + return FmNoMoreData; + /*endif*/ + for (i = 0; i < skip_count; i++) + { + type = FrameInstGetNextType (fm->fi, &info); + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + fm->idx++; + break; + + case BIT16: + fm->idx += 2; + break; + + case BIT32: + fm->idx += 4; + break; + + case BIT64: + fm->idx += 8; + break; + + case BARRAY: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + break; + + case PADDING: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + return FrameMgrSkipToken (fm, skip_count); + + case ITER: + return FmInvalidCall; + + case EOL: + return FmEOD; + default: + break; + } + /*endswitch*/ + } + /*endfor*/ + return FmSuccess; +} + +void FrameMgrReset (FrameMgr fm) +{ + fm->idx = 0; + FrameInstReset (fm->fi); +} + +Bool FrameMgrIsIterLoopEnd (FrameMgr fm, FmStatus* status) +{ + do + { + if (_FrameMgrIsIterLoopEnd (fm)) + return True; + /*endif*/ + } + while (_FrameMgrProcessPadding (fm, status)); + + return False; +} + + +/* Internal routines */ + +static Bool _FrameMgrIsIterLoopEnd (FrameMgr fm) +{ + return FrameInstIsIterLoopEnd (fm->fi); +} + +static Bool _FrameMgrProcessPadding (FrameMgr fm, FmStatus* status) +{ + XimFrameTypeInfoRec info; + XimFrameType next_type = FrameInstPeekNextType (fm->fi, &info); + FrameIter fitr; + + if (next_type == PADDING) + { + if (info.num == NO_VALUE) + { + *status = FmInvalidCall; + return True; + } + /*endif*/ + next_type = FrameInstGetNextType (fm->fi, &info); + fm->idx += info.num; + if ((fitr = _FrameIterCounterIncr (fm->iters, info.num))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + *status = FmSuccess; + return True; + } + /*endif*/ + *status = FmSuccess; + return False; +} + +static FrameInst FrameInstInit (XimFrame frame) +{ + FrameInst fi; + + fi = (FrameInst) Xmalloc (sizeof (FrameInstRec)); + + fi->template = frame; + fi->cur_no = 0; + ChainMgrInit (&fi->cm); + return fi; +} + +static void FrameInstFree (FrameInst fi) +{ + ChainIterRec ci; + int frame_no; + ExtraDataRec d; + + ChainIterInit (&ci, &fi->cm); + + while (ChainIterGetNext (&ci, &frame_no, &d)) + { + register XimFrameType type; + type = fi->template[frame_no].type; + if (type == ITER) + { + if (d.iter) + IterFree (d.iter); + /*endif*/ + } + else if (type == POINTER) + { + if (d.fi) + FrameInstFree (d.fi); + /*endif*/ + } + /*endif*/ + } + /*endwhile*/ + ChainIterFree (&ci); + ChainMgrFree (&fi->cm); + Xfree (fi); +} + +static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info) +{ + XimFrameType ret_type; + + ret_type = fi->template[fi->cur_no].type; + + switch (ret_type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case EOL: + fi->cur_no = _FrameInstIncrement(fi->template, fi->cur_no); + break; + + case COUNTER_BIT8: + case COUNTER_BIT16: + case COUNTER_BIT32: + case COUNTER_BIT64: + if (info) + { + register int offset, iter_idx; + + info->counter.is_byte_len = + (((long) fi->template[fi->cur_no].data & 0xFF)) == FmCounterByte; + offset = ((long) fi->template[fi->cur_no].data) >> 8; + iter_idx = fi->cur_no + offset; + if (fi->template[iter_idx].type == ITER) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL) + { + dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, iter_idx, dr); + } + /*endif*/ + info->counter.iter = d->iter; + } + else + { + /* Should never reach here */ + } + /*endif*/ + } + /*endif*/ + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + break; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + break; + + case PADDING: + if (info) + { + register int unit; + register int number; + register int size; + register int i; + + unit = _UNIT ((long) fi->template[fi->cur_no].data); + number = _NUMBER ((long) fi->template[fi->cur_no].data); + + i = fi->cur_no; + size = 0; + while (number > 0) + { + i = _FrameInstDecrement (fi->template, i); + size += _FrameInstGetItemSize (fi, i); + number--; + } + /*endwhile*/ + info->num = (unit - (size%unit))%unit; + } + /*endif*/ + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + break; + + case ITER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = IterGetNextType (d->iter, info); + if (sub_type == EOL) + { + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + ret_type = FrameInstGetNextType (fi, info); + } + else + { + ret_type = sub_type; + } + /*endif*/ + } + break; + + case POINTER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = FrameInstGetNextType (d->fi, info); + if (sub_type == EOL) + { + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + ret_type = FrameInstGetNextType (fi, info); + } + else + { + ret_type = sub_type; + } + /*endif*/ + } + break; + default: + break; + } + /*endswitch*/ + return ret_type; +} + +static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info) +{ + XimFrameType ret_type; + + ret_type = fi->template[fi->cur_no].type; + + switch (ret_type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case EOL: + break; + + case COUNTER_BIT8: + case COUNTER_BIT16: + case COUNTER_BIT32: + case COUNTER_BIT64: + if (info) + { + register int offset; + register int iter_idx; + + info->counter.is_byte_len = + (((long) fi->template[fi->cur_no].data) & 0xFF) == FmCounterByte; + offset = ((long)fi->template[fi->cur_no].data) >> 8; + iter_idx = fi->cur_no + offset; + if (fi->template[iter_idx].type == ITER) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL) + { + dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, iter_idx, dr); + } + /*endif*/ + info->counter.iter = d->iter; + } + else + { + /* Should not be reached here */ + } + /*endif*/ + } + /*endif*/ + break; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + break; + + case PADDING: + if (info) + { + register int unit; + register int number; + register int size; + register int i; + + unit = _UNIT ((long) fi->template[fi->cur_no].data); + number = _NUMBER ((long) fi->template[fi->cur_no].data); + + i = fi->cur_no; + size = 0; + while (number > 0) + { + i = _FrameInstDecrement (fi->template, i); + size += _FrameInstGetItemSize (fi, i); + number--; + } + /*endwhile*/ + info->num = (unit - (size%unit))%unit; + } + /*endif*/ + break; + + case ITER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = IterPeekNextType (d->iter, info); + if (sub_type == EOL) + ret_type = FrameInstPeekNextType (fi, info); + else + ret_type = sub_type; + /*endif*/ + } + break; + + case POINTER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = FrameInstPeekNextType (d->fi, info); + if (sub_type == EOL) + ret_type = FrameInstPeekNextType (fi, info); + else + ret_type = sub_type; + /*endif*/ + default: + break; + } + break; + } + /*endswitch*/ + return ret_type; +} + +static Bool FrameInstIsIterLoopEnd (FrameInst fi) +{ + Bool ret = False; + + if (fi->template[fi->cur_no].type == ITER) + { + ExtraData d = ChainMgrGetExtraData (&fi->cm, fi->cur_no); + Bool yourself; + + if (d) + { + ret = IterIsLoopEnd (d->iter, &yourself); + if (ret && yourself) + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + /*endif*/ + } + /*endif*/ + } + /*endif*/ + return (ret); +} + +static FrameIter _FrameMgrAppendIter (FrameMgr fm, Iter it, int end) +{ + FrameIter p = fm->iters; + + while (p && p->next) + p = p->next; + /*endwhile*/ + + if (!p) + { + fm->iters = + p = (FrameIter) Xmalloc (sizeof (FrameIterRec)); + } + else + { + p->next = (FrameIter) Xmalloc (sizeof (FrameIterRec)); + p = p->next; + } + /*endif*/ + if (p) + { + p->iter = it; + p->counting = False; + p->counter = 0; + p->end = end; + p->next = NULL; + } + /*endif*/ + return (p); +} + +static void _FrameMgrRemoveIter (FrameMgr fm, FrameIter it) +{ + FrameIter prev; + FrameIter p; + + prev = NULL; + p = fm->iters; + while (p) + { + if (p == it) + { + if (prev) + prev->next = p->next; + else + fm->iters = p->next; + /*endif*/ + Xfree (p); + break; + } + /*endif*/ + prev = p; + p = p->next; + } + /*endwhile*/ +} + +static FrameIter _FrameIterCounterIncr (FrameIter fitr, int i) +{ + FrameIter p = fitr; + + while (p) + { + if (p->counting) + { + p->counter += i; + if (p->counter >= p->end) + { + IterFixIteration (p->iter); + return (p); + } + /*endif*/ + } + /*endif*/ + p = p->next; + } + /*endwhile*/ + return (NULL); +} + +static void _IterStartWatch (Iter it, void *client_data) +{ + FrameIter p = (FrameIter) client_data; + p->counting = True; +} + +static FmStatus FrameInstSetSize (FrameInst fi, int num) +{ + ExtraData d; + ExtraDataRec dr; + XimFrameType type; + register int i; + + i = 0; + while ((type = fi->template[i].type) != EOL) + { + switch (type) + { + case BARRAY: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.num = -1; + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + if (d->num == NO_VALUE) + { + d->num = num; + return FmSuccess; + } + /*endif*/ + break; + case ITER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.iter = IterInit (&fi->template[i + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + if (IterSetSize (d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + + case POINTER: + if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) + { + dr.fi = FrameInstInit(fi->template[i + 1].data); + d = ChainMgrSetData(&fi->cm, i, dr); + } + /*endif*/ + if (FrameInstSetSize(d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + default: + break; + } + /*endswitch*/ + i = _FrameInstIncrement(fi->template, i); + } + /*endwhile*/ + return FmNoMoreData; +} + +static int FrameInstGetSize (FrameInst fi) +{ + XimFrameType type; + register int i; + ExtraData d; + ExtraDataRec dr; + int ret_size; + + i = fi->cur_no; + while ((type = fi->template[i].type) != EOL) + { + switch (type) + { + case BARRAY: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + return NO_VALUE; + /*endif*/ + return d->num; + + case ITER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.iter = IterInit (&fi->template[i + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + ret_size = IterGetSize(d->iter); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + break; + + case POINTER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.fi = FrameInstInit (fi->template[i + 1].data); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + ret_size = FrameInstGetSize (d->fi); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + break; + default: + break; + } + /*endswitch*/ + i = _FrameInstIncrement (fi->template, i); + } + /*endwhile*/ + return NO_VALID_FIELD; +} + +static FmStatus FrameInstSetIterCount (FrameInst fi, int num) +{ + ExtraData d; + ExtraDataRec dr; + register int i; + XimFrameType type; + + i = 0; + while ((type = fi->template[i].type) != EOL) + { + switch (type) + { + case ITER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.iter = IterInit (&fi->template[i + 1], num); + (void)ChainMgrSetData (&fi->cm, i, dr); + return FmSuccess; + } + /*endif*/ + if (IterSetIterCount (d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + + case POINTER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.fi = FrameInstInit (fi->template[i + 1].data); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + if (FrameInstSetIterCount (d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + + default: + break; + } + /*endswitch*/ + i = _FrameInstIncrement (fi->template, i); + } + /*endwhile*/ + return FmNoMoreData; +} + +static int FrameInstGetTotalSize (FrameInst fi) +{ + register int size; + register int i; + + size = 0; + i = 0; + + while (fi->template[i].type != EOL) + { + size += _FrameInstGetItemSize (fi, i); + i = _FrameInstIncrement (fi->template, i); + } + /*endwhile*/ + return size; +} + +static void FrameInstReset (FrameInst fi) +{ + ChainIterRec ci; + int frame_no; + ExtraDataRec d; + + ChainIterInit (&ci, &fi->cm); + + while (ChainIterGetNext (&ci, &frame_no, &d)) + { + register XimFrameType type; + type = fi->template[frame_no].type; + if (type == ITER) + { + if (d.iter) + IterReset (d.iter); + /*endif*/ + } + else if (type == POINTER) + { + if (d.fi) + FrameInstReset (d.fi); + /*endif*/ + } + /*endif*/ + } + /*endwhile*/ + ChainIterFree (&ci); + + fi->cur_no = 0; +} + +static Iter IterInit (XimFrame frame, int count) +{ + Iter it; + register XimFrameType type; + + it = (Iter) Xmalloc (sizeof (IterRec)); + it->template = frame; + it->max_count = (count == NO_VALUE) ? 0 : count; + it->allow_expansion = (count == NO_VALUE); + it->cur_no = 0; + it->start_watch_proc = NULL; + it->client_data = NULL; + it->start_counter = False; + + type = frame->type; + if (type & COUNTER_MASK) + { + /* COUNTER_XXX cannot be an item of a ITER */ + Xfree (it); + return NULL; + } + /*endif*/ + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + /* Do nothing */ + break; + + case BARRAY: + case ITER: + case POINTER: + ChainMgrInit (&it->cm); + break; + + default: + Xfree (it); + return NULL; /* This should never occur */ + } + /*endswitch*/ + return it; +} + +static void IterFree (Iter it) +{ + switch (it->template->type) + { + case BARRAY: + ChainMgrFree (&it->cm); + break; + + case ITER: + { + ChainIterRec ci; + int count; + ExtraDataRec d; + + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &d)) + IterFree (d.iter); + /*endwhile*/ + ChainIterFree (&ci); + ChainMgrFree (&it->cm); + } + break; + + case POINTER: + { + ChainIterRec ci; + int count; + ExtraDataRec dr; + + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &dr)) + FrameInstFree (dr.fi); + /*endwhile*/ + ChainIterFree (&ci); + ChainMgrFree (&it->cm); + } + break; + + default: + break; + } + /*endswitch*/ + Xfree (it); +} + +static Bool IterIsLoopEnd (Iter it, Bool *myself) +{ + Bool ret = False; + *myself = False; + + if (!it->allow_expansion && (it->cur_no == it->max_count)) + { + *myself = True; + return True; + } + /*endif*/ + + if (it->template->type == POINTER) + { + ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no); + if (d) + { + if (FrameInstIsIterLoopEnd (d->fi)) + { + ret = True; + } + else + { + if (FrameInstIsEnd (d->fi)) + { + it->cur_no++; + if (!it->allow_expansion && it->cur_no == it->max_count) + { + *myself = True; + ret = True; + } + /*endif*/ + } + /*endif*/ + } + /*endif*/ + } + /*endif*/ + } + else if (it->template->type == ITER) + { + ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no); + if (d) + { + Bool yourself; + + if (IterIsLoopEnd (d->iter, &yourself)) + ret = True; + /*endif*/ + } + /*endif*/ + } + /*endif*/ + + return ret; +} + +static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info) +{ + XimFrameType type = it->template->type; + + if (it->start_counter) + { + (*it->start_watch_proc) (it, it->client_data); + it->start_counter = False; + } + /*endif*/ + if (it->cur_no >= it->max_count) + { + if (it->allow_expansion) + it->max_count = it->cur_no + 1; + else + return EOL; + /*endif*/ + } + /*endif*/ + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + it->cur_no++; + return type; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + it->cur_no++; + return BARRAY; + + case ITER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = IterGetNextType (d->iter, info); + if (ret_type == EOL) + { + it->cur_no++; + ret_type = IterGetNextType (it, info); + } + /*endif*/ + return ret_type; + } + + case POINTER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = FrameInstGetNextType (d->fi, info); + if (ret_type == EOL) + { + it->cur_no++; + ret_type = IterGetNextType (it, info); + } + /*endif*/ + return ret_type; + } + + default: + return (XimFrameType) NULL; + } + /*endswitch*/ + return (XimFrameType) NULL; /* This should never occur */ +} + +static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info) +{ + XimFrameType type = it->template->type; + + if (!it->allow_expansion && it->cur_no >= it->max_count) + return (EOL); + /*endif*/ + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + return type; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + return BARRAY; + + case ITER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = IterPeekNextType (d->iter, info); + if (ret_type == EOL) + ret_type = IterPeekNextType (it, info); + /*endif*/ + return ret_type; + } + + case POINTER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = FrameInstPeekNextType (d->fi, info); + if (ret_type == EOL) + ret_type = IterPeekNextType (it, info); + /*endif*/ + return (ret_type); + } + + default: + break; + } + /*endswitch*/ + /* Reaching here is a bug! */ + return (XimFrameType) NULL; +} + +static FmStatus IterSetSize (Iter it, int num) +{ + XimFrameType type; + register int i; + + if (!it->allow_expansion && it->max_count == 0) + return FmNoMoreData; + /*endif*/ + + type = it->template->type; + switch (type) + { + case BARRAY: + { + ExtraData d; + ExtraDataRec dr; + + for (i = 0; i < it->max_count; i++) + { + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.num = NO_VALUE; + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (d->num == NO_VALUE) + { + d->num = num; + return FmSuccess; + } + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.num = num; + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + return FmSuccess; + } + /*endif*/ + } + return FmNoMoreData; + + case ITER: + { + ExtraData d; + ExtraDataRec dr; + + for (i = 0; i < it->max_count; i++) + { + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (IterSetSize (d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.iter = IterInit (it->template + 1, NO_VALUE); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + if (IterSetSize(dr.iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endif*/ + } + return FmNoMoreData; + + case POINTER: + { + ExtraData d; + ExtraDataRec dr; + + for (i = 0; i < it->max_count; i++) + { + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (FrameInstSetSize (d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.fi = FrameInstInit (it->template[1].data); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + if (FrameInstSetSize (dr.fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endif*/ + } + return FmNoMoreData; + + default: + break; + } + /*endswitch*/ + return FmNoMoreData; +} + +static int IterGetSize (Iter it) +{ + register int i; + ExtraData d; + ExtraDataRec dr; + + if (it->cur_no >= it->max_count) + return NO_VALID_FIELD; + /*endif*/ + + switch (it->template->type) + { + case BARRAY: + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + return d->num; + + case ITER: + for (i = it->cur_no; i < it->max_count; i++) + { + int ret_size; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + ret_size = IterGetSize (d->iter); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + } + /*endfor*/ + return NO_VALID_FIELD; + + case POINTER: + for (i = it->cur_no; i < it->max_count; i++) + { + int ret_size; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + ret_size = FrameInstGetSize (d->fi); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + } + /*endfor*/ + return NO_VALID_FIELD; + + default: + break; + } + /*endswitch*/ + return NO_VALID_FIELD; +} + +static FmStatus IterSetIterCount (Iter it, int num) +{ + register int i; + + if (it->allow_expansion) + { + it->max_count = num; + it->allow_expansion = False; + return FmSuccess; + } + /*endif*/ + + if (it->max_count == 0) + return FmNoMoreData; + /*endif*/ + + switch (it->template->type) + { + case ITER: + for (i = 0; i < it->max_count; i++) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) + { + dr.iter = IterInit(it->template + 1, num); + (void)ChainMgrSetData(&it->cm, i, dr); + return FmSuccess; + } + /*endif*/ + if (IterSetIterCount(d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.iter = IterInit (it->template + 1, num); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + return FmSuccess; + } + /*endif*/ + break; + + case POINTER: + for (i = 0; i < it->max_count; i++) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (FrameInstSetIterCount (d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.fi = FrameInstInit (it->template[1].data); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + if (FrameInstSetIterCount (dr.fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endif*/ + break; + + default: + break; + } + /*endswitch*/ + return FmNoMoreData; +} + +static int IterGetTotalSize (Iter it) +{ + register int size, i; + XimFrameType type; + + if (it->allow_expansion) + return NO_VALUE; + /*endif*/ + if (it->max_count == 0) + return 0; + /*endif*/ + + size = 0; + type = it->template->type; + + switch (type) + { + case BIT8: + size = it->max_count; + break; + + case BIT16: + size = it->max_count*2; + break; + + case BIT32: + size = it->max_count*4; + break; + + case BIT64: + size = it->max_count*8; + break; + + case BARRAY: + for (i = 0; i < it->max_count; i++) + { + register int num; + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + return NO_VALUE; + /*endif*/ + if ((num = d->num) == NO_VALUE) + return NO_VALUE; + /*endif*/ + size += num; + } + /*endfor*/ + break; + + case ITER: + for (i = 0; i < it->max_count; i++) + { + register int num; + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + return NO_VALUE; + /*endif*/ + if ((num = IterGetTotalSize (d->iter)) == NO_VALUE) + return NO_VALUE; + /*endif*/ + size += num; + } + /*endfor*/ + break; + + case POINTER: + for (i = 0; i < it->max_count; i++) + { + register int num; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if ((num = FrameInstGetTotalSize (d->fi)) == NO_VALUE) + return NO_VALUE; + /*endif*/ + size += num; + } + /*endfor*/ + break; + + default: + break; + } + /*endswitch*/ + return size; +} + +static void IterReset (Iter it) +{ + ChainIterRec ci; + int count; + ExtraDataRec d; + + switch (it->template->type) + { + case ITER: + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &d)) + IterReset (d.iter); + /*endwhile*/ + ChainIterFree (&ci); + break; + + case POINTER: + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &d)) + FrameInstReset (d.fi); + /*endwhile*/ + ChainIterFree (&ci); + break; + + default: + break; + } + /*endswitch*/ + it->cur_no = 0; +} + +static void IterSetStartWatch (Iter it, + IterStartWatchProc proc, + void *client_data) +{ + it->start_watch_proc = proc; + it->client_data = client_data; +} + +static ExtraData ChainMgrSetData (ChainMgr cm, + int frame_no, + ExtraDataRec data) +{ + Chain cur = (Chain) Xmalloc (sizeof (ChainRec)); + + cur->frame_no = frame_no; + cur->d = data; + cur->next = NULL; + + if (cm->top == NULL) + { + cm->top = cm->tail = cur; + } + else + { + cm->tail->next = cur; + cm->tail = cur; + } + /*endif*/ + return &cur->d; +} + +static ExtraData ChainMgrGetExtraData (ChainMgr cm, int frame_no) +{ + Chain cur; + + cur = cm->top; + + while (cur) + { + if (cur->frame_no == frame_no) + return &cur->d; + /*endif*/ + cur = cur->next; + } + /*endwhile*/ + return NULL; +} + +static Bool ChainIterGetNext (ChainIter ci, int *frame_no, ExtraData d) +{ + if (ci->cur == NULL) + return False; + /*endif*/ + + *frame_no = ci->cur->frame_no; + *d = ci->cur->d; + + ci->cur = ci->cur->next; + + return True; +} + +static int _FrameInstIncrement (XimFrame frame, int count) +{ + XimFrameType type; + + type = frame[count].type; + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case BARRAY: + case PADDING: + return count + 1; + + case POINTER: + return count + 2; + + case ITER: + return _FrameInstIncrement (frame, count + 1); + default: + break; + } + /*endswitch*/ + return - 1; /* Error */ +} + +static int _FrameInstDecrement (XimFrame frame, int count) +{ + register int i; + XimFrameType type; + + if (count == 0) + return - 1; /* cannot decrement */ + /*endif*/ + + if (count == 1) + return 0; /* BOGUS - It should check the contents of data */ + /*endif*/ + + type = frame[count - 2].type; + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case BARRAY: + case PADDING: + case PTR_ITEM: + return count - 1; + + case POINTER: + case ITER: + i = count - 3; + while (i >= 0) + { + if (frame[i].type != ITER) + return i + 1; + /*endif*/ + i--; + } + /*endwhile*/ + return 0; + default: + break; + } + /*enswitch*/ + return - 1; /* Error */ +} + +static int _FrameInstGetItemSize (FrameInst fi, int cur_no) +{ + XimFrameType type; + + type = fi->template[cur_no].type; + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + return 1; + + case BIT16: + return 2; + + case BIT32: + return 4; + + case BIT64: + return 8; + + case BARRAY: + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + if (d->num == NO_VALUE) + return NO_VALUE; + /*endif*/ + return d->num; + } + + case PADDING: + { + register int unit; + register int number; + register int size; + register int i; + + unit = _UNIT ((long) fi->template[cur_no].data); + number = _NUMBER ((long) fi->template[cur_no].data); + + i = cur_no; + size = 0; + while (number > 0) + { + i = _FrameInstDecrement (fi->template, i); + size += _FrameInstGetItemSize (fi, i); + number--; + } + /*endwhile*/ + size = (unit - (size%unit))%unit; + return size; + } + + case ITER: + { + ExtraData d; + int sub_size; + + if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + sub_size = IterGetTotalSize (d->iter); + if (sub_size == NO_VALUE) + return NO_VALUE; + /*endif*/ + return sub_size; + } + + case POINTER: + { + ExtraData d; + int sub_size; + + if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + sub_size = FrameInstGetTotalSize (d->fi); + if (sub_size == NO_VALUE) + return NO_VALUE; + /*endif*/ + return sub_size; + } + + default: + break; + } + /*endswitch*/ + return NO_VALUE; +} diff --git a/ism/modules/frontend/imdkit/FrameMgr.h b/ism/modules/frontend/imdkit/FrameMgr.h new file mode 100644 index 0000000..ce7ed50 --- /dev/null +++ b/ism/modules/frontend/imdkit/FrameMgr.h @@ -0,0 +1,131 @@ +/****************************************************************** +Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts, + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + Author: Hiroyuki Miyamoto Digital Equipment Corporation + miyamoto@jrd.dec.com + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef FRAMEMGR_H +#define FRAMEMGR_H + +#include +#include +#include + +#if defined(VAXC) && !defined(__DECC) +#define xim_externalref globalref +#define xim_externaldef globaldef +#else +#define xim_externalref extern +#define xim_externaldef +#endif + +/* Definitions for FrameMgr */ + +#define COUNTER_MASK 0x10 + +typedef enum +{ + BIT8 = 0x1, /* {CARD8* | INT8*} */ + BIT16 = 0x2, /* {CARD16* | INT16*} */ + BIT32 = 0x3, /* {CARD32* | INT32*} */ + BIT64 = 0x4, /* {CARD64* | INT64*} */ + BARRAY = 0x5, /* int*, void* */ + ITER = 0x6, /* int* */ + POINTER = 0x7, /* specifies next item is a PTR_ITEM */ + PTR_ITEM = 0x8, /* specifies the item has a pointer */ + /* BOGUS - POINTER and PTR_ITEM + * In the current implementation, PTR_ITEM should be lead by + * POINTER. But actually, it's just redundant logically. Someone + * may remove this redundancy and POINTER from the enum member but he + * should also modify the logic in FrameMgr program. + */ + PADDING = 0x9, /* specifies that a padding is needed. + * This requires extra data in data field. + */ + EOL = 0xA, /* specifies the end of list */ + + COUNTER_BIT8 = COUNTER_MASK | 0x1, + COUNTER_BIT16 = COUNTER_MASK | 0x2, + COUNTER_BIT32 = COUNTER_MASK | 0x3, + COUNTER_BIT64 = COUNTER_MASK | 0x4 +} XimFrameType; + +/* Convenient macro */ +#define _FRAME(a) {a, NULL} +#define _PTR(p) {PTR_ITEM, (void *)p} +/* PADDING's usage of data field + * B15-B8 : Shows the number of effective items. + * B7-B0 : Shows padding unit. ex) 04 shows 4 unit padding. + */ +#define _PAD2(n) {PADDING, (void*)((n)<<8|2)} +#define _PAD4(n) {PADDING, (void*)((n)<<8|4)} + +#define FmCounterByte 0 +#define FmCounterNumber 1 + +#define _BYTE_COUNTER(type, offset) \ + {(COUNTER_MASK|type), (void*)((offset)<<8|FmCounterByte)} + +#define _NUMBER_COUNTER(type, offset) \ + {(COUNTER_MASK|type), (void*)((offset)<<8|FmCounterNumber)} + +typedef struct _XimFrame +{ + XimFrameType type; + void* data; /* For PTR_ITEM and PADDING */ +} XimFrameRec, *XimFrame; + +typedef enum +{ + FmSuccess, + FmEOD, + FmInvalidCall, + FmBufExist, + FmCannotCalc, + FmNoMoreData +} FmStatus; + +typedef struct _FrameMgr *FrameMgr; + +FrameMgr FrameMgrInit(XimFrame frame, char* area, Bool byte_swap); +void FrameMgrInitWithData(FrameMgr fm, XimFrame frame, void* area, + Bool byte_swap); +void FrameMgrFree(FrameMgr fm); +FmStatus FrameMgrSetBuffer(FrameMgr, void*); +FmStatus _FrameMgrPutToken(FrameMgr, void*, int); +FmStatus _FrameMgrGetToken(FrameMgr, void*, int); +FmStatus FrameMgrSetSize(FrameMgr, int); +FmStatus FrameMgrSetIterCount(FrameMgr, int); +FmStatus FrameMgrSetTotalSize(FrameMgr, int); +int FrameMgrGetTotalSize(FrameMgr); +int FrameMgrGetSize(FrameMgr); +FmStatus FrameMgrSkipToken(FrameMgr, int); +void FrameMgrReset(FrameMgr); +Bool FrameMgrIsIterLoopEnd(FrameMgr, FmStatus*); + +#define FrameMgrPutToken(fm, obj) _FrameMgrPutToken((fm), &(obj), sizeof(obj)) +#define FrameMgrGetToken(fm, obj) _FrameMgrGetToken((fm), &(obj), sizeof(obj)) + +#endif /* FRAMEMGR_H */ diff --git a/ism/modules/frontend/imdkit/IMConn.c b/ism/modules/frontend/imdkit/IMConn.c new file mode 100755 index 0000000..6d36589 --- /dev/null +++ b/ism/modules/frontend/imdkit/IMConn.c @@ -0,0 +1,176 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include +#include "IMdkit.h" +#include + +#define Va_start(a,b) va_start(a,b) + +static void _IMCountVaList(va_list var, int *total_count) +{ + char *attr; + + *total_count = 0; + + for (attr = va_arg (var, char*); attr; attr = va_arg (var, char*)) + { + (void)va_arg (var, XIMArg *); + ++(*total_count); + } + /*endfor*/ +} + +static void _IMVaToNestedList(va_list var, int max_count, XIMArg **args_return) +{ + XIMArg *args; + char *attr; + + if (max_count <= 0) + { + *args_return = (XIMArg *) NULL; + return; + } + /*endif*/ + + args = (XIMArg *) malloc ((unsigned) (max_count + 1)*sizeof (XIMArg)); + *args_return = args; + if (!args) + return; + /*endif*/ + + for (attr = va_arg (var, char*); attr; attr = va_arg (var, char *)) + { + args->name = attr; + args->value = va_arg (var, XPointer); + args++; + } + /*endfor*/ + args->name = (char*)NULL; +} + +static char *_FindModifiers (XIMArg *args) +{ + char *modifiers; + + while (args->name) + { + if (strcmp (args->name, IMModifiers) == 0) + { + modifiers = args->value; + return modifiers; + } + else + { + args++; + } + /*endif*/ + } + /*endwhile*/ + return NULL; +} + +XIMS _GetIMS (char *modifiers) +{ + XIMS ims; + extern IMMethodsRec Xi18n_im_methods; + + if ((ims = (XIMS) malloc (sizeof (XIMProtocolRec))) == (XIMS) NULL) + return ((XIMS) NULL); + /*endif*/ + memset ((void *) ims, 0, sizeof (XIMProtocolRec)); + + if (modifiers == NULL + || + modifiers[0] == '\0' + || + strcmp (modifiers, "Xi18n") == 0) + { + ims->methods = &Xi18n_im_methods; + return ims; + } + /*endif*/ + XFree (ims); + return (XIMS) NULL; +} + +XIMS IMOpenIM (Display *display, ...) +{ + va_list var; + int total_count; + XIMArg *args; + XIMS ims; + char *modifiers; + Status ret; + + Va_start (var, display); + _IMCountVaList (var, &total_count); + va_end (var); + + Va_start (var, display); + _IMVaToNestedList (var, total_count, &args); + va_end (var); + + modifiers = _FindModifiers (args); + + ims = _GetIMS (modifiers); + if (ims == (XIMS) NULL) + return (XIMS) NULL; + /*endif*/ + + ims->core.display = display; + + ims->protocol = (*ims->methods->setup) (display, args); + XFree (args); + if (ims->protocol == (void *) NULL) + { + XFree (ims); + return (XIMS) NULL; + } + /*endif*/ + ret = (ims->methods->openIM) (ims); + if (ret == False) + { + XFree (ims); + return (XIMS) NULL; + } + /*endif*/ + return (XIMS) ims; +} + +Status IMCloseIM (XIMS ims) +{ + (ims->methods->closeIM) (ims); + XFree (ims); + return True; +} diff --git a/ism/modules/frontend/imdkit/IMMethod.c b/ism/modules/frontend/imdkit/IMMethod.c new file mode 100755 index 0000000..5a33878 --- /dev/null +++ b/ism/modules/frontend/imdkit/IMMethod.c @@ -0,0 +1,65 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" + +/* Public Function */ +void IMForwardEvent (XIMS ims, XPointer call_data) +{ + (ims->methods->forwardEvent) (ims, call_data); +} + +void IMCommitString (XIMS ims, XPointer call_data) +{ + (ims->methods->commitString) (ims, call_data); +} + +int IMCallCallback (XIMS ims, XPointer call_data) +{ + return (ims->methods->callCallback) (ims, call_data); +} + +int IMPreeditStart (XIMS ims, XPointer call_data) +{ + return (ims->methods->preeditStart) (ims, call_data); +} + +int IMPreeditEnd (XIMS ims, XPointer call_data) +{ + return (ims->methods->preeditEnd) (ims, call_data); +} + +int IMSyncXlib(XIMS ims, XPointer call_data) +{ + ims->sync = True; + return (ims->methods->syncXlib) (ims, call_data); +} diff --git a/ism/modules/frontend/imdkit/IMValues.c b/ism/modules/frontend/imdkit/IMValues.c new file mode 100755 index 0000000..687014a --- /dev/null +++ b/ism/modules/frontend/imdkit/IMValues.c @@ -0,0 +1,124 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include "IMdkit.h" +#include + +#define Va_start(a,b) va_start(a,b) + +static void _IMCountVaList (va_list var, int *total_count) +{ + char *attr; + + *total_count = 0; + + for (attr = va_arg (var, char *); attr; attr = va_arg (var, char *)) + { + (void)va_arg (var, XIMArg *); + ++(*total_count); + } + /*endfor*/ +} + +static void _IMVaToNestedList (va_list var, int max_count, XIMArg **args_return) +{ + XIMArg *args; + char *attr; + + if (max_count <= 0) + { + *args_return = (XIMArg *) NULL; + return; + } + /*endif*/ + + args = (XIMArg *) malloc ((unsigned) (max_count + 1)*sizeof (XIMArg)); + *args_return = args; + if (!args) + return; + /*endif*/ + for (attr = va_arg (var, char *); attr; attr = va_arg (var, char *)) + { + args->name = attr; + args->value = va_arg (var, XPointer); + args++; + } + /*endfor*/ + args->name = (char *) NULL; +} + +char *IMGetIMValues (XIMS ims, ...) +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + Va_start (var, ims); + _IMCountVaList (var, &total_count); + va_end (var); + + Va_start (var, ims); + _IMVaToNestedList (var, total_count, &args); + va_end (var); + + ret = (*ims->methods->getIMValues) (ims, args); + + if (args) + XFree ((char *) args); + /*endif*/ + return ret; +} + +char *IMSetIMValues (XIMS ims, ...) +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + Va_start (var, ims); + _IMCountVaList (var, &total_count); + va_end (var); + + Va_start (var, ims); + _IMVaToNestedList (var, total_count, &args); + va_end (var); + + ret = (*ims->methods->setIMValues) (ims, args); + + if (args) + XFree ((char *) args); + /*endif*/ + return ret; +} diff --git a/ism/modules/frontend/imdkit/IMdkit.h b/ism/modules/frontend/imdkit/IMdkit.h new file mode 100644 index 0000000..6f8d673 --- /dev/null +++ b/ism/modules/frontend/imdkit/IMdkit.h @@ -0,0 +1,144 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _IMdkit_h +#define _IMdkit_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* IM Attributes Name */ +#define IMModifiers "modifiers" +#define IMServerWindow "serverWindow" +#define IMServerName "serverName" +#define IMServerTransport "serverTransport" +#define IMLocale "locale" +#define IMInputStyles "inputStyles" +#define IMProtocolHandler "protocolHandler" +#define IMOnKeysList "onKeysList" +#define IMOffKeysList "offKeysList" +#define IMEncodingList "encodingList" +#define IMFilterEventMask "filterEventMask" +#define IMProtocolDepend "protocolDepend" + +/* Masks for IM Attributes Name */ +#define I18N_IMSERVER_WIN 0x0001 /* IMServerWindow */ +#define I18N_IM_NAME 0x0002 /* IMServerName */ +#define I18N_IM_LOCALE 0x0004 /* IMLocale */ +#define I18N_IM_ADDRESS 0x0008 /* IMServerTransport */ +#define I18N_INPUT_STYLES 0x0010 /* IMInputStyles */ +#define I18N_ON_KEYS 0x0020 /* IMOnKeysList */ +#define I18N_OFF_KEYS 0x0040 /* IMOffKeysList */ +#define I18N_IM_HANDLER 0x0080 /* IMProtocolHander */ +#define I18N_ENCODINGS 0x0100 /* IMEncodingList */ +#define I18N_FILTERMASK 0x0200 /* IMFilterEventMask */ +#define I18N_PROTO_DEPEND 0x0400 /* IMProtoDepend */ + +typedef struct +{ + char *name; + XPointer value; +} XIMArg; + +typedef struct +{ + CARD32 keysym; + CARD32 modifier; + CARD32 modifier_mask; +} XIMTriggerKey; + +typedef struct +{ + unsigned short count_keys; + XIMTriggerKey *keylist; +} XIMTriggerKeys; + +typedef char *XIMEncoding; + +typedef struct +{ + unsigned short count_encodings; + XIMEncoding *supported_encodings; +} XIMEncodings; + +typedef struct _XIMS *XIMS; + +typedef struct +{ + void* (*setup) (Display *, XIMArg *); + Status (*openIM) (XIMS); + Status (*closeIM) (XIMS); + char* (*setIMValues) (XIMS, XIMArg *); + char* (*getIMValues) (XIMS, XIMArg *); + Status (*forwardEvent) (XIMS, XPointer); + Status (*commitString) (XIMS, XPointer); + int (*callCallback) (XIMS, XPointer); + int (*preeditStart) (XIMS, XPointer); + int (*preeditEnd) (XIMS, XPointer); + int (*syncXlib) (XIMS, XPointer); +} IMMethodsRec, *IMMethods; + +typedef struct +{ + Display *display; + int screen; +} IMCoreRec, *IMCore; + +typedef struct _XIMS +{ + IMMethods methods; + IMCoreRec core; + Bool sync; + void *protocol; +} XIMProtocolRec; + +/* + * X function declarations. + */ +extern XIMS IMOpenIM (Display *, ...); +extern Status IMCloseIM (XIMS); +extern char *IMSetIMValues (XIMS, ...); +extern char *IMGetIMValues (XIMS, ...); +void IMForwardEvent (XIMS, XPointer); +void IMCommitString (XIMS, XPointer); +int IMCallCallback (XIMS, XPointer); +int IMPreeditStart (XIMS, XPointer); +int IMPreeditEnd (XIMS, XPointer); +int IMSyncXlib (XIMS, XPointer); + +#ifdef __cplusplus +} +#endif + +#endif /* IMdkit_h */ diff --git a/ism/modules/frontend/imdkit/Makefile.am b/ism/modules/frontend/imdkit/Makefile.am new file mode 100755 index 0000000..96381bd --- /dev/null +++ b/ism/modules/frontend/imdkit/Makefile.am @@ -0,0 +1,46 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in + +noinst_HEADERS = FrameMgr.h \ + Xi18n.h \ + Xi18nX.h \ + XimProto.h \ + IMdkit.h \ + XimFunc.h \ + Xtrans.h + + +noinst_LTLIBRARIES = libXimd.la + +libXimd_la_SOURCES = FrameMgr.c \ + i18nIc.c \ + i18nPtHdr.c \ + i18nX.c \ + IMValues.c \ + i18nAttr.c \ + i18nIMProto.c \ + IMConn.c \ + i18nClbk.c \ + i18nMethod.c \ + i18nUtil.c \ + IMMethod.c + +libXimd_la_CFLAGS = @X_CFLAGS@ +libXimd_la_LDFLAGS = @X_LIBS@ + diff --git a/ism/modules/frontend/imdkit/Xi18n.h b/ism/modules/frontend/imdkit/Xi18n.h new file mode 100644 index 0000000..aaf7768 --- /dev/null +++ b/ism/modules/frontend/imdkit/Xi18n.h @@ -0,0 +1,505 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _Xi18n_h +#define _Xi18n_h +#include +#include +#include +#include "XimProto.h" + +/* + * Minor Protocol Number for Extension Protocol + */ +#define XIM_EXTENSION 128 +#define XIM_EXT_SET_EVENT_MASK (0x30) +#define XIM_EXT_FORWARD_KEYEVENT (0x32) +#define XIM_EXT_MOVE (0x33) +#define COMMON_EXTENSIONS_NUM 3 + +#include +#include "IMdkit.h" + +/* XI18N Valid Attribute Name Definition */ +#define ExtForwardKeyEvent "extForwardKeyEvent" +#define ExtMove "extMove" +#define ExtSetEventMask "extSetEventMask" + +/* + * Padding macro + */ +#define IMPAD(length) ((4 - ((length)%4))%4) + +/* + * Target Atom for Transport Connection + */ +#define LOCALES "LOCALES" +#define TRANSPORT "TRANSPORT" + +#define I18N_OPEN 0 +#define I18N_SET 1 +#define I18N_GET 2 + +typedef struct +{ + char *transportname; + int namelen; + Bool (*checkAddr) (); +} TransportSW; + +typedef struct _XIMPending +{ + unsigned char *p; + struct _XIMPending *next; +} XIMPending; + +typedef struct _XimProtoHdr +{ + CARD8 major_opcode; + CARD8 minor_opcode; + CARD16 length; +} XimProtoHdr; + +typedef struct +{ + CARD16 attribute_id; + CARD16 type; + CARD16 length; + char *name; +} XIMAttr; + +typedef struct +{ + CARD16 attribute_id; + CARD16 type; + CARD16 length; + char *name; +} XICAttr; + +typedef struct +{ + int attribute_id; + CARD16 name_length; + char *name; + int value_length; + void *value; + int type; +} XIMAttribute; + +typedef struct +{ + int attribute_id; + CARD16 name_length; + char *name; + int value_length; + void *value; + int type; +} XICAttribute; + +typedef struct +{ + int length; + char *name; +} XIMStr; + +typedef struct +{ + CARD16 major_opcode; + CARD16 minor_opcode; + CARD16 length; + char *name; +} XIMExt; + +typedef struct _Xi18nClient +{ + int connect_id; + CARD8 byte_order; + /* + '?': initial value + 'B': for Big-Endian + 'l': for little-endian + */ + int sync; + XIMPending *pending; + void *trans_rec; /* contains transport specific data */ + struct _Xi18nClient *next; +} Xi18nClient; + +typedef struct _Xi18nCore *Xi18n; + +/* + * Callback Struct for XIM Protocol + */ +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; +} IMAnyStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD8 byte_order; + CARD16 major_version; + CARD16 minor_version; +} IMConnectStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; +} IMDisConnectStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + XIMStr lang; +} IMOpenStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; +} IMCloseStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 number; + XIMStr *extension; +} IMQueryExtensionStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 number; + char **im_attr_list; +} IMGetIMValuesStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 preedit_attr_num; + CARD16 status_attr_num; + CARD16 ic_attr_num; + XICAttribute *preedit_attr; + XICAttribute *status_attr; + XICAttribute *ic_attr; +} IMChangeICStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMDestroyICStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 length; + char *commit_string; +} IMResetICStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMChangeFocusStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + BITMASK16 sync_bit; + CARD16 serial_number; + XEvent event; +} IMForwardEventStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 flag; + KeySym keysym; + char *commit_string; +} IMCommitStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD32 flag; + CARD32 key_index; + CARD32 event_mask; +} IMTriggerNotifyStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 encoding_number; + XIMStr *encoding; /* name information */ + CARD16 encoding_info_number; + XIMStr *encodinginfo; /* detailed information */ + CARD16 category; /* #0 for name, #1 for detail */ + INT16 enc_index; /* index of the encoding determined */ +} IMEncodingNegotiationStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD32 flag; + CARD32 forward_event_mask; + CARD32 sync_event_mask; +} IMSetEventMaskStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD32 filter_event_mask; + CARD32 intercept_event_mask; + CARD32 select_event_mask; + CARD32 forward_event_mask; + CARD32 sync_event_mask; +} IMExtSetEventMaskStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 x; + CARD16 y; +} IMMoveStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + BITMASK16 flag; + CARD16 error_code; + CARD16 str_length; + CARD16 error_type; + char *error_detail; +} IMErrorStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMPreeditStateStruct; + +/* Callbacks */ +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMGeometryCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + union + { + int return_value; /* PreeditStart */ + XIMPreeditDrawCallbackStruct draw; /* PreeditDraw */ + XIMPreeditCaretCallbackStruct caret; /* PreeditCaret */ + } todo; +} IMPreeditCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + union + { + XIMStatusDrawCallbackStruct draw; /* StatusDraw */ + } todo; +} IMStatusCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + XIMStringConversionCallbackStruct strconv; +} IMStrConvCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMSyncXlibStruct; + +typedef union _IMProtocol +{ + int major_code; + IMAnyStruct any; + IMConnectStruct imconnect; + IMDisConnectStruct imdisconnect; + IMOpenStruct imopen; + IMCloseStruct imclose; + IMQueryExtensionStruct queryext; + IMGetIMValuesStruct getim; + IMEncodingNegotiationStruct encodingnego; + IMExtSetEventMaskStruct extsetevent; + IMMoveStruct extmove; + IMSetEventMaskStruct setevent; + IMChangeICStruct changeic; + IMDestroyICStruct destroyic; + IMResetICStruct resetic; + IMChangeFocusStruct changefocus; + IMCommitStruct commitstring; + IMForwardEventStruct forwardevent; + IMTriggerNotifyStruct triggernotify; + IMPreeditStateStruct preedit_state; + IMErrorStruct imerror; + IMGeometryCBStruct geometry_callback; + IMPreeditCBStruct preedit_callback; + IMStatusCBStruct status_callback; + IMStrConvCBStruct strconv_callback; + IMSyncXlibStruct sync_xlib; + long pad[32]; +} IMProtocol; + +typedef int (*IMProtoHandler) (XIMS, IMProtocol*); + +#define DEFAULT_FILTER_MASK (KeyPressMask) + +/* Xi18nAddressRec structure */ +typedef struct _Xi18nAddressRec +{ + Display *dpy; + CARD8 im_byteOrder; /* byte order 'B' or 'l' */ + /* IM Values */ + long imvalue_mask; + Window im_window; /* IMServerWindow */ + char *im_name; /* IMServerName */ + char *im_locale; /* IMLocale */ + char *im_addr; /* IMServerTransport */ + XIMStyles input_styles; /* IMInputStyles */ + XIMTriggerKeys on_keys; /* IMOnKeysList */ + XIMTriggerKeys off_keys; /* IMOffKeysList */ + XIMEncodings encoding_list; /* IMEncodingList */ + IMProtoHandler improto; /* IMProtocolHander */ + long filterevent_mask; /* IMFilterEventMask */ + /* XIM_SERVERS target Atoms */ + Atom selection; + Atom Localename; + Atom Transportname; + /* XIM/XIC Attr */ + int im_attr_num; + XIMAttr *xim_attr; + int ic_attr_num; + XICAttr *xic_attr; + CARD16 preeditAttr_id; + CARD16 statusAttr_id; + CARD16 separatorAttr_id; + /* XIMExtension List */ + int ext_num; + XIMExt extension[COMMON_EXTENSIONS_NUM]; + /* transport specific connection address */ + void *connect_addr; + /* actual data is defined: + XSpecRec in Xi18nX.h for X-based connection. + TransSpecRec in Xi18nTr.h for Socket-based connection. + */ + /* clients table */ + Xi18nClient *clients; + Xi18nClient *free_clients; +} Xi18nAddressRec; + +typedef struct _Xi18nMethodsRec +{ + Bool (*begin) (XIMS); + Bool (*end) (XIMS); + Bool (*send) (XIMS, CARD16, unsigned char*, long); + Bool (*wait) (XIMS, CARD16, CARD8, CARD8); + Bool (*disconnect) (XIMS, CARD16); +} Xi18nMethodsRec; + +typedef struct _Xi18nCore +{ + Xi18nAddressRec address; + Xi18nMethodsRec methods; +} Xi18nCore; + +#endif + diff --git a/ism/modules/frontend/imdkit/Xi18nX.h b/ism/modules/frontend/imdkit/Xi18nX.h new file mode 100644 index 0000000..ff91b1a --- /dev/null +++ b/ism/modules/frontend/imdkit/Xi18nX.h @@ -0,0 +1,52 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _Xi18nTrX_h +#define _Xi18nTrX_h + +#define _XIM_PROTOCOL "_XIM_PROTOCOL" +#define _XIM_XCONNECT "_XIM_XCONNECT" + +#define XCM_DATA_LIMIT 20 + +typedef struct _XClient +{ + Window client_win; /* client window */ + Window accept_win; /* accept window */ +} XClient; + +typedef struct +{ + Atom xim_request; + Atom connect_request; +} XSpecRec; + +#endif diff --git a/ism/modules/frontend/imdkit/XimFunc.h b/ism/modules/frontend/imdkit/XimFunc.h new file mode 100644 index 0000000..a9f4a04 --- /dev/null +++ b/ism/modules/frontend/imdkit/XimFunc.h @@ -0,0 +1,72 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _XimFunc_h +#define _XimFunc_h + +/* i18nAttr.c */ +void _Xi18nInitAttrList (Xi18n i18n_core); +void _Xi18nInitExtension(Xi18n i18n_core); + +/* i18nClbk.c */ +int _Xi18nGeometryCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditStartCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditDrawCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditCaretCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditDoneCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStatusStartCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStatusDrawCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStatusDoneCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStringConversionCallback (XIMS ims, IMProtocol *call_data); + +/* i18nIc.c */ +void _Xi18nChangeIC (XIMS ims, IMProtocol *call_data, unsigned char *p, + int create_flag); +void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p); + +/* i18nUtil.c */ +int _Xi18nNeedSwap (Xi18n i18n_core, CARD16 connect_id); +Xi18nClient *_Xi18nNewClient(Xi18n i18n_core); +Xi18nClient *_Xi18nFindClient (Xi18n i18n_core, CARD16 connect_id); +void _Xi18nDeleteClient (Xi18n i18n_core, CARD16 connect_id); +void _Xi18nSendMessage (XIMS ims, CARD16 connect_id, CARD8 major_opcode, + CARD8 minor_opcode, unsigned char *data, long length); +void _Xi18nSendTriggerKey (XIMS ims, CARD16 connect_id); +void _Xi18nSetEventMask (XIMS ims, CARD16 connect_id, CARD16 im_id, + CARD16 ic_id, CARD32 forward_mask, CARD32 sync_mask); + +/* Xlib internal */ +void _XRegisterFilterByType(Display*, Window, int, int, + Bool (*filter)(Display*, Window, XEvent*, XPointer), XPointer); +void _XUnregisterFilter(Display*, Window, + Bool (*filter)(Display*, Window, XEvent*, XPointer), XPointer); + +#endif diff --git a/ism/modules/frontend/imdkit/XimProto.h b/ism/modules/frontend/imdkit/XimProto.h new file mode 100644 index 0000000..e3ed168 --- /dev/null +++ b/ism/modules/frontend/imdkit/XimProto.h @@ -0,0 +1,230 @@ +/* $XConsortium: XimProto.h,v 1.2 94/01/20 18:02:24 rws Exp $ */ +/****************************************************************** + + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of FUJITSU LIMITED +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +FUJITSU LIMITED makes no representations about the suitability of +this software for any purpose. +It is provided "as is" without express or implied warranty. + +FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + Author: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _XIMPROTO_H +#define _XIMPROTO_H + +/* + * Default Preconnection selection target + */ +#define XIM_SERVERS "XIM_SERVERS" +#define XIM_LOCALES "LOCALES" +#define XIM_TRANSPORT "TRANSPORT" + +/* + * categories in XIM_SERVERS + */ +#define XIM_SERVER_CATEGORY "@server=" +#define XIM_LOCAL_CATEGORY "@locale=" +#define XIM_TRANSPORT_CATEGORY "@transport=" + +/* + * Xim implementation revision + */ +#define PROTOCOLMAJORVERSION 0 +#define PROTOCOLMINORVERSION 0 + +/* + * Major Protocol number + */ +#define XIM_CONNECT 1 +#define XIM_CONNECT_REPLY 2 +#define XIM_DISCONNECT 3 +#define XIM_DISCONNECT_REPLY 4 + +#define XIM_AUTH_REQUIRED 10 +#define XIM_AUTH_REPLY 11 +#define XIM_AUTH_NEXT 12 +#define XIM_AUTH_SETUP 13 +#define XIM_AUTH_NG 14 + +#define XIM_ERROR 20 + +#define XIM_OPEN 30 +#define XIM_OPEN_REPLY 31 +#define XIM_CLOSE 32 +#define XIM_CLOSE_REPLY 33 +#define XIM_REGISTER_TRIGGERKEYS 34 +#define XIM_TRIGGER_NOTIFY 35 +#define XIM_TRIGGER_NOTIFY_REPLY 36 +#define XIM_SET_EVENT_MASK 37 +#define XIM_ENCODING_NEGOTIATION 38 +#define XIM_ENCODING_NEGOTIATION_REPLY 39 +#define XIM_QUERY_EXTENSION 40 +#define XIM_QUERY_EXTENSION_REPLY 41 +#define XIM_SET_IM_VALUES 42 +#define XIM_SET_IM_VALUES_REPLY 43 +#define XIM_GET_IM_VALUES 44 +#define XIM_GET_IM_VALUES_REPLY 45 + +#define XIM_CREATE_IC 50 +#define XIM_CREATE_IC_REPLY 51 +#define XIM_DESTROY_IC 52 +#define XIM_DESTROY_IC_REPLY 53 +#define XIM_SET_IC_VALUES 54 +#define XIM_SET_IC_VALUES_REPLY 55 +#define XIM_GET_IC_VALUES 56 +#define XIM_GET_IC_VALUES_REPLY 57 +#define XIM_SET_IC_FOCUS 58 +#define XIM_UNSET_IC_FOCUS 59 +#define XIM_FORWARD_EVENT 60 +#define XIM_SYNC 61 +#define XIM_SYNC_REPLY 62 +#define XIM_COMMIT 63 +#define XIM_RESET_IC 64 +#define XIM_RESET_IC_REPLY 65 + +#define XIM_GEOMETRY 70 +#define XIM_STR_CONVERSION 71 +#define XIM_STR_CONVERSION_REPLY 72 +#define XIM_PREEDIT_START 73 +#define XIM_PREEDIT_START_REPLY 74 +#define XIM_PREEDIT_DRAW 75 +#define XIM_PREEDIT_CARET 76 +#define XIM_PREEDIT_CARET_REPLY 77 +#define XIM_PREEDIT_DONE 78 +#define XIM_STATUS_START 79 +#define XIM_STATUS_DRAW 80 +#define XIM_STATUS_DONE 81 + +/* + * values for the flag of XIM_ERROR + */ +#define XIM_IMID_VALID 0x0001 +#define XIM_ICID_VALID 0x0002 + +/* + * XIM Error Code + */ +#define XIM_BadAlloc 1 +#define XIM_BadStyle 2 +#define XIM_BadClientWindow 3 +#define XIM_BadFocusWindow 4 +#define XIM_BadArea 5 +#define XIM_BadSpotLocation 6 +#define XIM_BadColormap 7 +#define XIM_BadAtom 8 +#define XIM_BadPixel 9 +#define XIM_BadPixmap 10 +#define XIM_BadName 11 +#define XIM_BadCursor 12 +#define XIM_BadProtocol 13 +#define XIM_BadForeground 14 +#define XIM_BadBackground 15 +#define XIM_LocaleNotSupported 16 +#define XIM_BadSomething 999 + +/* + * byte order + */ +#define BIGENDIAN (CARD8) 0x42 /* MSB first */ +#define LITTLEENDIAN (CARD8) 0x6c /* LSB first */ + +/* + * values for the type of XIMATTR & XICATTR + */ +#define XimType_SeparatorOfNestedList 0 +#define XimType_CARD8 1 +#define XimType_CARD16 2 +#define XimType_CARD32 3 +#define XimType_STRING8 4 +#define XimType_Window 5 +#define XimType_XIMStyles 10 +#define XimType_XRectangle 11 +#define XimType_XPoint 12 +#define XimType_XFontSet 13 +#define XimType_XIMOptions 14 +#define XimType_XIMHotKeyTriggers 15 +#define XimType_XIMHotKeyState 16 +#define XimType_XIMStringConversion 17 +#define XimType_XIMValuesList 18 +#define XimType_NEST 0x7FFF + +/* + * values for the category of XIM_ENCODING_NEGOTIATON_REPLY + */ +#define XIM_Encoding_NameCategory 0 +#define XIM_Encoding_DetailCategory 1 + +/* + * value for the index of XIM_ENCODING_NEGOTIATON_REPLY + */ +#define XIM_Default_Encoding_IDX -1 + +/* + * value for the flag of XIM_FORWARD_EVENT, XIM_COMMIT + */ +#define XimSYNCHRONUS 0x0001 +#define XimLookupChars 0x0002 +#define XimLookupKeySym 0x0004 +#define XimLookupBoth 0x0006 + +/* + * request packet header size + */ +#define XIM_HEADER_SIZE \ + sizeof(CARD8) /* sizeof mejor-opcode */ \ + + sizeof(CARD8) /* sizeof minor-opcode */ \ + + sizeof(INT16) /* sizeof length */ + +/* + * Client Message data size + */ +#define XIM_CM_DATA_SIZE 20 + +/* + * XIM data structure + */ +typedef CARD16 BITMASK16; +typedef CARD32 BITMASK32; +typedef CARD32 EVENTMASK; + +typedef CARD16 XIMID; /* Input Method ID */ +typedef CARD16 XICID; /* Input Context ID */ + +/* + * Padding macro + */ +#define XIM_PAD(length) ((4 - ((length) % 4)) % 4) + +#define XIM_SET_PAD(ptr, length) \ + { \ + register int Counter = XIM_PAD((int)length); \ + if (Counter) { \ + register char *Ptr = (char *)(ptr) + (length); \ + length += Counter; \ + for (; Counter; --Counter, ++Ptr) \ + *Ptr = '\0'; \ + } \ + } + +#endif + diff --git a/ism/modules/frontend/imdkit/Xtrans.h b/ism/modules/frontend/imdkit/Xtrans.h new file mode 100644 index 0000000..cae691c --- /dev/null +++ b/ism/modules/frontend/imdkit/Xtrans.h @@ -0,0 +1,470 @@ +/* $XConsortium: Xtrans.h,v 1.24 94/05/02 10:45:32 mor Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +/* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name NCR not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. NCR makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _XTRANS_H_ +#define _XTRANS_H_ + +#include +#include + + +/* + * Set the functions names according to where this code is being compiled. + */ + +#ifdef X11_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _X11Trans##func +#else +#define TRANS(func) _X11Trans/**/func +#endif +#endif /* X11_t */ + +#ifdef XSERV_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _XSERVTrans##func +#else +#define TRANS(func) _XSERVTrans/**/func +#endif +#define X11_t +#endif /* X11_t */ + +#ifdef XIM_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _XimdXTrans##func +#else +#define TRANS(func) _XimdXTrans/**/func +#endif +#endif /* XIM_t */ + +#ifdef FS_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _FSTrans##func +#else +#define TRANS(func) _FSTrans/**/func +#endif +#endif /* FS_t */ + +#ifdef FONT_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _FontTrans##func +#else +#define TRANS(func) _FontTrans/**/func +#endif +#endif /* FONT_t */ + +#ifdef ICE_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _IceTrans##func +#else +#define TRANS(func) _IceTrans/**/func +#endif +#endif /* ICE_t */ + +#ifdef TEST_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _TESTTrans##func +#else +#define TRANS(func) _TESTTrans/**/func +#endif +#endif /* TEST_t */ + +#if !defined(TRANS) +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _XTrans##func +#else +#define TRANS(func) _XTrans/**/func +#endif +#endif /* !TRANS */ + + +/* + * Create a single address structure that can be used wherever + * an address structure is needed. struct sockaddr is not big enough + * to hold a sockadd_un, so we create this definition to have a single + * structure that is big enough for all the structures we might need. + * + * This structure needs to be independent of the socket/TLI interface used. + */ + +#define XTRANS_MAX_ADDR_LEN 128 /* large enough to hold sun_path */ + +typedef struct { + unsigned char addr[XTRANS_MAX_ADDR_LEN]; +} Xtransaddr; + + +#ifdef LONG64 +typedef int BytesReadable_t; +#else +typedef long BytesReadable_t; +#endif + + +#if defined(WIN32) || (defined(USG) && !defined(CRAY) && !defined(umips) && !defined(MOTOROLA) && !defined(uniosu) && !defined(__sxg__)) + +/* + * TRANS(Readv) and TRANS(Writev) use struct iovec, normally found + * in Berkeley systems in . See the readv(2) and writev(2) + * manual pages for details. + */ + +struct iovec { + caddr_t iov_base; + int iov_len; +}; + +#else +#include +#endif + +typedef struct _XtransConnInfo *XtransConnInfo; + + +/* + * Transport Option definitions + */ + +#define TRANS_NONBLOCKING 1 +#define TRANS_CLOSEONEXEC 2 + + +/* + * Return values of Connect (0 is success) + */ + +#define TRANS_CONNECT_FAILED -1 +#define TRANS_TRY_CONNECT_AGAIN -2 + + +/* + * Return values of Accept (0 is success) + */ + +#define TRANS_ACCEPT_BAD_MALLOC -1 +#define TRANS_ACCEPT_FAILED -2 +#define TRANS_ACCEPT_MISC_ERROR -3 + + +/* + * ResetListener return values + */ + +#define TRANS_RESET_NOOP 1 +#define TRANS_RESET_NEW_FD 2 +#define TRANS_RESET_FAILURE 3 + + +/* + * Function prototypes for the exposed interface + */ + +#ifdef TRANS_CLIENT + +XtransConnInfo TRANS(OpenCOTSClient)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_CLIENT */ + +#ifdef TRANS_SERVER + +XtransConnInfo TRANS(OpenCOTSServer)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_SERVER */ + +#ifdef TRANS_CLIENT + +XtransConnInfo TRANS(OpenCLTSClient)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_CLIENT */ + +#ifdef TRANS_SERVER + +XtransConnInfo TRANS(OpenCLTSServer)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_SERVER */ + +#ifdef TRANS_REOPEN + +XtransConnInfo TRANS(ReopenCOTSServer)( +#if NeedFunctionPrototypes + int, /* trans_id */ + int, /* fd */ + char * /* port */ +#endif +); + +XtransConnInfo TRANS(ReopenCLTSServer)( +#if NeedFunctionPrototypes + int, /* trans_id */ + int, /* fd */ + char * /* port */ +#endif +); + +int TRANS(GetReopenInfo)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int *, /* trans_id */ + int *, /* fd */ + char ** /* port */ +#endif +); + +#endif /* TRANS_REOPEN */ + + +int TRANS(SetOption)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int, /* option */ + int /* arg */ +#endif +); + +#ifdef TRANS_SERVER + +int TRANS(CreateListener)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char * /* port */ +#endif +); + +int TRANS(ResetListener)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +XtransConnInfo TRANS(Accept)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int * /* status */ +#endif +); + +#endif /* TRANS_SERVER */ + +#ifdef TRANS_CLIENT + +int TRANS(Connect)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char * /* address */ +#endif +); + +#endif /* TRANS_CLIENT */ + +int TRANS(BytesReadable)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + BytesReadable_t * /* pend */ +#endif +); + +int TRANS(Read)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Write)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Readv)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + struct iovec *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Writev)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + struct iovec *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Disconnect)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(Close)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(CloseForCloning)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(IsLocal)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(GetMyAddr)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int *, /* familyp */ + int *, /* addrlenp */ + Xtransaddr ** /* addrp */ +#endif +); + +int TRANS(GetPeerAddr)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int *, /* familyp */ + int *, /* addrlenp */ + Xtransaddr ** /* addrp */ +#endif +); + +int TRANS(GetConnectionNumber)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +#ifdef TRANS_SERVER + +int TRANS(MakeAllCOTSServerListeners)( +#if NeedFunctionPrototypes + char *, /* port */ + int *, /* partial */ + int *, /* count_ret */ + XtransConnInfo ** /* ciptrs_ret */ +#endif +); + +int TRANS(MakeAllCLTSServerListeners)( +#if NeedFunctionPrototypes + char *, /* port */ + int *, /* partial */ + int *, /* count_ret */ + XtransConnInfo ** /* ciptrs_ret */ +#endif +); + +#endif /* TRANS_SERVER */ + + +/* + * Function Prototypes for Utility Functions. + */ + +#ifdef X11_t + +int TRANS(ConvertAddress)( +#if NeedFunctionPrototypes + int *, /* familyp */ + int *, /* addrlenp */ + Xtransaddr * /* addrp */ +#endif +); + +#endif /* X11_t */ + +#ifdef ICE_t + +char * +TRANS(GetMyNetworkId)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +char * +TRANS(GetPeerNetworkId)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +#endif /* ICE_t */ + +#endif /* _XTRANS_H_ */ diff --git a/ism/modules/frontend/imdkit/i18nAttr.c b/ism/modules/frontend/imdkit/i18nAttr.c new file mode 100755 index 0000000..0d10e64 --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nAttr.c @@ -0,0 +1,175 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "XimFunc.h" + +typedef struct +{ + char *name; + CARD16 type; +} IMListOfAttr; + +typedef struct +{ + char *name; + CARD8 major_opcode; + CARD8 minor_opcode; +} IMExtList; + +IMListOfAttr Default_IMattr[] = +{ + {XNQueryInputStyle, XimType_XIMStyles}, +/* {XNQueryIMValuesList, XimType_XIMValuesList}, */ + {(char *) NULL, (CARD16) 0} +}; + +IMListOfAttr Default_ICattr[] = +{ + {XNInputStyle, XimType_CARD32}, + {XNClientWindow, XimType_Window}, + {XNFocusWindow, XimType_Window}, + {XNFilterEvents, XimType_CARD32}, + {XNPreeditAttributes, XimType_NEST}, + {XNStatusAttributes, XimType_NEST}, + {XNFontSet, XimType_XFontSet}, + {XNArea, XimType_XRectangle}, + {XNAreaNeeded, XimType_XRectangle}, + {XNColormap, XimType_CARD32}, + {XNStdColormap, XimType_CARD32}, + {XNForeground, XimType_CARD32}, + {XNBackground, XimType_CARD32}, + {XNBackgroundPixmap, XimType_CARD32}, + {XNSpotLocation, XimType_XPoint}, + {XNLineSpace, XimType_CARD32}, + {XNPreeditState, XimType_CARD32}, + {XNSeparatorofNestedList, XimType_SeparatorOfNestedList}, + {(char *) NULL, (CARD16) NULL} +}; + +IMExtList Default_Extension[] = +{ + {"XIM_EXT_MOVE", XIM_EXTENSION, XIM_EXT_MOVE}, + {"XIM_EXT_SET_EVENT_MASK", XIM_EXTENSION, XIM_EXT_SET_EVENT_MASK}, + {"XIM_EXT_FORWARD_KEYEVENT", XIM_EXTENSION, XIM_EXT_FORWARD_KEYEVENT}, + {(char *) NULL, (CARD8) NULL, (CARD8) NULL} +}; + +static void CountAttrList(IMListOfAttr *attr, int *total_count) +{ + *total_count = 0; + + while (attr->name != NULL) + { + attr++; + ++(*total_count); + } +} + +static XIMAttr *CreateAttrList (Xi18n i18n_core, + IMListOfAttr *attr, + int *total_count) +{ + XIMAttr *args, *p; + unsigned int buf_size; + + CountAttrList(attr, total_count); + + buf_size = (unsigned) (*total_count + 1)*sizeof (XIMAttr); + args = (XIMAttr *) malloc (buf_size); + if (!args) + return (XIMAttr *) NULL; + /*endif*/ + memset (args, 0, buf_size); + + for (p = args; attr->name != NULL; attr++, p++) + { + p->name = attr->name; + p->length = strlen (attr->name); + p->type = (CARD16) attr->type; + p->attribute_id = XrmStringToQuark (p->name); + if (strcmp (p->name, XNPreeditAttributes) == 0) + i18n_core->address.preeditAttr_id = p->attribute_id; + else if (strcmp (p->name, XNStatusAttributes) == 0) + i18n_core->address.statusAttr_id = p->attribute_id; + else if (strcmp (p->name, XNSeparatorofNestedList) == 0) + i18n_core->address.separatorAttr_id = p->attribute_id; + /*endif*/ + } + /*endfor*/ + p->name = (char *) NULL; + + return args; +} + +void _Xi18nInitAttrList (Xi18n i18n_core) +{ + XIMAttr *args; + int total_count; + + /* init IMAttr list */ + if (i18n_core->address.xim_attr) + XFree ((char *)i18n_core->address.xim_attr); + /*endif*/ + args = CreateAttrList (i18n_core, Default_IMattr, &total_count); + + i18n_core->address.im_attr_num = total_count; + i18n_core->address.xim_attr = (XIMAttr *)args; + + /* init ICAttr list */ + if (i18n_core->address.xic_attr) + XFree ((char *) i18n_core->address.xic_attr); + /*endif*/ + args = CreateAttrList (i18n_core, Default_ICattr, &total_count); + + i18n_core->address.ic_attr_num = total_count; + i18n_core->address.xic_attr = (XICAttr *) args; +} + +void _Xi18nInitExtension(Xi18n i18n_core) +{ + register int i; + IMExtList *extensions = (IMExtList *) Default_Extension; + XIMExt *ext_list = (XIMExt *) i18n_core->address.extension; + + for (i = 0; extensions->name; i++, ext_list++, extensions++) + { + ext_list->major_opcode = extensions->major_opcode; + ext_list->minor_opcode = extensions->minor_opcode; + ext_list->name = extensions->name; + ext_list->length = strlen(ext_list->name); + } + /*endfor*/ + i18n_core->address.ext_num = i; +} diff --git a/ism/modules/frontend/imdkit/i18nClbk.c b/ism/modules/frontend/imdkit/i18nClbk.c new file mode 100755 index 0000000..b3edf3a --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nClbk.c @@ -0,0 +1,513 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "FrameMgr.h" +#include "XimFunc.h" + +int _Xi18nGeometryCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec geometry_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMGeometryCBStruct *geometry_CB = + (IMGeometryCBStruct *) &call_data->geometry_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (geometry_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, geometry_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_GEOMETRY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_GEOMETRY is an asyncronous protocol, + so return immediately. */ + return True; +} + +int _Xi18nPreeditStartCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_start_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct*) &call_data->preedit_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (preedit_start_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage(ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_START, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + return True; +} + +int _Xi18nPreeditDrawCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_draw_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + XIMPreeditDrawCallbackStruct *draw = + (XIMPreeditDrawCallbackStruct *) &preedit_CB->todo.draw; + CARD16 connect_id = call_data->any.connect_id; + register int feedback_count; + register int i; + BITMASK32 status = 0x0; + + if (draw->text->length == 0) + status = 0x00000001; + else if (draw->text->feedback[0] == 0) + status = 0x00000002; + /*endif*/ + + fm = FrameMgrInit (preedit_draw_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set length of preedit string */ + FrameMgrSetSize (fm, draw->text->length); + + /* set iteration count for list of feedback */ + for (i = 0; draw->text->feedback[i] != 0; i++) + ; + /*endfor*/ + feedback_count = i; + FrameMgrSetIterCount (fm, feedback_count); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + FrameMgrPutToken (fm, draw->caret); + FrameMgrPutToken (fm, draw->chg_first); + FrameMgrPutToken (fm, draw->chg_length); + FrameMgrPutToken (fm, status); + FrameMgrPutToken (fm, draw->text->length); + FrameMgrPutToken (fm, draw->text->string); + for (i = 0; i < feedback_count; i++) + FrameMgrPutToken (fm, draw->text->feedback[i]); + /*endfor*/ + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_DRAW, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_PREEDIT_DRAW is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nPreeditCaretCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_caret_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct*) &call_data->preedit_callback; + XIMPreeditCaretCallbackStruct *caret = + (XIMPreeditCaretCallbackStruct *) &preedit_CB->todo.caret; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (preedit_caret_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + FrameMgrPutToken (fm, caret->position); + FrameMgrPutToken (fm, caret->direction); + FrameMgrPutToken (fm, caret->style); + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_CARET, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + return True; +} + +int _Xi18nPreeditDoneCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_done_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (preedit_done_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_DONE, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_PREEDIT_DONE is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStatusStartCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec status_start_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMStatusCBStruct *status_CB = + (IMStatusCBStruct*) &call_data->status_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (status_start_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_STATUS_START, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STATUS_START is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStatusDrawCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm = (FrameMgr)0; + extern XimFrameRec status_draw_text_fr[]; + extern XimFrameRec status_draw_bitmap_fr[]; + register int total_size = 0; + unsigned char *reply = NULL; + IMStatusCBStruct *status_CB = + (IMStatusCBStruct *) &call_data->status_callback; + XIMStatusDrawCallbackStruct *draw = + (XIMStatusDrawCallbackStruct *) &status_CB->todo.draw; + CARD16 connect_id = call_data->any.connect_id; + register int feedback_count; + register int i; + BITMASK32 status = 0x0; + + switch (draw->type) + { + case XIMTextType: + fm = FrameMgrInit (status_draw_text_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + if (draw->data.text->length == 0) + status = 0x00000001; + else if (draw->data.text->feedback[0] == 0) + status = 0x00000002; + /*endif*/ + + /* set length of status string */ + FrameMgrSetSize(fm, draw->data.text->length); + /* set iteration count for list of feedback */ + for (i = 0; draw->data.text->feedback[i] != 0; i++) + ; + /*endfor*/ + feedback_count = i; + FrameMgrSetIterCount (fm, feedback_count); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + FrameMgrPutToken (fm, draw->type); + FrameMgrPutToken (fm, status); + FrameMgrPutToken (fm, draw->data.text->length); + FrameMgrPutToken (fm, draw->data.text->string); + for (i = 0; i < feedback_count; i++) + FrameMgrPutToken (fm, draw->data.text->feedback[i]); + /*endfor*/ + break; + + case XIMBitmapType: + fm = FrameMgrInit (status_draw_bitmap_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + FrameMgrPutToken (fm, draw->data.bitmap); + break; + } + /*endswitch*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_STATUS_DRAW, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STATUS_DRAW is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStatusDoneCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec status_done_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMStatusCBStruct *status_CB = + (IMStatusCBStruct *) &call_data->status_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (status_done_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_STATUS_DONE, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STATUS_DONE is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStringConversionCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec str_conversion_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMStrConvCBStruct *call_back = + (IMStrConvCBStruct *) &call_data->strconv_callback; + XIMStringConversionCallbackStruct *strconv = + (XIMStringConversionCallbackStruct *) &call_back->strconv; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (str_conversion_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, call_back->icid); + FrameMgrPutToken (fm, strconv->position); + FrameMgrPutToken (fm, strconv->direction); + FrameMgrPutToken (fm, strconv->operation); + + _Xi18nSendMessage (ims, connect_id, + XIM_STR_CONVERSION, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STR_CONVERSION is a syncronous protocol, + so should wait here for XIM_STR_CONVERSION_REPLY. */ + if (i18n_core->methods.wait (ims, + connect_id, + XIM_STR_CONVERSION_REPLY, + 0) == False) + { + return False; + } + /*endif*/ + return True; +} diff --git a/ism/modules/frontend/imdkit/i18nIMProto.c b/ism/modules/frontend/imdkit/i18nIMProto.c new file mode 100755 index 0000000..526f622 --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nIMProto.c @@ -0,0 +1,773 @@ +/****************************************************************** +Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts, +Copyright 1993, 1994 by Hewlett-Packard Company + +Copyright 1994, 1995 by Sun Microsystems, Inc. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL DIGITAL AND HEWLETT-PACKARD COMPANY BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hiroyuki Miyamoto Digital Equipment Corporation + miyamoto@jrd.dec.com + Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +/* Protocol Packet frames */ + +#include "FrameMgr.h" + +/* Data type definitions */ + +static XimFrameRec ximattr_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* type of the value */ + _FRAME(BIT16), /* length of im-attribute */ + _FRAME(BARRAY), /* im-attribute */ + _PAD4(2), + _FRAME(EOL), +}; + +static XimFrameRec xicattr_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* type of the value */ + _FRAME(BIT16), /* length of ic-attribute */ + _FRAME(BARRAY), /* ic-attribute */ + _PAD4(2), + _FRAME(EOL), +}; + +static XimFrameRec ximattribute_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* value length */ + _FRAME(BARRAY), /* value */ + _PAD4(1), + _FRAME(EOL), +}; + +static XimFrameRec xicattribute_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* value length */ + _FRAME(BARRAY), /* value */ + _PAD4(1), + _FRAME(EOL), +}; + +static XimFrameRec ximtriggerkey_fr[] = +{ + _FRAME(BIT32), /* keysym */ + _FRAME(BIT32), /* modifier */ + _FRAME(BIT32), /* modifier mask */ + _FRAME(EOL), +}; + +static XimFrameRec encodinginfo_fr[] = +{ + _FRAME(BIT16), /* length of encoding info */ + _FRAME(BARRAY), /* encoding info */ + _PAD4(2), + _FRAME(EOL), +}; + +static XimFrameRec str_fr[] = +{ + _FRAME(BIT8), /* number of byte */ + _FRAME(BARRAY), /* string */ + _FRAME(EOL), +}; + +static XimFrameRec xpcs_fr[] = +{ + _FRAME(BIT16), /* length of string in bytes */ + _FRAME(BARRAY), /* string */ + _PAD4(2), +}; + +static XimFrameRec ext_fr[] = +{ + _FRAME(BIT16), /* extension major-opcode */ + _FRAME(BIT16), /* extension minor-opcode */ + _FRAME(BIT16), /* length of extension name */ + _FRAME(BARRAY), /* extension name */ + _PAD4(2), + _FRAME(EOL), +}; + +static XimFrameRec inputstyle_fr[] = +{ + _FRAME(BIT32), /* inputstyle */ + _FRAME(EOL), +}; +/* Protocol definitions */ + +xim_externaldef XimFrameRec attr_head_fr[] = +{ + _FRAME(BIT16), /* attribute id */ + _FRAME(BIT16), /* attribute length */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec short_fr[] = +{ + _FRAME(BIT16), /* value */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec long_fr[] = +{ + _FRAME(BIT32), /* value */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec xrectangle_fr[] = +{ + _FRAME(BIT16), /* x */ + _FRAME(BIT16), /* y */ + _FRAME(BIT16), /* width */ + _FRAME(BIT16), /* height */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec xpoint_fr[] = +{ + _FRAME(BIT16), /* x */ + _FRAME(BIT16), /* y */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec fontset_fr[] = +{ + _FRAME(BIT16), /* length of base font name */ + _FRAME(BARRAY), /* base font name list */ + _PAD4(2), /* unused */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec input_styles_fr[] = +{ + _FRAME(BIT16), /* number of list */ + _PAD4(1), /* unused */ + _FRAME(ITER), /* XIMStyle list */ + _FRAME(POINTER), + _PTR(inputstyle_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec packet_header_fr[] = +{ + _FRAME(BIT8), /* major-opcode */ + _FRAME(BIT8), /* minor-opcode */ + _FRAME(BIT16), /* length */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec error_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* Error Code */ + _FRAME(BIT16), /* length of error detail */ + _FRAME(BIT16), /* type of error detail */ + _FRAME(BARRAY), /* error detail */ + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec connect_fr[] = +{ + _FRAME(BIT8), /* byte order */ + _PAD2(1), /* unused */ + _FRAME(BIT16), /* client-major-protocol-version */ + _FRAME(BIT16), /* client-minor-protocol-version */ + _BYTE_COUNTER(BIT16, 1), /* length of client-auth-protocol-names */ + _FRAME(ITER), /* client-auth-protocol-names */ + _FRAME(POINTER), + _PTR(xpcs_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec connect_reply_fr[] = +{ + _FRAME(BIT16), /* server-major-protocol-version */ + _FRAME(BIT16), /* server-minor-protocol-version */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_required_fr[] = +{ + _FRAME(BIT8), /* auth-protocol-index */ + _FRAME(BIT8), /* auth-data1 */ + _FRAME(BARRAY), /* auth-data2 */ + _PAD4(3), + _FRAME(EOL), +}; + + +xim_externaldef XimFrameRec auth_reply_fr[] = +{ + _FRAME(BIT8), + _FRAME(BARRAY), + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_next_fr[] = +{ + _FRAME(BIT8), /* auth-data1 */ + _FRAME(BARRAY), /* auth-data2 */ + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_setup_fr[] = +{ + _BYTE_COUNTER(BIT16, 2), /* number of client-auth-protocol-names */ + _PAD4(1), /* unused */ + _FRAME(ITER), /* server-auth-protocol-names */ + _FRAME(POINTER), + _PTR(xpcs_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_ng_fr[] = +{ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec disconnect_fr[] = +{ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec disconnect_reply_fr[] = +{ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec open_fr[] = +{ + _FRAME(POINTER), /* locale name */ + _PTR(str_fr), + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec open_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of IM attributes supported */ + _FRAME(ITER), /* IM attribute supported */ + _FRAME(POINTER), + _PTR(ximattr_fr), + _BYTE_COUNTER(BIT16, 2), /* number of IC attribute supported */ + _PAD4(1), /* unused */ + _FRAME(ITER), /* IC attribute supported */ + _FRAME(POINTER), + _PTR(xicattr_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec close_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _PAD4(1), /* unused */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec close_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _PAD4(1), /* unused */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec register_triggerkeys_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _PAD4(1), /* unused */ + _BYTE_COUNTER(BIT32, 1), /* byte length of on-keys */ + _FRAME(ITER), /* on-keys list */ + _FRAME(POINTER), + _PTR(ximtriggerkey_fr), + _BYTE_COUNTER(BIT32, 1), /* byte length of off-keys */ + _FRAME(ITER), /* off-keys list */ + _FRAME(POINTER), + _PTR(ximtriggerkey_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec trigger_notify_fr[] = +{ + _FRAME(BIT16), /* input-mehotd-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* flag */ + _FRAME(BIT32), /* index of keys list */ + _FRAME(BIT32), /* client-select-event-mask */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec trigger_notify_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_event_mask_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* forward-event-mask */ + _FRAME(BIT32), /* synchronous-event-mask */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec encoding_negotiation_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of encodings listed by name */ + _FRAME(ITER), /* supported list of encoding in IM library */ + _FRAME(POINTER), + _PTR(str_fr), + _PAD4(1), + _BYTE_COUNTER(BIT16, 2), /* byte length of encodings listed by + detailed data */ + _PAD4(1), + _FRAME(ITER), /* list of encodings supported in the + IM library */ + _FRAME(POINTER), + _PTR(encodinginfo_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec encoding_negotiation_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* category of the encoding determined */ + _FRAME(BIT16), /* index of the encoding dterminated */ + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec query_extension_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of extensions supported + by the IM library */ + _FRAME(ITER), /* extensions supported by the IM library */ + _FRAME(POINTER), + _PTR(str_fr), + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec query_extension_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of extensions supported + by the IM server */ + _FRAME(ITER), /* list of extensions supported by the + IM server */ + _FRAME(POINTER), + _PTR(ext_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_im_values_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of im-attribute-id */ + _FRAME(ITER), /* im-attribute-id */ + _FRAME(BIT16), + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_im_values_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of im-attribute returned */ + _FRAME(ITER), /* im-attribute returned */ + _FRAME(POINTER), + _PTR(ximattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec create_ic_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of ic-attributes */ + _FRAME(ITER), /* ic-attributes */ + _FRAME(POINTER), + _PTR(xicattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec create_ic_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec destroy_ic_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec destroy_ic_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_ic_values_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _BYTE_COUNTER(BIT16, 2), /* byte length of ic-attributes */ + _PAD4(1), + _FRAME(ITER), /* ic-attribute */ + _FRAME(POINTER), + _PTR(xicattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_ic_values_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_ic_values_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of ic-attribute-id */ + _FRAME(ITER), /* ic-attribute */ + _FRAME(BIT16), + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_ic_values_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _BYTE_COUNTER(BIT16, 2), /* byte length of ic-attribute */ + _PAD4(1), + _FRAME(ITER), /* ic-attribute */ + _FRAME(POINTER), + _PTR(xicattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_ic_focus_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec unset_ic_focus_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec forward_event_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* sequence number */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec wire_keyevent_fr[] = { + _FRAME(BIT8), /* type */ + _FRAME(BIT8), /* detail */ + _FRAME(BIT16), /* serial number */ + _FRAME(BIT32), /* time */ + _FRAME(BIT32), /* root */ + _FRAME(BIT32), /* window */ + _FRAME(BIT32), /* subwindow */ + _FRAME(BIT16), /* rootX */ + _FRAME(BIT16), /* rootY */ + _FRAME(BIT16), /* X */ + _FRAME(BIT16), /* Y */ + _FRAME(BIT16), /* state */ + _FRAME(BIT8), /* sameScreen */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec sync_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec sync_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +#if 0 +xim_externaldef XimFrameRec commit_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(1), + _BYTE_COUNTER(BIT16, 1), /* byte length of keysym */ + _FRAME(ITER), /* keysym */ + _FRAME(BIT32), + _PAD4(1), + _FRAME(EOL), +}; +#endif + +xim_externaldef XimFrameRec commit_chars_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec commit_both_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _PAD4(1), /* unused */ + _FRAME(BIT32), /* keysym */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec reset_ic_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec reset_ic_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec geometry_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec str_conversion_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* XIMStringConversionPosition */ + _FRAME(BIT32), /* XIMStringConversionType */ + _FRAME(BIT32), /* XIMStringConversionOperation */ + _FRAME(BIT16), /* length to multiply the + XIMStringConversionType */ + _FRAME(BIT16), /* length of the string to be + substituted */ +#if 0 + _FRAME(BARRAY), /* string */ + _PAD4(1), +#endif + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec str_conversion_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* XIMStringConversionFeedback */ + _FRAME(BIT16), /* length of the retrieved string */ + _FRAME(BARRAY), /* retrieved string */ + _PAD4(2), + _BYTE_COUNTER(BIT16, 2), /* number of feedback array */ + _PAD4(1), + _FRAME(ITER), /* feedback array */ + _FRAME(BIT32), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_start_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_start_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* return value */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_draw_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* caret */ + _FRAME(BIT32), /* chg_first */ + _FRAME(BIT32), /* chg_length */ + _FRAME(BIT32), /* status */ + _FRAME(BIT16), /* length of preedit string */ + _FRAME(BARRAY), /* preedit string */ + _PAD4(2), + _BYTE_COUNTER(BIT16, 2), /* number of feedback array */ + _PAD4(1), + _FRAME(ITER), /* feedback array */ + _FRAME(BIT32), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_caret_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* position */ + _FRAME(BIT32), /* direction */ + _FRAME(BIT32), /* style */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_caret_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* position */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_done_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_start_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_draw_text_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* type */ + _FRAME(BIT32), /* status */ + _FRAME(BIT16), /* length of status string */ + _FRAME(BARRAY), /* status string */ + _PAD4(2), + _BYTE_COUNTER(BIT16, 2), /* number of feedback array */ + _PAD4(1), + _FRAME(ITER), /* feedback array */ + _FRAME(BIT32), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_draw_bitmap_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* type */ + _FRAME(BIT32), /* pixmap data */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_done_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec ext_set_event_mask_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* filter-event-mask */ + _FRAME(BIT32), /* intercept-event-mask */ + _FRAME(BIT32), /* select-event-mask */ + _FRAME(BIT32), /* forward-event-mask */ + _FRAME(BIT32), /* synchronous-event-mask */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec ext_forward_keyevent_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* sequence number */ + _FRAME(BIT8), /* xEvent.u.u.type */ + _FRAME(BIT8), /* keycode */ + _FRAME(BIT16), /* state */ + _FRAME(BIT32), /* time */ + _FRAME(BIT32), /* window */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec ext_move_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* X */ + _FRAME(BIT16), /* Y */ + _FRAME(EOL), +}; diff --git a/ism/modules/frontend/imdkit/i18nIc.c b/ism/modules/frontend/imdkit/i18nIc.c new file mode 100755 index 0000000..61b576f --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nIc.c @@ -0,0 +1,1106 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "FrameMgr.h" +#include "XimFunc.h" + +#define IC_SIZE 64 + +/* Set IC values */ +static void SetCardAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + FrameMgr fm; + + /*endif*/ + if (value_length == sizeof (CARD8)) + { + memmove (*value_buf, p, value_length); + } + else if (value_length == sizeof (CARD16)) + { + INT16 value; + extern XimFrameRec short_fr[]; + + fm = FrameMgrInit (short_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, value); + FrameMgrFree (fm); + memmove (*value_buf, &value, value_length); + } + else if (value_length == sizeof(CARD32)) + { + INT32 value; + extern XimFrameRec long_fr[]; + + fm = FrameMgrInit (long_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, value); + FrameMgrFree (fm); + memmove (*value_buf, &value, value_length); + } + /*endif*/ + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = *value_buf; + + *value_buf += value_length; +} + +static void SetFontAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + char *base_name; + CARD16 base_length; + FrameMgr fm; + extern XimFrameRec fontset_fr[]; + + fm = FrameMgrInit (fontset_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, base_length); + FrameMgrSetSize (fm, base_length); + + /*endif*/ + FrameMgrGetToken (fm, base_name); + FrameMgrFree(fm); + strncpy ((char *) (*value_buf), base_name, base_length); + ((char *) *value_buf)[base_length] = (char) 0; + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = *value_buf; + + *value_buf += (base_length + 1); +} + +static void SetPointAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + XPoint *buf; + FrameMgr fm; + extern XimFrameRec xpoint_fr[]; + + buf = (XPoint *) (*value_buf); + + fm = FrameMgrInit (xpoint_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, buf->x); + FrameMgrGetToken (fm, buf->y); + FrameMgrFree (fm); + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = (char *) buf; + + *value_buf += value_length; +} + +static void SetRectAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + XRectangle *buf; + FrameMgr fm; + extern XimFrameRec xrectangle_fr[]; + + buf = (XRectangle *) (*value_buf); + + fm = FrameMgrInit (xrectangle_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, buf->x); + FrameMgrGetToken (fm, buf->y); + FrameMgrGetToken (fm, buf->width); + FrameMgrGetToken (fm, buf->height); + FrameMgrFree (fm); + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = (char *) buf; + + *value_buf += value_length; +} + +#if 0 +static void SetHotKeyAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + INT32 list_number; + XIMTriggerKey *hotkeys; + + memmove (&list_number, p, sizeof(INT32)); p += sizeof(INT32); + + hotkeys = (XIMTriggerKey *) (*value_buf); + + memmove (hotkeys, p, list_number*sizeof (XIMTriggerKey)); + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = (char *) hotkeys; + + *value_buf += value_length; +} +#endif + +/* get IC values */ +static void GetAttrHeader (unsigned char *rec, + XICAttribute *list, + int need_swap) +{ + FrameMgr fm; + extern XimFrameRec attr_head_fr[]; + + fm = FrameMgrInit (attr_head_fr, (char *) rec, need_swap); + /* put data */ + FrameMgrPutToken (fm, list->attribute_id); + FrameMgrPutToken (fm, list->value_length); + FrameMgrFree (fm); +} + +static void GetCardAttribute (char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof (CARD16)*2; + + if (list->value_length == sizeof (CARD8)) + { + memmove (recp, list->value, list->value_length); + } + else if (list->value_length == sizeof (CARD16)) + { + INT16 *value = (INT16 *) list->value; + extern XimFrameRec short_fr[]; + + fm = FrameMgrInit (short_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, *value); + FrameMgrFree (fm); + } + else if (list->value_length == sizeof (CARD32)) + { + INT32 *value = (INT32 *) list->value; + extern XimFrameRec long_fr[]; + + fm = FrameMgrInit (long_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, *value); + FrameMgrFree (fm); + } + /*endif*/ +} + +static void GetFontAttribute(char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + extern XimFrameRec fontset_fr[]; + char *base_name = (char *) list->value; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof (CARD16)*2; + + fm = FrameMgrInit (fontset_fr, (char *)recp, need_swap); + /* put data */ + FrameMgrSetSize (fm, list->value_length); + FrameMgrPutToken (fm, list->value_length); + FrameMgrPutToken (fm, base_name); + FrameMgrFree (fm); +} + +static void GetRectAttribute (char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + extern XimFrameRec xrectangle_fr[]; + XRectangle *rect = (XRectangle *) list->value; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof(CARD16)*2; + + fm = FrameMgrInit (xrectangle_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, rect->x); + FrameMgrPutToken (fm, rect->y); + FrameMgrPutToken (fm, rect->width); + FrameMgrPutToken (fm, rect->height); + FrameMgrFree (fm); +} + +static void GetPointAttribute (char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + extern XimFrameRec xpoint_fr[]; + XPoint *rect = (XPoint *) list->value; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof(CARD16)*2; + + fm = FrameMgrInit (xpoint_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, rect->x); + FrameMgrPutToken (fm, rect->y); + FrameMgrFree (fm); +} + +static int ReadICValue (Xi18n i18n_core, + CARD16 icvalue_id, + int value_length, + void *p, + XICAttribute *value_ret, + CARD16 *number_ret, + int need_swap, + void **value_buf) +{ + XICAttr *ic_attr = i18n_core->address.xic_attr; + int i; + + *number_ret = (CARD16) 0; + + for (i = 0; i < i18n_core->address.ic_attr_num; i++, ic_attr++) + { + if (ic_attr->attribute_id == icvalue_id) + break; + /*endif*/ + } + /*endfor*/ + switch (ic_attr->type) + { + case XimType_NEST: + { + int total_length = 0; + CARD16 attribute_ID; + INT16 attribute_length; + unsigned char *p1 = (unsigned char *) p; + CARD16 ic_len = 0; + CARD16 number; + FrameMgr fm; + extern XimFrameRec attr_head_fr[]; + + while (total_length < value_length) + { + fm = FrameMgrInit (attr_head_fr, (char *) p1, need_swap); + /* get data */ + FrameMgrGetToken (fm, attribute_ID); + FrameMgrGetToken (fm, attribute_length); + FrameMgrFree (fm); + p1 += sizeof (CARD16)*2; + ReadICValue (i18n_core, + attribute_ID, + attribute_length, + p1, + (value_ret + ic_len), + &number, + need_swap, + value_buf); + ic_len++; + *number_ret += number; + p1 += attribute_length; + p1 += IMPAD (attribute_length); + total_length += (CARD16) sizeof(CARD16)*2 + + (INT16) attribute_length + + IMPAD (attribute_length); + } + /*endwhile*/ + return ic_len; + } + + case XimType_CARD8: + case XimType_CARD16: + case XimType_CARD32: + case XimType_Window: + SetCardAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + + case XimType_XFontSet: + SetFontAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + + case XimType_XRectangle: + SetRectAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + + case XimType_XPoint: + SetPointAttribute(value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + +#if 0 + case XimType_XIMHotKeyTriggers: + SetHotKeyAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; +#endif + } + /*endswitch*/ + return 0; +} + +static XICAttribute *CreateNestedList (CARD16 attr_id, + XICAttribute *list, + int number, + int need_swap) +{ + XICAttribute *nest_list = NULL; + register int i; + char *values = NULL; + char *valuesp; + int value_length = 0; + + if (number == 0) + return NULL; + /*endif*/ + for (i = 0; i < number; i++) + { + value_length += sizeof (CARD16)*2; + value_length += list[i].value_length; + value_length += IMPAD (list[i].value_length); + } + /*endfor*/ + if ((values = (char *) malloc (value_length)) == NULL) + return NULL; + /*endif*/ + memset (values, 0, value_length); + + valuesp = values; + for (i = 0; i < number; i++) + { + switch (list[i].type) + { + case XimType_CARD8: + case XimType_CARD16: + case XimType_CARD32: + case XimType_Window: + GetCardAttribute (valuesp, &list[i], need_swap); + break; + + case XimType_XFontSet: + GetFontAttribute (valuesp, &list[i], need_swap); + break; + + case XimType_XRectangle: + GetRectAttribute (valuesp, &list[i], need_swap); + break; + + case XimType_XPoint: + GetPointAttribute (valuesp, &list[i], need_swap); + break; + +#if 0 + case XimType_XIMHotKeyTriggers: + GetHotKeyAttribute (valuesp, &list[i], need_swap); + break; +#endif + } + /*endswitch*/ + valuesp += sizeof (CARD16)*2; + valuesp += list[i].value_length; + valuesp += IMPAD(list[i].value_length); + } + /*endfor*/ + + nest_list = (XICAttribute *) malloc (sizeof (XICAttribute)); + if (nest_list == NULL) + return NULL; + /*endif*/ + memset (nest_list, 0, sizeof (XICAttribute)); + nest_list->value = (void *) malloc (value_length); + if (nest_list->value == NULL) + return NULL; + /*endif*/ + memset (nest_list->value, 0, sizeof (value_length)); + + nest_list->attribute_id = attr_id; + nest_list->value_length = value_length; + memmove (nest_list->value, values, value_length); + + XFree (values); + return nest_list; +} + +static Bool IsNestedList (Xi18n i18n_core, CARD16 icvalue_id) +{ + XICAttr *ic_attr = i18n_core->address.xic_attr; + int i; + + for (i = 0; i < i18n_core->address.ic_attr_num; i++, ic_attr++) + { + if (ic_attr->attribute_id == icvalue_id) + { + if (ic_attr->type == XimType_NEST) + return True; + /*endif*/ + return False; + } + /*endif*/ + } + /*endfor*/ + return False; +} + +static Bool IsSeparator (Xi18n i18n_core, CARD16 icvalue_id) +{ + return (i18n_core->address.separatorAttr_id == icvalue_id); +} + +static int GetICValue (Xi18n i18n_core, + XICAttribute *attr_ret, + CARD16 *id_list, + int list_num) +{ + XICAttr *xic_attr = i18n_core->address.xic_attr; + register int i; + register int j; + register int n; + + i = + n = 0; + if (IsNestedList (i18n_core, id_list[i])) + { + i++; + while (i < list_num && !IsSeparator (i18n_core, id_list[i])) + { + for (j = 0; j < i18n_core->address.ic_attr_num; j++) + { + if (xic_attr[j].attribute_id == id_list[i]) + { + attr_ret[n].attribute_id = xic_attr[j].attribute_id; + attr_ret[n].name_length = xic_attr[j].length; + attr_ret[n].name = malloc (xic_attr[j].length + 1); + strcpy(attr_ret[n].name, xic_attr[j].name); + attr_ret[n].type = xic_attr[j].type; + n++; + i++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endwhile*/ + } + else + { + for (j = 0; j < i18n_core->address.ic_attr_num; j++) + { + if (xic_attr[j].attribute_id == id_list[i]) + { + attr_ret[n].attribute_id = xic_attr[j].attribute_id; + attr_ret[n].name_length = xic_attr[j].length; + attr_ret[n].name = malloc (xic_attr[j].length + 1); + strcpy(attr_ret[n].name, xic_attr[j].name); + attr_ret[n].type = xic_attr[j].type; + n++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endif*/ + return n; +} + +static void SwapAttributes (XICAttribute *list, + int number){ + FrameMgr fm; + CARD16 c16; + extern XimFrameRec short_fr[]; + CARD32 c32; + extern XimFrameRec long_fr[]; + XPoint xpoint; + extern XimFrameRec xpoint_fr[]; + XRectangle xrect; + extern XimFrameRec xrectangle_fr[]; + int i; + + for (i = 0; i < number; ++i, ++list) { + if (list->value == NULL) + continue; + switch (list->type) { + case XimType_CARD16: + fm = FrameMgrInit (short_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, c16); + memmove(list->value, &c16, sizeof(CARD16)); + FrameMgrFree (fm); + break; + case XimType_CARD32: + case XimType_Window: + fm = FrameMgrInit (long_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, c32); + memmove(list->value, &c32, sizeof(CARD32)); + FrameMgrFree (fm); + break; + case XimType_XRectangle: + fm = FrameMgrInit (xrectangle_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, xrect); + memmove(list->value, &xrect, sizeof(XRectangle)); + FrameMgrFree (fm); + break; + case XimType_XPoint: + fm = FrameMgrInit (xpoint_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, xpoint); + memmove(list->value, &xpoint, sizeof(XPoint)); + FrameMgrFree (fm); + break; + default: + break; + } + } +} + +/* called from CreateICMessageProc and SetICValueMessageProc */ +void _Xi18nChangeIC (XIMS ims, + IMProtocol *call_data, + unsigned char *p, + int create_flag) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + CARD16 byte_length; + register int total_size; + unsigned char *reply = NULL; + register int i; + register int attrib_num; + XICAttribute *attrib_list; + XICAttribute pre_attr[IC_SIZE]; + XICAttribute sts_attr[IC_SIZE]; + XICAttribute ic_attr[IC_SIZE]; + CARD16 preedit_ic_num = 0; + CARD16 status_ic_num = 0; + CARD16 ic_num = 0; + CARD16 connect_id = call_data->any.connect_id; + IMChangeICStruct *changeic = (IMChangeICStruct *) &call_data->changeic; + extern XimFrameRec create_ic_fr[]; + extern XimFrameRec create_ic_reply_fr[]; + extern XimFrameRec set_ic_values_fr[]; + extern XimFrameRec set_ic_values_reply_fr[]; + CARD16 input_method_ID; + + void *value_buf = NULL; + void *value_buf_ptr; + + register int total_value_length = 0; + + memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE); + + if (create_flag == True) + { + fm = FrameMgrInit (create_ic_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + } + else + { + fm = FrameMgrInit (set_ic_values_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, changeic->icid); + FrameMgrGetToken (fm, byte_length); + } + /*endif*/ + attrib_list = (XICAttribute *) malloc (sizeof (XICAttribute)*IC_SIZE); + if (!attrib_list) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (attrib_list, 0, sizeof(XICAttribute)*IC_SIZE); + + attrib_num = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + void *value; + int value_length; + + FrameMgrGetToken (fm, attrib_list[attrib_num].attribute_id); + FrameMgrGetToken (fm, value_length); + FrameMgrSetSize (fm, value_length); + attrib_list[attrib_num].value_length = value_length; + FrameMgrGetToken (fm, value); + attrib_list[attrib_num].value = (void *) malloc (value_length + 1); + memmove (attrib_list[attrib_num].value, value, value_length); + ((char *)attrib_list[attrib_num].value)[value_length] = '\0'; + attrib_num++; + total_value_length += (value_length + 1); + } + /*endwhile*/ + + value_buf = (void *) malloc (total_value_length); + value_buf_ptr = value_buf; + + if (!value_buf) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + for (i = 0; i < attrib_num; i++) + XFree (attrib_list[i].value); + /*endfor*/ + XFree (attrib_list); + return; + } + /*endif*/ + + for (i = 0; i < attrib_num; i++) + { + CARD16 number; + + if (IsNestedList (i18n_core, attrib_list[i].attribute_id)) + { + if (attrib_list[i].attribute_id + == i18n_core->address.preeditAttr_id) + { + ReadICValue (i18n_core, + attrib_list[i].attribute_id, + attrib_list[i].value_length, + attrib_list[i].value, + &pre_attr[preedit_ic_num], + &number, + _Xi18nNeedSwap(i18n_core, connect_id), + &value_buf_ptr); + preedit_ic_num += number; + } + else if (attrib_list[i].attribute_id == i18n_core->address.statusAttr_id) + { + ReadICValue (i18n_core, + attrib_list[i].attribute_id, + attrib_list[i].value_length, + attrib_list[i].value, + &sts_attr[status_ic_num], + &number, + _Xi18nNeedSwap (i18n_core, connect_id), + &value_buf_ptr); + status_ic_num += number; + } + else + { + /* another nested list.. possible? */ + } + /*endif*/ + } + else + { + ReadICValue (i18n_core, + attrib_list[i].attribute_id, + attrib_list[i].value_length, + attrib_list[i].value, + &ic_attr[ic_num], + &number, + _Xi18nNeedSwap (i18n_core, connect_id), + &value_buf_ptr); + ic_num += number; + } + /*endif*/ + } + /*endfor*/ + for (i = 0; i < attrib_num; i++) + XFree (attrib_list[i].value); + /*endfor*/ + XFree (attrib_list); + + FrameMgrFree (fm); + + changeic->preedit_attr_num = preedit_ic_num; + changeic->status_attr_num = status_ic_num; + changeic->ic_attr_num = ic_num; + changeic->preedit_attr = pre_attr; + changeic->status_attr = sts_attr; + changeic->ic_attr = ic_attr; + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) { + XFree (value_buf); + return; + } + /*endif*/ + } + + XFree (value_buf); + + /*endif*/ + if (create_flag == True) + { + fm = FrameMgrInit (create_ic_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + } + else + { + fm = FrameMgrInit (set_ic_values_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + } + /*endif*/ + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, changeic->icid); + + if (create_flag == True) + { + _Xi18nSendMessage (ims, + connect_id, + XIM_CREATE_IC_REPLY, + 0, + reply, + total_size); + } + else + { + _Xi18nSendMessage (ims, + connect_id, + XIM_SET_IC_VALUES_REPLY, + 0, + reply, + total_size); + } + /*endif*/ + if (create_flag == True) + { + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + + if (on_key_num == 0 && off_key_num == 0) + { + long mask; + + if (i18n_core->address.imvalue_mask & I18N_FILTERMASK) + mask = i18n_core->address.filterevent_mask; + else + mask = DEFAULT_FILTER_MASK; + /*endif*/ + /* static event flow is default */ + _Xi18nSetEventMask (ims, + connect_id, + input_method_ID, + changeic->icid, + mask, + ~mask); + } + /*endif*/ + } + /*endif*/ + FrameMgrFree (fm); + XFree(reply); +} + +/* called from GetICValueMessageProc */ +void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + extern XimFrameRec get_ic_values_fr[]; + extern XimFrameRec get_ic_values_reply_fr[]; + CARD16 byte_length; + register int total_size; + unsigned char *reply = NULL; + XICAttribute *preedit_ret = NULL; + XICAttribute *status_ret = NULL; + register int i; + register int number; + int iter_count; + CARD16 *attrID_list; + XICAttribute pre_attr[IC_SIZE]; + XICAttribute sts_attr[IC_SIZE]; + XICAttribute ic_attr[IC_SIZE]; + CARD16 pre_count = 0; + CARD16 sts_count = 0; + CARD16 ic_count = 0; + IMChangeICStruct *getic = (IMChangeICStruct *) &call_data->changeic; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE); + + fm = FrameMgrInit (get_ic_values_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, getic->icid); + FrameMgrGetToken (fm, byte_length); + + attrID_list = (CARD16 *) malloc (sizeof (CARD16)*IC_SIZE); /* bogus */ + memset (attrID_list, 0, sizeof (CARD16)*IC_SIZE); + + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + FrameMgrGetToken (fm, attrID_list[number++]); + /*endwhile*/ + FrameMgrFree (fm); + + i = 0; + while (i < number) + { + int read_number; + + if (IsNestedList (i18n_core, attrID_list[i])) + { + if (attrID_list[i] == i18n_core->address.preeditAttr_id) + { + read_number = GetICValue (i18n_core, + &pre_attr[pre_count], + &attrID_list[i], + number); + i += read_number + 1; + pre_count += read_number; + } + else if (attrID_list[i] == i18n_core->address.statusAttr_id) + { + read_number = GetICValue (i18n_core, + &sts_attr[sts_count], + &attrID_list[i], + number); + i += read_number + 1; + sts_count += read_number; + } + else + { + /* another nested list.. possible? */ + } + /*endif*/ + } + else + { + read_number = GetICValue (i18n_core, + &ic_attr[ic_count], + &attrID_list[i], + number); + i += read_number; + ic_count += read_number; + } + /*endif*/ + } + /*endwhile*/ + getic->preedit_attr_num = pre_count; + getic->status_attr_num = sts_count; + getic->ic_attr_num = ic_count; + getic->preedit_attr = pre_attr; + getic->status_attr = sts_attr; + getic->ic_attr = ic_attr; + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + if (_Xi18nNeedSwap (i18n_core, connect_id)) + SwapAttributes(getic->ic_attr, getic->ic_attr_num); + } + /*endif*/ + iter_count = getic->ic_attr_num; + + preedit_ret = CreateNestedList (i18n_core->address.preeditAttr_id, + getic->preedit_attr, + getic->preedit_attr_num, + _Xi18nNeedSwap (i18n_core, connect_id)); + if (preedit_ret) + iter_count++; + /*endif*/ + status_ret = CreateNestedList (i18n_core->address.statusAttr_id, + getic->status_attr, + getic->status_attr_num, + _Xi18nNeedSwap (i18n_core, connect_id)); + if (status_ret) + iter_count++; + /*endif*/ + + fm = FrameMgrInit (get_ic_values_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of ic_attribute */ + FrameMgrSetIterCount (fm, iter_count); + + /* set length of BARRAY item in xicattribute_fr */ + for (i = 0; i < (int) getic->ic_attr_num; i++) + FrameMgrSetSize (fm, ic_attr[i].value_length); + /*endfor*/ + + if (preedit_ret) + FrameMgrSetSize (fm, preedit_ret->value_length); + /*endif*/ + if (status_ret) + FrameMgrSetSize (fm, status_ret->value_length); + /*endif*/ + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (reply == NULL) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, getic->icid); + + for (i = 0; i < (int) getic->ic_attr_num; i++) + { + FrameMgrPutToken (fm, ic_attr[i].attribute_id); + FrameMgrPutToken (fm, ic_attr[i].value_length); + FrameMgrPutToken (fm, ic_attr[i].value); + } + /*endfor*/ + if (preedit_ret) + { + FrameMgrPutToken (fm, preedit_ret->attribute_id); + FrameMgrPutToken (fm, preedit_ret->value_length); + FrameMgrPutToken (fm, preedit_ret->value); + } + /*endif*/ + if (status_ret) + { + FrameMgrPutToken (fm, status_ret->attribute_id); + FrameMgrPutToken (fm, status_ret->value_length); + FrameMgrPutToken (fm, status_ret->value); + } + /*endif*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_GET_IC_VALUES_REPLY, + 0, + reply, + total_size); + XFree (reply); + XFree (attrID_list); + + for (i = 0; i < (int) getic->ic_attr_num; i++) + { + if (getic->ic_attr[i].name) + XFree (getic->ic_attr[i].name); + /*endif*/ + if (getic->ic_attr[i].value) + XFree (getic->ic_attr[i].value); + /*endif*/ + } + /*endfor*/ + for (i = 0; i < (int) getic->preedit_attr_num; i++) + { + if (getic->preedit_attr[i].name) + XFree (getic->preedit_attr[i].name); + /*endif*/ + if (getic->preedit_attr[i].value) + XFree (getic->preedit_attr[i].value); + /*endif*/ + } + /*endfor*/ + for (i = 0; i < (int) getic->status_attr_num; i++) + { + if (getic->status_attr[i].name) + XFree (getic->status_attr[i].name); + /*endif*/ + if (getic->status_attr[i].value) + XFree (getic->status_attr[i].value); + /*endif*/ + } + /*endfor*/ + + if (preedit_ret) + { + XFree (preedit_ret->value); + XFree (preedit_ret); + } + /*endif*/ + if (status_ret) + { + XFree (status_ret->value); + XFree (status_ret); + } + /*endif*/ + FrameMgrFree (fm); +} diff --git a/ism/modules/frontend/imdkit/i18nMethod.c b/ism/modules/frontend/imdkit/i18nMethod.c new file mode 100755 index 0000000..203f831 --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nMethod.c @@ -0,0 +1,1150 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#ifndef NEED_EVENTS +#define NEED_EVENTS +#endif +#include +#undef NEED_EVENTS +#include "FrameMgr.h" +#include "IMdkit.h" +#include "Xi18n.h" +#include "XimFunc.h" + +extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16); + +static void *xi18n_setup (Display *, XIMArg *); +static Status xi18n_openIM (XIMS); +static Status xi18n_closeIM (XIMS); +static char *xi18n_setIMValues (XIMS, XIMArg *); +static char *xi18n_getIMValues (XIMS, XIMArg *); +static Status xi18n_forwardEvent (XIMS, XPointer); +static Status xi18n_commit (XIMS, XPointer); +static int xi18n_callCallback (XIMS, XPointer); +static int xi18n_preeditStart (XIMS, XPointer); +static int xi18n_preeditEnd (XIMS, XPointer); +static int xi18n_syncXlib (XIMS, XPointer); + +#ifndef XIM_SERVERS +#define XIM_SERVERS "XIM_SERVERS" +#endif +static Atom XIM_Servers = None; + + +IMMethodsRec Xi18n_im_methods = +{ + xi18n_setup, + xi18n_openIM, + xi18n_closeIM, + xi18n_setIMValues, + xi18n_getIMValues, + xi18n_forwardEvent, + xi18n_commit, + xi18n_callCallback, + xi18n_preeditStart, + xi18n_preeditEnd, + xi18n_syncXlib, +}; + +extern Bool _Xi18nCheckXAddress (Xi18n, TransportSW *, char *); +extern Bool _Xi18nCheckTransAddress (Xi18n, TransportSW *, char *); + +TransportSW _TransR[] = +{ + {"X", 1, _Xi18nCheckXAddress}, +#ifdef TCPCONN + {"tcp", 3, _Xi18nCheckTransAddress}, + {"local", 5, _Xi18nCheckTransAddress}, +#endif +#ifdef DNETCONN + {"decnet", 6, _Xi18nCheckTransAddress}, +#endif + {(char *) NULL, 0, (Bool (*) ()) NULL} +}; + +static Bool GetInputStyles (Xi18n i18n_core, XIMStyles **p_style) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMStyles *p; + int i; + + p = &address->input_styles; + if ((*p_style = (XIMStyles *) malloc (sizeof (XIMStyles) + + p->count_styles*sizeof (XIMStyle))) + == NULL) + { + return False; + } + /*endif*/ + (*p_style)->count_styles = p->count_styles; + (*p_style)->supported_styles = (XIMStyle *) ((XPointer) *p_style + sizeof (XIMStyles)); + for (i = 0; i < (int) p->count_styles; i++) + (*p_style)->supported_styles[i] = p->supported_styles[i]; + /*endfor*/ + return True; +} + +static Bool GetOnOffKeys (Xi18n i18n_core, long mask, XIMTriggerKeys **p_key) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMTriggerKeys *p; + int i; + + if (mask & I18N_ON_KEYS) + p = &address->on_keys; + else + p = &address->off_keys; + /*endif*/ + if ((*p_key = (XIMTriggerKeys *) malloc (sizeof(XIMTriggerKeys) + + p->count_keys*sizeof(XIMTriggerKey))) + == NULL) + { + return False; + } + /*endif*/ + (*p_key)->count_keys = p->count_keys; + (*p_key)->keylist = + (XIMTriggerKey *) ((XPointer) *p_key + sizeof(XIMTriggerKeys)); + for (i = 0; i < (int) p->count_keys; i++) + { + (*p_key)->keylist[i].keysym = p->keylist[i].keysym; + (*p_key)->keylist[i].modifier = p->keylist[i].modifier; + (*p_key)->keylist[i].modifier_mask = p->keylist[i].modifier_mask; + } + /*endfor*/ + return True; +} + +static Bool GetEncodings(Xi18n i18n_core, XIMEncodings **p_encoding) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMEncodings *p; + int i; + + p = &address->encoding_list; + + if ((*p_encoding = (XIMEncodings *) malloc (sizeof (XIMEncodings) + + p->count_encodings*sizeof(XIMEncoding))) == NULL) + { + return False; + } + /*endif*/ + (*p_encoding)->count_encodings = p->count_encodings; + (*p_encoding)->supported_encodings = + (XIMEncoding *) ((XPointer)*p_encoding + sizeof (XIMEncodings)); + for (i = 0; i < (int) p->count_encodings; i++) + { + (*p_encoding)->supported_encodings[i] + = (char *) malloc (strlen (p->supported_encodings[i]) + 1); + strcpy ((*p_encoding)->supported_encodings[i], + p->supported_encodings[i]); + } + /*endif*/ + return True; +} + +static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMArg *p; + + if (mode == I18N_OPEN || mode == I18N_SET) + { + for (p = args; p->name != NULL; p++) + { + if (strcmp (p->name, IMLocale) == 0) + { + if (address->imvalue_mask & I18N_IM_LOCALE) + return IMLocale; + /*endif*/ + address->im_locale = (char *) malloc (strlen (p->value) + 1); + if (!address->im_locale) + return IMLocale; + /*endif*/ + strcpy (address->im_locale, p->value); + address->imvalue_mask |= I18N_IM_LOCALE; + } + else if (strcmp (p->name, IMServerTransport) == 0) + { + if (address->imvalue_mask & I18N_IM_ADDRESS) + return IMServerTransport; + /*endif*/ + address->im_addr = (char *) malloc (strlen (p->value) + 1); + if (!address->im_addr) + return IMServerTransport; + /*endif*/ + strcpy(address->im_addr, p->value); + address->imvalue_mask |= I18N_IM_ADDRESS; + } + else if (strcmp (p->name, IMServerName) == 0) + { + if (address->imvalue_mask & I18N_IM_NAME) + return IMServerName; + /*endif*/ + address->im_name = (char *) malloc (strlen (p->value) + 1); + if (!address->im_name) + return IMServerName; + /*endif*/ + strcpy (address->im_name, p->value); + address->imvalue_mask |= I18N_IM_NAME; + } + else if (strcmp (p->name, IMServerWindow) == 0) + { + if (address->imvalue_mask & I18N_IMSERVER_WIN) + return IMServerWindow; + /*endif*/ + address->im_window = (Window) p->value; + address->imvalue_mask |= I18N_IMSERVER_WIN; + } + else if (strcmp (p->name, IMInputStyles) == 0) + { + if (address->imvalue_mask & I18N_INPUT_STYLES) + return IMInputStyles; + /*endif*/ + address->input_styles.count_styles = + ((XIMStyles*)p->value)->count_styles; + address->input_styles.supported_styles = + (XIMStyle *) malloc (sizeof (XIMStyle)*address->input_styles.count_styles); + if (address->input_styles.supported_styles == (XIMStyle *) NULL) + return IMInputStyles; + /*endif*/ + memmove (address->input_styles.supported_styles, + ((XIMStyles *) p->value)->supported_styles, + sizeof (XIMStyle)*address->input_styles.count_styles); + address->imvalue_mask |= I18N_INPUT_STYLES; + } + else if (strcmp (p->name, IMProtocolHandler) == 0) + { + address->improto = (IMProtoHandler) p->value; + address->imvalue_mask |= I18N_IM_HANDLER; + } + else if (strcmp (p->name, IMOnKeysList) == 0) + { + if (address->imvalue_mask & I18N_ON_KEYS) + return IMOnKeysList; + /*endif*/ + address->on_keys.count_keys = + ((XIMTriggerKeys *) p->value)->count_keys; + address->on_keys.keylist = + (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->on_keys.count_keys); + if (address->on_keys.keylist == (XIMTriggerKey *) NULL) + return IMOnKeysList; + /*endif*/ + memmove (address->on_keys.keylist, + ((XIMTriggerKeys *) p->value)->keylist, + sizeof (XIMTriggerKey)*address->on_keys.count_keys); + address->imvalue_mask |= I18N_ON_KEYS; + } + else if (strcmp (p->name, IMOffKeysList) == 0) + { + if (address->imvalue_mask & I18N_OFF_KEYS) + return IMOffKeysList; + /*endif*/ + address->off_keys.count_keys = + ((XIMTriggerKeys *) p->value)->count_keys; + address->off_keys.keylist = + (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->off_keys.count_keys); + if (address->off_keys.keylist == (XIMTriggerKey *) NULL) + return IMOffKeysList; + /*endif*/ + memmove (address->off_keys.keylist, + ((XIMTriggerKeys *) p->value)->keylist, + sizeof (XIMTriggerKey)*address->off_keys.count_keys); + address->imvalue_mask |= I18N_OFF_KEYS; + } + else if (strcmp (p->name, IMEncodingList) == 0) + { + if (address->imvalue_mask & I18N_ENCODINGS) + return IMEncodingList; + /*endif*/ + address->encoding_list.count_encodings = + ((XIMEncodings *) p->value)->count_encodings; + address->encoding_list.supported_encodings = + (XIMEncoding *) malloc (sizeof (XIMEncoding)*address->encoding_list.count_encodings); + if (address->encoding_list.supported_encodings + == (XIMEncoding *) NULL) + { + return IMEncodingList; + } + /*endif*/ + memmove (address->encoding_list.supported_encodings, + ((XIMEncodings *) p->value)->supported_encodings, + sizeof (XIMEncoding)*address->encoding_list.count_encodings); + address->imvalue_mask |= I18N_ENCODINGS; + } + else if (strcmp (p->name, IMFilterEventMask) == 0) + { + if (address->imvalue_mask & I18N_FILTERMASK) + return IMFilterEventMask; + /*endif*/ + address->filterevent_mask = (long) p->value; + address->imvalue_mask |= I18N_FILTERMASK; + } + /*endif*/ + } + /*endfor*/ + if (mode == I18N_OPEN) + { + /* check mandatory IM values */ + if (!(address->imvalue_mask & I18N_IM_LOCALE)) + { + /* locales must be set in IMOpenIM */ + return IMLocale; + } + /*endif*/ + if (!(address->imvalue_mask & I18N_IM_ADDRESS)) + { + /* address must be set in IMOpenIM */ + return IMServerTransport; + } + /*endif*/ + } + /*endif*/ + } + else if (mode == I18N_GET) + { + for (p = args; p->name != NULL; p++) + { + if (strcmp (p->name, IMLocale) == 0) + { + p->value = (char *) malloc (strlen (address->im_locale) + 1); + if (!p->value) + return IMLocale; + /*endif*/ + strcpy (p->value, address->im_locale); + } + else if (strcmp (p->name, IMServerTransport) == 0) + { + p->value = (char *) malloc (strlen (address->im_addr) + 1); + if (!p->value) + return IMServerTransport; + /*endif*/ + strcpy (p->value, address->im_addr); + } + else if (strcmp (p->name, IMServerName) == 0) + { + if (address->imvalue_mask & I18N_IM_NAME) + { + p->value = (char *) malloc (strlen (address->im_name) + 1); + if (!p->value) + return IMServerName; + /*endif*/ + strcpy (p->value, address->im_name); + } + else + { + return IMServerName; + } + /*endif*/ + } + else if (strcmp (p->name, IMServerWindow) == 0) + { + if (address->imvalue_mask & I18N_IMSERVER_WIN) + *((Window *) (p->value)) = address->im_window; + else + return IMServerWindow; + /*endif*/ + } + else if (strcmp (p->name, IMInputStyles) == 0) + { + if (GetInputStyles (i18n_core, + (XIMStyles **) p->value) == False) + { + return IMInputStyles; + } + /*endif*/ + } + else if (strcmp (p->name, IMProtocolHandler) == 0) + { + if (address->imvalue_mask & I18N_IM_HANDLER) + *((IMProtoHandler *) (p->value)) = address->improto; + else + return IMProtocolHandler; + /*endif*/ + } + else if (strcmp (p->name, IMOnKeysList) == 0) + { + if (address->imvalue_mask & I18N_ON_KEYS) + { + if (GetOnOffKeys (i18n_core, + I18N_ON_KEYS, + (XIMTriggerKeys **) p->value) == False) + { + return IMOnKeysList; + } + /*endif*/ + } + else + { + return IMOnKeysList; + } + /*endif*/ + } + else if (strcmp (p->name, IMOffKeysList) == 0) + { + if (address->imvalue_mask & I18N_OFF_KEYS) + { + if (GetOnOffKeys (i18n_core, + I18N_OFF_KEYS, + (XIMTriggerKeys **) p->value) == False) + { + return IMOffKeysList; + } + /*endif*/ + } + else + { + return IMOffKeysList; + } + /*endif*/ + } + else if (strcmp (p->name, IMEncodingList) == 0) + { + if (address->imvalue_mask & I18N_ENCODINGS) + { + if (GetEncodings (i18n_core, + (XIMEncodings **) p->value) == False) + { + return IMEncodingList; + } + /*endif*/ + } + else + { + return IMEncodingList; + } + /*endif*/ + } + else if (strcmp (p->name, IMFilterEventMask) == 0) + { + if (address->imvalue_mask & I18N_FILTERMASK) + *((long *) (p->value)) = address->filterevent_mask; + else + return IMFilterEventMask; + /*endif*/ + } + /*endif*/ + } + /*endfor*/ + } + /*endif*/ + return NULL; +} + +static int CheckIMName (Xi18n i18n_core) +{ + char *address = i18n_core->address.im_addr; + int i; + + for (i = 0; _TransR[i].transportname; i++) + { + while (*address == ' ' || *address == '\t') + address++; + /*endwhile*/ + if (strncmp (address, + _TransR[i].transportname, + _TransR[i].namelen) == 0 + && + address[_TransR[i].namelen] == '/') + { + if (_TransR[i].checkAddr (i18n_core, + &_TransR[i], + address + _TransR[i].namelen + 1) == True) + { + return True; + } + /*endif*/ + return False; + } + /*endif*/ + } + /*endfor*/ + return False; +} + +static int SetXi18nSelectionOwner(Xi18n i18n_core) +{ + Display *dpy = i18n_core->address.dpy; + Window ims_win = i18n_core->address.im_window; + Window root = RootWindow (dpy, DefaultScreen (dpy)); + Atom realtype; + int realformat; + unsigned long bytesafter; + long *data=NULL; + unsigned long length; + Atom atom; + int i; + int found; + int forse = False; + char buf[256]; + + (void)snprintf(buf, 256, "@server=%s", i18n_core->address.im_name); + if ((atom = XInternAtom(dpy, buf, False)) == 0) + return False; + i18n_core->address.selection = atom; + + if (XIM_Servers == None) + XIM_Servers = XInternAtom (dpy, XIM_SERVERS, False); + /*endif*/ + XGetWindowProperty (dpy, + root, + XIM_Servers, + 0L, + 1000000L, + False, + XA_ATOM, + &realtype, + &realformat, + &length, + &bytesafter, + (unsigned char **) (&data)); + if (realtype != None && (realtype != XA_ATOM || realformat != 32)) { + if (data != NULL) + XFree ((char *) data); + return False; + } + + found = False; + for (i = 0; i < length; i++) { + if (data[i] == atom) { + Window owner; + found = True; + if ((owner = XGetSelectionOwner (dpy, atom)) != ims_win) { + if (owner == None || forse == True) + XSetSelectionOwner (dpy, atom, ims_win, CurrentTime); + else + return False; + } + break; + } + } + + if (found == False) { + XSetSelectionOwner (dpy, atom, ims_win, CurrentTime); + XChangeProperty (dpy, + root, + XIM_Servers, + XA_ATOM, + 32, + PropModePrepend, + (unsigned char *) &atom, + 1); + } + else { + /* + * We always need to generate the PropertyNotify to the Root Window + */ + XChangeProperty (dpy, + root, + XIM_Servers, + XA_ATOM, + 32, + PropModePrepend, + (unsigned char *) data, + 0); + } + if (data != NULL) + XFree ((char *) data); + + /* Intern "LOCALES" and "TRANSOPORT" Target Atoms */ + i18n_core->address.Localename = XInternAtom (dpy, LOCALES, False); + i18n_core->address.Transportname = XInternAtom (dpy, TRANSPORT, False); + return (XGetSelectionOwner (dpy, atom) == ims_win); +} + +static int DeleteXi18nAtom(Xi18n i18n_core) +{ + Display *dpy = i18n_core->address.dpy; + Window root = RootWindow (dpy, DefaultScreen (dpy)); + Atom realtype; + int realformat; + unsigned long bytesafter; + long *data=NULL; + unsigned long length; + Atom atom; + int i, ret; + int found; + char buf[256]; + + (void)snprintf(buf, 256, "@server=%s", i18n_core->address.im_name); + if ((atom = XInternAtom(dpy, buf, False)) == 0) + return False; + i18n_core->address.selection = atom; + + if (XIM_Servers == None) + XIM_Servers = XInternAtom (dpy, XIM_SERVERS, False); + XGetWindowProperty (dpy, + root, + XIM_Servers, + 0L, + 1000000L, + False, + XA_ATOM, + &realtype, + &realformat, + &length, + &bytesafter, + (unsigned char **) (&data)); + if (realtype != XA_ATOM || realformat != 32) { + if (data != NULL) + XFree ((char *) data); + return False; + } + + found = False; + for (i = 0; i < length; i++) { + if (data[i] == atom) { + found = True; + break; + } + } + + if (found == True) { + for (i=i+1; iaddress.dpy = dpy; + + if (ParseArgs (i18n_core, I18N_OPEN, args) != NULL) + { + XFree (i18n_core); + return NULL; + } + /*endif*/ + if (*(char *) &endian) + i18n_core->address.im_byteOrder = 'l'; + else + i18n_core->address.im_byteOrder = 'B'; + /*endif*/ + + /* install IMAttr and ICAttr list in i18n_core */ + _Xi18nInitAttrList (i18n_core); + + /* install IMExtension list in i18n_core */ + _Xi18nInitExtension (i18n_core); + + return i18n_core; +} + +static void ReturnSelectionNotify (Xi18n i18n_core, XSelectionRequestEvent *ev) +{ + XEvent event; + Display *dpy = i18n_core->address.dpy; + char buf[4096]; + + event.type = SelectionNotify; + event.xselection.requestor = ev->requestor; + event.xselection.selection = ev->selection; + event.xselection.target = ev->target; + event.xselection.time = ev->time; + event.xselection.property = ev->property; + if (ev->target == i18n_core->address.Localename) + { + snprintf (buf, 4096, "@locale=%s", i18n_core->address.im_locale); + } + else if (ev->target == i18n_core->address.Transportname) + { + snprintf (buf, 4096, "@transport=%s", i18n_core->address.im_addr); + } + /*endif*/ + XChangeProperty (dpy, + event.xselection.requestor, + ev->target, + ev->target, + 8, + PropModeReplace, + (unsigned char *) buf, + strlen (buf)); + XSendEvent (dpy, event.xselection.requestor, False, NoEventMask, &event); + XFlush (i18n_core->address.dpy); +} + +static Bool WaitXSelectionRequest (Display *dpy, + Window win, + XEvent *ev, + XPointer client_data) +{ + XIMS ims = (XIMS) client_data; + Xi18n i18n_core = ims->protocol; + + if (((XSelectionRequestEvent *) ev)->selection + == i18n_core->address.selection) + { + ReturnSelectionNotify (i18n_core, (XSelectionRequestEvent *) ev); + return True; + } + /*endif*/ + return False; +} + +static Status xi18n_openIM(XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + + if (!CheckIMName (i18n_core) + || + !SetXi18nSelectionOwner (i18n_core) + || + !i18n_core->methods.begin (ims)) + { + XFree (i18n_core->address.im_name); + XFree (i18n_core->address.im_locale); + XFree (i18n_core->address.im_addr); + XFree (i18n_core); + return False; + } + /*endif*/ + + _XRegisterFilterByType (dpy, + i18n_core->address.im_window, + SelectionRequest, + SelectionRequest, + WaitXSelectionRequest, + (XPointer)ims); + XFlush(dpy); + return True; +} + +static Status xi18n_closeIM(XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + + DeleteXi18nAtom(i18n_core); + if (!i18n_core->methods.end (ims)) + return False; + + _XUnregisterFilter (dpy, + i18n_core->address.im_window, + WaitXSelectionRequest, + (XPointer)ims); + XFree (i18n_core->address.im_name); + XFree (i18n_core->address.im_locale); + XFree (i18n_core->address.im_addr); + XFree (i18n_core); + return True; +} + +static char *xi18n_setIMValues (XIMS ims, XIMArg *args) +{ + Xi18n i18n_core = ims->protocol; + char *ret; + + if ((ret = ParseArgs (i18n_core, I18N_SET, args)) != NULL) + return ret; + /*endif*/ + return NULL; +} + +static char *xi18n_getIMValues (XIMS ims, XIMArg *args) +{ + Xi18n i18n_core = ims->protocol; + char *ret; + + if ((ret = ParseArgs (i18n_core, I18N_GET, args)) != NULL) + return ret; + /*endif*/ + return NULL; +} + +static void EventToWireEvent (XEvent *ev, xEvent *event, + CARD16 *serial, Bool byte_swap) +{ + FrameMgr fm; + extern XimFrameRec wire_keyevent_fr[]; + extern XimFrameRec short_fr[]; + BYTE b; + CARD16 c16; + CARD32 c32; + + *serial = (CARD16)(ev->xany.serial >> 16); + switch (ev->type) { + case KeyPress: + case KeyRelease: + { + XKeyEvent *kev = (XKeyEvent*)ev; + /* create FrameMgr */ + fm = FrameMgrInit(wire_keyevent_fr, (char *)(&(event->u)), byte_swap); + + /* set values */ + b = (BYTE)kev->type; FrameMgrPutToken(fm, b); + b = (BYTE)kev->keycode; FrameMgrPutToken(fm, b); + c16 = (CARD16)(kev->serial & (unsigned long)0xffff); + FrameMgrPutToken(fm, c16); + c32 = (CARD32)kev->time; FrameMgrPutToken(fm, c32); + c32 = (CARD32)kev->root; FrameMgrPutToken(fm, c32); + c32 = (CARD32)kev->window; FrameMgrPutToken(fm, c32); + c32 = (CARD32)kev->subwindow; FrameMgrPutToken(fm, c32); + c16 = (CARD16)kev->x_root; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->y_root; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->x; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->y; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->state; FrameMgrPutToken(fm, c16); + b = (BYTE)kev->same_screen; FrameMgrPutToken(fm, b); + } + break; + default: + /* create FrameMgr */ + fm = FrameMgrInit(short_fr, (char *)(&(event->u.u.sequenceNumber)), + byte_swap); + c16 = (CARD16)(ev->xany.serial & (unsigned long)0xffff); + FrameMgrPutToken(fm, c16); + break; + } + /* free FrameMgr */ + FrameMgrFree(fm); +} + +static Status xi18n_forwardEvent (XIMS ims, XPointer xp) +{ + Xi18n i18n_core = ims->protocol; + IMForwardEventStruct *call_data = (IMForwardEventStruct *)xp; + FrameMgr fm; + extern XimFrameRec forward_event_fr[]; + register int total_size; + unsigned char *reply = NULL; + unsigned char *replyp; + CARD16 serial; + int event_size; + Xi18nClient *client; + + client = (Xi18nClient *) _Xi18nFindClient (i18n_core, call_data->connect_id); + + /* create FrameMgr */ + fm = FrameMgrInit (forward_event_fr, + NULL, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + event_size = sizeof (xEvent); + reply = (unsigned char *) malloc (total_size + event_size); + if (!reply) + { + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_ERROR, + 0, + 0, + 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size + event_size); + FrameMgrSetBuffer (fm, reply); + replyp = reply; + + call_data->sync_bit = 1; /* always sync */ + client->sync = True; + + FrameMgrPutToken (fm, call_data->connect_id); + FrameMgrPutToken (fm, call_data->icid); + FrameMgrPutToken (fm, call_data->sync_bit); + + replyp += total_size; + EventToWireEvent (&(call_data->event), + (xEvent *) replyp, + &serial, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + + FrameMgrPutToken (fm, serial); + + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_FORWARD_EVENT, + 0, + reply, + total_size + event_size); + + XFree (reply); + FrameMgrFree (fm); + + return True; +} + +static Status xi18n_commit (XIMS ims, XPointer xp) +{ + Xi18n i18n_core = ims->protocol; + IMCommitStruct *call_data = (IMCommitStruct *)xp; + FrameMgr fm; + extern XimFrameRec commit_chars_fr[]; + extern XimFrameRec commit_both_fr[]; + register int total_size; + unsigned char *reply = NULL; + CARD16 str_length; + + call_data->flag |= XimSYNCHRONUS; /* always sync */ + + if (!(call_data->flag & XimLookupKeySym) + && + (call_data->flag & XimLookupChars)) + { + fm = FrameMgrInit (commit_chars_fr, + NULL, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + + /* set length of STRING8 */ + str_length = strlen (call_data->commit_string); + FrameMgrSetSize (fm, str_length); + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_ERROR, + 0, + 0, + 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + str_length = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, call_data->connect_id); + FrameMgrPutToken (fm, call_data->icid); + FrameMgrPutToken (fm, call_data->flag); + FrameMgrPutToken (fm, str_length); + FrameMgrPutToken (fm, call_data->commit_string); + } + else + { + fm = FrameMgrInit (commit_both_fr, + NULL, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + /* set length of STRING8 */ + str_length = strlen (call_data->commit_string); + if (str_length > 0) + FrameMgrSetSize (fm, str_length); + /*endif*/ + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_ERROR, + 0, + 0, + 0); + return False; + } + /*endif*/ + FrameMgrSetBuffer (fm, reply); + FrameMgrPutToken (fm, call_data->connect_id); + FrameMgrPutToken (fm, call_data->icid); + FrameMgrPutToken (fm, call_data->flag); + FrameMgrPutToken (fm, call_data->keysym); + if (str_length > 0) + { + str_length = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, str_length); + FrameMgrPutToken (fm, call_data->commit_string); + } + /*endif*/ + } + /*endif*/ + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_COMMIT, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + return True; +} + +static int xi18n_callCallback (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + switch (call_data->major_code) + { + case XIM_GEOMETRY: + return _Xi18nGeometryCallback (ims, call_data); + + case XIM_PREEDIT_START: + return _Xi18nPreeditStartCallback (ims, call_data); + + case XIM_PREEDIT_DRAW: + return _Xi18nPreeditDrawCallback (ims, call_data); + + case XIM_PREEDIT_CARET: + return _Xi18nPreeditCaretCallback (ims, call_data); + + case XIM_PREEDIT_DONE: + return _Xi18nPreeditDoneCallback (ims, call_data); + + case XIM_STATUS_START: + return _Xi18nStatusStartCallback (ims, call_data); + + case XIM_STATUS_DRAW: + return _Xi18nStatusDrawCallback (ims, call_data); + + case XIM_STATUS_DONE: + return _Xi18nStatusDoneCallback (ims, call_data); + + case XIM_STR_CONVERSION: + return _Xi18nStringConversionCallback (ims, call_data); + } + /*endswitch*/ + return False; +} + +/* preeditStart and preeditEnd are used only for Dynamic Event Flow. */ +static int xi18n_preeditStart (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + Xi18n i18n_core = ims->protocol; + IMPreeditStateStruct *preedit_state = + (IMPreeditStateStruct *) &call_data->preedit_state; + long mask; + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + + if (on_key_num == 0 && off_key_num == 0) + return False; + /*endif*/ + if (i18n_core->address.imvalue_mask & I18N_FILTERMASK) + mask = i18n_core->address.filterevent_mask; + else + mask = DEFAULT_FILTER_MASK; + /*endif*/ + _Xi18nSetEventMask (ims, + preedit_state->connect_id, + preedit_state->connect_id, + preedit_state->icid, + mask, + ~mask); + return True; +} + +static int xi18n_preeditEnd (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + Xi18n i18n_core = ims->protocol; + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + IMPreeditStateStruct *preedit_state; + + preedit_state = (IMPreeditStateStruct *) &call_data->preedit_state; + + if (on_key_num == 0 && off_key_num == 0) + return False; + /*endif*/ + + _Xi18nSetEventMask (ims, + preedit_state->connect_id, + preedit_state->connect_id, + preedit_state->icid, + 0, + 0); + return True; +} + +static int xi18n_syncXlib (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + Xi18n i18n_core = ims->protocol; + IMSyncXlibStruct *sync_xlib; + + extern XimFrameRec sync_fr[]; + FrameMgr fm; + CARD16 connect_id = call_data->any.connect_id; + int total_size; + unsigned char *reply; + + sync_xlib = (IMSyncXlibStruct *) &call_data->sync_xlib; + fm = FrameMgrInit (sync_fr, NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + total_size = FrameMgrGetTotalSize(fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + /* input input-method ID */ + FrameMgrPutToken (fm, connect_id); + /* input input-context ID */ + FrameMgrPutToken (fm, sync_xlib->icid); + _Xi18nSendMessage (ims, connect_id, XIM_SYNC, 0, reply, total_size); + + FrameMgrFree (fm); + XFree(reply); + return True; +} + diff --git a/ism/modules/frontend/imdkit/i18nPtHdr.c b/ism/modules/frontend/imdkit/i18nPtHdr.c new file mode 100755 index 0000000..4c43a37 --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nPtHdr.c @@ -0,0 +1,1848 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include +#ifndef NEED_EVENTS +#define NEED_EVENTS +#endif +#include +#undef NEED_EVENTS +#include "FrameMgr.h" +#include "IMdkit.h" +#include "Xi18n.h" +#include "XimFunc.h" + +#ifdef XIM_DEBUG +#include + +static void DebugLog(char * msg) +{ + fprintf(stderr, msg); +} +#endif + +extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16); + +static void GetProtocolVersion (CARD16 client_major, + CARD16 client_minor, + CARD16 *server_major, + CARD16 *server_minor) +{ + *server_major = client_major; + *server_minor = client_minor; +} + +static void ConnectMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec connect_fr[], connect_reply_fr[]; + register int total_size; + CARD16 server_major_version, server_minor_version; + unsigned char *reply = NULL; + IMConnectStruct *imconnect = + (IMConnectStruct*) &call_data->imconnect; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (connect_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, imconnect->byte_order); + FrameMgrGetToken (fm, imconnect->major_version); + FrameMgrGetToken (fm, imconnect->minor_version); + + FrameMgrFree (fm); + + GetProtocolVersion (imconnect->major_version, + imconnect->minor_version, + &server_major_version, + &server_minor_version); +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + fm = FrameMgrInit (connect_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, server_major_version); + FrameMgrPutToken (fm, server_minor_version); + + _Xi18nSendMessage (ims, + connect_id, + XIM_CONNECT_REPLY, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree (reply); +} + +static void DisConnectMessageProc (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + unsigned char *reply = NULL; + CARD16 connect_id = call_data->any.connect_id; + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + _Xi18nSendMessage (ims, + connect_id, + XIM_DISCONNECT_REPLY, + 0, + reply, + 0); + + i18n_core->methods.disconnect (ims, connect_id); +} + +static void OpenMessageProc(XIMS ims, IMProtocol *call_data, unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec open_fr[]; + extern XimFrameRec open_reply_fr[]; + unsigned char *reply = NULL; + int str_size; + register int i, total_size; + CARD16 connect_id = call_data->any.connect_id; + int str_length; + char *name; + IMOpenStruct *imopen = (IMOpenStruct *) &call_data->imopen; + + fm = FrameMgrInit (open_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + FrameMgrGetToken (fm, name); + imopen->lang.length = str_length; + imopen->lang.name = malloc (str_length + 1); + strncpy (imopen->lang.name, name, str_length); + imopen->lang.name[str_length] = (char) 0; + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + if ((i18n_core->address.imvalue_mask & I18N_ON_KEYS) + || + (i18n_core->address.imvalue_mask & I18N_OFF_KEYS)) + { + _Xi18nSendTriggerKey (ims, connect_id); + } + /*endif*/ + XFree (imopen->lang.name); + + fm = FrameMgrInit (open_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of imattr */ + FrameMgrSetIterCount (fm, i18n_core->address.im_attr_num); + + /* set length of BARRAY item in ximattr_fr */ + for (i = 0; i < i18n_core->address.im_attr_num; i++) + { + str_size = strlen (i18n_core->address.xim_attr[i].name); + FrameMgrSetSize (fm, str_size); + } + /*endfor*/ + /* set iteration count for list of icattr */ + FrameMgrSetIterCount (fm, i18n_core->address.ic_attr_num); + /* set length of BARRAY item in xicattr_fr */ + for (i = 0; i < i18n_core->address.ic_attr_num; i++) + { + str_size = strlen (i18n_core->address.xic_attr[i].name); + FrameMgrSetSize (fm, str_size); + } + /*endfor*/ + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + /* input input-method ID */ + FrameMgrPutToken (fm, connect_id); + + for (i = 0; i < i18n_core->address.im_attr_num; i++) + { + str_size = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].attribute_id); + FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].type); + FrameMgrPutToken (fm, str_size); + FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].name); + } + /*endfor*/ + for (i = 0; i < i18n_core->address.ic_attr_num; i++) + { + str_size = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].attribute_id); + FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].type); + FrameMgrPutToken (fm, str_size); + FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].name); + } + /*endfor*/ + + _Xi18nSendMessage (ims, + connect_id, + XIM_OPEN_REPLY, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree (reply); +} + +static void CloseMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec close_fr[]; + extern XimFrameRec close_reply_fr[]; + unsigned char *reply = NULL; + register int total_size; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (close_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + fm = FrameMgrInit (close_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + connect_id, + XIM_ERROR, + 0, + 0, + 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + + _Xi18nSendMessage (ims, + connect_id, + XIM_CLOSE_REPLY, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree (reply); +} + +static XIMExt *MakeExtensionList (Xi18n i18n_core, + XIMStr *lib_extension, + int number, + int *reply_number) +{ + XIMExt *ext_list; + XIMExt *im_ext = (XIMExt *) i18n_core->address.extension; + int im_ext_len = i18n_core->address.ext_num; + int i; + int j; + + *reply_number = 0; + + if (number == 0) + { + /* query all extensions */ + *reply_number = im_ext_len; + } + else + { + for (i = 0; i < im_ext_len; i++) + { + for (j = 0; j < (int) number; j++) + { + if (strcmp (lib_extension[j].name, im_ext[i].name) == 0) + { + (*reply_number)++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + } + /*endif*/ + + if (!(*reply_number)) + return NULL; + /*endif*/ + ext_list = (XIMExt *) malloc (sizeof (XIMExt)*(*reply_number)); + if (!ext_list) + return NULL; + /*endif*/ + memset (ext_list, 0, sizeof (XIMExt)*(*reply_number)); + + if (number == 0) + { + /* query all extensions */ + for (i = 0; i < im_ext_len; i++) + { + ext_list[i].major_opcode = im_ext[i].major_opcode; + ext_list[i].minor_opcode = im_ext[i].minor_opcode; + ext_list[i].length = im_ext[i].length; + ext_list[i].name = malloc (im_ext[i].length + 1); + strcpy (ext_list[i].name, im_ext[i].name); + } + /*endfor*/ + } + else + { + int n = 0; + + for (i = 0; i < im_ext_len; i++) + { + for (j = 0; j < (int)number; j++) + { + if (strcmp (lib_extension[j].name, im_ext[i].name) == 0) + { + ext_list[n].major_opcode = im_ext[i].major_opcode; + ext_list[n].minor_opcode = im_ext[i].minor_opcode; + ext_list[n].length = im_ext[i].length; + ext_list[n].name = malloc (im_ext[i].length + 1); + strcpy (ext_list[n].name, im_ext[i].name); + n++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + } + /*endif*/ + return ext_list; +} + +static void QueryExtensionMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + extern XimFrameRec query_extension_fr[]; + extern XimFrameRec query_extension_reply_fr[]; + unsigned char *reply = NULL; + int str_size; + register int i; + register int number; + register int total_size; + int byte_length; + int reply_number = 0; + XIMExt *ext_list; + IMQueryExtensionStruct *query_ext = + (IMQueryExtensionStruct *) &call_data->queryext; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (query_extension_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + query_ext->extension = (XIMStr *) malloc (sizeof (XIMStr)*10); + memset (query_ext->extension, 0, sizeof (XIMStr)*10); + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + char *name; + int str_length; + + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + query_ext->extension[number].length = str_length; + FrameMgrGetToken (fm, name); + query_ext->extension[number].name = malloc (str_length + 1); + strncpy (query_ext->extension[number].name, name, str_length); + query_ext->extension[number].name[str_length] = (char) 0; + number++; + } + /*endwhile*/ + query_ext->number = number; + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + FrameMgrFree (fm); + + ext_list = MakeExtensionList (i18n_core, + query_ext->extension, + number, + &reply_number); + + for (i = 0; i < number; i++) + XFree (query_ext->extension[i].name); + /*endfor*/ + XFree (query_ext->extension); + + fm = FrameMgrInit (query_extension_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of extensions */ + FrameMgrSetIterCount (fm, reply_number); + + /* set length of BARRAY item in ext_fr */ + for (i = 0; i < reply_number; i++) + { + str_size = strlen (ext_list[i].name); + FrameMgrSetSize (fm, str_size); + } + /*endfor*/ + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + connect_id, + XIM_ERROR, + 0, + 0, + 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + + for (i = 0; i < reply_number; i++) + { + str_size = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, ext_list[i].major_opcode); + FrameMgrPutToken (fm, ext_list[i].minor_opcode); + FrameMgrPutToken (fm, str_size); + FrameMgrPutToken (fm, ext_list[i].name); + } + /*endfor*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_QUERY_EXTENSION_REPLY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + for (i = 0; i < reply_number; i++) + XFree (ext_list[i].name); + /*endfor*/ + XFree ((char *) ext_list); +} + +static void SyncReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec sync_reply_fr[]; + CARD16 connect_id = call_data->any.connect_id; + Xi18nClient *client; + CARD16 input_method_ID; + CARD16 input_context_ID; + + client = (Xi18nClient *)_Xi18nFindClient (i18n_core, connect_id); + fm = FrameMgrInit (sync_reply_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, input_context_ID); + FrameMgrFree (fm); + + client->sync = False; + + if (ims->sync == True) { + ims->sync = False; + if (i18n_core->address.improto) { + call_data->sync_xlib.major_code = XIM_SYNC_REPLY; + call_data->sync_xlib.minor_code = 0; + call_data->sync_xlib.connect_id = input_method_ID; + call_data->sync_xlib.icid = input_context_ID; + i18n_core->address.improto(ims, call_data); + } + } +} + +static void GetIMValueFromName (Xi18n i18n_core, + CARD16 connect_id, + char *buf, + char *name, + int *length) +{ + register int i; + + if (strcmp (name, XNQueryInputStyle) == 0) + { + XIMStyles *styles = (XIMStyles *) &i18n_core->address.input_styles; + + *length = sizeof (CARD16)*2; /* count_styles, unused */ + *length += styles->count_styles*sizeof (CARD32); + + if (buf != NULL) + { + FrameMgr fm; + extern XimFrameRec input_styles_fr[]; + unsigned char *data = NULL; + int total_size; + + fm = FrameMgrInit (input_styles_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of input_style */ + FrameMgrSetIterCount (fm, styles->count_styles); + + total_size = FrameMgrGetTotalSize (fm); + data = (unsigned char *) malloc (total_size); + if (!data) + return; + /*endif*/ + memset (data, 0, total_size); + FrameMgrSetBuffer (fm, data); + + FrameMgrPutToken (fm, styles->count_styles); + for (i = 0; i < (int) styles->count_styles; i++) + FrameMgrPutToken (fm, styles->supported_styles[i]); + /*endfor*/ + memmove (buf, data, total_size); + FrameMgrFree (fm); + + /* ADDED BY SUZHE */ + free (data); + /* ADDED BY SUZHE */ + } + /*endif*/ + } + /*endif*/ + + else if (strcmp (name, XNQueryIMValuesList) == 0) { + } +} + +static XIMAttribute *MakeIMAttributeList (Xi18n i18n_core, + CARD16 connect_id, + CARD16 *list, + int *number, + int *length) +{ + XIMAttribute *attrib_list; + int list_num; + XIMAttr *attr = i18n_core->address.xim_attr; + int list_len = i18n_core->address.im_attr_num; + register int i; + register int j; + int value_length; + int number_ret = 0; + + *length = 0; + list_num = 0; + for (i = 0; i < *number; i++) + { + for (j = 0; j < list_len; j++) + { + if (attr[j].attribute_id == list[i]) + { + list_num++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + attrib_list = (XIMAttribute *) malloc (sizeof (XIMAttribute)*list_num); + if (!attrib_list) + return NULL; + /*endif*/ + memset (attrib_list, 0, sizeof (XIMAttribute)*list_num); + number_ret = list_num; + list_num = 0; + for (i = 0; i < *number; i++) + { + for (j = 0; j < list_len; j++) + { + if (attr[j].attribute_id == list[i]) + { + attrib_list[list_num].attribute_id = attr[j].attribute_id; + attrib_list[list_num].name_length = attr[j].length; + attrib_list[list_num].name = attr[j].name; + attrib_list[list_num].type = attr[j].type; + GetIMValueFromName (i18n_core, + connect_id, + NULL, + attr[j].name, + &value_length); + attrib_list[list_num].value_length = value_length; + attrib_list[list_num].value = (void *) malloc (value_length); + memset(attrib_list[list_num].value, 0, value_length); + GetIMValueFromName (i18n_core, + connect_id, + attrib_list[list_num].value, + attr[j].name, + &value_length); + *length += sizeof (CARD16)*2; + *length += value_length; + *length += IMPAD (value_length); + list_num++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + *number = number_ret; + return attrib_list; +} + +static void GetIMValuesMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + extern XimFrameRec get_im_values_fr[]; + extern XimFrameRec get_im_values_reply_fr[]; + CARD16 byte_length; + int list_len, total_size; + unsigned char *reply = NULL; + int iter_count; + register int i; + register int j; + int number; + CARD16 *im_attrID_list; + char **name_list; + CARD16 name_number; + XIMAttribute *im_attribute_list; + IMGetIMValuesStruct *getim = (IMGetIMValuesStruct *)&call_data->getim; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + /* create FrameMgr */ + fm = FrameMgrInit (get_im_values_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + im_attrID_list = (CARD16 *) malloc (sizeof (CARD16)*20); + memset (im_attrID_list, 0, sizeof (CARD16)*20); + name_list = (char **)malloc(sizeof(char *) * 20); + memset(name_list, 0, sizeof(char *) * 20); + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + FrameMgrGetToken (fm, im_attrID_list[number]); + number++; + } + FrameMgrFree (fm); + + name_number = 0; + for (i = 0; i < number; i++) { + for (j = 0; j < i18n_core->address.im_attr_num; j++) { + if (i18n_core->address.xim_attr[j].attribute_id == + im_attrID_list[i]) { + name_list[name_number++] = + i18n_core->address.xim_attr[j].name; + break; + } + } + } + getim->number = name_number; + getim->im_attr_list = name_list; + XFree (name_list); + + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) { + if (!(i18n_core->address.improto (ims, call_data))) + return; + } +#endif /* PROTOCOL_RICH */ + + im_attribute_list = MakeIMAttributeList (i18n_core, + connect_id, + im_attrID_list, + &number, + &list_len); + if (im_attrID_list) + XFree (im_attrID_list); + /*endif*/ + + fm = FrameMgrInit (get_im_values_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + iter_count = number; + + /* set iteration count for list of im_attribute */ + FrameMgrSetIterCount (fm, iter_count); + + /* set length of BARRAY item in ximattribute_fr */ + for (i = 0; i < iter_count; i++) + FrameMgrSetSize (fm, im_attribute_list[i].value_length); + /*endfor*/ + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + + for (i = 0; i < iter_count; i++) + { + FrameMgrPutToken (fm, im_attribute_list[i].attribute_id); + FrameMgrPutToken (fm, im_attribute_list[i].value_length); + FrameMgrPutToken (fm, im_attribute_list[i].value); + } + /*endfor*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_GET_IM_VALUES_REPLY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + for (i = 0; i < iter_count; i++) + XFree(im_attribute_list[i].value); + XFree (im_attribute_list); +} + +static void CreateICMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + _Xi18nChangeIC (ims, call_data, p, True); +} + +static void SetICValuesMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + _Xi18nChangeIC (ims, call_data, p, False); +} + +static void GetICValuesMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + _Xi18nGetIC (ims, call_data, p); +} + +static void SetICFocusMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec set_ic_focus_fr[]; + IMChangeFocusStruct *setfocus; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + setfocus = (IMChangeFocusStruct *) &call_data->changefocus; + + fm = FrameMgrInit (set_ic_focus_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, setfocus->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void UnsetICFocusMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec unset_ic_focus_fr[]; + IMChangeFocusStruct *unsetfocus; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + unsetfocus = (IMChangeFocusStruct *) &call_data->changefocus; + + fm = FrameMgrInit (unset_ic_focus_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, unsetfocus->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void DestroyICMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec destroy_ic_fr[]; + extern XimFrameRec destroy_ic_reply_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMDestroyICStruct *destroy = + (IMDestroyICStruct *) &call_data->destroyic; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (destroy_ic_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, destroy->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + fm = FrameMgrInit (destroy_ic_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, destroy->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_DESTROY_IC_REPLY, + 0, + reply, + total_size); + XFree(reply); + FrameMgrFree (fm); +} + +static void ResetICMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec reset_ic_fr[]; + extern XimFrameRec reset_ic_reply_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMResetICStruct *resetic = + (IMResetICStruct *) &call_data->resetic; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (reset_ic_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, resetic->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + /* create FrameMgr */ + fm = FrameMgrInit (reset_ic_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set length of STRING8 */ + FrameMgrSetSize (fm, resetic->length); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, resetic->icid); + FrameMgrPutToken(fm, resetic->length); + FrameMgrPutToken (fm, resetic->commit_string); + + _Xi18nSendMessage (ims, + connect_id, + XIM_RESET_IC_REPLY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree(reply); +} + +static int WireEventToEvent (Xi18n i18n_core, + xEvent *event, + CARD16 serial, + XEvent *ev, + Bool byte_swap) +{ + FrameMgr fm; + extern XimFrameRec wire_keyevent_fr[]; + BYTE b; + CARD16 c16; + CARD32 c32; + int ret = False; + + /* create FrameMgr */ + fm = FrameMgrInit(wire_keyevent_fr, (char *)(&(event->u)), byte_swap); + + + /* get & set type */ + FrameMgrGetToken(fm, b); + ev->type = (unsigned int)b; + /* get detail */ + FrameMgrGetToken(fm, b); + /* get & set serial */ + FrameMgrGetToken(fm, c16); + ev->xany.serial = (unsigned long)c16; + ev->xany.serial |= serial << 16; + ev->xany.send_event = False; + ev->xany.display = i18n_core->address.dpy; + + /* Remove SendEvent flag from event type to emulate KeyPress/Release */ + ev->type &= 0x7F; + + switch (ev->type) { + case KeyPress: + case KeyRelease: + { + XKeyEvent *kev = (XKeyEvent*)ev; + + /* set keycode (detail) */ + kev->keycode = (unsigned int)b; + + /* get & set values */ + FrameMgrGetToken(fm, c32); kev->time = (Time)c32; + FrameMgrGetToken(fm, c32); kev->root = (Window)c32; + FrameMgrGetToken(fm, c32); kev->window = (Window)c32; + FrameMgrGetToken(fm, c32); kev->subwindow = (Window)c32; + FrameMgrGetToken(fm, c16); kev->x_root = (int)c16; + FrameMgrGetToken(fm, c16); kev->y_root = (int)c16; + FrameMgrGetToken(fm, c16); kev->x = (int)c16; + FrameMgrGetToken(fm, c16); kev->y = (int)c16; + FrameMgrGetToken(fm, c16); kev->state = (unsigned int)c16; + FrameMgrGetToken(fm, b); kev->same_screen = (Bool)b; + } + ret = True; + break; + default: + break; + } + /* free FrameMgr */ + FrameMgrFree(fm); + return ret; +} + +static void ForwardEventMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec forward_event_fr[]; + xEvent wire_event; + IMForwardEventStruct *forward = + (IMForwardEventStruct*) &call_data->forwardevent; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (forward_event_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, forward->icid); + FrameMgrGetToken (fm, forward->sync_bit); + FrameMgrGetToken (fm, forward->serial_number); + p += sizeof (CARD16)*4; + memmove (&wire_event, p, sizeof (xEvent)); + + FrameMgrFree (fm); + + if (WireEventToEvent (i18n_core, + &wire_event, + forward->serial_number, + &forward->event, + _Xi18nNeedSwap (i18n_core, connect_id)) == True) + { + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + } + /*endif*/ +} + +static void ExtForwardKeyEventMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec ext_forward_keyevent_fr[]; + CARD8 type, keycode; + CARD16 state; + CARD32 ev_time, window; + IMForwardEventStruct *forward = + (IMForwardEventStruct *) &call_data->forwardevent; + XEvent *ev = (XEvent *) &forward->event; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (ext_forward_keyevent_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, forward->icid); + FrameMgrGetToken (fm, forward->sync_bit); + FrameMgrGetToken (fm, forward->serial_number); + FrameMgrGetToken (fm, type); + FrameMgrGetToken (fm, keycode); + FrameMgrGetToken (fm, state); + FrameMgrGetToken (fm, ev_time); + FrameMgrGetToken (fm, window); + + FrameMgrFree (fm); + + if (type != KeyPress) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + + /* make a faked keypress event */ + ev->type = (int)type; + ev->xany.send_event = True; + ev->xany.display = i18n_core->address.dpy; + ev->xany.serial = (unsigned long) forward->serial_number; + ((XKeyEvent *) ev)->keycode = (unsigned int) keycode; + ((XKeyEvent *) ev)->state = (unsigned int) state; + ((XKeyEvent *) ev)->time = (Time) ev_time; + ((XKeyEvent *) ev)->window = (Window) window; + ((XKeyEvent *) ev)->root = DefaultRootWindow (ev->xany.display); + ((XKeyEvent *) ev)->x = 0; + ((XKeyEvent *) ev)->y = 0; + ((XKeyEvent *) ev)->x_root = 0; + ((XKeyEvent *) ev)->y_root = 0; + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void ExtMoveMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec ext_move_fr[]; + IMMoveStruct *extmove = + (IMMoveStruct*) & call_data->extmove; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (ext_move_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, extmove->icid); + FrameMgrGetToken (fm, extmove->x); + FrameMgrGetToken (fm, extmove->y); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void ExtensionMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + switch (call_data->any.minor_code) + { + case XIM_EXT_FORWARD_KEYEVENT: + ExtForwardKeyEventMessageProc (ims, call_data, p); + break; + + case XIM_EXT_MOVE: + ExtMoveMessageProc (ims, call_data, p); + break; + } + /*endswitch*/ +} + +static void TriggerNotifyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec trigger_notify_fr[], trigger_notify_reply_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMTriggerNotifyStruct *trigger = + (IMTriggerNotifyStruct *) &call_data->triggernotify; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + CARD32 flag; + + fm = FrameMgrInit (trigger_notify_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, trigger->icid); + FrameMgrGetToken (fm, trigger->flag); + FrameMgrGetToken (fm, trigger->key_index); + FrameMgrGetToken (fm, trigger->event_mask); + /* + In order to support Front End Method, this event_mask must be saved + per clients so that it should be restored by an XIM_EXT_SET_EVENT_MASK + call when preediting mode is reset to off. + */ + + flag = trigger->flag; + + FrameMgrFree (fm); + + fm = FrameMgrInit (trigger_notify_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, trigger->icid); + + /* NOTE: + XIM_TRIGGER_NOTIFY_REPLY should be sent before XIM_SET_EVENT_MASK + in case of XIM_TRIGGER_NOTIFY(flag == ON), while it should be + sent after XIM_SET_EVENT_MASK in case of + XIM_TRIGGER_NOTIFY(flag == OFF). + */ + if (flag == 0) + { + /* on key */ + _Xi18nSendMessage (ims, + connect_id, + XIM_TRIGGER_NOTIFY_REPLY, + 0, + reply, + total_size); + IMPreeditStart (ims, (XPointer)call_data); + } + /*endif*/ + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + if (flag == 1) + { + /* off key */ + IMPreeditEnd (ims, (XPointer) call_data); + _Xi18nSendMessage (ims, + connect_id, + XIM_TRIGGER_NOTIFY_REPLY, + 0, + reply, + total_size); + } + /*endif*/ + FrameMgrFree (fm); + XFree (reply); +} + +static INT16 ChooseEncoding (Xi18n i18n_core, + IMEncodingNegotiationStruct *enc_nego) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) & i18n_core->address; + XIMEncodings *p; + int i, j; + int enc_index=0; + + p = (XIMEncodings *) &address->encoding_list; + for (i = 0; i < (int) p->count_encodings; i++) + { + for (j = 0; j < (int) enc_nego->encoding_number; j++) + { + if (strcmp (p->supported_encodings[i], + enc_nego->encoding[j].name) == 0) + { + enc_index = j; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + + return (INT16) enc_index; +#if 0 + return (INT16) XIM_Default_Encoding_IDX; +#endif +} + +static void EncodingNegotiatonMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + CARD16 byte_length; + extern XimFrameRec encoding_negotiation_fr[]; + extern XimFrameRec encoding_negotiation_reply_fr[]; + register int i, total_size; + unsigned char *reply = NULL; + IMEncodingNegotiationStruct *enc_nego = + (IMEncodingNegotiationStruct *) &call_data->encodingnego; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (encoding_negotiation_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + + /* get ENCODING STR field */ + FrameMgrGetToken (fm, byte_length); + if (byte_length > 0) + { + enc_nego->encoding = (XIMStr *) malloc (sizeof (XIMStr)*10); + memset (enc_nego->encoding, 0, sizeof (XIMStr)*10); + i = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + char *name; + int str_length; + + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + enc_nego->encoding[i].length = str_length; + FrameMgrGetToken (fm, name); + enc_nego->encoding[i].name = malloc (str_length + 1); + strncpy (enc_nego->encoding[i].name, name, str_length); + enc_nego->encoding[i].name[str_length] = '\0'; + i++; + } + /*endwhile*/ + enc_nego->encoding_number = i; + } + /*endif*/ + /* get ENCODING INFO field */ + FrameMgrGetToken (fm, byte_length); + if (byte_length > 0) + { + enc_nego->encodinginfo = (XIMStr *) malloc (sizeof (XIMStr)*10); + memset (enc_nego->encodinginfo, 0, sizeof (XIMStr)*10); + i = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + char *name; + int str_length; + + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + enc_nego->encodinginfo[i].length = str_length; + FrameMgrGetToken (fm, name); + enc_nego->encodinginfo[i].name = malloc (str_length + 1); + strncpy (enc_nego->encodinginfo[i].name, name, str_length); + enc_nego->encodinginfo[i].name[str_length] = '\0'; + i++; + } + /*endwhile*/ + enc_nego->encoding_info_number = i; + } + /*endif*/ + + enc_nego->enc_index = ChooseEncoding (i18n_core, enc_nego); + enc_nego->category = 0; + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + FrameMgrFree (fm); + + fm = FrameMgrInit (encoding_negotiation_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, enc_nego->category); + FrameMgrPutToken (fm, enc_nego->enc_index); + + _Xi18nSendMessage (ims, + connect_id, + XIM_ENCODING_NEGOTIATION_REPLY, + 0, + reply, + total_size); + XFree (reply); + + /* free data for encoding list */ + if (enc_nego->encoding) + { + for (i = 0; i < (int) enc_nego->encoding_number; i++) + XFree (enc_nego->encoding[i].name); + /*endfor*/ + XFree (enc_nego->encoding); + } + /*endif*/ + if (enc_nego->encodinginfo) + { + for (i = 0; i < (int) enc_nego->encoding_info_number; i++) + XFree (enc_nego->encodinginfo[i].name); + /*endfor*/ + XFree (enc_nego->encodinginfo); + } + /*endif*/ + FrameMgrFree (fm); +} + +void PreeditStartReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_start_reply_fr[]; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (preedit_start_reply_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, preedit_CB->icid); + FrameMgrGetToken (fm, preedit_CB->todo.return_value); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +void PreeditCaretReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_caret_reply_fr[]; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + XIMPreeditCaretCallbackStruct *caret = + (XIMPreeditCaretCallbackStruct *) & preedit_CB->todo.caret; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (preedit_caret_reply_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, preedit_CB->icid); + FrameMgrGetToken (fm, caret->position); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +void StrConvReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + return; +} + +static void AddQueue (Xi18nClient *client, unsigned char *p) +{ + XIMPending *new; + XIMPending *last; + + if ((new = (XIMPending *) malloc (sizeof (XIMPending))) == NULL) + return; + /*endif*/ + new->p = p; + new->next = (XIMPending *) NULL; + if (!client->pending) + { + client->pending = new; + } + else + { + for (last = client->pending; last->next; last = last->next) + ; + /*endfor*/ + last->next = new; + } + /*endif*/ + return; +} + +static void ProcessQueue (XIMS ims, CARD16 connect_id) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient *client = (Xi18nClient *) _Xi18nFindClient (i18n_core, + connect_id); + + while (client->sync == False && client->pending) + { + XimProtoHdr *hdr = (XimProtoHdr *) client->pending->p; + unsigned char *p1 = (unsigned char *) (hdr + 1); + IMProtocol call_data; + + call_data.major_code = hdr->major_opcode; + call_data.any.minor_code = hdr->minor_opcode; + call_data.any.connect_id = connect_id; + + switch (hdr->major_opcode) + { + case XIM_FORWARD_EVENT: + ForwardEventMessageProc(ims, &call_data, p1); + break; + } + /*endswitch*/ + XFree (hdr); + { + XIMPending *old = client->pending; + + client->pending = old->next; + XFree (old); + } + } + /*endwhile*/ + return; +} + + +void _Xi18nMessageHandler (XIMS ims, + CARD16 connect_id, + unsigned char *p, + Bool *delete) +{ + XimProtoHdr *hdr = (XimProtoHdr *)p; + unsigned char *p1 = (unsigned char *)(hdr + 1); + IMProtocol call_data; + Xi18n i18n_core = ims->protocol; + Xi18nClient *client; + + client = (Xi18nClient *) _Xi18nFindClient (i18n_core, connect_id); + if (hdr == (XimProtoHdr *) NULL) + return; + /*endif*/ + + memset (&call_data, 0, sizeof(IMProtocol)); + + call_data.major_code = hdr->major_opcode; + call_data.any.minor_code = hdr->minor_opcode; + call_data.any.connect_id = connect_id; + + switch (call_data.major_code) + { + case XIM_CONNECT: +#ifdef XIM_DEBUG + DebugLog("-- XIM_CONNECT\n"); +#endif + ConnectMessageProc (ims, &call_data, p1); + break; + + case XIM_DISCONNECT: +#ifdef XIM_DEBUG + DebugLog("-- XIM_DISCONNECT\n"); +#endif + DisConnectMessageProc (ims, &call_data); + break; + + case XIM_OPEN: +#ifdef XIM_DEBUG + DebugLog("-- XIM_OPEN\n"); +#endif + OpenMessageProc (ims, &call_data, p1); + break; + + case XIM_CLOSE: +#ifdef XIM_DEBUG + DebugLog("-- XIM_CLOSE\n"); +#endif + CloseMessageProc (ims, &call_data, p1); + break; + + case XIM_QUERY_EXTENSION: +#ifdef XIM_DEBUG + DebugLog("-- XIM_QUERY_EXTENSION\n"); +#endif + QueryExtensionMessageProc (ims, &call_data, p1); + break; + + case XIM_GET_IM_VALUES: +#ifdef XIM_DEBUG + DebugLog("-- XIM_GET_IM_VALUES\n"); +#endif + GetIMValuesMessageProc (ims, &call_data, p1); + break; + + case XIM_CREATE_IC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_CREATE_IC\n"); +#endif + CreateICMessageProc (ims, &call_data, p1); + break; + + case XIM_SET_IC_VALUES: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SET_IC_VALUES\n"); +#endif + SetICValuesMessageProc (ims, &call_data, p1); + break; + + case XIM_GET_IC_VALUES: +#ifdef XIM_DEBUG + DebugLog("-- XIM_GET_IC_VALUES\n"); +#endif + GetICValuesMessageProc (ims, &call_data, p1); + break; + + case XIM_SET_IC_FOCUS: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SET_IC_FOCUS\n"); +#endif + SetICFocusMessageProc (ims, &call_data, p1); + break; + + case XIM_UNSET_IC_FOCUS: +#ifdef XIM_DEBUG + DebugLog("-- XIM_UNSET_IC_FOCUS\n"); +#endif + UnsetICFocusMessageProc (ims, &call_data, p1); + break; + + case XIM_DESTROY_IC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_DESTROY_IC\n"); +#endif + DestroyICMessageProc (ims, &call_data, p1); + break; + + case XIM_RESET_IC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_RESET_IC\n"); +#endif + ResetICMessageProc (ims, &call_data, p1); + break; + + case XIM_FORWARD_EVENT: +#ifdef XIM_DEBUG + DebugLog("-- XIM_FORWARD_EVENT\n"); +#endif + if (client->sync == True) + { + AddQueue (client, p); + *delete = False; + } + else + { + ForwardEventMessageProc (ims, &call_data, p1); + } + break; + + case XIM_EXTENSION: +#ifdef XIM_DEBUG + DebugLog("-- XIM_EXTENSION\n"); +#endif + ExtensionMessageProc (ims, &call_data, p1); + break; + + case XIM_SYNC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SYNC\n"); +#endif + break; + + case XIM_SYNC_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SYNC_REPLY\n"); +#endif + SyncReplyMessageProc (ims, &call_data, p1); + ProcessQueue (ims, connect_id); + break; + + case XIM_TRIGGER_NOTIFY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_TRIGGER_NOTIFY\n"); +#endif + TriggerNotifyMessageProc (ims, &call_data, p1); + break; + + case XIM_ENCODING_NEGOTIATION: +#ifdef XIM_DEBUG + DebugLog("-- XIM_ENCODING_NEGOTIATION\n"); +#endif + EncodingNegotiatonMessageProc (ims, &call_data, p1); + break; + + case XIM_PREEDIT_START_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_PREEDIT_START_REPLY\n"); +#endif + PreeditStartReplyMessageProc (ims, &call_data, p1); + break; + + case XIM_PREEDIT_CARET_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_PREEDIT_CARET_REPLY\n"); +#endif + PreeditCaretReplyMessageProc (ims, &call_data, p1); + break; + + case XIM_STR_CONVERSION_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_STR_CONVERSION_REPLY\n"); +#endif + StrConvReplyMessageProc (ims, &call_data, p1); + break; + } + /*endswitch*/ +} diff --git a/ism/modules/frontend/imdkit/i18nUtil.c b/ism/modules/frontend/imdkit/i18nUtil.c new file mode 100755 index 0000000..22a2376 --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nUtil.c @@ -0,0 +1,276 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "FrameMgr.h" +#include "XimFunc.h" + +Xi18nClient *_Xi18nFindClient (Xi18n, CARD16); + +int +_Xi18nNeedSwap (Xi18n i18n_core, CARD16 connect_id) +{ + CARD8 im_byteOrder = i18n_core->address.im_byteOrder; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + + return (client->byte_order != im_byteOrder); +} + +Xi18nClient *_Xi18nNewClient(Xi18n i18n_core) +{ + static CARD16 connect_id = 0; + int new_connect_id; + Xi18nClient *client; + + if (i18n_core->address.free_clients) + { + client = i18n_core->address.free_clients; + i18n_core->address.free_clients = client->next; + new_connect_id = client->connect_id; + } + else + { + client = (Xi18nClient *) malloc (sizeof (Xi18nClient)); + new_connect_id = ++connect_id; + } + /*endif*/ + memset (client, 0, sizeof (Xi18nClient)); + client->connect_id = new_connect_id; + client->pending = (XIMPending *) NULL; + client->sync = False; + client->byte_order = '?'; /* initial value */ + memset (&client->pending, 0, sizeof (XIMPending *)); + client->next = i18n_core->address.clients; + i18n_core->address.clients = client; + + return (Xi18nClient *) client; +} + +Xi18nClient *_Xi18nFindClient (Xi18n i18n_core, CARD16 connect_id) +{ + Xi18nClient *client = i18n_core->address.clients; + + while (client) + { + if (client->connect_id == connect_id) + return client; + /*endif*/ + client = client->next; + } + /*endwhile*/ + return NULL; +} + +void _Xi18nDeleteClient (Xi18n i18n_core, CARD16 connect_id) +{ + Xi18nClient *target = _Xi18nFindClient (i18n_core, connect_id); + Xi18nClient *ccp; + Xi18nClient *ccp0; + + for (ccp = i18n_core->address.clients, ccp0 = NULL; + ccp != NULL; + ccp0 = ccp, ccp = ccp->next) + { + if (ccp == target) + { + if (ccp0 == NULL) + i18n_core->address.clients = ccp->next; + else + ccp0->next = ccp->next; + /*endif*/ + /* put it back to free list */ + target->next = i18n_core->address.free_clients; + i18n_core->address.free_clients = target; + return; + } + /*endif*/ + } + /*endfor*/ +} + +void _Xi18nSendMessage (XIMS ims, + CARD16 connect_id, + CARD8 major_opcode, + CARD8 minor_opcode, + unsigned char *data, + long length) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec packet_header_fr[]; + unsigned char *reply_hdr = NULL; + int header_size; + unsigned char *reply = NULL; + unsigned char *replyp; + int reply_length; + long p_len = length/4; + + fm = FrameMgrInit (packet_header_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + header_size = FrameMgrGetTotalSize (fm); + reply_hdr = (unsigned char *) malloc (header_size); + if (reply_hdr == NULL) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + FrameMgrSetBuffer (fm, reply_hdr); + + /* put data */ + FrameMgrPutToken (fm, major_opcode); + FrameMgrPutToken (fm, minor_opcode); + FrameMgrPutToken (fm, p_len); + + reply_length = header_size + length; + reply = (unsigned char *) malloc (reply_length); + replyp = reply; + memmove (reply, reply_hdr, header_size); + replyp += header_size; + memmove (replyp, data, length); + + i18n_core->methods.send (ims, connect_id, reply, reply_length); + + XFree (reply); + XFree (reply_hdr); + FrameMgrFree (fm); +} + +void _Xi18nSendTriggerKey (XIMS ims, CARD16 connect_id) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec register_triggerkeys_fr[]; + XIMTriggerKey *on_keys = i18n_core->address.on_keys.keylist; + XIMTriggerKey *off_keys = i18n_core->address.off_keys.keylist; + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + unsigned char *reply = NULL; + register int i, total_size; + CARD16 im_id; + + if (on_key_num == 0 && off_key_num == 0) + return; + /*endif*/ + + fm = FrameMgrInit (register_triggerkeys_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for on-keys list */ + FrameMgrSetIterCount (fm, on_key_num); + /* set iteration count for off-keys list */ + FrameMgrSetIterCount (fm, off_key_num); + + /* get total_size */ + total_size = FrameMgrGetTotalSize (fm); + + reply = (unsigned char *) malloc (total_size); + if (!reply) + return; + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + /* Right now XIM_OPEN_REPLY hasn't been sent to this new client, so + the input-method-id is still invalid, and should be set to zero... + Reter to $(XC)/lib/X11/imDefLkup.c:_XimRegisterTriggerKeysCallback + */ + im_id = 0; + FrameMgrPutToken (fm, im_id); /* input-method-id */ + for (i = 0; i < on_key_num; i++) + { + FrameMgrPutToken (fm, on_keys[i].keysym); + FrameMgrPutToken (fm, on_keys[i].modifier); + FrameMgrPutToken (fm, on_keys[i].modifier_mask); + } + /*endfor*/ + for (i = 0; i < off_key_num; i++) + { + FrameMgrPutToken (fm, off_keys[i].keysym); + FrameMgrPutToken (fm, off_keys[i].modifier); + FrameMgrPutToken (fm, off_keys[i].modifier_mask); + } + /*endfor*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_REGISTER_TRIGGERKEYS, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree(reply); +} + +void _Xi18nSetEventMask (XIMS ims, + CARD16 connect_id, + CARD16 im_id, + CARD16 ic_id, + CARD32 forward_mask, + CARD32 sync_mask) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec set_event_mask_fr[]; + unsigned char *reply = NULL; + register int total_size; + + fm = FrameMgrInit (set_event_mask_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + return; + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, im_id); /* input-method-id */ + FrameMgrPutToken (fm, ic_id); /* input-context-id */ + FrameMgrPutToken (fm, forward_mask); + FrameMgrPutToken (fm, sync_mask); + + _Xi18nSendMessage (ims, + connect_id, + XIM_SET_EVENT_MASK, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree(reply); +} diff --git a/ism/modules/frontend/imdkit/i18nX.c b/ism/modules/frontend/imdkit/i18nX.c new file mode 100755 index 0000000..a5ba080 --- /dev/null +++ b/ism/modules/frontend/imdkit/i18nX.c @@ -0,0 +1,497 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include "FrameMgr.h" +#include "IMdkit.h" +#include "Xi18n.h" +#include "Xi18nX.h" +#include "XimFunc.h" + +extern Xi18nClient *_Xi18nFindClient(Xi18n, CARD16); +extern Xi18nClient *_Xi18nNewClient(Xi18n); +extern void _Xi18nDeleteClient(Xi18n, CARD16); +static Bool WaitXConnectMessage(Display*, Window, + XEvent*, XPointer); +static Bool WaitXIMProtocol(Display*, Window, XEvent*, XPointer); + +static XClient *NewXClient (Xi18n i18n_core, Window new_client) +{ + Display *dpy = i18n_core->address.dpy; + Xi18nClient *client = _Xi18nNewClient (i18n_core); + XClient *x_client; + + x_client = (XClient *) malloc (sizeof (XClient)); + x_client->client_win = new_client; + x_client->accept_win = XCreateSimpleWindow (dpy, + DefaultRootWindow(dpy), + 0, + 0, + 1, + 1, + 1, + 0, + 0); + client->trans_rec = x_client; + return ((XClient *) x_client); +} + +static unsigned char *ReadXIMMessage (XIMS ims, + XClientMessageEvent *ev, + int *connect_id) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient *client = i18n_core->address.clients; + XClient *x_client = NULL; + FrameMgr fm; + extern XimFrameRec packet_header_fr[]; + unsigned char *p = NULL; + unsigned char *p1; + + while (client != NULL) { + x_client = (XClient *) client->trans_rec; + if (x_client->accept_win == ev->window) { + *connect_id = client->connect_id; + break; + } + client = client->next; + } + + if (ev->format == 8) { + /* ClientMessage only */ + XimProtoHdr *hdr = (XimProtoHdr *) ev->data.b; + unsigned char *rec = (unsigned char *) (hdr + 1); + register int total_size; + CARD8 major_opcode; + CARD8 minor_opcode; + CARD16 length; + extern int _Xi18nNeedSwap (Xi18n, CARD16); + + if (client->byte_order == '?') + { + if (hdr->major_opcode != XIM_CONNECT) + return (unsigned char *) NULL; /* can do nothing */ + client->byte_order = (CARD8) rec[0]; + } + + fm = FrameMgrInit (packet_header_fr, + (char *) hdr, + _Xi18nNeedSwap (i18n_core, *connect_id)); + total_size = FrameMgrGetTotalSize (fm); + /* get data */ + FrameMgrGetToken (fm, major_opcode); + FrameMgrGetToken (fm, minor_opcode); + FrameMgrGetToken (fm, length); + FrameMgrFree (fm); + + if ((p = (unsigned char *) malloc (total_size + length * 4)) == NULL) + return (unsigned char *) NULL; + + p1 = p; + memmove (p1, &major_opcode, sizeof (CARD8)); + p1 += sizeof (CARD8); + memmove (p1, &minor_opcode, sizeof (CARD8)); + p1 += sizeof (CARD8); + memmove (p1, &length, sizeof (CARD16)); + p1 += sizeof (CARD16); + memmove (p1, rec, length * 4); + } + else if (ev->format == 32) { + /* ClientMessage and WindowProperty */ + unsigned long length = (unsigned long) ev->data.l[0]; + Atom atom = (Atom) ev->data.l[1]; + int return_code; + Atom actual_type_ret; + int actual_format_ret; + unsigned long bytes_after_ret; + unsigned char *prop; + unsigned long nitems; + + return_code = XGetWindowProperty (i18n_core->address.dpy, + x_client->accept_win, + atom, + 0L, + length, + True, + AnyPropertyType, + &actual_type_ret, + &actual_format_ret, + &nitems, + &bytes_after_ret, + &prop); + if (return_code != Success || actual_format_ret == 0 || nitems == 0) { + if (return_code == Success) + XFree (prop); + return (unsigned char *) NULL; + } + if (length != nitems) + length = nitems; + if (actual_format_ret == 16) + length *= 2; + else if (actual_format_ret == 32) + length *= 4; + + /* if hit, it might be an error */ + if ((p = (unsigned char *) malloc (length)) == NULL) + return (unsigned char *) NULL; + + memmove (p, prop, length); + XFree (prop); + } + return (unsigned char *) p; +} + +static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev) +{ + Xi18n i18n_core = ims->protocol; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + XEvent event; + Display *dpy = i18n_core->address.dpy; + Window new_client = ev->data.l[0]; + CARD32 major_version = ev->data.l[1]; + CARD32 minor_version = ev->data.l[2]; + XClient *x_client = NewXClient (i18n_core, new_client); + + if (ev->window != i18n_core->address.im_window) + return; /* incorrect connection request */ + /*endif*/ + if (major_version != 0 || minor_version != 0) + { + major_version = + minor_version = 0; + /* Only supporting only-CM & Property-with-CM method */ + } + /*endif*/ + _XRegisterFilterByType (dpy, + x_client->accept_win, + ClientMessage, + ClientMessage, + WaitXIMProtocol, + (XPointer)ims); + event.xclient.type = ClientMessage; + event.xclient.display = dpy; + event.xclient.window = new_client; + event.xclient.message_type = spec->connect_request; + event.xclient.format = 32; + event.xclient.data.l[0] = x_client->accept_win; + event.xclient.data.l[1] = major_version; + event.xclient.data.l[2] = minor_version; + event.xclient.data.l[3] = XCM_DATA_LIMIT; + + XSendEvent (dpy, + new_client, + False, + NoEventMask, + &event); + XFlush (dpy); +} + +static Bool Xi18nXBegin (XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + + spec->xim_request = XInternAtom (i18n_core->address.dpy, + _XIM_PROTOCOL, + False); + spec->connect_request = XInternAtom (i18n_core->address.dpy, + _XIM_XCONNECT, + False); + + _XRegisterFilterByType (dpy, + i18n_core->address.im_window, + ClientMessage, + ClientMessage, + WaitXConnectMessage, + (XPointer)ims); + return True; +} + +static Bool Xi18nXEnd(XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + + _XUnregisterFilter (dpy, + i18n_core->address.im_window, + WaitXConnectMessage, + (XPointer)ims); + return True; +} + +static char *MakeNewAtom (CARD16 connect_id, char *atomName) +{ + static int sequence = 0; + + sprintf (atomName, + "_server%d_%d", + connect_id, + ((sequence > 20) ? (sequence = 0) : sequence++)); + return atomName; +} + +static Bool Xi18nXSend (XIMS ims, + CARD16 connect_id, + unsigned char *reply, + long length) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + XClient *x_client = (XClient *) client->trans_rec; + XEvent event; + + event.type = ClientMessage; + event.xclient.window = x_client->client_win; + event.xclient.message_type = spec->xim_request; + + if (length > XCM_DATA_LIMIT) + { + Atom atom; + char atomName[16]; + Atom actual_type_ret; + int actual_format_ret; + int return_code; + unsigned long nitems_ret; + unsigned long bytes_after_ret; + unsigned char *win_data; + + event.xclient.format = 32; + atom = XInternAtom (i18n_core->address.dpy, + MakeNewAtom (connect_id, atomName), + False); + return_code = XGetWindowProperty (i18n_core->address.dpy, + x_client->client_win, + atom, + 0L, + 10000L, + False, + XA_STRING, + &actual_type_ret, + &actual_format_ret, + &nitems_ret, + &bytes_after_ret, + &win_data); + if (return_code != Success) + return False; + /*endif*/ + if (win_data) + XFree ((char *) win_data); + /*endif*/ + XChangeProperty (i18n_core->address.dpy, + x_client->client_win, + atom, + XA_STRING, + 8, + PropModeAppend, + (unsigned char *) reply, + length); + event.xclient.data.l[0] = length; + event.xclient.data.l[1] = atom; + } + else + { + unsigned char buffer[XCM_DATA_LIMIT]; + int i; + + event.xclient.format = 8; + + /* Clear unused field with NULL */ + memmove(buffer, reply, length); + for (i = length; i < XCM_DATA_LIMIT; i++) + buffer[i] = (char) 0; + /*endfor*/ + length = XCM_DATA_LIMIT; + memmove (event.xclient.data.b, buffer, length); + } + XSendEvent (i18n_core->address.dpy, + x_client->client_win, + False, + NoEventMask, + &event); + XFlush (i18n_core->address.dpy); + return True; +} + +static Bool CheckCMEvent (Display *display, XEvent *event, XPointer xi18n_core) +{ + Xi18n i18n_core = (Xi18n) ((void *) xi18n_core); + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + + if ((event->type == ClientMessage) + && + (event->xclient.message_type == spec->xim_request)) + { + return True; + } + /*endif*/ + return False; +} + +static Bool Xi18nXWait (XIMS ims, + CARD16 connect_id, + CARD8 major_opcode, + CARD8 minor_opcode) +{ + Xi18n i18n_core = ims->protocol; + XEvent event; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + XClient *x_client = (XClient *) client->trans_rec; + + for (;;) + { + unsigned char *packet; + XimProtoHdr *hdr; + int connect_id_ret; + + XIfEvent (i18n_core->address.dpy, + &event, + CheckCMEvent, + (XPointer) i18n_core); + if (event.xclient.window == x_client->accept_win) + { + if ((packet = ReadXIMMessage (ims, + (XClientMessageEvent *) & event, + &connect_id_ret)) + == (unsigned char*) NULL) + { + return False; + } + /*endif*/ + hdr = (XimProtoHdr *)packet; + + if ((hdr->major_opcode == major_opcode) + && + (hdr->minor_opcode == minor_opcode)) + { + return True; + } + else if (hdr->major_opcode == XIM_ERROR) + { + return False; + } + /*endif*/ + } + /*endif*/ + } + /*endfor*/ +} + +static Bool Xi18nXDisconnect (XIMS ims, CARD16 connect_id) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + XClient *x_client = (XClient *) client->trans_rec; + + XDestroyWindow (dpy, x_client->accept_win); + _XUnregisterFilter (dpy, + x_client->accept_win, + WaitXIMProtocol, + (XPointer)ims); + XFree (x_client); + _Xi18nDeleteClient (i18n_core, connect_id); + return True; +} + +Bool _Xi18nCheckXAddress (Xi18n i18n_core, + TransportSW *transSW, + char *address) +{ + XSpecRec *spec; + + if (!(spec = (XSpecRec *) malloc (sizeof (XSpecRec)))) + return False; + /*endif*/ + + i18n_core->address.connect_addr = (XSpecRec *) spec; + i18n_core->methods.begin = Xi18nXBegin; + i18n_core->methods.end = Xi18nXEnd; + i18n_core->methods.send = Xi18nXSend; + i18n_core->methods.wait = Xi18nXWait; + i18n_core->methods.disconnect = Xi18nXDisconnect; + return True; +} + +static Bool WaitXConnectMessage (Display *dpy, + Window win, + XEvent *ev, + XPointer client_data) +{ + XIMS ims = (XIMS)client_data; + Xi18n i18n_core = ims->protocol; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + + if (((XClientMessageEvent *) ev)->message_type + == spec->connect_request) + { + ReadXConnectMessage (ims, (XClientMessageEvent *) ev); + return True; + } + /*endif*/ + return False; +} + +static Bool WaitXIMProtocol (Display *dpy, + Window win, + XEvent *ev, + XPointer client_data) +{ + extern void _Xi18nMessageHandler (XIMS, CARD16, unsigned char *, Bool *); + XIMS ims = (XIMS) client_data; + Xi18n i18n_core = ims->protocol; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + Bool delete = True; + unsigned char *packet; + int connect_id; + + if (((XClientMessageEvent *) ev)->message_type + == spec->xim_request) + { + if ((packet = ReadXIMMessage (ims, + (XClientMessageEvent *) ev, + &connect_id)) + == (unsigned char *) NULL) + { + return False; + } + /*endif*/ + _Xi18nMessageHandler (ims, connect_id, packet, &delete); + if (delete == True) + XFree (packet); + /*endif*/ + return True; + } + /*endif*/ + return False; +} diff --git a/ism/modules/frontend/scim_socket_frontend.cpp b/ism/modules/frontend/scim_socket_frontend.cpp new file mode 100644 index 0000000..6f7b1fd --- /dev/null +++ b/ism/modules/frontend/scim_socket_frontend.cpp @@ -0,0 +1,2125 @@ +/** @file scim_socket_frontend.cpp + * implementation of class SocketFrontEnd. + */ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Add helper ISE management + * a. Load helper ISE module + * b. Launch helper ISE + * 2. Dynamic load keyboard ISE + * 3. Add new interface APIs for keyboard ISE + * a. expand_candidate (), contract_candidate () and set_candidate_style () + * b. socket_select_aux (), socket_set_prediction_allow () and socket_set_layout () + * c. socket_update_candidate_item_layout (), socket_update_cursor_position () and socket_update_displayed_candidate_number () + * d. socket_candidate_more_window_show (), socket_candidate_more_window_hide () and socket_longpress_candidate () + * e. socket_set_imdata () and socket_reset_option () + * + * $Id: scim_socket_frontend.cpp,v 1.37 2005/07/03 08:36:42 suzhe Exp $ + * + */ + +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_FRONTEND +#define Uses_SCIM_SOCKET +#define Uses_SCIM_TRANSACTION +#define Uses_STL_UTILITY +#define Uses_C_STDIO +#define Uses_C_STDLIB +#define Uses_SCIM_CONFIG_BASE +#define Uses_SCIM_UTILITY +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_PANEL_AGENT + +#include + +#include +#include "scim_private.h" +#include "scim.h" +#include "scim_socket_frontend.h" +#include "scim_helper.h" +#include "scim_helper_module.h" +#include "isf_query_utility.h" +#include +#include +#include +#include +#include + +#define scim_module_init socket_LTX_scim_module_init +#define scim_module_exit socket_LTX_scim_module_exit +#define scim_frontend_module_init socket_LTX_scim_frontend_module_init +#define scim_frontend_module_run socket_LTX_scim_frontend_module_run + +#define SCIM_CONFIG_FRONTEND_SOCKET_CONFIG_READONLY "/FrontEnd/Socket/ConfigReadOnly" +#define SCIM_CONFIG_FRONTEND_SOCKET_MAXCLIENTS "/FrontEnd/Socket/MaxClients" + +using namespace scim; + +static Pointer _scim_frontend (0); + +static int _argc; +static char **_argv = NULL; + +//Module Interface +extern "C" { + void scim_module_init (void) + { + SCIM_DEBUG_FRONTEND(1) << "Initializing Socket FrontEnd module...\n"; + } + + void scim_module_exit (void) + { + SCIM_DEBUG_FRONTEND(1) << "Exiting Socket FrontEnd module...\n"; + _scim_frontend.reset (); + } + + void scim_frontend_module_init (const BackEndPointer &backend, + const ConfigPointer &config, + int argc, + char **argv) + { + if (_scim_frontend.null ()) { + SCIM_DEBUG_FRONTEND(1) << "Initializing Socket FrontEnd module (more)...\n"; + _scim_frontend = new SocketFrontEnd (backend, config); + _argc = argc; + _argv = argv; + } + } + + void scim_frontend_module_run (void) + { + struct tms tiks_buf; + clock_t start = times (&tiks_buf); + if (!_scim_frontend.null ()) { + SCIM_DEBUG_FRONTEND(1) << "Starting Socket FrontEnd module...\n"; + _scim_frontend->init (_argc, _argv); + gettime (start, "Init socket frontend"); + _scim_frontend->run (); + } + } +} + +/** + * To reduce the number of the servers, we merge the function of + * HelperManager process into the SocketFrontEnd. +*/ + +typedef std::vector < std::pair > HelperRepository; + +static HelperRepository __helpers; +static std::vector __load_engine_list; + +void SocketFrontEnd::load_helper_modules (const std::vector &load_engine_list) +{ + SCIM_DEBUG_MAIN (1) << "load_helper_modules ()\n"; + + size_t i; + + __load_engine_list.clear (); + for (i = 0; i < load_engine_list.size (); ++i) + __load_engine_list.push_back (load_engine_list [i]); + + std::vector mod_list; + std::vector all_helper_list; + + scim_get_helper_module_list (all_helper_list); + + // Get the helper module list which should be loaded. + if (load_engine_list.size () && all_helper_list.size ()) { + for (i = 0; i < all_helper_list.size (); ++i) { + if (std::find (load_engine_list.begin (), + load_engine_list.end (), + all_helper_list [i]) != load_engine_list.end ()) + mod_list.push_back (all_helper_list [i]); + } + } + + if (mod_list.size ()) { + HelperInfo info; + std::vector info_list; + std::vector tmp_list; + bool ret = isf_read_ise_info_list (USER_ENGINE_FILE_NAME, info_list); + if (!ret) { + std::cerr << __func__ << " Failed to read(" << USER_ENGINE_FILE_NAME << ")\n"; + } + for (size_t i = 0; i < info_list.size (); ++i) { + if (info_list [i].mode != TOOLBAR_HELPER_MODE) + continue; + if (std::find (mod_list.begin (), mod_list.end (), info_list [i].module) != mod_list.end ()) { + info.uuid = info_list [i].uuid; + info.name = info_list [i].name; + info.icon = info_list [i].icon; + info.option = info_list [i].option; + SCIM_DEBUG_MAIN (3) << " " << info.uuid << ": " << info.name << "\n"; + __helpers.push_back (std::make_pair (info, info_list [i].module)); + tmp_list.push_back (info_list [i].module); + } + } + + HelperModule module; + std::ofstream engine_list_file (USER_ENGINE_FILE_NAME, std::ios::app); + if (!engine_list_file) { + std::cerr << __func__ << " Failed to open(" << USER_ENGINE_FILE_NAME << ")\n"; + } + + for (size_t i = 0; i < mod_list.size (); ++i) { + if (std::find (tmp_list.begin (), tmp_list.end (), mod_list [i]) != tmp_list.end ()) + continue; + + SCIM_DEBUG_MAIN (2) << " Load module: " << mod_list [i] << "\n"; + + if (module.load (mod_list [i]) && module.valid ()) { + size_t num = module.number_of_helpers (); + + SCIM_DEBUG_MAIN (2) << " Find " << num << " Helpers:\n"; + + for (size_t j = 0; j < num; ++j) { + if (module.get_helper_info (j, info)) { + SCIM_DEBUG_MAIN (3) << " " << info.uuid << ": " << info.name << "\n"; + __helpers.push_back (std::make_pair (info, mod_list [i])); + + if (engine_list_file) { + char mode[12]; + char option[12]; + snprintf (mode, sizeof (mode), "%d", (int)TOOLBAR_HELPER_MODE); + snprintf (option, sizeof (option), "%d", info.option); + + String line = isf_combine_ise_info_string (info.name, info.uuid, mod_list [i], isf_get_normalized_language (module.get_helper_lang (j)), + info.icon, String (mode), String (option), String ("")); + engine_list_file << line; + engine_list_file.flush (); + } + } + } + } + + module.unload (); + } + } +} + +void SocketFrontEnd::get_helper_list (const Socket &client) +{ + HelperRepository::iterator it = __helpers.begin (); + + m_send_trans.clear (); + m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); + m_send_trans.put_data ((uint32)__helpers.size ()); + + for (; it != __helpers.end (); ++it) { + m_send_trans.put_data (it->first.uuid); + m_send_trans.put_data (it->first.name); + m_send_trans.put_data (it->first.icon); + m_send_trans.put_data (it->first.description); + m_send_trans.put_data (it->first.option); + } +} + +#ifndef SCIM_HELPER_LAUNCHER_PROGRAM + #define SCIM_HELPER_LAUNCHER_PROGRAM (SCIM_LIBEXECDIR "/scim-helper-launcher") +#endif +static std::vector __active_helpers; + +void SocketFrontEnd::run_helper (const Socket &client) +{ + String uuid; + String config; + String display; + if (!(m_receive_trans.get_data (uuid) && uuid.length () + && m_receive_trans.get_data (config) + && m_receive_trans.get_data (display))) + { + m_send_trans.put_command (SCIM_TRANS_CMD_FAIL); + return; + } + + for (size_t i = 0; i < __helpers.size (); ++i) { + if (__helpers [i].first.uuid == uuid && __helpers [i].second.length ()) { + + __active_helpers.push_back(__helpers [i].first.name); + + int pid; + + pid = fork (); + + if (pid < 0) return; + + if (pid == 0) { + if (m_socket_server.is_running ()) + m_socket_server.shutdown (); + + const char *argv [] = { SCIM_HELPER_LAUNCHER_PROGRAM, + "--daemon", + "--config", const_cast (config.c_str ()), + "--display", const_cast (display.c_str ()), + const_cast (__helpers [i].second.c_str ()), + const_cast (__helpers [i].first.uuid.c_str ()), + 0}; + + SCIM_DEBUG_MAIN(2) << " Call scim-helper-launcher.\n"; + + execv (SCIM_HELPER_LAUNCHER_PROGRAM, (char **)argv); + exit (-1); + } + + //int status; + //waitpid (pid, &status, 0); + + break; + } + } + + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + SCIM_DEBUG_MAIN(2) << " exit run_helper ().\n"; +} + +/** + * get_active_ise_list + * Get the active ise list. we can control the loading of ISEs through + * the command option "-e" of scim process. + */ +void +SocketFrontEnd::get_active_ise_list (int clientid) +{ + m_send_trans.put_data (__load_engine_list); +} + +void +SocketFrontEnd::unregister_helper () +{ + String name; + if (m_receive_trans.get_data (name) && name.length ()) + { + std::vector::iterator iter = __active_helpers.begin (); + for (; iter != __active_helpers.end (); iter++) + { + if (!name.compare (*iter)) + { + __active_helpers.erase (iter); + break; + } + } + } + + m_send_trans.put_command (SCIM_TRANS_CMD_OK); +} + +SocketFrontEnd::SocketFrontEnd (const BackEndPointer &backend, + const ConfigPointer &config) + : FrontEndBase (backend), + m_config (config), + m_stay (true), + m_config_readonly (false), + m_socket_timeout (scim_get_default_socket_timeout ()), + m_current_instance (-1), + m_current_socket_client (-1), + m_current_socket_client_key (0) +{ + SCIM_DEBUG_FRONTEND (2) << " Constructing SocketFrontEnd object...\n"; +} + +SocketFrontEnd::~SocketFrontEnd () +{ + SCIM_DEBUG_FRONTEND (2) << " Destructing SocketFrontEnd object...\n"; + if (m_socket_server.is_running ()) + m_socket_server.shutdown (); +} + +void +SocketFrontEnd::show_preedit_string (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_PREEDIT_STRING); +} + +void +SocketFrontEnd::show_aux_string (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_AUX_STRING); +} + +void +SocketFrontEnd::show_lookup_table (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE); +} + +void +SocketFrontEnd::hide_preedit_string (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_PREEDIT_STRING); +} + +void +SocketFrontEnd::hide_aux_string (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_AUX_STRING); +} + +void +SocketFrontEnd::hide_lookup_table (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE); +} + +void +SocketFrontEnd::update_preedit_caret (int id, int caret) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET); + m_send_trans.put_data ((uint32) caret); + } +} + +void +SocketFrontEnd::update_preedit_string (int id, + const WideString & str, + const AttributeList & attrs) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING); + m_send_trans.put_data (str); + m_send_trans.put_data (attrs); + } +} + +void +SocketFrontEnd::update_aux_string (int id, + const WideString & str, + const AttributeList & attrs) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_AUX_STRING); + m_send_trans.put_data (str); + m_send_trans.put_data (attrs); + } +} + +void +SocketFrontEnd::commit_string (int id, const WideString & str) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_COMMIT_STRING); + m_send_trans.put_data (str); + } +} + +void +SocketFrontEnd::forward_key_event (int id, const KeyEvent & key) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_FORWARD_KEY_EVENT); + m_send_trans.put_data (key); + } +} + +void +SocketFrontEnd::update_lookup_table (int id, const LookupTable & table) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE); + m_send_trans.put_data (table); + } +} + +void +SocketFrontEnd::register_properties (int id, const PropertyList &properties) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_REGISTER_PROPERTIES); + m_send_trans.put_data (properties); + } +} + +void +SocketFrontEnd::update_property (int id, const Property &property) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PROPERTY); + m_send_trans.put_data (property); + } +} + +void +SocketFrontEnd::beep (int id) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_BEEP); + } +} + +void +SocketFrontEnd::start_helper (int id, const String &helper_uuid) +{ + SCIM_DEBUG_FRONTEND (2) << "start_helper (" << helper_uuid << ")\n"; + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_START_HELPER); + m_send_trans.put_data (helper_uuid); + } +} + +void +SocketFrontEnd::stop_helper (int id, const String &helper_uuid) +{ + SCIM_DEBUG_FRONTEND (2) << "stop_helper (" << helper_uuid << ")\n"; + + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_STOP_HELPER); + m_send_trans.put_data (helper_uuid); + } +} + +void +SocketFrontEnd::send_helper_event (int id, const String &helper_uuid, const Transaction &trans) +{ + if (m_current_instance == id) { + m_send_trans.put_command (SCIM_TRANS_CMD_SEND_HELPER_EVENT); + m_send_trans.put_data (helper_uuid); + m_send_trans.put_data (trans); + } +} + +bool +SocketFrontEnd::get_surrounding_text (int id, WideString &text, int &cursor, int maxlen_before, int maxlen_after) +{ + text.clear (); + cursor = 0; + + if (m_current_instance == id && m_current_socket_client >= 0 && (maxlen_before != 0 || maxlen_after != 0)) { + if (maxlen_before < 0) maxlen_before = -1; + if (maxlen_after < 0) maxlen_after = -1; + + m_temp_trans.clear (); + m_temp_trans.put_command (SCIM_TRANS_CMD_REPLY); + m_temp_trans.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT); + m_temp_trans.put_data ((uint32) maxlen_before); + m_temp_trans.put_data ((uint32) maxlen_after); + + Socket socket_client (m_current_socket_client); + + if (m_temp_trans.write_to_socket (socket_client) && + m_temp_trans.read_from_socket (socket_client, m_socket_timeout)) { + + int cmd; + uint32 key; + uint32 cur; + + if (m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST && + m_temp_trans.get_data (key) && key == m_current_socket_client_key && + m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_GET_SURROUNDING_TEXT && + m_temp_trans.get_data (text) && m_temp_trans.get_data (cur)) { + cursor = (int) cur; + return true; + } + } + } + return false; +} + +bool +SocketFrontEnd::delete_surrounding_text (int id, int offset, int len) +{ + if (m_current_instance == id && m_current_socket_client >= 0 && len > 0) { + m_temp_trans.clear (); + m_temp_trans.put_command (SCIM_TRANS_CMD_REPLY); + m_temp_trans.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT); + m_temp_trans.put_data ((uint32) offset); + m_temp_trans.put_data ((uint32) len); + + Socket socket_client (m_current_socket_client); + + if (m_temp_trans.write_to_socket (socket_client) && + m_temp_trans.read_from_socket (socket_client, m_socket_timeout)) { + + int cmd; + uint32 key; + + if (m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST && + m_temp_trans.get_data (key) && key == m_current_socket_client_key && + m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT && + m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + return true; + } + } + return false; +} + +void +SocketFrontEnd::expand_candidate (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (ISM_TRANS_CMD_EXPAND_CANDIDATE); +} + +void +SocketFrontEnd::contract_candidate (int id) +{ + if (m_current_instance == id) + m_send_trans.put_command (ISM_TRANS_CMD_CONTRACT_CANDIDATE); +} + +void +SocketFrontEnd::set_candidate_style (int id, + ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line, + ISF_CANDIDATE_MODE_T mode) +{ + if (m_current_instance == id) { + m_send_trans.put_command (ISM_TRANS_CMD_SET_CANDIDATE_UI); + m_send_trans.put_data ((uint32) portrait_line); + m_send_trans.put_data ((uint32) mode); + } +} + +void +SocketFrontEnd::init (int argc, char **argv) +{ + int max_clients = -1; + + std::vector engine_list; + + if (!m_config.null ()) { + String str; + + m_config_readonly = m_config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_CONFIG_READONLY), false); + + max_clients = m_config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_MAXCLIENTS), -1); + + m_config->signal_connect_reload (slot (this, &SocketFrontEnd::reload_config_callback)); + } else { + m_config_readonly = false; + max_clients = -1; + } + + if (!m_socket_server.create (scim_get_default_socket_frontend_address ())) + throw FrontEndError ("SocketFrontEnd -- Cannot create SocketServer."); + + m_socket_server.set_max_clients (max_clients); + + m_socket_server.signal_connect_accept ( + slot (this, &SocketFrontEnd::socket_accept_callback)); + + m_socket_server.signal_connect_receive ( + slot (this, &SocketFrontEnd::socket_receive_callback)); + + m_socket_server.signal_connect_exception( + slot (this, &SocketFrontEnd::socket_exception_callback)); + + if (argv && argc > 1) { + for (int i = 1; i < argc && argv [i]; ++i) { + if (String ("-e") == argv [i] || String ("--engines") == argv [i]) { + if (++i >= argc) { + std::cerr << "No argument for option " << argv [i-1] << "\n"; + break; + } + if (String (argv [i]) != "none") { + scim_split_string_list (engine_list, String (argv [i]), ','); + } + continue; + } + if (String ("--no-stay") == argv [i]) + m_stay = false; + } + } + + load_helper_modules (engine_list); + + /** + * initialize the random number generator. + */ + srand (time (0)); + + signal (SIGCHLD, SIG_IGN); +} + +void +SocketFrontEnd::run () +{ + if (m_socket_server.valid ()) + m_socket_server.run (); +} + +uint32 +SocketFrontEnd::generate_key () const +{ + return (uint32)rand (); +} + +bool +SocketFrontEnd::check_client_connection (const Socket &client) const +{ + SCIM_DEBUG_FRONTEND (1) << "check_client_connection (" << client.get_id () << ").\n"; + + unsigned char buf [sizeof(uint32)]; + + int nbytes = client.read_with_timeout (buf, sizeof(uint32), m_socket_timeout); + + if (nbytes == sizeof (uint32)) + return true; + + if (nbytes < 0) { + SCIM_DEBUG_FRONTEND (2) << " Error occurred when reading socket (" << client.get_id () + << "):" << client.get_error_message () << "\n"; + } else { + SCIM_DEBUG_FRONTEND (2) << " Timeout when reading socket (" << client.get_id () + << ").\n"; + } + + return false; +} + +void +SocketFrontEnd::socket_accept_callback (SocketServer *server, const Socket &client) +{ + SCIM_DEBUG_FRONTEND (1) << "socket_accept_callback (" << client.get_id () << ").\n"; +} + +void +SocketFrontEnd::socket_receive_callback (SocketServer *server, const Socket &client) +{ + int id = client.get_id (); + int cmd; + uint32 key; + bool reply = true; + + ClientInfo client_info; + + SCIM_DEBUG_FRONTEND (1) << "socket_receive_callback (" << id << ").\n"; + + // Check if the client is closed. + if (!check_client_connection (client)) { + SCIM_DEBUG_FRONTEND (2) << " closing client connection.\n"; + socket_close_connection (server, client); + return; + } + + client_info = socket_get_client_info (client); + + // If it's a new client, then request to open the connection first. + if (client_info.type == UNKNOWN_CLIENT) { + socket_open_connection (server, client); + return; + } + + // If can not read the transaction, + // or the transaction is not started with SCIM_TRANS_CMD_REQUEST, + // or the key is mismatch, + // just return. + if (!m_receive_trans.read_from_socket (client, m_socket_timeout) || + !m_receive_trans.get_command (cmd) || cmd != SCIM_TRANS_CMD_REQUEST || + !m_receive_trans.get_data (key) || key != (uint32) client_info.key) + return; + + m_current_socket_client = id; + m_current_socket_client_key = key; + + m_send_trans.clear (); + m_send_trans.put_command (SCIM_TRANS_CMD_REPLY); + + // Move the read ptr to the end. + if (!m_send_trans.get_command (cmd)) + return; + + while (m_receive_trans.get_command (cmd)) { + if (cmd == SCIM_TRANS_CMD_PROCESS_KEY_EVENT) + socket_process_key_event (id); + else if (cmd == SCIM_TRANS_CMD_MOVE_PREEDIT_CARET) + socket_move_preedit_caret (id); + else if (cmd == ISM_TRANS_CMD_SELECT_AUX) + socket_select_aux (id); + else if (cmd == SCIM_TRANS_CMD_SELECT_CANDIDATE) + socket_select_candidate (id); + else if (cmd == SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE) + socket_update_lookup_table_page_size (id); + else if (cmd == SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP) + socket_lookup_table_page_up (id); + else if (cmd == SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN) + socket_lookup_table_page_down (id); + else if (cmd == ISM_TRANS_CMD_SET_PREDICTION_ALLOW) + socket_set_prediction_allow (id); + else if (cmd == ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT) + socket_update_candidate_item_layout (id); + else if (cmd == ISM_TRANS_CMD_UPDATE_CURSOR_POSITION) + socket_update_cursor_position (id); + else if (cmd == ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE) + socket_update_displayed_candidate_number (id); + else if (cmd == ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW) + socket_candidate_more_window_show (id); + else if (cmd == ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE) + socket_candidate_more_window_hide (id); + else if (cmd == ISM_TRANS_CMD_LONGPRESS_CANDIDATE) + socket_longpress_candidate (id); + else if (cmd == ISM_TRANS_CMD_SET_ISE_IMDATA) + socket_set_imdata (id); + else if (cmd == ISM_TRANS_CMD_SET_LAYOUT) + socket_set_layout (id); + else if (cmd == ISM_TRANS_CMD_RESET_ISE_OPTION) + socket_reset_option (id); + else if (cmd == SCIM_TRANS_CMD_RESET) + socket_reset (id); + else if (cmd == SCIM_TRANS_CMD_FOCUS_IN) + socket_focus_in (id); + else if (cmd == SCIM_TRANS_CMD_FOCUS_OUT) + socket_focus_out (id); + else if (cmd == SCIM_TRANS_CMD_TRIGGER_PROPERTY) + socket_trigger_property (id); + else if (cmd == SCIM_TRANS_CMD_PROCESS_HELPER_EVENT) + socket_process_helper_event (id); + else if (cmd == SCIM_TRANS_CMD_UPDATE_CLIENT_CAPABILITIES) + socket_update_client_capabilities (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_LIST) + socket_get_factory_list (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_NAME) + socket_get_factory_name (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_AUTHORS) + socket_get_factory_authors (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_CREDITS) + socket_get_factory_credits (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_HELP) + socket_get_factory_help (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_LOCALES) + socket_get_factory_locales (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_ICON_FILE) + socket_get_factory_icon_file (id); + else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_LANGUAGE) + socket_get_factory_language (id); + else if (cmd == SCIM_TRANS_CMD_NEW_INSTANCE) + socket_new_instance (id); + else if (cmd == SCIM_TRANS_CMD_DELETE_INSTANCE) + socket_delete_instance (id); + else if (cmd == SCIM_TRANS_CMD_DELETE_ALL_INSTANCES) + socket_delete_all_instances (id); + else if (cmd == SCIM_TRANS_CMD_FLUSH_CONFIG) + socket_flush_config (id); + else if (cmd == SCIM_TRANS_CMD_ERASE_CONFIG) + socket_erase_config (id); + else if (cmd == SCIM_TRANS_CMD_RELOAD_CONFIG) + socket_reload_config (id); + else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_STRING) + socket_get_config_string (id); + else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_STRING) + socket_set_config_string (id); + else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_INT) + socket_get_config_int (id); + else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_INT) + socket_set_config_int (id); + else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_BOOL) + socket_get_config_bool (id); + else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_BOOL) + socket_set_config_bool (id); + else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_DOUBLE) + socket_get_config_double (id); + else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_DOUBLE) + socket_set_config_double (id); + else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_VECTOR_STRING) + socket_get_config_vector_string (id); + else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_VECTOR_STRING) + socket_set_config_vector_string (id); + else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_VECTOR_INT) + socket_get_config_vector_int (id); + else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_VECTOR_INT) + socket_set_config_vector_int (id); + else if (cmd == ISM_TRANS_CMD_GET_ACTIVE_ISE_LIST) + get_active_ise_list (id); + else if (cmd == SCIM_TRANS_CMD_LOAD_FILE) + socket_load_file (id); + else if (cmd == SCIM_TRANS_CMD_CLOSE_CONNECTION) { + socket_close_connection (server, client); + m_current_socket_client = -1; + m_current_socket_client_key = 0; + return; + } else if (cmd == SCIM_TRANS_CMD_HELPER_MANAGER_GET_HELPER_LIST) { + SCIM_DEBUG_FRONTEND (1) << "receive cmd SCIM_TRANS_CMD_HELPER_MANAGER_GET_HELPER_LIST\n"; + get_helper_list (client); + } else if (cmd == SCIM_TRANS_CMD_HELPER_MANAGER_RUN_HELPER) { + SCIM_DEBUG_FRONTEND (1) << "receive cmd SCIM_TRANS_CMD_HELPER_MANAGER_RUN_HELPER\n"; + reply = false; + run_helper (client); + } else if (cmd == SCIM_TRANS_CMD_HELPER_MANAGER_STOP_HELPER) { + SCIM_DEBUG_FRONTEND (1) << "receive cmd SCIM_TRANS_CMD_HELPER_MANAGER_STOP_HELPER\n"; + unregister_helper (); + } else if (cmd == SCIM_TRANS_CMD_HELPER_MANAGER_SEND_DISPLAY) { + SCIM_DEBUG_FRONTEND (1) << "receive cmd SCIM_TRANS_CMD_HELPER_MANAGER_SEND_DISPLAY\n"; + socket_set_display_name (id); + } else if (cmd == SCIM_TRANS_CMD_HELPER_MANAGER_SEND_ISE_LIST) { + SCIM_DEBUG_FRONTEND (1) << "receive cmd SCIM_TRANS_CMD_HELPER_MANAGER_SEND_ISE_LIST\n"; + reply = false; + socket_update_ise_list (id); + } else if (cmd == ISM_TRANS_CMD_TURN_ON_LOG) { + SCIM_DEBUG_FRONTEND (1) << "receive cmd ISM_TRANS_CMD_TURN_ON_LOG\n"; + socket_turn_on_log (id); + } + } + + // Send reply to client + if (m_send_trans.get_data_type () == SCIM_TRANS_DATA_UNKNOWN) + m_send_trans.put_command (SCIM_TRANS_CMD_FAIL); + + if (reply) + m_send_trans.write_to_socket (client); + + m_current_socket_client = -1; + m_current_socket_client_key = 0; + + SCIM_DEBUG_FRONTEND (1) << "End of socket_receive_callback (" << id << ").\n"; +} + +bool +SocketFrontEnd::socket_open_connection (SocketServer *server, const Socket &client) +{ + SCIM_DEBUG_FRONTEND (2) << " Open socket connection for client " << client.get_id () << " number of clients=" << m_socket_client_repository.size () << ".\n"; + + uint32 key; + String type = scim_socket_accept_connection (key, + String ("SocketFrontEnd,HelperLauncher"), + String ("SocketIMEngine,SocketConfig,HelperManager"), + client, + m_socket_timeout); + + if (type.length ()) { + ClientInfo info; + info.key = key; + info.type = ((type == "SocketIMEngine") ? IMENGINE_CLIENT + : ((type == "SocketConfig") ? CONFIG_CLIENT : HELPER_MANAGER_CLIENT)); + + SCIM_DEBUG_MAIN (2) << " Add client to repository. Type=" << type << " key=" << key << "\n"; + m_socket_client_repository [client.get_id ()] = info; + return true; + } + + // Client did not pass the registration process, close it. + SCIM_DEBUG_FRONTEND (2) << " Failed to create new connection.\n"; + server->close_connection (client); + return false; +} + +void +SocketFrontEnd::socket_close_connection (SocketServer *server, const Socket &client) +{ + SCIM_DEBUG_FRONTEND (2) << " Close client connection " << client.get_id () << " number of clients=" << m_socket_client_repository.size () << ".\n"; + + ClientInfo client_info = socket_get_client_info (client); + + server->close_connection (client); + + if (client_info.type != UNKNOWN_CLIENT) { + m_socket_client_repository.erase (client.get_id ()); + + if (client_info.type == IMENGINE_CLIENT) + socket_delete_all_instances (client.get_id ()); + + if (!m_socket_client_repository.size () && !m_stay) + server->shutdown (); + } +} + +SocketFrontEnd::ClientInfo +SocketFrontEnd::socket_get_client_info (const Socket &client) +{ + static ClientInfo null_client = { 0, UNKNOWN_CLIENT }; + SocketClientRepository::iterator it = m_socket_client_repository.find (client.get_id ()); + + if (it != m_socket_client_repository.end ()) + return it->second; + + return null_client; +} + +void +SocketFrontEnd::socket_exception_callback (SocketServer *server, const Socket &client) +{ + SCIM_DEBUG_FRONTEND (1) << "socket_exception_callback (" << client.get_id () << ").\n"; + + socket_close_connection (server, client); +} + +//client_id is client's socket id +void +SocketFrontEnd::socket_get_factory_list (int /*client_id*/) +{ + String encoding; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_list.\n"; + + if (m_receive_trans.get_data (encoding)) { + std::vector uuids; + + if (encoding == "") + get_factory_list (uuids); + else + get_factory_list_for_encoding (uuids, encoding); + + SCIM_DEBUG_FRONTEND (3) << " Encoding (" << encoding + << ") Num(" << uuids.size () << ").\n"; + + m_send_trans.put_data (uuids); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_factory_name (int /*client_id*/) +{ + String sfid; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_name.\n"; + + if (m_receive_trans.get_data (sfid)) { + WideString name = get_factory_name (sfid); + + m_send_trans.put_data (name); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_factory_authors (int /*client_id*/) +{ + String sfid; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_authors.\n"; + + if (m_receive_trans.get_data (sfid)) { + WideString authors = get_factory_authors (sfid); + + m_send_trans.put_data (authors); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_factory_credits (int /*client_id*/) +{ + String sfid; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_credits.\n"; + + if (m_receive_trans.get_data (sfid)) { + WideString credits = get_factory_credits (sfid); + + m_send_trans.put_data (credits); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_factory_help (int /*client_id*/) +{ + String sfid; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_help.\n"; + + if (m_receive_trans.get_data (sfid)) { + WideString help = get_factory_help (sfid); + + m_send_trans.put_data (help); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_factory_locales (int /*client_id*/) +{ + String sfid; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_locales.\n"; + + if (m_receive_trans.get_data (sfid)) { + String locales = get_factory_locales (sfid); + + SCIM_DEBUG_FRONTEND (3) << " Locales (" << locales << ").\n"; + + m_send_trans.put_data (locales); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_factory_icon_file (int /*client_id*/) +{ + String sfid; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_icon_file.\n"; + + if (m_receive_trans.get_data (sfid)) { + String iconfile = get_factory_icon_file (sfid); + + SCIM_DEBUG_FRONTEND (3) << " ICON File (" << iconfile << ").\n"; + + m_send_trans.put_data (iconfile); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_factory_language (int /*client_id*/) +{ + String sfid; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_language.\n"; + + if (m_receive_trans.get_data (sfid)) { + String language = get_factory_language (sfid); + + SCIM_DEBUG_FRONTEND (3) << " Language (" << language << ").\n"; + + m_send_trans.put_data (language); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_new_instance (int client_id) +{ + String sfid; + String encoding; + + SCIM_DEBUG_FRONTEND (2) << " socket_new_instance.\n"; + + if (m_receive_trans.get_data (sfid) && + m_receive_trans.get_data (encoding)) { + int siid = new_instance (m_config, sfid, encoding); + + // Instance created OK. + if (siid >= 0) { + SocketInstanceRepository::iterator it = + std::lower_bound (m_socket_instance_repository.begin (), + m_socket_instance_repository.end (), + std::pair (client_id, siid)); + + if (it == m_socket_instance_repository.end ()) + m_socket_instance_repository.push_back (std::pair (client_id, siid)); + else + m_socket_instance_repository.insert (it, std::pair (client_id, siid)); + + SCIM_DEBUG_FRONTEND (3) << " InstanceID (" << siid << ").\n"; + + m_send_trans.put_data ((uint32)siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } + } +} + +void +SocketFrontEnd::socket_delete_instance (int client_id) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << " socket_delete_instance.\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " InstanceID (" << siid << ").\n"; + + m_current_instance = (int) siid; + + delete_instance ((int) siid); + + m_current_instance = -1; + + SocketInstanceRepository::iterator it = + std::lower_bound (m_socket_instance_repository.begin (), + m_socket_instance_repository.end (), + std::pair (client_id, siid)); + + if (it != m_socket_instance_repository.end () && + *it == std::pair (client_id, siid)) + m_socket_instance_repository.erase (it); + + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_delete_all_instances (int client_id) +{ + SCIM_DEBUG_FRONTEND (2) << " socket_delete_all_instances.\n"; + + SocketInstanceRepository::iterator it; + + SocketInstanceRepository::iterator lit = + std::lower_bound (m_socket_instance_repository.begin (), + m_socket_instance_repository.end (), + std::pair (client_id, 0)); + + SocketInstanceRepository::iterator uit = + std::upper_bound (m_socket_instance_repository.begin (), + m_socket_instance_repository.end (), + std::pair (client_id, INT_MAX)); + + if (lit != uit) { + for (it = lit; it != uit; ++it) { + m_current_instance = it->second; + delete_instance (it->second); + } + m_current_instance = -1; + m_socket_instance_repository.erase (lit, uit); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_process_key_event (int /*client_id*/) +{ + uint32 siid; + KeyEvent event; + + SCIM_DEBUG_FRONTEND (2) << " socket_process_key_event.\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (event)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") KeyEvent (" + << event.code << "," << event.mask << ").\n"; + + m_current_instance = (int) siid; + + if (process_key_event ((int) siid, event)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + else + m_send_trans.put_command (SCIM_TRANS_CMD_FAIL); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_move_preedit_caret (int /*client_id*/) +{ + uint32 siid; + uint32 caret; + + SCIM_DEBUG_FRONTEND (2) << " socket_move_preedit_caret.\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (caret)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid + << ") Caret (" << caret << ").\n"; + + m_current_instance = (int) siid; + + move_preedit_caret ((int) siid, caret); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_select_aux (int /*client_id*/) +{ + uint32 siid; + uint32 item; + + SCIM_DEBUG_FRONTEND (2) << " socket_select_aux.\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (item)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") Item (" << item << ").\n"; + + m_current_instance = (int) siid; + + select_aux ((int) siid, item); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_select_candidate (int /*client_id*/) +{ + uint32 siid; + uint32 item; + + SCIM_DEBUG_FRONTEND (2) << " socket_select_candidate.\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (item)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") Item (" << item << ").\n"; + + m_current_instance = (int) siid; + + select_candidate ((int) siid, item); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_update_lookup_table_page_size (int /*client_id*/) +{ + uint32 siid; + uint32 size; + + SCIM_DEBUG_FRONTEND (2) << " socket_update_lookup_table_page_size.\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (size)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") PageSize (" << size << ").\n"; + + m_current_instance = (int) siid; + + update_lookup_table_page_size ((int) siid, size); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_lookup_table_page_up (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << " socket_lookup_table_page_up.\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + lookup_table_page_up ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_lookup_table_page_down (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << " socket_lookup_table_page_down.\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + lookup_table_page_down ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_set_prediction_allow (int /*client_id*/) +{ + uint32 siid; + uint32 allow; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (allow)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + set_prediction_allow ((int) siid, (bool) allow); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_set_layout (int /*client_id*/) +{ + uint32 siid; + uint32 layout; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (layout)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + set_layout ((int) siid, layout); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_update_candidate_item_layout (int /*client_id*/) +{ + uint32 siid; + std::vector row_items; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (row_items)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") RowSize (" << row_items.size () << ").\n"; + + m_current_instance = (int) siid; + + update_candidate_item_layout ((int) siid, row_items); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_update_cursor_position (int /*client_id*/) +{ + uint32 siid; + unsigned int cursor_pos; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (cursor_pos)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") New cursor (" << cursor_pos << ").\n"; + + m_current_instance = (int) siid; + + update_cursor_position ((int) siid, cursor_pos); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_update_displayed_candidate_number (int /*client_id*/) +{ + uint32 siid; + unsigned int number; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (number)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") displayed candidate number (" << number << ").\n"; + + m_current_instance = (int) siid; + + update_displayed_candidate_number ((int) siid, number); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_candidate_more_window_show (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + candidate_more_window_show ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_candidate_more_window_hide (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + candidate_more_window_hide ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_longpress_candidate (int /*client_id*/) +{ + uint32 siid; + unsigned int index; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (index)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") index (" << index << ").\n"; + + m_current_instance = (int) siid; + + longpress_candidate ((int) siid, index); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_set_imdata (int /*client_id*/) +{ + uint32 siid; + char *imdata = NULL; + unsigned int length; + + SCIM_DEBUG_FRONTEND (2) << __func__ << "\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (&imdata, length)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") length (" << length << ").\n"; + + m_current_instance = (int) siid; + + set_imdata ((int) siid, imdata, length); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } + + if (NULL != imdata) + delete [] imdata; +} + +void +SocketFrontEnd::socket_reset_option (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << " socket_reset_option.\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + reset_option ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_reset (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << " socket_reset.\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + reset ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_focus_in (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << " socket_focus_in.\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + focus_in ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_focus_out (int /*client_id*/) +{ + uint32 siid; + + SCIM_DEBUG_FRONTEND (2) << " socket_focus_out.\n"; + + if (m_receive_trans.get_data (siid)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + focus_out ((int) siid); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_trigger_property (int /*client_id*/) +{ + uint32 siid; + String property; + + SCIM_DEBUG_FRONTEND (2) << " socket_trigger_property.\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (property)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + trigger_property ((int) siid, property); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_process_helper_event (int /*client_id*/) +{ + uint32 siid; + String helper_uuid; + Transaction trans; + + SCIM_DEBUG_FRONTEND (2) << " socket_process_helper_event.\n"; + + if (m_receive_trans.get_data (siid) && + m_receive_trans.get_data (helper_uuid) && + m_receive_trans.get_data (trans)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + process_helper_event ((int) siid, helper_uuid, trans); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + +void +SocketFrontEnd::socket_update_client_capabilities (int /*client_id*/) +{ + uint32 siid; + uint32 cap; + + SCIM_DEBUG_FRONTEND (2) << " socket_update_client_capabilities.\n"; + + if (m_receive_trans.get_data (siid) && m_receive_trans.get_data (cap)) { + + SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n"; + + m_current_instance = (int) siid; + + update_client_capabilities ((int) siid, cap); + + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + + m_current_instance = -1; + } +} + + +void +SocketFrontEnd::socket_flush_config (int /*client_id*/) +{ + if (m_config_readonly || m_config.null ()) + return; + + SCIM_DEBUG_FRONTEND (2) << " socket_flush_config.\n"; + + if (m_config->flush ()) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); +} + +void +SocketFrontEnd::socket_erase_config (int /*client_id*/) +{ + if (m_config_readonly || m_config.null ()) + return; + + String key; + + SCIM_DEBUG_FRONTEND (2) << " socket_erase_config.\n"; + + if (m_receive_trans.get_data (key)) { + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + if (m_config->erase (key)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_reload_config (int /*client_id*/) +{ + static timeval last_timestamp = {0, 0}; + + if (m_config.null ()) + return; + + SCIM_DEBUG_FRONTEND (2) << " socket_reload_config.\n"; + + timeval timestamp; + + gettimeofday (×tamp, 0); + + if (timestamp.tv_sec >= last_timestamp.tv_sec) + m_config->reload (); + + gettimeofday (&last_timestamp, 0); + + m_send_trans.put_command (SCIM_TRANS_CMD_OK); +} + +void +SocketFrontEnd::socket_set_display_name (int /*client_id*/) +{ + String name; + + if (m_receive_trans.get_data (name) && name.length () > 0) + m_display = name; + + m_send_trans.put_command (SCIM_TRANS_CMD_OK); +} + +void +SocketFrontEnd::socket_update_ise_list (int /*client_id*/) +{ + String strName; + //std::vector name_list; + std::vector imengine_list; + std::vector helper_list; + + if (m_receive_trans.get_data (strName) && strName.length () > 0) { + //std::cout << "ISE name list:" << strName << "\n"; + //scim_split_string_list (name_list, strName); + + scim_get_imengine_module_list (imengine_list); + scim_get_helper_module_list (helper_list); + + for (size_t i = 0; i < imengine_list.size (); ++i) { + if (std::find (__load_engine_list.begin (), __load_engine_list.end (), imengine_list [i]) == __load_engine_list.end ()) { + SCIM_DEBUG_FRONTEND (3) << "add_module " << imengine_list [i] << " in " << __FUNCTION__ << "\n"; + //add_module (m_config, imengine_list [i], true); + add_module_info (m_config, imengine_list [i]); + __load_engine_list.push_back (imengine_list [i]); + } + } + + HelperModule module; + HelperInfo info; + for (size_t i = 0; i < helper_list.size (); ++i) { + if (std::find (__load_engine_list.begin (), __load_engine_list.end (), helper_list [i]) == __load_engine_list.end ()) { + if (module.load (helper_list [i]) && module.valid ()) { + size_t num = module.number_of_helpers (); + for (size_t j = 0; j < num; ++j) { + if (module.get_helper_info (j, info)) + __helpers.push_back (std::make_pair (info, helper_list [i])); + } + __load_engine_list.push_back (helper_list [i]); + } + module.unload (); + } + } + } + + m_send_trans.put_command (SCIM_TRANS_CMD_OK); +} + +void +SocketFrontEnd::socket_get_config_string (int /*client_id*/) +{ + if (m_config.null ()) return; + + String key; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_config_string.\n"; + + if (m_receive_trans.get_data (key)) { + String value; + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + if (m_config->read (key, &value)) { + m_send_trans.put_data (value); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } + } +} + +void +SocketFrontEnd::socket_set_config_string (int /*client_id*/) +{ + if (m_config_readonly || m_config.null ()) + return; + + String key; + String value; + + SCIM_DEBUG_FRONTEND (2) << " socket_set_config_string.\n"; + + if (m_receive_trans.get_data (key) && + m_receive_trans.get_data (value)) { + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n"; + + if (m_config->write (key, value)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_config_int (int /*client_id*/) +{ + if (m_config.null ()) return; + + String key; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_config_int.\n"; + + if (m_receive_trans.get_data (key)) { + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + int value; + if (m_config->read (key, &value)) { + m_send_trans.put_data ((uint32) value); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } + } +} + +void +SocketFrontEnd::socket_set_config_int (int /*client_id*/) +{ + if (m_config_readonly || m_config.null ()) + return; + + String key; + uint32 value; + + SCIM_DEBUG_FRONTEND (2) << " socket_set_config_int.\n"; + + if (m_receive_trans.get_data (key) && + m_receive_trans.get_data (value)) { + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n"; + + if (m_config->write (key, (int) value)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_config_bool (int /*client_id*/) +{ + if (m_config.null ()) return; + + String key; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_config_bool.\n"; + + if (m_receive_trans.get_data (key)) { + bool value; + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + if (m_config->read (key, &value)) { + m_send_trans.put_data ((uint32) value); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } + } +} + +void +SocketFrontEnd::socket_set_config_bool (int /*client_id*/) +{ + if (m_config_readonly || m_config.null ()) + return; + + String key; + uint32 value; + + SCIM_DEBUG_FRONTEND (2) << " socket_set_config_bool.\n"; + + if (m_receive_trans.get_data (key) && + m_receive_trans.get_data (value)) { + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n"; + + if (m_config->write (key, (bool) value)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_config_double (int /*client_id*/) +{ + if (m_config.null ()) return; + + String key; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_config_double.\n"; + + if (m_receive_trans.get_data (key)) { + double value; + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + if (m_config->read (key, &value)) { + char buf [80]; + snprintf (buf, 79, "%lE", value); + m_send_trans.put_data (String (buf)); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } + } +} + +void +SocketFrontEnd::socket_set_config_double (int /*client_id*/) +{ + if (m_config_readonly || m_config.null ()) + return; + + String key; + String str; + + SCIM_DEBUG_FRONTEND (2) << " socket_set_config_double.\n"; + + if (m_receive_trans.get_data (key) && + m_receive_trans.get_data (str)) { + double value; + sscanf (str.c_str (), "%lE", &value); + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n"; + + if (m_config->write (key, value)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_config_vector_string (int /*client_id*/) +{ + if (m_config.null ()) return; + + String key; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_config_vector_string.\n"; + + if (m_receive_trans.get_data (key)) { + std::vector vec; + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + if (m_config->read (key, &vec)) { + m_send_trans.put_data (vec); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } + } +} + +void +SocketFrontEnd::socket_set_config_vector_string (int /*client_id*/) +{ + if (m_config_readonly || m_config.null ()) + return; + + String key; + std::vector vec; + + SCIM_DEBUG_FRONTEND (2) << " socket_set_config_vector_string.\n"; + + if (m_receive_trans.get_data (key) && + m_receive_trans.get_data (vec)) { + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + if (m_config->write (key, vec)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_get_config_vector_int (int /*client_id*/) +{ + if (m_config.null ()) return; + + String key; + + SCIM_DEBUG_FRONTEND (2) << " socket_get_config_vector_int.\n"; + + if (m_receive_trans.get_data (key)) { + std::vector vec; + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + if (m_config->read (key, &vec)) { + std::vector reply; + + for (uint32 i=0; i vec; + + SCIM_DEBUG_FRONTEND (2) << " socket_set_config_vector_int.\n"; + + if (m_receive_trans.get_data (key) && + m_receive_trans.get_data (vec)) { + std::vector req; + + SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n"; + + for (uint32 i=0; iwrite (key, req)) + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } +} + +void +SocketFrontEnd::socket_load_file (int /*client_id*/) +{ + String filename; + char *bufptr = 0; + size_t filesize = 0; + + SCIM_DEBUG_FRONTEND (2) << " socket_load_file.\n"; + + if (m_receive_trans.get_data (filename)) { + SCIM_DEBUG_FRONTEND (3) << " File (" << filename << ").\n"; + + filesize = scim_load_file (filename, &bufptr); + if (filesize > 0) { + m_send_trans.put_data (bufptr, filesize); + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + } + + delete [] bufptr; + } +} + +void +SocketFrontEnd::socket_turn_on_log (int /*client_id*/) +{ + uint32 isOn; + SCIM_DEBUG_FRONTEND (2) << " socket_turn_on_log.\n"; + + if (m_receive_trans.get_data (isOn)) { + if (isOn) { + DebugOutput::enable_debug (SCIM_DEBUG_AllMask); + DebugOutput::set_verbose_level (7); + } else { + DebugOutput::disable_debug (SCIM_DEBUG_AllMask); + DebugOutput::set_verbose_level (0); + } + m_send_trans.put_command (SCIM_TRANS_CMD_OK); + return; + } + + m_send_trans.put_command (SCIM_TRANS_CMD_FAIL); + return; +} + +void +SocketFrontEnd::reload_config_callback (const ConfigPointer &config) +{ + SCIM_DEBUG_FRONTEND (1) << "Reload configuration.\n"; + + int max_clients = -1; + + m_config_readonly = config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_CONFIG_READONLY), false); + max_clients = config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_MAXCLIENTS), -1); + + m_socket_server.set_max_clients (max_clients); +} + +/* +vi:ts=4:nowrap:expandtab +*/ diff --git a/ism/modules/frontend/scim_socket_frontend.h b/ism/modules/frontend/scim_socket_frontend.h new file mode 100644 index 0000000..cf5de4d --- /dev/null +++ b/ism/modules/frontend/scim_socket_frontend.h @@ -0,0 +1,235 @@ +/** + * @file scim_socket_frontend.h + * @brief definition of SocketFrontEnd related classes. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Add helper ISE management + * a. Load helper ISE module + * b. Launch helper ISE + * 2. Dynamic load keyboard ISE + * 3. Add new interface APIs for keyboard ISE + * a. expand_candidate (), contract_candidate () and set_candidate_style () + * b. socket_select_aux (), socket_set_prediction_allow () and socket_set_layout () + * c. socket_update_candidate_item_layout (), socket_update_cursor_position () and socket_update_displayed_candidate_number () + * d. socket_candidate_more_window_show (), socket_candidate_more_window_hide () and socket_longpress_candidate () + * e. socket_set_imdata () and socket_reset_option () + * + * $Id: scim_socket_frontend.h,v 1.26 2005/04/14 17:01:56 suzhe Exp $ + */ + +#if !defined (__SCIM_SOCKET_FRONTEND_H) +#define __SCIM_SOCKET_FRONTEND_H + +#include "scim_stl_map.h" + +using namespace scim; + +class SocketFrontEnd : public FrontEndBase +{ + enum ClientType { + UNKNOWN_CLIENT, + IMENGINE_CLIENT, + CONFIG_CLIENT, + HELPER_MANAGER_CLIENT + }; + + struct ClientInfo { + uint32 key; + ClientType type; + }; + + /** + * ::first = socket id, ::second = instance id. + */ + typedef std::vector > SocketInstanceRepository; + +#if SCIM_USE_STL_EXT_HASH_MAP + typedef __gnu_cxx::hash_map > SocketClientRepository; +#elif SCIM_USE_STL_HASH_MAP + typedef std::hash_map > SocketClientRepository; +#else + typedef std::map SocketClientRepository; +#endif + + ConfigPointer m_config; + String m_display; + + SocketServer m_socket_server; + + Transaction m_send_trans; + Transaction m_receive_trans; + Transaction m_temp_trans; + + SocketInstanceRepository m_socket_instance_repository; + + SocketClientRepository m_socket_client_repository; + + bool m_stay; + + bool m_config_readonly; + + int m_socket_timeout; + + int m_current_instance; + + int m_current_socket_client; + + uint32 m_current_socket_client_key; + +public: + SocketFrontEnd (const BackEndPointer &backend, + const ConfigPointer &config); + + virtual ~SocketFrontEnd (); + +protected: + virtual void show_preedit_string (int id); + virtual void show_aux_string (int id); + virtual void show_lookup_table (int id); + + virtual void hide_preedit_string (int id); + virtual void hide_aux_string (int id); + virtual void hide_lookup_table (int id); + + virtual void update_preedit_caret (int id, int caret); + virtual void update_preedit_string (int id, const WideString & str, const AttributeList & attrs); + virtual void update_aux_string (int id, const WideString & str, const AttributeList & attrs); + virtual void commit_string (int id, const WideString & str); + virtual void forward_key_event (int id, const KeyEvent & key); + virtual void update_lookup_table (int id, const LookupTable & table); + + virtual void register_properties (int id, const PropertyList & properties); + virtual void update_property (int id, const Property & property); + + virtual void beep (int id); + + virtual void start_helper (int id, const String &helper_uuid); + virtual void stop_helper (int id, const String &helper_uuid); + virtual void send_helper_event (int id, const String &helper_uuid, const Transaction &trans); + + virtual bool get_surrounding_text (int id, WideString &text, int &cursor, int maxlen_before, int maxlen_after); + virtual bool delete_surrounding_text (int id, int offset, int len); + + virtual void expand_candidate (int id); + virtual void contract_candidate (int id); + virtual void set_candidate_style (int id, + ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line, + ISF_CANDIDATE_MODE_T mode); + +public: + virtual void init (int argc, char **argv); + virtual void run (); + +private: + void load_helper_modules (const std::vector &load_engine_list); + void get_helper_list (const Socket &client); + void run_helper (const Socket &client); + + void get_active_ise_list (int client_id); + void unregister_helper (); + + uint32 generate_key () const; + + bool check_client_connection (const Socket &client) const; + + void socket_accept_callback (SocketServer *server, const Socket &client); + void socket_receive_callback (SocketServer *server, const Socket &client); + void socket_exception_callback (SocketServer *server, const Socket &client); + + bool socket_open_connection (SocketServer *server, const Socket &client); + void socket_close_connection (SocketServer *server, const Socket &client); + ClientInfo socket_get_client_info (const Socket &client); + + //client_id is client's socket id + void socket_get_factory_list (int client_id); + void socket_get_factory_name (int client_id); + void socket_get_factory_authors (int client_id); + void socket_get_factory_credits (int client_id); + void socket_get_factory_help (int client_id); + void socket_get_factory_locales (int client_id); + void socket_get_factory_icon_file (int client_id); + void socket_get_factory_language (int client_id); + + void socket_new_instance (int client_id); + void socket_delete_instance (int client_id); + void socket_delete_all_instances (int client_id); + + void socket_process_key_event (int client_id); + void socket_move_preedit_caret (int client_id); + void socket_select_aux (int client_id); + void socket_select_candidate (int client_id); + void socket_update_lookup_table_page_size (int client_id); + void socket_lookup_table_page_up (int client_id); + void socket_lookup_table_page_down (int client_id); + void socket_set_prediction_allow (int client_id); + void socket_set_layout (int client_id); + void socket_reset_option (int client_id); + void socket_reset (int client_id); + void socket_focus_in (int client_id); + void socket_focus_out (int client_id); + void socket_trigger_property (int client_id); + void socket_process_helper_event (int client_id); + void socket_update_client_capabilities (int client_id); + + void socket_flush_config (int client_id); + void socket_erase_config (int client_id); + void socket_get_config_string (int client_id); + void socket_set_config_string (int client_id); + void socket_get_config_int (int client_id); + void socket_set_config_int (int client_id); + void socket_get_config_bool (int client_id); + void socket_set_config_bool (int client_id); + void socket_get_config_double (int client_id); + void socket_set_config_double (int client_id); + void socket_get_config_vector_string (int client_id); + void socket_set_config_vector_string (int client_id); + void socket_get_config_vector_int (int client_id); + void socket_set_config_vector_int (int client_id); + void socket_reload_config (int client_id); + void socket_set_display_name (int client_id); + void socket_update_ise_list (int client_id); + + void socket_load_file (int client_id); + void socket_turn_on_log (int client_id); + + void reload_config_callback (const ConfigPointer &config); + + void socket_update_candidate_item_layout (int client_id); + void socket_update_cursor_position (int client_id); + void socket_update_displayed_candidate_number (int client_id); + void socket_candidate_more_window_show (int client_id); + void socket_candidate_more_window_hide (int client_id); + void socket_longpress_candidate (int client_id); + void socket_set_imdata (int client_id); +}; + +#endif + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/frontend/scim_x11_frontend.cpp b/ism/modules/frontend/scim_x11_frontend.cpp new file mode 100644 index 0000000..2108af7 --- /dev/null +++ b/ism/modules/frontend/scim_x11_frontend.cpp @@ -0,0 +1,2038 @@ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/** @file scim_x11_frontend.cpp + * implementation of class X11FrontEnd. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Implement aux and preedit show/hide/update for helper ISE + * a. panel_slot_select_aux () + * b. panel_slot_show_preedit_string (), panel_slot_hide_preedit_string () and panel_slot_update_preedit_string () + * + * $Id: scim_x11_frontend.cpp,v 1.179.2.6 2007/06/16 06:23:38 suzhe Exp $ + * + */ + +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_FRONTEND +#define Uses_SCIM_ICONV +#define Uses_SCIM_SOCKET +#define Uses_SCIM_TRANSACTION +#define Uses_SCIM_HOTKEY +#define Uses_SCIM_PANEL_CLIENT +#define Uses_C_LOCALE +#define Uses_C_STDIO +#define Uses_C_STDLIB + +#include +#include +#include +#include +#include +#include +#include +#include +#include "imdkit/IMdkit.h" +#include "imdkit/Xi18n.h" + +#include "scim_private.h" +#include "scim.h" + +#include "scim_x11_ic.h" +#include "scim_x11_frontend.h" +#include "scim_x11_utils.h" + +#define scim_module_init x11_LTX_scim_module_init +#define scim_module_exit x11_LTX_scim_module_exit +#define scim_frontend_module_init x11_LTX_scim_frontend_module_init +#define scim_frontend_module_run x11_LTX_scim_frontend_module_run + +#define SCIM_CONFIG_FRONTEND_X11_BROKEN_WCHAR "/FrontEnd/X11/BrokenWchar" +#define SCIM_CONFIG_FRONTEND_X11_DYNAMIC "/FrontEnd/X11/Dynamic" +#define SCIM_CONFIG_FRONTEND_X11_SERVER_NAME "/FrontEnd/X11/ServerName" +#define SCIM_CONFIG_FRONTEND_X11_ONTHESPOT "/FrontEnd/X11/OnTheSpot" + +#define SCIM_KEYBOARD_ICON_FILE (SCIM_ICONDIR "/keyboard.png") + +using namespace scim; + +//Local static data +static Pointer _scim_frontend (0); + +//Module Interface +extern "C" { + void scim_module_init (void) + { + SCIM_DEBUG_FRONTEND(1) << "Initializing X11 FrontEnd module...\n"; + } + + void scim_module_exit (void) + { + SCIM_DEBUG_FRONTEND(1) << "Exiting X11 FrontEnd module...\n"; + _scim_frontend.reset (); + } + + void scim_frontend_module_init (const BackEndPointer &backend, + const ConfigPointer &config, + int argc, + char **argv) + { + if (config.null () || backend.null ()) + throw FrontEndError (String ("X11 FrontEnd couldn't run without Config and BackEnd.\n")); + + if (_scim_frontend.null ()) { + SCIM_DEBUG_FRONTEND(1) << "Initializing X11 FrontEnd module (more)...\n"; + _scim_frontend = new X11FrontEnd (backend, config); + _scim_frontend->init (argc, argv); + } + } + + void scim_frontend_module_run (void) + { + if (!_scim_frontend.null ()) { + SCIM_DEBUG_FRONTEND(1) << "Starting X11 FrontEnd module...\n"; + _scim_frontend->run (); + } + } +} + +X11FrontEnd::X11FrontEnd (const BackEndPointer &backend, + const ConfigPointer &config, + const String& server_name) + : FrontEndBase (backend), + m_xims (0), + m_display (0), + m_xims_window (0), + m_server_name (server_name), + m_focus_ic (0), + m_xims_dynamic (true), + m_wchar_ucs4_equal (scim_if_wchar_ucs4_equal ()), + m_broken_wchar (false), + m_shared_input_method (false), + m_keyboard_layout (SCIM_KEYBOARD_Default), + m_valid_key_mask (SCIM_KEY_AllMasks), + m_should_exit (false), + m_iconv (String ()), + m_config (config), + m_old_x_error_handler (0) +{ + if (!_scim_frontend.null () && _scim_frontend != this) { + throw FrontEndError ( + String ("X11 -- only one frontend can be created!")); + } + + if (!m_server_name.length ()) + m_server_name = String ("SCIM"); + + // Attach Panel Client signal. + m_panel_client.signal_connect_reload_config (slot (this, &X11FrontEnd::panel_slot_reload_config)); + m_panel_client.signal_connect_exit (slot (this, &X11FrontEnd::panel_slot_exit)); + m_panel_client.signal_connect_update_lookup_table_page_size (slot (this, &X11FrontEnd::panel_slot_update_lookup_table_page_size)); + m_panel_client.signal_connect_lookup_table_page_up (slot (this, &X11FrontEnd::panel_slot_lookup_table_page_up)); + m_panel_client.signal_connect_lookup_table_page_down (slot (this, &X11FrontEnd::panel_slot_lookup_table_page_down)); + m_panel_client.signal_connect_trigger_property (slot (this, &X11FrontEnd::panel_slot_trigger_property)); + m_panel_client.signal_connect_process_helper_event (slot (this, &X11FrontEnd::panel_slot_process_helper_event)); + m_panel_client.signal_connect_move_preedit_caret (slot (this, &X11FrontEnd::panel_slot_move_preedit_caret)); + m_panel_client.signal_connect_select_candidate (slot (this, &X11FrontEnd::panel_slot_select_candidate)); + m_panel_client.signal_connect_process_key_event (slot (this, &X11FrontEnd::panel_slot_process_key_event)); + m_panel_client.signal_connect_commit_string (slot (this, &X11FrontEnd::panel_slot_commit_string)); + m_panel_client.signal_connect_forward_key_event (slot (this, &X11FrontEnd::panel_slot_forward_key_event)); + m_panel_client.signal_connect_request_help (slot (this, &X11FrontEnd::panel_slot_request_help)); + m_panel_client.signal_connect_request_factory_menu (slot (this, &X11FrontEnd::panel_slot_request_factory_menu)); + m_panel_client.signal_connect_change_factory (slot (this, &X11FrontEnd::panel_slot_change_factory)); + + m_panel_client.signal_connect_select_aux (slot (this, &X11FrontEnd::panel_slot_select_aux)); + m_panel_client.signal_connect_show_preedit_string (slot (this, &X11FrontEnd::panel_slot_show_preedit_string)); + m_panel_client.signal_connect_hide_preedit_string (slot (this, &X11FrontEnd::panel_slot_hide_preedit_string)); + m_panel_client.signal_connect_update_preedit_string (slot (this, &X11FrontEnd::panel_slot_update_preedit_string)); +} + +X11FrontEnd::~X11FrontEnd () +{ + if (m_xims) { + if (validate_ic (m_focus_ic)) { + m_panel_client.prepare (m_focus_ic->icid); + focus_out (m_focus_ic->siid); + m_panel_client.turn_off (m_focus_ic->icid); + m_panel_client.send (); + ims_sync_ic (m_focus_ic); + } + + XSync(m_display, False); + IMCloseIM (m_xims); + } + + if (m_display && m_xims_window) { + XDestroyWindow (m_display, m_xims_window); + XCloseDisplay (m_display); + } + + m_panel_client.close_connection (); +} + +void +X11FrontEnd::show_preedit_string (int siid) +{ + SCIM_DEBUG_FRONTEND(2) << " Show preedit string, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) { + if (ims_is_preedit_callback_mode (m_focus_ic)) + ims_preedit_callback_start (m_focus_ic); + else + m_panel_client.show_preedit_string (m_focus_ic->icid); + } +} + +void +X11FrontEnd::show_aux_string (int siid) +{ + SCIM_DEBUG_FRONTEND(2) << " Show aux string, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) + m_panel_client.show_aux_string (m_focus_ic->icid); +} + +void +X11FrontEnd::show_lookup_table (int siid) +{ + SCIM_DEBUG_FRONTEND(2) << " Show lookup table, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) + m_panel_client.show_lookup_table (m_focus_ic->icid); +} + +void +X11FrontEnd::hide_preedit_string (int siid) +{ + SCIM_DEBUG_FRONTEND(2) << " Hide preedit string, siid=" << siid << "\n"; + + if (is_focused_ic (siid)) { + if (ims_is_preedit_callback_mode (m_focus_ic)) + ims_preedit_callback_done (m_focus_ic); + else + m_panel_client.hide_preedit_string (m_focus_ic->icid); + } +} + +void +X11FrontEnd::hide_aux_string (int siid) +{ + SCIM_DEBUG_FRONTEND(2) << " Hide aux string, siid=" << siid << "\n"; + + if (is_focused_ic (siid)) + m_panel_client.hide_aux_string (m_focus_ic->icid); +} + +void +X11FrontEnd::hide_lookup_table (int siid) +{ + SCIM_DEBUG_FRONTEND(2) << " Hide lookup table, siid=" << siid << "\n"; + + if (is_focused_ic (siid)) + m_panel_client.hide_lookup_table (m_focus_ic->icid); +} + +void +X11FrontEnd::update_preedit_caret (int siid, int caret) +{ + SCIM_DEBUG_FRONTEND(2) << " Update preedit caret, siid=" << siid << " caret=" << caret << "\n"; + + if (is_inputing_ic (siid)) { + if (ims_is_preedit_callback_mode (m_focus_ic)) + ims_preedit_callback_caret (m_focus_ic, caret); + else + m_panel_client.update_preedit_caret (m_focus_ic->icid, caret); + } +} + +void +X11FrontEnd::update_preedit_string (int siid, const WideString & str, const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(2) << " Update preedit string, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) { + if (ims_is_preedit_callback_mode (m_focus_ic)) + ims_preedit_callback_draw (m_focus_ic, str, attrs); + else + m_panel_client.update_preedit_string (m_focus_ic->icid, str, attrs); + } +} + +void +X11FrontEnd::update_aux_string (int siid, const WideString & str, const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(2) << " Update aux string, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) + m_panel_client.update_aux_string (m_focus_ic->icid, str, attrs); +} + +void +X11FrontEnd::update_lookup_table (int siid, const LookupTable & table) +{ + SCIM_DEBUG_FRONTEND(2) << " Update lookup table, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) + m_panel_client.update_lookup_table (m_focus_ic->icid, table); +} + +void +X11FrontEnd::commit_string (int siid, const WideString & str) +{ + SCIM_DEBUG_FRONTEND(2) << " Commit string, siid=" << siid << "\n"; + + if (is_focused_ic (siid)) + ims_commit_string (m_focus_ic, str); +} + +void +X11FrontEnd::forward_key_event (int siid, const KeyEvent & key) +{ + SCIM_DEBUG_FRONTEND(2) << " Forward keyevent, siid=" << siid << "\n"; + + if (is_focused_ic (siid)) + ims_forward_key_event (m_focus_ic, key); +} + +void +X11FrontEnd::register_properties (int siid, const PropertyList &properties) +{ + SCIM_DEBUG_FRONTEND(2) << " Register properties, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) + m_panel_client.register_properties (m_focus_ic->icid, properties); +} + +void +X11FrontEnd::update_property (int siid, const Property &property) +{ + SCIM_DEBUG_FRONTEND(2) << " Update property, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) + m_panel_client.update_property (m_focus_ic->icid, property); +} + +void +X11FrontEnd::beep (int siid) +{ + SCIM_DEBUG_FRONTEND(2) << " Beep, siid=" << siid << "\n"; + + if (is_inputing_ic (siid)) + XBell (m_display, 0); +} + +void +X11FrontEnd::start_helper (int siid, const String &helper_uuid) +{ + SCIM_DEBUG_FRONTEND(2) << " Start helper, siid=" << siid << " Helper=" << helper_uuid << "\n"; + + X11IC *ic = m_ic_manager.find_ic_by_siid (siid); + + if (validate_ic (ic)) + m_panel_client.start_helper (ic->icid, helper_uuid); +} + +void +X11FrontEnd::stop_helper (int siid, const String &helper_uuid) +{ + SCIM_DEBUG_FRONTEND(2) << " Stop helper, siid=" << siid << " Helper=" << helper_uuid << "\n"; + + X11IC *ic = m_ic_manager.find_ic_by_siid (siid); + + if (validate_ic (ic)) + m_panel_client.stop_helper (ic->icid, helper_uuid); +} + +void +X11FrontEnd::send_helper_event (int siid, const String &helper_uuid, const Transaction &trans) +{ + SCIM_DEBUG_FRONTEND(2) << " Send helper event, siid=" << siid << " Helper=" << helper_uuid << "\n"; + + X11IC *ic = m_ic_manager.find_ic_by_siid (siid); + + if (validate_ic (ic)) + m_panel_client.send_helper_event (ic->icid, helper_uuid, trans); +} + +bool +X11FrontEnd::get_surrounding_text (int siid, WideString &text, int &cursor, int maxlen_before, int maxlen_after) +{ + SCIM_DEBUG_FRONTEND(2) << " Get surrounding text, siid=" << siid << "\n"; + + text.clear (); + cursor = 0; + + if (is_inputing_ic (siid)) { +// return ims_string_conversion_callback_retrieval (m_focus_ic, text, cursor, maxlen_before, maxlen_after); + return false; + } + + return false; +} + +bool +X11FrontEnd::delete_surrounding_text (int siid, int offset, int len) +{ + SCIM_DEBUG_FRONTEND(2) << " Delete surrounding text, siid=" << siid << " offset = " << offset << " len = " << len << "\n"; + + if (is_inputing_ic (siid)) { +// return ims_string_conversion_callback_substitution (m_focus_ic, offset, len); + return false; + } + + return false; +} + +void +X11FrontEnd::init (int argc, char **argv) +{ + String str; + + SCIM_DEBUG_FRONTEND (1) << "X11 -- Loading configuration.\n"; + + //Read settings. + reload_config_callback (m_config); + + m_server_name = + m_config->read (String (SCIM_CONFIG_FRONTEND_X11_SERVER_NAME), + m_server_name); + + m_xims_dynamic = + m_config->read (String (SCIM_CONFIG_FRONTEND_X11_DYNAMIC), + true); + + m_config->signal_connect_reload (slot (this, &X11FrontEnd::reload_config_callback)); + + m_display_name = init_ims (); + + SCIM_DEBUG_FRONTEND (1) << "X11 -- Connecting to panel daemon.\n"; + + if (m_panel_client.open_connection (m_config->get_name (), m_display_name) < 0) + throw FrontEndError (String ("X11 -- failed to connect to the panel daemon!")); + + // Only use ComposeKeyFactory when it's enabled. + if (validate_factory (SCIM_COMPOSE_KEY_FACTORY_UUID, "UTF-8")) + m_fallback_factory = new ComposeKeyFactory (); + else + m_fallback_factory = new DummyIMEngineFactory (); + + m_fallback_instance = m_fallback_factory->create_instance (String ("UTF-8"), 0); + m_fallback_instance->signal_connect_commit_string (slot (this, &X11FrontEnd::fallback_commit_string_cb)); +} + +void +X11FrontEnd::run () +{ + if (!m_display || !m_xims_window || !m_xims || m_panel_client.get_connection_number () < 0) { + SCIM_DEBUG_FRONTEND(1) << "X11 -- Cannot run without initialization!\n"; + return; + } + + XEvent event; + + fd_set read_fds, active_fds; + + int panel_fd = m_panel_client.get_connection_number (); + int xserver_fd = ConnectionNumber (m_display); + int max_fd = (panel_fd > xserver_fd) ? panel_fd : xserver_fd; + + FD_ZERO (&active_fds); + FD_SET (panel_fd, &active_fds); + FD_SET (xserver_fd, &active_fds); + + m_should_exit = false; + + // Select between the X Server and the Panel GUI. + while (!m_should_exit) { + int ret; + + read_fds = active_fds; + + // Process the events which are already send to me from the X Server + // before calling select. + while (XPending (m_display)) { + XNextEvent (m_display, &event); + XFilterEvent (&event, None); + } + + if ((ret = select (max_fd + 1, &read_fds, NULL, NULL, NULL)) < 0) { + SCIM_DEBUG_FRONTEND(1) << "X11 -- Error when watching events!\n"; + return; + } + + if (m_should_exit) break; + + if (FD_ISSET (panel_fd, &read_fds)) { + if (!m_panel_client.filter_event ()) { + SCIM_DEBUG_FRONTEND(1) << "X11 -- Lost connection with panel daemon, re-establish it!\n"; + + m_panel_client.close_connection (); + + max_fd = xserver_fd; + FD_ZERO (&active_fds); + FD_SET (xserver_fd, &active_fds); + + if (m_panel_client.open_connection (m_config->get_name (), m_display_name) >= 0) { + panel_fd = m_panel_client.get_connection_number (); + FD_SET (panel_fd, &active_fds); + max_fd = (panel_fd > xserver_fd) ? panel_fd : xserver_fd; + } else { + panel_fd = -1; + SCIM_DEBUG_FRONTEND(1) << "X11 -- Lost connection with panel daemon, can't re-establish it!\n"; + } + } + } + // X Events will be processed at beginning of the loop. + } +} + +String +X11FrontEnd::get_supported_locales (void) +{ + std::vector all_locales; + std::vector supported_locales; + + scim_split_string_list (all_locales, get_all_locales (), ','); + + String last = String (setlocale (LC_CTYPE, 0)); + + for (size_t i = 0; i < all_locales.size (); ++i) { + if (setlocale (LC_CTYPE, all_locales [i].c_str ()) && XSupportsLocale ()) + supported_locales.push_back (all_locales [i]); + } + + setlocale (LC_CTYPE, last.c_str ()); + + return scim_combine_string_list (supported_locales, ','); +} + +int +X11FrontEnd::get_default_instance (const String &language, const String &encoding) +{ + DefaultInstanceMap::iterator it = m_default_instance_map.find (encoding); + String sfid = get_default_factory (language, encoding); + + if (it == m_default_instance_map.end ()) { + int siid = new_instance (m_config, sfid, encoding); + + m_default_instance_map [encoding] = siid; + + return siid; + } else if (get_instance_uuid (it->second) != sfid) { + replace_instance (it->second, sfid); + } + return it->second; +} + +String +X11FrontEnd::init_ims (void) +{ + XIMStyle ims_styles_overspot [] = { + XIMPreeditPosition | XIMStatusNothing, + XIMPreeditNothing | XIMStatusNothing, + XIMPreeditPosition | XIMStatusCallbacks, + XIMPreeditNothing | XIMStatusCallbacks, + 0 + }; + + XIMStyle ims_styles_onspot [] = { + XIMPreeditPosition | XIMStatusNothing, + XIMPreeditCallbacks | XIMStatusNothing, + XIMPreeditNothing | XIMStatusNothing, + XIMPreeditPosition | XIMStatusCallbacks, + XIMPreeditCallbacks | XIMStatusCallbacks, + XIMPreeditNothing | XIMStatusCallbacks, + 0 + }; + + XIMEncoding ims_encodings[] = { + "COMPOUND_TEXT", + 0 + }; + + XIMStyles styles; + XIMEncodings encodings; + + String locales; + + locales = get_supported_locales (); + + SCIM_DEBUG_FRONTEND(1) << "Initializing XIMS: " + << m_server_name << " with locale (" << locales.length () << "): " << locales << " ...\n"; + + // Initialize X Display and Root Windows. + if (m_xims != (XIMS) 0) { + throw FrontEndError (String ("X11 -- XIMS already initialized!")); + } + + m_display = XOpenDisplay (NULL); + + if (!m_display) + throw FrontEndError (String ("X11 -- Cannot open Display!")); + + m_xims_window = XCreateSimpleWindow (m_display, + DefaultRootWindow (m_display), + -1, -1, 1, 1, 0, 0, 0); + + if (!m_xims_window) + throw FrontEndError (String ("X11 -- Cannot create IMS Window!")); + + XSetWindowAttributes attrs; + unsigned long attrmask; + + attrs.override_redirect = true; + attrmask = CWOverrideRedirect; + + XChangeWindowAttributes (m_display, m_xims_window, attrmask, &attrs); + XSelectInput (m_display, m_xims_window, KeyPressMask | KeyReleaseMask); + + m_old_x_error_handler = XSetErrorHandler (x_error_handler); + + // Initialize XIMS. + if (m_config->read (String (SCIM_CONFIG_FRONTEND_ON_THE_SPOT), true) && + m_config->read (String (SCIM_CONFIG_FRONTEND_X11_ONTHESPOT), true)) { + styles.count_styles = sizeof (ims_styles_onspot)/sizeof (XIMStyle) - 1; + styles.supported_styles = ims_styles_onspot; + } else { + styles.count_styles = sizeof (ims_styles_overspot)/sizeof (XIMStyle) - 1; + styles.supported_styles = ims_styles_overspot; + } + + encodings.count_encodings = sizeof (ims_encodings)/sizeof (XIMEncoding) - 1; + encodings.supported_encodings = ims_encodings; + + m_xims = IMOpenIM(m_display, + IMModifiers, "Xi18n", + IMServerWindow, m_xims_window, + IMServerName, m_server_name.c_str (), + IMLocale, locales.c_str (), + IMServerTransport, "X/", + IMInputStyles, &styles, + IMEncodingList, &encodings, + IMProtocolHandler, ims_protocol_handler, + IMFilterEventMask, KeyPressMask | KeyReleaseMask, + NULL); + + if (m_xims == (XIMS)NULL) + throw FrontEndError (String ("X11 -- failed to initialize XIM Server!")); + + if (m_xims_dynamic) { + XIMTriggerKey xim_on_key_list[10]; + XIMTriggerKey xim_off_key_list[10]; + + XIMTriggerKeys xim_on_keys; + XIMTriggerKeys xim_off_keys; + + uint32 count_trigger_keys, count_on_keys, count_off_keys; + + KeyEventList keys; + + m_frontend_hotkey_matcher.find_hotkeys (SCIM_FRONTEND_HOTKEY_TRIGGER, keys); + + for (count_trigger_keys=0; count_trigger_keys < 10 && count_trigger_keys < keys.size (); ++count_trigger_keys) { + XKeyEvent xkey = scim_x11_keyevent_scim_to_x11 (m_display, keys [count_trigger_keys]); + xim_on_key_list [count_trigger_keys].keysym = keys [count_trigger_keys].code; + xim_on_key_list [count_trigger_keys].modifier = xkey.state; + xim_on_key_list [count_trigger_keys].modifier_mask = xkey.state; + } + + m_frontend_hotkey_matcher.find_hotkeys (SCIM_FRONTEND_HOTKEY_ON, keys); + + for (count_on_keys=count_trigger_keys; count_on_keys < 10 && (count_on_keys - count_trigger_keys) < keys.size (); ++count_on_keys) { + XKeyEvent xkey = scim_x11_keyevent_scim_to_x11 (m_display, keys [count_on_keys - count_trigger_keys]); + xim_on_key_list [count_on_keys].keysym = keys [count_on_keys - count_trigger_keys].code; + xim_on_key_list [count_on_keys].modifier = xkey.state; + xim_on_key_list [count_on_keys].modifier_mask = xkey.state; + } + + m_frontend_hotkey_matcher.find_hotkeys (SCIM_FRONTEND_HOTKEY_OFF, keys); + + for (count_off_keys=0; count_off_keys < 10 && count_off_keys < keys.size (); ++count_off_keys) { + XKeyEvent xkey = scim_x11_keyevent_scim_to_x11 (m_display, keys [count_off_keys]); + xim_off_key_list [count_off_keys].keysym = keys [count_off_keys].code; + xim_off_key_list [count_off_keys].modifier = xkey.state; + xim_off_key_list [count_off_keys].modifier_mask = xkey.state; + } + + xim_on_keys.count_keys = count_on_keys; + xim_on_keys.keylist = xim_on_key_list; + + xim_off_keys.count_keys = count_off_keys; + xim_off_keys.keylist = xim_off_key_list; + + IMSetIMValues(m_xims, IMOnKeysList, &xim_on_keys, IMOffKeysList, &xim_off_keys, NULL); + } + + return String (DisplayString (m_display)); +} + +bool +X11FrontEnd::filter_hotkeys (X11IC *ic, const KeyEvent &scimkey) +{ + bool ok = false; + + if (!is_focused_ic (ic)) return false; + + m_frontend_hotkey_matcher.push_key_event (scimkey); + m_imengine_hotkey_matcher.push_key_event (scimkey); + + FrontEndHotkeyAction hotkey_action = m_frontend_hotkey_matcher.get_match_result (); + + // Match trigger and show factory menu hotkeys. + if (hotkey_action == SCIM_FRONTEND_HOTKEY_TRIGGER) { + if (!ic->xims_on) + ims_turn_on_ic (ic); + else + ims_turn_off_ic (ic); + ok = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON) { + if (!ic->xims_on) ims_turn_on_ic (ic); + ok = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF) { + if (ic->xims_on) ims_turn_off_ic (ic); + ok = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_NEXT_FACTORY) { + String encoding = scim_get_locale_encoding (ic->locale); + String language = scim_get_locale_language (ic->locale); + String sfid = get_next_factory ("", encoding, get_instance_uuid (ic->siid)); + if (validate_factory (sfid, encoding)) { + ims_turn_off_ic (ic); + replace_instance (ic->siid, sfid); + m_panel_client.register_input_context (ic->icid, get_instance_uuid (ic->siid)); + set_ic_capabilities (ic); + set_default_factory (language, sfid); + ims_turn_on_ic (ic); + } + ok = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY) { + String encoding = scim_get_locale_encoding (ic->locale); + String language = scim_get_locale_language (ic->locale); + String sfid = get_previous_factory ("", encoding, get_instance_uuid (ic->siid)); + if (validate_factory (sfid, encoding)) { + ims_turn_off_ic (ic); + replace_instance (ic->siid, sfid); + m_panel_client.register_input_context (ic->icid, get_instance_uuid (ic->siid)); + set_ic_capabilities (ic); + set_default_factory (language, sfid); + ims_turn_on_ic (ic); + } + ok = true; + } else if (hotkey_action == SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) { + panel_req_show_factory_menu (ic); + ok = true; + } else if (m_imengine_hotkey_matcher.is_matched ()) { + String encoding = scim_get_locale_encoding (ic->locale); + String language = scim_get_locale_language (ic->locale); + ISEInfo info = m_imengine_hotkey_matcher.get_match_result (); + String sfid = info.uuid; + if (info.type == IMENGINE_T) { + if (validate_factory (sfid, encoding)) { + ims_turn_off_ic (ic); + replace_instance (ic->siid, sfid); + m_panel_client.register_input_context (ic->icid, get_instance_uuid (ic->siid)); + set_ic_capabilities (ic); + set_default_factory (language, sfid); + ims_turn_on_ic (ic); + } + } + ok = true; + } + return ok; +} + +int +X11FrontEnd::ims_open_handler (XIMS ims, IMOpenStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Open handler: LANG=" << call_data->lang.name + << " Connect ID=" << call_data->connect_id << "\n"; + + m_ic_manager.new_connection (call_data); + return 1; +} + +int +X11FrontEnd::ims_close_handler (XIMS ims, IMCloseStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Close handler: Connect ID=" + << call_data->connect_id << "\n"; + + m_ic_manager.delete_connection (call_data); + return 1; +} + +int +X11FrontEnd::ims_create_ic_handler (XIMS ims, IMChangeICStruct *call_data) +{ + String locale = m_ic_manager.get_connection_locale (call_data->connect_id); + String language = scim_get_locale_language (locale); + String encoding = scim_get_locale_encoding (locale); + + SCIM_DEBUG_FRONTEND(2) << " IMS Create handler: Encoding=" << encoding << "\n"; + + if (language.empty () || encoding.empty ()) + return 0; + + int siid = -1; + + if (m_shared_input_method) { + siid = get_default_instance (language, encoding); + } else { + String sfid = get_default_factory (language, encoding); + siid = new_instance (m_config, sfid, encoding); + } + + if (siid >= 0) { + uint32 attrs = m_ic_manager.create_ic (call_data, siid); + + X11IC *ic = m_ic_manager.find_ic (call_data->icid); + + SCIM_DEBUG_FRONTEND(2) << " IMS Create handler OK: SIID=" + << siid << " ICID = " << ic->icid << " Connect ID=" << call_data->connect_id << "\n"; + + m_panel_client.prepare (ic->icid); + + m_panel_client.register_input_context (ic->icid, get_instance_uuid (siid)); + + if (attrs & SCIM_X11_IC_INPUT_STYLE) + set_ic_capabilities (ic); + + m_panel_client.send (); + + if (m_shared_input_method) { + ic->xims_on = m_config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), ic->xims_on); + ic->shared_siid = true; + } + + return 1; + } else { + SCIM_DEBUG_FRONTEND(2) << " IMS Create handler Failed: " + << " Connect ID=" << call_data->connect_id << "\n"; + } + return 0; +} + +int +X11FrontEnd::ims_set_ic_values_handler (XIMS ims, IMChangeICStruct *call_data) +{ + uint32 changes; + + X11IC *ic = m_ic_manager.find_ic (call_data->icid); + + if (!validate_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "Cannot find IC for icid " << call_data->icid << "\n"; + return 0; + } + + changes = m_ic_manager.set_ic_values (call_data); + + if (changes & SCIM_X11_IC_ENCODING) { + SCIM_DEBUG_FRONTEND(1) << "Cannot change IC encoding on the fly!\n"; + return 0; + } + + SCIM_DEBUG_FRONTEND(2) << " IMS Set IC values handler, ICID=" + << call_data->icid << " Connect ID=" + << call_data->connect_id << " Changes=" + << changes << "\n"; + + m_panel_client.prepare (ic->icid); + + //It's focus IC + if (is_focused_ic (ic)) { + if (changes & SCIM_X11_IC_PRE_SPOT_LOCATION) + panel_req_update_spot_location (ic); + } + + // Update the client capabilities, if the input style was changed. + if (changes & SCIM_X11_IC_INPUT_STYLE) + set_ic_capabilities (ic); + + m_panel_client.send (); + + return 1; +} + +int +X11FrontEnd::ims_get_ic_values_handler (XIMS ims, IMChangeICStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Get IC values handler, ICID=" + << call_data->icid << " Connect ID=" + << call_data->connect_id << "\n"; + + m_ic_manager.get_ic_values (call_data); + return 1; +} + +int +X11FrontEnd::ims_destroy_ic_handler (XIMS ims, IMDestroyICStruct *call_data) +{ + X11IC *ic = m_ic_manager.find_ic (call_data->icid); + + SCIM_DEBUG_FRONTEND(2) << " IMS Destroy IC handler, ICID=" + << call_data->icid << " Connect ID=" + << call_data->connect_id << "\n"; + + if (!validate_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "Cannot find IC for icid " << call_data->icid << "\n"; + return 0; + } + + m_panel_client.prepare (ic->icid); + + if (is_focused_ic (ic)) { + focus_out (ic->siid); + m_panel_client.turn_off (ic->icid); + m_panel_client.focus_out (ic->icid); + } + + X11IC *old_focus = m_focus_ic; + + m_focus_ic = ic; + + if (!ic->shared_siid) delete_instance (ic->siid); + + m_panel_client.remove_input_context (ic->icid); + m_panel_client.send (); + + if (is_focused_ic (ic)) + m_focus_ic = 0; + else + m_focus_ic = old_focus; + + m_ic_manager.destroy_ic (call_data); + return 1; +} + +int +X11FrontEnd::ims_set_ic_focus_handler (XIMS ims, IMChangeFocusStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Set IC focus handler, ID=" + << call_data->icid << " Connect ID=" + << call_data->connect_id << "\n"; + + X11IC *ic =m_ic_manager.find_ic (call_data->icid); + + if (!validate_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "Cannot find IC for icid " << call_data->icid << "\n"; + return 0; + } + + if (validate_ic (m_focus_ic) && m_focus_ic->icid != ic->icid) { + m_panel_client.prepare (m_focus_ic->icid); + stop_ic (m_focus_ic); + m_panel_client.focus_out (m_focus_ic->icid); + m_panel_client.send (); + } + + String encoding = scim_get_locale_encoding (ic->locale); + String language = scim_get_locale_language (ic->locale); + bool need_reg = false; + bool need_cap = false; + bool need_reset = false; + + m_focus_ic = ic; + + m_panel_client.prepare (ic->icid); + + if (m_shared_input_method) { + SCIM_DEBUG_FRONTEND(3) << "Shared input method.\n"; + + if (!ic->shared_siid) { + delete_instance (ic->siid); + ic->shared_siid = true; + } + + ic->siid = get_default_instance (language, encoding); + ic->onspot_preedit_started = false; + ic->onspot_preedit_length = 0; + ic->onspot_caret = 0; + + ic->xims_on = m_config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), ic->xims_on); + + need_reg = true; + need_cap = true; + need_reset = true; + } else if (ic->shared_siid) { + String sfid = get_default_factory (language, encoding); + ic->siid = new_instance (m_config, sfid, encoding); + ic->onspot_preedit_started = false; + ic->onspot_preedit_length = 0; + ic->onspot_caret = 0; + ic->shared_siid = false; + need_reg = true; + need_cap = true; + } + + panel_req_focus_in (ic); + + if (need_reset) reset (ic->siid); + if (need_cap) set_ic_capabilities (ic); + if (need_reg) m_panel_client.register_input_context (ic->icid, get_instance_uuid (ic->siid)); + + if (ic->xims_on) { + start_ic (ic); + } else { + m_panel_client.turn_off (ic->icid); + } + + m_panel_client.send (); + + return 1; +} + +int +X11FrontEnd::ims_unset_ic_focus_handler (XIMS ims, IMChangeFocusStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Unset IC focus handler, ID=" + << call_data->icid << " Connect ID=" + << call_data->connect_id << "\n"; + + X11IC *ic =m_ic_manager.find_ic (call_data->icid); + + if (!validate_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "Cannot find IC for icid " << call_data->icid << "\n"; + return 0; + } + + if (is_focused_ic (ic)) { + m_panel_client.prepare (ic->icid); + stop_ic (ic); + m_panel_client.focus_out (ic->icid); + m_panel_client.send (); + m_focus_ic = 0; + } + + return 1; +} + +int +X11FrontEnd::ims_reset_ic_handler (XIMS ims, IMResetICStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Reset IC handler, ID=" + << call_data->icid << " Connect ID=" + << call_data->connect_id << "\n"; + + X11IC *ic =m_ic_manager.find_ic (call_data->icid); + + if (!validate_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "Cannot find IC for icid " << call_data->icid << "\n"; + return 0; + } + + m_panel_client.prepare (ic->icid); + reset (ic->siid); + m_panel_client.send (); + + return 1; +} + +int +X11FrontEnd::ims_trigger_notify_handler (XIMS ims, IMTriggerNotifyStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Trigger notify handler, Flag=" + << call_data->flag << " KeyIndex=" + << call_data->key_index << " EventMask=" + << call_data->event_mask << "\n"; + + X11IC *ic =m_ic_manager.find_ic (call_data->icid); + + if (!validate_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "Cannot find IC for icid " << call_data->icid << "\n"; + return 0; + } + + int ret = 0; + + m_panel_client.prepare (ic->icid); + + if (!call_data->flag) { + ims_turn_on_ic (ic); + ret = 1; + } else { + ims_turn_off_ic (ic); + ret = 1; + } + + m_panel_client.send (); + + return ret; +} + +int +X11FrontEnd::ims_forward_event_handler (XIMS ims, IMForwardEventStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Forward event handler, ICID=" + << call_data->icid << " Connect ID=" + << call_data->connect_id << " SerialNo=" + << call_data->serial_number << "EventType=" + << call_data->event.type << "\n"; + + if (call_data->event.type != KeyPress && call_data->event.type != KeyRelease) + return 1; + + X11IC *ic = m_ic_manager.find_ic (call_data->icid); + + if (!validate_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "Cannot find IC for icid " << call_data->icid << "\n"; + return 0; + } + + // If the ic is not focused, then return. + if (!is_focused_ic (ic)) { + SCIM_DEBUG_FRONTEND(1) << "IC " << call_data->icid << " is not focused, focus it first.\n"; + ims_set_ic_focus_handler (ims, (IMChangeFocusStruct *) call_data); + } + + XKeyEvent *event = (XKeyEvent*) &(call_data->event); + KeyEvent scimkey = scim_x11_keyevent_x11_to_scim (m_display, *event); + + scimkey.mask &= m_valid_key_mask; + + // Set keyboard layout information. + scimkey.layout = m_keyboard_layout; + + SCIM_DEBUG_FRONTEND(3) << " KeyEvent:\n" + << " Type=" << event->type << " Display=" << event->display << " Serial=" << event->serial << " Send=" << event->send_event << "\n" + << " X=" << event->x << " Y=" << event->y << " XRoot=" << event->x_root << " YRoot=" << event->y_root << "\n" + << " Time=" << event->time << " SameScreen=" << event->same_screen << " SubWin=" << event->subwindow << " Win=" << event->window << "\n" + << " Root=" << event->root << " KeyCode=" << event->keycode << " State=" << event->state << "\n" + << " scimKeyEvent=(" << scimkey.code << "," << scimkey.mask << ")\n"; + + m_panel_client.prepare (ic->icid); + + if (!filter_hotkeys (ic, scimkey)) { + if (!ic->xims_on || !process_key_event (ic->siid, scimkey)) { + if (!m_fallback_instance->process_key_event (scimkey)) + IMForwardEvent (ims, (XPointer) call_data); + } + } + + m_panel_client.send (); + + return 1; +} + +int +X11FrontEnd::ims_sync_reply_handler (XIMS ims, IMSyncXlibStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Sync reply handler.\n"; + return 1; +} + +int +X11FrontEnd::ims_preedit_start_reply_handler (XIMS ims, IMPreeditCBStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Preedit start reply handler.\n"; + return 1; +} + +int +X11FrontEnd::ims_preedit_caret_reply_handler (XIMS ims, IMPreeditCBStruct *call_data) +{ + SCIM_DEBUG_FRONTEND(2) << " IMS Preedit caret reply handler.\n"; + return 1; +} + +void +X11FrontEnd::ims_commit_string (const X11IC *ic, const WideString& str) +{ + IMCommitStruct cms; + XTextProperty tp; + + SCIM_DEBUG_FRONTEND(2) << " IMS Committing string.\n"; + + if (ims_wcstocts (tp, ic, str)) { + memset (&cms, 0, sizeof (cms)); + cms.major_code = XIM_COMMIT; + cms.icid = ic->icid; + cms.connect_id = ic->connect_id; + cms.flag = XimLookupChars; + cms.commit_string = (char *) tp.value; + IMCommitString (m_xims, (XPointer) & cms); + XFree (tp.value); + } +} + +void +X11FrontEnd::ims_forward_key_event (const X11IC *ic, const KeyEvent &key) +{ + IMForwardEventStruct fe; + XEvent xkp; + + //create event + xkp.xkey = scim_x11_keyevent_scim_to_x11 (m_display, key); + + memset (&fe, 0, sizeof (fe)); + fe.major_code = XIM_FORWARD_EVENT; + fe.icid = ic->icid; + fe.connect_id = ic->connect_id; + fe.sync_bit = 0; + fe.serial_number = 0L; + + if (ic->focus_win) + xkp.xkey.window = ic->focus_win; + else if (ic->client_win) + xkp.xkey.window = ic->client_win; + + memcpy (&(fe.event), &xkp, sizeof (fe.event)); + IMForwardEvent (m_xims, (XPointer) & fe); +} + +bool +X11FrontEnd::ims_wcstocts (XTextProperty &tp,const X11IC *ic, const WideString& src) +{ + if (!validate_ic (ic)) return false; + + String last = String (setlocale (LC_CTYPE, 0)); + + if (!setlocale (LC_CTYPE, ic->locale.c_str ())) { + SCIM_DEBUG_FRONTEND(3) << " wcstocts -- unspported locale " << ic->locale.c_str () << "\n"; + + setlocale (LC_CTYPE, last.c_str ()); + return false; + } + + int ret; + + if (m_wchar_ucs4_equal && !m_broken_wchar) { + wchar_t *wclist [1]; + + SCIM_DEBUG_FRONTEND(3) << " Convert WideString to COMPOUND_TEXT -- Using XwcTextListToTextProperty.\n"; + + wclist [0] = new wchar_t [src.length () + 1]; + memcpy (wclist [0], src.data (), sizeof (wchar_t) * src.length ()); + wclist [0][src.length ()] = 0; + ret = XwcTextListToTextProperty (m_display, wclist, 1, XCompoundTextStyle, &tp); + delete [] wclist [0]; + } else { + char *clist [1]; + String mbs; + + SCIM_DEBUG_FRONTEND(3) << " Convert WideString to COMPOUND_TEXT -- Using XmbTextListToTextProperty.\n"; + + if (!m_iconv.set_encoding (ic->encoding)) { + SCIM_DEBUG_FRONTEND(3) << " Convert WideString to COMPOUND_TEXT -- Cannot initialize iconv for encoding " + << ic->encoding << "\n"; + + setlocale (LC_CTYPE, last.c_str ()); + return false; + } + + m_iconv.convert (mbs, src); + clist [0] = (char *) mbs.c_str (); + ret = XmbTextListToTextProperty (m_display, clist, 1, XCompoundTextStyle, &tp); + } + + setlocale (LC_CTYPE, last.c_str ()); + return ret >= 0; +} + +bool +X11FrontEnd::ims_is_preedit_callback_mode (const X11IC *ic) +{ + return validate_ic (ic) && (ic->input_style & XIMPreeditCallbacks); +} + +void +X11FrontEnd::ims_preedit_callback_start (X11IC *ic) +{ + if (!validate_ic (ic) || ic->onspot_preedit_started) return; + + ic->onspot_preedit_started = true; + + SCIM_DEBUG_FRONTEND(2) << " Onspot preedit start, ICID=" + << ic->icid << " Connect ID=" << ic->connect_id << "\n"; + + IMPreeditCBStruct pcb; + + pcb.major_code = XIM_PREEDIT_START; + pcb.minor_code = 0; + pcb.connect_id = ic->connect_id; + pcb.icid = ic->icid; + pcb.todo.return_value = 0; + IMCallCallback (m_xims, (XPointer) & pcb); +} + +void +X11FrontEnd::ims_preedit_callback_done (X11IC *ic) +{ + if (!validate_ic (ic) || !ic->onspot_preedit_started) return; + + SCIM_DEBUG_FRONTEND(2) << " Onspot preedit done, ICID=" + << ic->icid << " Connect ID=" << ic->connect_id << "\n"; + + // First clear the preedit string. + ims_preedit_callback_draw (ic, WideString ()); + + ic->onspot_preedit_started = false; + + IMPreeditCBStruct pcb; + + pcb.major_code = XIM_PREEDIT_DONE; + pcb.minor_code = 0; + pcb.connect_id = ic->connect_id; + pcb.icid = ic->icid; + pcb.todo.return_value = 0; + IMCallCallback (m_xims, (XPointer) & pcb); +} + +void +X11FrontEnd::ims_preedit_callback_draw (X11IC *ic, const WideString& str, const AttributeList & attrs) +{ + if (!validate_ic (ic)) return; + + if (!ic->onspot_preedit_started) + ims_preedit_callback_start (ic); + + SCIM_DEBUG_FRONTEND(2) << " Onspot preedit draw, ICID=" + << ic->icid << " Connect ID=" << ic->connect_id << "\n"; + + IMPreeditCBStruct pcb; + XIMText text; + XIMFeedback *feedback; + XIMFeedback attr; + XTextProperty tp; + + unsigned int i, j, len; + + len = str.length (); + if (!len && !ic->onspot_preedit_length) + return; + + feedback = new XIMFeedback [str.length () + 1]; + + for (i = 0; i < len; ++i) + feedback [i] = 0; + + for (i = 0; i < attrs.size (); ++i) { + attr = 0; + if (attrs [i].get_type () == SCIM_ATTR_DECORATE) { + if (attrs [i].get_value () == SCIM_ATTR_DECORATE_REVERSE) + attr = XIMReverse; + else if (attrs [i].get_value () == SCIM_ATTR_DECORATE_HIGHLIGHT) + attr = XIMHighlight; + } + for (j = attrs [i].get_start (); j < attrs [i].get_end () && j < len; ++j) + feedback [j] |= attr; + } + + for (i = 0; i < len; ++i) + if (!feedback [i]) + feedback [i] = XIMUnderline; + + feedback [len] = 0; + + pcb.major_code = XIM_PREEDIT_DRAW; + pcb.connect_id = ic->connect_id; + pcb.icid = ic->icid; + + pcb.todo.draw.caret = len; + pcb.todo.draw.chg_first = 0; + pcb.todo.draw.chg_length = ic->onspot_preedit_length; + pcb.todo.draw.text = &text; + + text.feedback = feedback; + + if (len > 0 && ims_wcstocts (tp, ic, str)) { + text.encoding_is_wchar = false; + text.length = strlen ((char*)tp.value); + text.string.multi_byte = (char*)tp.value; + IMCallCallback (m_xims, (XPointer) & pcb); + XFree (tp.value); + } else { + text.encoding_is_wchar = false; + text.length = 0; + text.string.multi_byte = ""; + IMCallCallback (m_xims, (XPointer) & pcb); + len = 0; + } + + ic->onspot_preedit_length = len; + + delete [] feedback; +} + +void +X11FrontEnd::ims_preedit_callback_caret (X11IC *ic, int caret) +{ + if (!validate_ic (ic) || !ic->onspot_preedit_started || caret > ic->onspot_preedit_length || caret < 0) + return; + + SCIM_DEBUG_FRONTEND(2) << " Onspot preedit caret, ICID=" + << ic->icid << " Connect ID=" << ic->connect_id << "\n"; + + //save the caret position for future usage when updating preedit string. + ic->onspot_caret = caret; + + //client usually does not support this callback + IMPreeditCBStruct pcb; + + pcb.major_code = XIM_PREEDIT_CARET; + pcb.connect_id = ic->connect_id; + pcb.icid = ic->icid; + pcb.todo.caret.direction = XIMAbsolutePosition; + pcb.todo.caret.position = caret; + pcb.todo.caret.style = XIMIsPrimary; + IMCallCallback (m_xims, (XPointer) & pcb); +} + +bool +X11FrontEnd::ims_string_conversion_callback_retrieval (X11IC *ic, WideString &text, int &cursor, int maxlen_before, int maxlen_after) +{ +#if 0 + if (!validate_ic (ic) || (maxlen_before == 0 && maxlen_after == 0)) + return false; + + SCIM_DEBUG_FRONTEND(2) << " String conversion callback retrieval, ICID=" + << ic->icid << " Connect ID=" << ic->connect_id << "\n"; + + //client usually does not support this callback + IMStrConvCBStruct sccb; + + sccb.major_code = XIM_STR_CONVERSION; + sccb.connect_id = ic->connect_id; + sccb.icid = ic->icid; + sccb.strconv.text = 0; + + sccb.strconv.operation = XIMStringConversionRetrieval; + sccb.strconv.position = 0; + + sccb.strconv.direction = XIMBackwardChar; + sccb.strconv.factor = (short)((maxlen_before > 0) ? maxlen_before : 1); + + IMCallCallback (m_xims, (XPointer) & sccb); + + std::cerr << "Surrounding text: "; + + if (sccb.strconv.text && sccb.strconv.text->string.mbs) { + std::cerr << sccb.strconv.text->string.mbs << " "; + } + + sccb.strconv.direction = XIMForwardChar; + sccb.strconv.factor = (maxlen_after > 0) ? maxlen_after : 1; + + IMCallCallback (m_xims, (XPointer) & sccb); + + if (sccb.strconv.text && sccb.strconv.text->string.mbs) { + std::cerr << sccb.strconv.text->string.mbs; + } + + std::cerr << "\n"; +#endif + return false; +} + +bool +X11FrontEnd::ims_string_conversion_callback_substitution (X11IC *ic, int offset, int len) +{ +#if 0 + if (!validate_ic (ic) || len <= 0) + return false; + + SCIM_DEBUG_FRONTEND(2) << " String conversion callback substitution, ICID=" + << ic->icid << " Connect ID=" << ic->connect_id << "\n"; + + //client usually does not support this callback + IMStrConvCBStruct sccb; + + sccb.major_code = XIM_STR_CONVERSION; + sccb.connect_id = ic->connect_id; + sccb.icid = ic->icid; + sccb.strconv.text = 0; + sccb.strconv.operation = XIMStringConversionSubstitution; + sccb.strconv.position = (XIMStringConversionPosition) offset; + sccb.strconv.direction = XIMForwardChar; + sccb.strconv.factor = (short) len; + + IMCallCallback (m_xims, (XPointer) & sccb); + + return sccb.strconv.text != NULL; +#endif + return false; +} + +void +X11FrontEnd::ims_turn_on_ic (X11IC *ic) +{ + if (validate_ic (ic) && !ic->xims_on) { + SCIM_DEBUG_FRONTEND(2) << "ims_turn_on_ic.\n"; + + ic->xims_on = true; + + //Record the IC on/off status + if (m_shared_input_method) + m_config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true); + + if (is_focused_ic (ic)) { + panel_req_focus_in (ic); + start_ic (ic); + } + } +} + +void +X11FrontEnd::ims_turn_off_ic (X11IC *ic) +{ + if (validate_ic (ic) && ic->xims_on) { + SCIM_DEBUG_FRONTEND(2) << "ims_turn_off_ic.\n"; + + ic->xims_on = false; + + //Record the IC on/off status + if (m_shared_input_method) + m_config->write (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); + + if (is_focused_ic (ic)) + stop_ic (ic); + } +} + +void +X11FrontEnd::ims_sync_ic (X11IC *ic) +{ + if (validate_ic (ic)) { + IMSyncXlibStruct data; + + data.major_code = XIM_SYNC; + data.minor_code = 0; + data.connect_id = ic->connect_id; + data.icid = ic->icid; + + IMSyncXlib(m_xims, (XPointer) &data); + } +} + +void +X11FrontEnd::set_ic_capabilities (const X11IC *ic) +{ + if (validate_ic (ic)) { + unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES - SCIM_CLIENT_CAP_SURROUNDING_TEXT; + + if (!ims_is_preedit_callback_mode (ic)) + cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT; + + update_client_capabilities (ic->siid, cap); + } +} + +void +X11FrontEnd::start_ic (X11IC *ic) +{ + if (validate_ic (ic)) { + if (m_xims_dynamic) { + IMPreeditStateStruct ips; + ips.major_code = 0; + ips.minor_code = 0; + ips.icid = ic->icid; + ips.connect_id = ic->connect_id; + IMPreeditStart (m_xims, (XPointer) & ips); + } + + panel_req_update_screen (ic); + panel_req_update_spot_location (ic); + panel_req_update_factory_info (ic); + + m_panel_client.turn_on (ic->icid); + m_panel_client.hide_preedit_string (ic->icid); + m_panel_client.hide_aux_string (ic->icid); + m_panel_client.hide_lookup_table (ic->icid); + + if (ic->shared_siid) reset (ic->siid); + + focus_in (ic->siid); + } +} + +void +X11FrontEnd::stop_ic (X11IC *ic) +{ + if (validate_ic (ic)) { + focus_out (ic->siid); + if (ic->shared_siid) reset (ic->siid); + + if (ims_is_preedit_callback_mode (ic)) + ims_preedit_callback_done (ic); + + panel_req_update_factory_info (ic); + m_panel_client.turn_off (ic->icid); + + if (m_xims_dynamic) { + IMPreeditStateStruct ips; + ips.major_code = 0; + ips.minor_code = 0; + ips.icid = ic->icid; + ips.connect_id = ic->connect_id; + IMPreeditEnd (m_xims, (XPointer) & ips); + } + } +} + +int +X11FrontEnd::ims_protocol_handler (XIMS ims, IMProtocol *call_data) +{ + if (!_scim_frontend || !call_data || ims != _scim_frontend->m_xims) + return 0; + + switch (call_data->major_code) { + case XIM_OPEN: + return _scim_frontend->ims_open_handler (ims, (IMOpenStruct *) call_data); + case XIM_CLOSE: + return _scim_frontend->ims_close_handler (ims, (IMCloseStruct *) call_data); + case XIM_CREATE_IC: + return _scim_frontend->ims_create_ic_handler (ims, (IMChangeICStruct *) call_data); + case XIM_DESTROY_IC: + return _scim_frontend->ims_destroy_ic_handler (ims, (IMDestroyICStruct *) call_data); + case XIM_SET_IC_VALUES: + return _scim_frontend->ims_set_ic_values_handler (ims, (IMChangeICStruct *) call_data); + case XIM_GET_IC_VALUES: + return _scim_frontend->ims_get_ic_values_handler (ims, (IMChangeICStruct *) call_data); + case XIM_FORWARD_EVENT: + return _scim_frontend->ims_forward_event_handler (ims, (IMForwardEventStruct *) call_data); + case XIM_SET_IC_FOCUS: + return _scim_frontend->ims_set_ic_focus_handler (ims, (IMChangeFocusStruct *) call_data); + case XIM_UNSET_IC_FOCUS: + return _scim_frontend->ims_unset_ic_focus_handler (ims, (IMChangeFocusStruct *) call_data); + case XIM_RESET_IC: + return _scim_frontend->ims_reset_ic_handler (ims, (IMResetICStruct *) call_data); + case XIM_TRIGGER_NOTIFY: + return _scim_frontend->ims_trigger_notify_handler (ims, (IMTriggerNotifyStruct *) call_data); + case XIM_PREEDIT_START_REPLY: + return _scim_frontend->ims_preedit_start_reply_handler (ims, (IMPreeditCBStruct *) call_data); + case XIM_PREEDIT_CARET_REPLY: + return _scim_frontend->ims_preedit_caret_reply_handler (ims, (IMPreeditCBStruct *) call_data); + case XIM_SYNC_REPLY: + return _scim_frontend->ims_sync_reply_handler (ims, (IMSyncXlibStruct *) call_data); + default: + SCIM_DEBUG_FRONTEND(1) << "Unknown major code " << call_data->major_code << "\n"; + break; + } + return 1; +} + +int +X11FrontEnd::x_error_handler (Display *display, XErrorEvent *error) +{ +#if ENABLE_DEBUG + char buf [256]; + + XGetErrorText (display, error->error_code, buf, 256); + + SCIM_DEBUG_FRONTEND (1) + << "X Error occurred:\n" + << " Display = " << display << "\n" + << " Type = " << error->type << "\n" + << " Resourceid = " << error->resourceid << "\n" + << " Serial = " << error->serial << "\n" + << " ErrorCode = " << (uint32) error->error_code << "\n" + << " RequestCode = " << (uint32) error->request_code << "\n" + << " MinorCode = " << (uint32) error->minor_code << "\n" + << " Error Text = " << buf << "\n"; +#endif + + // trap all possible error for broken focus ic. + if ((error->error_code == BadWindow || + error->error_code == BadMatch) && + (error->request_code == X_GetWindowAttributes || + error->request_code == X_GetProperty || + error->request_code == X_SendEvent || + error->request_code == X_TranslateCoords)) { + SCIM_DEBUG_FRONTEND(1) << "Discard This Error\n"; + } else if (_scim_frontend && _scim_frontend->m_old_x_error_handler) { + _scim_frontend->m_old_x_error_handler (display, error); + } + + return 0; +} + + +//===================== Panel Slot callbacks ======================= +void +X11FrontEnd::panel_slot_reload_config (int context) +{ + m_config->reload (); +} + +void +X11FrontEnd::panel_slot_exit (int context) +{ + m_should_exit = true; +} + +void +X11FrontEnd::panel_slot_update_lookup_table_page_size (int context, int page_size) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + update_lookup_table_page_size (ic->siid, page_size); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_lookup_table_page_up (int context) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + lookup_table_page_up (ic->siid); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_lookup_table_page_down (int context) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + lookup_table_page_down (ic->siid); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_trigger_property (int context, const String &property) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + trigger_property (ic->siid, property); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_process_helper_event (int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic) && get_instance_uuid (ic->siid) == target_uuid) { + m_panel_client.prepare (ic->icid); + process_helper_event (ic->siid, helper_uuid, trans); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_move_preedit_caret (int context, int caret_pos) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + move_preedit_caret (ic->siid, caret_pos); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_select_candidate (int context, int cand_index) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + select_candidate (ic->siid, cand_index); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_process_key_event (int context, const KeyEvent &key) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + + if (!filter_hotkeys (ic, key)) { + if (!ic->xims_on || !process_key_event (ic->siid, key)) { + if (!m_fallback_instance->process_key_event (key)) + ims_forward_key_event (ic, key); + } + } + + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_commit_string (int context, const WideString &wstr) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + ims_commit_string (ic, wstr); + } +} +void +X11FrontEnd::panel_slot_forward_key_event (int context, const KeyEvent &key) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + ims_forward_key_event (ic, key); + } +} +void +X11FrontEnd::panel_slot_request_help (int context) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + panel_req_show_help (ic); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_request_factory_menu (int context) +{ + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + panel_req_show_factory_menu (ic); + m_panel_client.send (); + } +} +void +X11FrontEnd::panel_slot_change_factory (int context, const String &uuid) +{ + SCIM_DEBUG_FRONTEND (1) << "panel_slot_change_factory " << uuid << "\n"; + + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + if (uuid.length () == 0 && ic->xims_on) { + SCIM_DEBUG_FRONTEND (2) << "panel_slot_change_factory : turn off.\n"; + ims_turn_off_ic (ic); + } else if (uuid.length ()) { + String encoding = scim_get_locale_encoding (ic->locale); + String language = scim_get_locale_language (ic->locale); + if (validate_factory (uuid, encoding)) { + ims_turn_off_ic (ic); + replace_instance (ic->siid, uuid); + m_panel_client.register_input_context (ic->icid, get_instance_uuid (ic->siid)); + set_ic_capabilities (ic); + set_default_factory (language, uuid); + ims_turn_on_ic (ic); + } + } + m_panel_client.send (); + } +} + +void +X11FrontEnd::panel_slot_select_aux (int context, int aux_index) +{ + X11IC *ic = m_ic_manager.find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " aux=" << aux_index << " ic=" << ic << "\n"; + if (validate_ic (ic)) { + m_panel_client.prepare (ic->icid); + select_aux (ic->siid,aux_index); + m_panel_client.send (); + } +} + +void +X11FrontEnd::panel_slot_show_preedit_string (int context) +{ + X11IC *ic = m_ic_manager.find_ic (context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << "\n"; + if (validate_ic (ic)) { + show_preedit_string(ic->siid); + } +} + +void +X11FrontEnd::panel_slot_hide_preedit_string (int context) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + hide_preedit_string(ic->siid); + } +} + +void +X11FrontEnd::panel_slot_update_preedit_string (int context, + const WideString &str, + const AttributeList &attrs) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + X11IC *ic = m_ic_manager.find_ic (context); + if (validate_ic (ic)) { + update_preedit_string(ic->siid,str,attrs); + } +} + +//================ Panel Request methods ==================== +void +X11FrontEnd::panel_req_update_screen (const X11IC *ic) +{ + Window target = ic->focus_win ? ic->focus_win : ic->client_win; + XWindowAttributes xwa; + if (target && + XGetWindowAttributes (m_display, target, &xwa) && + validate_ic (ic)) { + int num = ScreenCount (m_display); + int idx; + for (idx = 0; idx < num; ++ idx) { + if (ScreenOfDisplay (m_display, idx) == xwa.screen) { + m_panel_client.update_screen (ic->icid, idx); + return; + } + } + } +} + +void +X11FrontEnd::panel_req_show_help (const X11IC *ic) +{ + String help; + String tmp; + + help = String (_("Smart Common Input Method platform ")) + + String (SCIM_VERSION) + + String (_("\n(C) 2002-2005 James Su \n\n")); + + if (ic->xims_on) { + help += utf8_wcstombs (get_instance_name (ic->siid)); + help += String (_(":\n\n")); + + help += utf8_wcstombs (get_instance_authors (ic->siid)); + help += String (_("\n\n")); + + help += utf8_wcstombs (get_instance_help (ic->siid)); + help += String (_("\n\n")); + + help += utf8_wcstombs (get_instance_credits (ic->siid)); + } + + m_panel_client.show_help (ic->icid, help); +} + +void +X11FrontEnd::panel_req_show_factory_menu (const X11IC *ic) +{ + std::vector uuids; + if (get_factory_list_for_encoding (uuids, ic->encoding)) { + std::vector menu; + for (size_t i = 0; i < uuids.size (); ++ i) { + menu.push_back (PanelFactoryInfo ( + uuids [i], + utf8_wcstombs (get_factory_name (uuids [i])), + get_factory_language (uuids [i]), + get_factory_icon_file (uuids [i]))); + } + m_panel_client.show_factory_menu (ic->icid, menu); + } +} + +void +X11FrontEnd::panel_req_focus_in (const X11IC * ic) +{ + m_panel_client.focus_in (ic->icid, get_instance_uuid (ic->siid)); +} + +void +X11FrontEnd::panel_req_update_factory_info (const X11IC *ic) +{ + if (is_focused_ic (ic)) { + PanelFactoryInfo info; + if (ic->xims_on) { + String uuid = get_instance_uuid (ic->siid); + info = PanelFactoryInfo (uuid, utf8_wcstombs (get_factory_name (uuid)), get_factory_language (uuid), get_factory_icon_file (uuid)); + } else { + info = PanelFactoryInfo (String (""), String (_("English/Keyboard")), String ("C"), String (SCIM_KEYBOARD_ICON_FILE)); + } + m_panel_client.update_factory_info (ic->icid, info); + } +} + +void +X11FrontEnd::panel_req_update_spot_location (const X11IC *ic) +{ + Window target = ic->focus_win ? ic->focus_win : ic->client_win; + XWindowAttributes xwa; + + if (target && + XGetWindowAttributes (m_display, target, &xwa) && + validate_ic (ic)) { + + int spot_x, spot_y, spot_top_y; + Window child; + + if (m_focus_ic->pre_attr.spot_location.x >= 0 && + m_focus_ic->pre_attr.spot_location.y >= 0) { + XTranslateCoordinates (m_display, target, + xwa.root, + m_focus_ic->pre_attr.spot_location.x + 8, + m_focus_ic->pre_attr.spot_location.y + 8, + &spot_x, &spot_y, &child); + spot_top_y = spot_y; + } else { + XTranslateCoordinates (m_display, target, + xwa.root, + 0, + xwa.height, + &spot_x, &spot_y, &child); + spot_top_y = spot_y; // Fix me + } + m_panel_client.update_spot_location (ic->icid, spot_x, spot_y, spot_top_y); + } +} + +void +X11FrontEnd::reload_config_callback (const ConfigPointer &config) +{ + SCIM_DEBUG_FRONTEND(1) << "Reload configuration.\n"; + + m_frontend_hotkey_matcher.load_hotkeys (config); + m_imengine_hotkey_matcher.load_hotkeys (config); + + KeyEvent key; + + scim_string_to_key (key, + config->read (String (SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK), + String ("Shift+Control+Alt+Lock"))); + + m_valid_key_mask = (key.mask > 0) ? key.mask : 0xFFFF; + m_valid_key_mask |= SCIM_KEY_ReleaseMask; + // Special treatment for two backslash keys on jp106 keyboard. + m_valid_key_mask |= SCIM_KEY_QuirkKanaRoMask; + + m_broken_wchar = + config->read (String (SCIM_CONFIG_FRONTEND_X11_BROKEN_WCHAR), + m_broken_wchar); + + m_shared_input_method = + config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), + m_shared_input_method); + + // Get keyboard layout setting + // Flush the global config first, in order to load the new configs from disk. + scim_global_config_flush (); + + m_keyboard_layout = scim_get_default_keyboard_layout (); +} + +void +X11FrontEnd::fallback_commit_string_cb (IMEngineInstanceBase * si, const WideString & str) +{ + if (validate_ic (m_focus_ic)) + ims_commit_string (m_focus_ic, str); +} + +/* +vi:ts=4:nowrap:expandtab +*/ diff --git a/ism/modules/frontend/scim_x11_frontend.h b/ism/modules/frontend/scim_x11_frontend.h new file mode 100644 index 0000000..158c931 --- /dev/null +++ b/ism/modules/frontend/scim_x11_frontend.h @@ -0,0 +1,238 @@ +/** + * @file scim_x11_frontend.h + * @brief definition of X11FrontEnd related classes. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Implement aux and preedit show/hide/update for helper ISE + * a. panel_slot_select_aux () + * b. panel_slot_show_preedit_string (), panel_slot_hide_preedit_string () and panel_slot_update_preedit_string () + * + * $Id: scim_x11_frontend.h,v 1.56 2005/06/26 16:35:12 suzhe Exp $ + */ + +#if !defined (__SCIM_X11_FRONTEND_H) +#define __SCIM_X11_FRONTEND_H + +#include "scim_stl_map.h" + +using namespace scim; + +class X11FrontEnd : public FrontEndBase +{ +// first = UUID. +// second= siid. +#if SCIM_USE_STL_EXT_HASH_MAP + typedef __gnu_cxx::hash_map DefaultInstanceMap; +#elif SCIM_USE_STL_HASH_MAP + typedef std::hash_map DefaultInstanceMap; +#else + typedef std::map DefaultInstanceMap; +#endif + + X11ICManager m_ic_manager; + XIMS m_xims; + Display *m_display; + Window m_xims_window; + String m_server_name; + String m_display_name; + + PanelClient m_panel_client; + + X11IC *m_focus_ic; + + FrontEndHotkeyMatcher m_frontend_hotkey_matcher; + IMEngineHotkeyMatcher m_imengine_hotkey_matcher; + + bool m_xims_dynamic; + bool m_wchar_ucs4_equal; + bool m_broken_wchar; + bool m_shared_input_method; + + KeyboardLayout m_keyboard_layout; + + int m_valid_key_mask; + + bool m_should_exit; + + IConvert m_iconv; + ConfigPointer m_config; + + IMEngineFactoryPointer m_fallback_factory; + IMEngineInstancePointer m_fallback_instance; + + DefaultInstanceMap m_default_instance_map; + + int (*m_old_x_error_handler) (Display *, XErrorEvent *); + +public: + X11FrontEnd (const BackEndPointer &backend, + const ConfigPointer &config, + const String &server_name = String ("SCIM")); + + virtual ~X11FrontEnd (); + +protected: + virtual void show_preedit_string (int siid); + virtual void show_aux_string (int siid); + virtual void show_lookup_table (int siid); + + virtual void hide_preedit_string (int siid); + virtual void hide_aux_string (int siid); + virtual void hide_lookup_table (int siid); + + virtual void update_preedit_caret (int siid, int caret); + virtual void update_preedit_string (int siid, const WideString & str, const AttributeList & attrs = AttributeList ()); + virtual void update_aux_string (int siid, const WideString & str, const AttributeList & attrs = AttributeList ()); + virtual void commit_string (int siid, const WideString & str); + virtual void forward_key_event (int siid, const KeyEvent & key); + virtual void update_lookup_table (int siid, const LookupTable & table); + + virtual void register_properties (int siid, const PropertyList & properties); + virtual void update_property (int siid, const Property & property); + virtual void beep (int siid); + virtual void start_helper (int siid, const String &helper_uuid); + virtual void stop_helper (int siid, const String &helper_uuid); + virtual void send_helper_event (int siid, const String &helper_uuid, const Transaction &trans); + + virtual bool get_surrounding_text (int siid, WideString &text, int &cursor, int maxlen_before, int maxlen_after); + virtual bool delete_surrounding_text (int siid, int offset, int len); + +public: + virtual void init (int argc, char **argv); + virtual void run (); + +private: + String get_supported_locales (void); + + int get_default_instance (const String &language, const String &encoding); + + // Return the display name + String init_ims (void); + + XKeyEvent keyevent_scim_to_x11 (const KeyEvent& key); + KeyEvent keyevent_x11_to_scim (const XKeyEvent& key); + + bool filter_hotkeys (X11IC *ic, const KeyEvent &key); + + int ims_open_handler (XIMS ims, IMOpenStruct *call_data); + int ims_close_handler (XIMS ims, IMCloseStruct *call_data); + int ims_create_ic_handler (XIMS ims, IMChangeICStruct *call_data); + int ims_set_ic_values_handler (XIMS ims, IMChangeICStruct *call_data); + int ims_get_ic_values_handler (XIMS ims, IMChangeICStruct *call_data); + int ims_destroy_ic_handler (XIMS ims, IMDestroyICStruct *call_data); + int ims_set_ic_focus_handler (XIMS ims, IMChangeFocusStruct *call_data); + int ims_unset_ic_focus_handler (XIMS ims, IMChangeFocusStruct *call_data); + int ims_reset_ic_handler (XIMS ims, IMResetICStruct *call_data); + int ims_trigger_notify_handler (XIMS ims, IMTriggerNotifyStruct *call_data); + int ims_forward_event_handler (XIMS ims, IMForwardEventStruct *call_data); + int ims_sync_reply_handler (XIMS ims, IMSyncXlibStruct *call_data); + int ims_preedit_start_reply_handler (XIMS ims, IMPreeditCBStruct *call_data); + int ims_preedit_caret_reply_handler (XIMS ims, IMPreeditCBStruct *call_data); + + void ims_commit_string (const X11IC *ic, const WideString& str); + void ims_forward_key_event (const X11IC *ic, const KeyEvent& key); + bool ims_wcstocts (XTextProperty &tp, const X11IC *ic, const WideString& src); + + bool ims_is_preedit_callback_mode (const X11IC *ic); + void ims_preedit_callback_start (X11IC *ic); + void ims_preedit_callback_done (X11IC *ic); + void ims_preedit_callback_draw (X11IC *ic, const WideString& str, const AttributeList & attrs = AttributeList ()); + void ims_preedit_callback_caret (X11IC *ic, int caret); + + bool ims_string_conversion_callback_retrieval (X11IC *ic, WideString &text, int &cursor, int maxlen_before, int maxlen_after); + bool ims_string_conversion_callback_substitution (X11IC *ic, int offset, int len); + + void ims_turn_on_ic (X11IC *ic); + void ims_turn_off_ic (X11IC *ic); + + void ims_sync_ic (X11IC *ic); + + void set_ic_capabilities (const X11IC *ic); + + void start_ic (X11IC *ic); + void stop_ic (X11IC *ic); + + bool is_focused_ic (int siid) { return validate_ic (m_focus_ic) && m_focus_ic->siid == siid; } + bool is_inputing_ic (int siid) { return is_focused_ic (siid) && m_focus_ic->xims_on; } + bool is_forwarding_ic (int siid) { return is_focused_ic (siid) && !m_focus_ic->xims_on; } + + bool is_focused_ic (const X11IC *ic) { return validate_ic (m_focus_ic) && validate_ic (ic) && m_focus_ic->icid == ic->icid; } + bool is_inputing_ic (const X11IC *ic) { return is_focused_ic (ic) && ic->xims_on; } + bool is_forwarding_ic (const X11IC *ic) { return is_focused_ic (ic) && !ic->xims_on; } + + bool is_input_mode () { + return validate_ic (m_focus_ic) && m_focus_ic->xims_on; + } + + bool is_forward_mode () { + return !is_input_mode (); + } + + void panel_slot_reload_config (int context); + void panel_slot_exit (int context); + void panel_slot_update_lookup_table_page_size (int context, int page_size); + void panel_slot_lookup_table_page_up (int context); + void panel_slot_lookup_table_page_down (int context); + void panel_slot_trigger_property (int context, const String &property); + void panel_slot_process_helper_event (int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans); + void panel_slot_move_preedit_caret (int context, int caret_pos); + void panel_slot_select_candidate (int context, int cand_index); + void panel_slot_process_key_event (int context, const KeyEvent &key); + void panel_slot_commit_string (int context, const WideString &wstr); + void panel_slot_forward_key_event (int context, const KeyEvent &key); + void panel_slot_request_help (int context); + void panel_slot_request_factory_menu (int context); + void panel_slot_change_factory (int context, const String &uuid); + + void panel_slot_select_aux (int context,int aux_index); + void panel_slot_show_preedit_string (int context); + void panel_slot_hide_preedit_string (int context); + void panel_slot_update_preedit_string (int context,const WideString &str,const AttributeList &attrs); + + void panel_req_update_screen (const X11IC *ic); + void panel_req_show_help (const X11IC *ic); + void panel_req_show_factory_menu (const X11IC *ic); + void panel_req_focus_in (const X11IC *ic); + void panel_req_update_factory_info (const X11IC *ic); + void panel_req_update_spot_location (const X11IC *ic); + + void reload_config_callback (const ConfigPointer &config); + + void fallback_commit_string_cb (IMEngineInstanceBase * si, const WideString & str); + +private: + static int ims_protocol_handler (XIMS ims, IMProtocol *call_data); + + static int x_error_handler (Display *display, XErrorEvent *error); + + static bool validate_ic (const X11IC * ic) { return ic && ic->icid > 0 && ic->siid >= 0; } +}; + +#endif + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/frontend/scim_x11_ic.cpp b/ism/modules/frontend/scim_x11_ic.cpp new file mode 100644 index 0000000..ec919f7 --- /dev/null +++ b/ism/modules/frontend/scim_x11_ic.cpp @@ -0,0 +1,473 @@ +/** @file scim_x11_ic.cpp + * implementation of class X11ICManager. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_x11_ic.cpp,v 1.19 2005/06/26 16:35:12 suzhe Exp $ + * + */ + +#include +#include +#include +#include "imdkit/IMdkit.h" +#include "imdkit/Xi18n.h" + +#include "scim_private.h" +#include "scim.h" +#include "scim_x11_ic.h" + +using namespace scim; + +static int +_is_attr (char *attr, XICAttribute * attr_list) +{ + return !strcmp (attr, attr_list->name); +} + +X11ICManager::X11ICManager () + : m_ic_list (NULL), + m_free_list (NULL) +{ +} + +X11ICManager::~X11ICManager () +{ + X11IC *it; + + it = m_ic_list; + while (it != NULL) { + m_ic_list = it->next; + delete it; + it = m_ic_list; + } + + it = m_free_list; + while (it != NULL) { + m_free_list = it->next; + delete it; + it = m_free_list; + } +} + +X11IC * +X11ICManager::new_ic () +{ + static CARD16 base_icid = 1; + X11IC *rec; + + if (m_free_list != NULL) { + rec = m_free_list; + m_free_list = m_free_list->next; + } else { + rec = new X11IC; + } + + if (base_icid == 0) base_icid = 1; + + rec->icid = base_icid ++; + + rec->next = m_ic_list; + m_ic_list = rec; + return rec; +} + +void +X11ICManager::delete_ic (CARD16 icid) +{ + X11IC *rec, *last = NULL; + + for (rec = m_ic_list; rec != NULL; last = rec, rec = rec->next) { + if (rec->icid == icid) { + if (last != NULL) + last->next = rec->next; + else + m_ic_list = rec->next; + + rec->next = m_free_list; + m_free_list = rec; + + rec->siid = -1; + rec->icid = 0; + rec->connect_id = 0; + rec->client_win = 0; + rec->focus_win = 0; + rec->shared_siid = false; + rec->xims_on = false; + rec->encoding = String (); + rec->locale = String (); + + return; + } + } + return; +} + +String +X11ICManager::get_connection_locale (CARD16 connect_id) +{ + ConnectionLocaleMap::iterator it = + m_connect_locales.find ((int)connect_id); + + if (it != m_connect_locales.end ()) + return it->second; + + return String (); +} + +void +X11ICManager::new_connection (IMOpenStruct *call_data) +{ + if (call_data == NULL) return; + + String locale = scim_validate_locale (String (call_data->lang.name)); + + if (!locale.length ()) { + locale = String ("C"); + } + + m_connect_locales [(int)call_data->connect_id] = locale; +} + +void +X11ICManager::delete_connection (IMCloseStruct *call_data) +{ + if (call_data == NULL) return; + + m_connect_locales.erase ((int)call_data->connect_id); +} + +uint32 +X11ICManager::create_ic (IMChangeICStruct *call_data, int siid) +{ + X11IC * rec; + + rec = new_ic (); + if (rec == NULL) return 0; + + call_data->icid = rec->icid; + rec->connect_id = call_data->connect_id; + rec->siid = siid; + rec->shared_siid = false; + rec->xims_on = true; + rec->onspot_preedit_started = false; + rec->onspot_preedit_length = 0; + rec->onspot_caret = 0; + rec->focus_win = (Window) 0; + rec->client_win = (Window) 0; + rec->input_style = 0; + rec->pre_attr.spot_location.x = -1; + rec->pre_attr.spot_location.y = -1; + + return store_ic_values (rec, call_data); +} + +X11IC * +X11ICManager::find_ic (CARD16 icid) +{ + X11IC *rec = m_ic_list; + while (rec != NULL) { + if (rec->icid == icid) + return rec; + rec = rec->next; + } + return NULL; +} + +X11IC * +X11ICManager::find_ic_by_siid (int siid) +{ + X11IC *rec = m_ic_list; + while (rec != NULL) { + if (rec->siid == siid) + return rec; + rec = rec->next; + } + return NULL; +} + +void +X11ICManager::destroy_ic (IMDestroyICStruct *call_data) +{ + if (call_data == NULL) return; + + delete_ic (call_data->icid); +} + +uint32 +X11ICManager::store_ic_values (X11IC *rec, IMChangeICStruct *call_data) +{ + XICAttribute *ic_attr = call_data->ic_attr; + XICAttribute *pre_attr = call_data->preedit_attr; + XICAttribute *sts_attr = call_data->status_attr; + + int i; + uint32 attrs = 0; + + // Set main attributes + for (i=0; i< (int) call_data->ic_attr_num; ++i, ++ic_attr) { + if (_is_attr (XNInputStyle, ic_attr)) { + rec->input_style = * (INT32 *) ic_attr->value; + attrs |= SCIM_X11_IC_INPUT_STYLE; + } else if (_is_attr (XNClientWindow, ic_attr)) { + rec->client_win = *(Window *) ic_attr->value; + attrs |= SCIM_X11_IC_CLIENT_WINDOW; + } else if (_is_attr (XNFocusWindow, ic_attr)) { + rec->focus_win = *(Window *) ic_attr->value; + attrs |= SCIM_X11_IC_FOCUS_WINDOW; + } else { + std::cerr << __FILE__ << "(" << __LINE__ << "):" + <<"Unknown attr: " << ic_attr->name << std::endl; + } + } + + // Set preedit attributes + for (i = 0; i < (int) call_data->preedit_attr_num; ++i, ++pre_attr) { + if (_is_attr (XNArea, pre_attr)) { + rec->pre_attr.area = *(XRectangle *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_AREA; + } else if (_is_attr (XNAreaNeeded, pre_attr)) { + rec->pre_attr.area_needed = *(XRectangle *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_AREA_NEEDED; + } else if (_is_attr (XNSpotLocation, pre_attr)) { + rec->pre_attr.spot_location = *(XPoint *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_SPOT_LOCATION; + } else if (_is_attr (XNColormap, pre_attr)) { + rec->pre_attr.cmap = *(Colormap *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_COLORMAP; + } else if (_is_attr (XNStdColormap, pre_attr)) { + rec->pre_attr.cmap = *(Colormap *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_COLORMAP; + } else if (_is_attr (XNForeground, pre_attr)) { + rec->pre_attr.foreground = *(CARD32 *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_FOREGROUND; + } else if (_is_attr (XNBackground, pre_attr)) { + rec->pre_attr.background = *(CARD32 *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_BACKGROUND; + } else if (_is_attr (XNBackgroundPixmap, pre_attr)) { + rec->pre_attr.bg_pixmap = *(Pixmap *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_BG_PIXMAP; + } else if (_is_attr (XNFontSet, pre_attr)) { + rec->pre_attr.base_font = (char*) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_FONTSET; + } else if (_is_attr (XNLineSpace, pre_attr)) { + rec->pre_attr.line_space = *(CARD32 *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_LINE_SPACE; + } else if (_is_attr (XNCursor, pre_attr)) { + rec->pre_attr.cursor = *(Cursor *) pre_attr->value; + attrs |= SCIM_X11_IC_PRE_CURSOR; + } else { + std::cerr << __FILE__ << "(" << __LINE__ << "):" + <<"Unknown attr: " << pre_attr->name << std::endl; + } + } + + // Set status attributes + for (i = 0; i < (int) call_data->status_attr_num; ++i, ++sts_attr) { + if (_is_attr (XNArea, sts_attr)) { + rec->sts_attr.area = *(XRectangle *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_AREA; + } else if (_is_attr (XNAreaNeeded, sts_attr)) { + rec->sts_attr.area_needed = *(XRectangle *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_AREA_NEEDED; + } else if (_is_attr (XNColormap, sts_attr)) { + rec->sts_attr.cmap = *(Colormap *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_COLORMAP; + } else if (_is_attr (XNStdColormap, sts_attr)) { + rec->sts_attr.cmap = *(Colormap *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_COLORMAP; + } else if (_is_attr (XNForeground, sts_attr)) { + rec->sts_attr.foreground = *(CARD32 *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_FOREGROUND; + } else if (_is_attr (XNBackground, sts_attr)) { + rec->sts_attr.background = *(CARD32 *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_BACKGROUND; + } else if (_is_attr (XNBackgroundPixmap, sts_attr)) { + rec->sts_attr.bg_pixmap = *(Pixmap *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_BG_PIXMAP; + } else if (_is_attr (XNFontSet, sts_attr)) { + rec->sts_attr.base_font = (char*) sts_attr->value; + attrs |= SCIM_X11_IC_STS_FONTSET; + } else if (_is_attr (XNLineSpace, sts_attr)) { + rec->sts_attr.line_space = *(CARD32 *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_LINE_SPACE; + } else if (_is_attr (XNCursor, sts_attr)) { + rec->sts_attr.cursor = *(Cursor *) sts_attr->value; + attrs |= SCIM_X11_IC_STS_CURSOR; + } else { + std::cerr << __FILE__ << "(" << __LINE__ << "):" + <<"Unknown attr: " << sts_attr->name << std::endl; + } + } + + String connect_locale = + get_connection_locale ((int)call_data->connect_id); + + if (connect_locale != rec->locale) { + rec->locale = connect_locale; + rec->encoding = scim_get_locale_encoding (connect_locale); + attrs |= SCIM_X11_IC_ENCODING; + } + + return attrs; +} + +uint32 +X11ICManager::set_ic_values (IMChangeICStruct *call_data) +{ + if (call_data == NULL) return 0; + + X11IC *rec = find_ic (call_data->icid); + + if (rec == NULL) return 0; + + return store_ic_values (rec, call_data); +} + +uint32 +X11ICManager::get_ic_values (IMChangeICStruct *call_data) +{ + if (call_data == NULL) return 0; + + XICAttribute *ic_attr = call_data->ic_attr; + XICAttribute *pre_attr = call_data->preedit_attr; + XICAttribute *sts_attr = call_data->status_attr; + + X11IC *rec = find_ic (call_data->icid); + + if (rec == NULL) return 0; + + int i; + uint32 attrs = 0; + + for (i = 0; i < (int) call_data->ic_attr_num; ++i, ++ic_attr) { + if (_is_attr (XNFilterEvents, ic_attr)) { + ic_attr->value = (void *) malloc (sizeof (CARD32)); + *(CARD32 *) ic_attr->value = KeyPressMask | KeyReleaseMask; + ic_attr->value_length = sizeof (CARD32); + attrs |= SCIM_X11_IC_FILTER_EVENTS; + } else { + std::cerr << __FILE__ << "(" << __LINE__ << "):" + <<"Unknown attr: " << ic_attr->name << std::endl; + } + } + + // preedit attributes + for (i = 0; i < (int) call_data->preedit_attr_num; ++i, ++pre_attr) { + if (_is_attr (XNArea, pre_attr)) { + pre_attr->value = (void *) malloc (sizeof (XRectangle)); + *(XRectangle *) pre_attr->value = rec->pre_attr.area; + pre_attr->value_length = sizeof (XRectangle); + attrs |= SCIM_X11_IC_PRE_AREA; + } else if (_is_attr (XNAreaNeeded, pre_attr)) { + pre_attr->value = (void *) malloc (sizeof (XRectangle)); + *(XRectangle *) pre_attr->value = rec->pre_attr.area_needed; + pre_attr->value_length = sizeof (XRectangle); + attrs |= SCIM_X11_IC_PRE_AREA_NEEDED; + } else if (_is_attr (XNSpotLocation, pre_attr)) { + pre_attr->value = (void *) malloc (sizeof (XPoint)); + *(XPoint *) pre_attr->value = rec->pre_attr.spot_location; + pre_attr->value_length = sizeof (XPoint); + attrs |= SCIM_X11_IC_PRE_SPOT_LOCATION; + } else if (_is_attr (XNFontSet, pre_attr)) { + CARD16 base_len = (CARD16) rec->pre_attr.base_font.size (); + int total_len = sizeof (CARD16) + (CARD16) base_len; + char *p; + pre_attr->value = (void *) malloc (total_len); + p = (char *) pre_attr->value; + memmove (p, &base_len, sizeof (CARD16)); + p += sizeof (CARD16); + strncpy (p, rec->pre_attr.base_font.c_str (), base_len); + pre_attr->value_length = total_len; + attrs |= SCIM_X11_IC_PRE_FONTSET; + } else if (_is_attr (XNForeground, pre_attr)) { + pre_attr->value = (void *) malloc (sizeof (CARD32)); + *(CARD32 *) pre_attr->value = rec->pre_attr.foreground; + pre_attr->value_length = sizeof (CARD32); + attrs |= SCIM_X11_IC_PRE_FOREGROUND; + } else if (_is_attr (XNBackground, pre_attr)) { + pre_attr->value = (void *) malloc (sizeof (CARD32)); + *(CARD32 *) pre_attr->value = rec->pre_attr.background; + pre_attr->value_length = sizeof (CARD32); + attrs |= SCIM_X11_IC_PRE_BACKGROUND; + } else if (_is_attr (XNLineSpace, pre_attr)) { + pre_attr->value = (void *) malloc (sizeof (CARD32)); + *(CARD32 *) pre_attr->value = rec->pre_attr.line_space; + pre_attr->value_length = sizeof (CARD32); + attrs |= SCIM_X11_IC_PRE_LINE_SPACE; + } else { + std::cerr << __FILE__ << "(" << __LINE__ << "):" + <<"Unknown attr: " << pre_attr->name << std::endl; + } + } + + // status attributes + for (i = 0; i < (int) call_data->status_attr_num; ++i, ++sts_attr) { + if (_is_attr (XNArea, sts_attr)) { + sts_attr->value = (void *) malloc (sizeof (XRectangle)); + *(XRectangle *) sts_attr->value = rec->sts_attr.area; + sts_attr->value_length = sizeof (XRectangle); + attrs |= SCIM_X11_IC_STS_AREA; + } else if (_is_attr (XNAreaNeeded, sts_attr)) { + sts_attr->value = (void *) malloc (sizeof (XRectangle)); + *(XRectangle *) sts_attr->value = rec->sts_attr.area_needed; + sts_attr->value_length = sizeof (XRectangle); + attrs |= SCIM_X11_IC_STS_AREA_NEEDED; + } else if (_is_attr (XNFontSet, sts_attr)) { + CARD16 base_len = (CARD16) rec->sts_attr.base_font.size (); + int total_len = sizeof (CARD16) + (CARD16) base_len; + char *p; + sts_attr->value = (void *) malloc (total_len); + p = (char *) sts_attr->value; + memmove (p, &base_len, sizeof (CARD16)); + p += sizeof (CARD16); + strncpy (p, rec->sts_attr.base_font.c_str (), base_len); + sts_attr->value_length = total_len; + attrs |= SCIM_X11_IC_STS_FONTSET; + } else if (_is_attr (XNForeground, sts_attr)) { + sts_attr->value = (void *) malloc (sizeof (CARD32)); + *(CARD32 *) sts_attr->value = rec->sts_attr.foreground; + sts_attr->value_length = sizeof (CARD32); + attrs |= SCIM_X11_IC_STS_FOREGROUND; + } else if (_is_attr (XNBackground, sts_attr)) { + sts_attr->value = (void *) malloc (sizeof (CARD32)); + *(CARD32 *) sts_attr->value = rec->sts_attr.background; + sts_attr->value_length = sizeof (CARD32); + attrs |= SCIM_X11_IC_STS_BACKGROUND; + } else if (_is_attr (XNLineSpace, sts_attr)) { + sts_attr->value = (void *) malloc (sizeof (CARD32)); + *(CARD32 *) sts_attr->value = rec->sts_attr.line_space; + sts_attr->value_length = sizeof (CARD32); + attrs |= SCIM_X11_IC_STS_LINE_SPACE; + } else { + std::cerr << __FILE__ << "(" << __LINE__ << "):" + <<"Unknown attr: " << sts_attr->name << std::endl; + } + } + + return attrs; +} + +/* +vi:ts=4:nowrap:expandtab +*/ diff --git a/ism/modules/frontend/scim_x11_ic.h b/ism/modules/frontend/scim_x11_ic.h new file mode 100644 index 0000000..4a01f3d --- /dev/null +++ b/ism/modules/frontend/scim_x11_ic.h @@ -0,0 +1,180 @@ +/** @file scim_x11_ic.h + * definition of X11IC related classes. + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_x11_ic.h,v 1.10 2005/06/26 16:35:12 suzhe Exp $ + */ + +#if !defined (__SCIM_X11_IC_H) +#define __SCIM_X11_IC_H + +#include "scim_stl_map.h" + +using namespace scim; + +struct X11PreeditAttributes +{ + XRectangle area; /* area */ + XRectangle area_needed; /* area needed */ + XPoint spot_location; /* spot location */ + Colormap cmap; /* colormap */ + CARD32 foreground; /* foreground */ + CARD32 background; /* background */ + Pixmap bg_pixmap; /* background pixmap */ + String base_font; /* base font of fontset */ + CARD32 line_space; /* line spacing */ + Cursor cursor; /* cursor */ +}; + +struct X11StatusAttributes +{ + XRectangle area; /* area */ + XRectangle area_needed; /* area needed */ + Colormap cmap; /* colormap */ + CARD32 foreground; /* foreground */ + CARD32 background; /* background */ + Pixmap bg_pixmap; /* background pixmap */ + String base_font; /* base font of fontset */ + CARD32 line_space; /* line spacing */ + Cursor cursor; /* cursor */ +}; + +struct X11IC +{ + int siid; /* server instance id */ + CARD16 icid; /* ic id */ + CARD16 connect_id; /* connect id */ + INT32 input_style; /* input style */ + Window client_win; /* client window */ + Window focus_win; /* focus window */ + String encoding; /* connection encoding */ + String locale; /* connection locale */ + X11PreeditAttributes pre_attr; /* preedit attributes */ + X11StatusAttributes sts_attr; /* status attributes */ + + bool shared_siid; + bool xims_on; + bool onspot_preedit_started; + int onspot_preedit_length; /* preedit length of onspot mode */ + int onspot_caret; /* caret position of onspot mode */ + + X11IC *next; +}; + +#define SCIM_X11_IC_INPUT_STYLE (1<<0) +#define SCIM_X11_IC_CLIENT_WINDOW (1<<1) +#define SCIM_X11_IC_FOCUS_WINDOW (1<<2) +#define SCIM_X11_IC_ENCODING (1<<3) +#define SCIM_X11_IC_PRE_AREA (1<<4) +#define SCIM_X11_IC_PRE_AREA_NEEDED (1<<5) +#define SCIM_X11_IC_PRE_SPOT_LOCATION (1<<6) +#define SCIM_X11_IC_PRE_COLORMAP (1<<7) +#define SCIM_X11_IC_PRE_FOREGROUND (1<<8) +#define SCIM_X11_IC_PRE_BACKGROUND (1<<9) +#define SCIM_X11_IC_PRE_BG_PIXMAP (1<<10) +#define SCIM_X11_IC_PRE_FONTSET (1<<11) +#define SCIM_X11_IC_PRE_LINE_SPACE (1<<12) +#define SCIM_X11_IC_PRE_CURSOR (1<<13) +#define SCIM_X11_IC_STS_AREA (1<<14) +#define SCIM_X11_IC_STS_AREA_NEEDED (1<<15) +#define SCIM_X11_IC_STS_COLORMAP (1<<16) +#define SCIM_X11_IC_STS_FOREGROUND (1<<17) +#define SCIM_X11_IC_STS_BACKGROUND (1<<18) +#define SCIM_X11_IC_STS_BG_PIXMAP (1<<19) +#define SCIM_X11_IC_STS_FONTSET (1<<20) +#define SCIM_X11_IC_STS_LINE_SPACE (1<<21) +#define SCIM_X11_IC_STS_CURSOR (1<<22) +#define SCIM_X11_IC_FILTER_EVENTS (1<<23) + +class X11ICManager +{ +#if SCIM_USE_STL_EXT_HASH_MAP + typedef __gnu_cxx::hash_map > ConnectionLocaleMap; +#elif SCIM_USE_STL_HASH_MAP + typedef std::hash_map > ConnectionLocaleMap; +#else + typedef std::map ConnectionLocaleMap; +#endif + + X11IC *m_ic_list; + X11IC *m_free_list; + + ConnectionLocaleMap m_connect_locales; + +public: + X11ICManager (); + ~X11ICManager (); + +private: + /** + * create an empty scimX11IC struct. + */ + X11IC * new_ic (); + + /** + * store the attributes in call_data to rec. + * @return a bitsets indicates which attributes are set. + */ + uint32 store_ic_values (X11IC *rec, IMChangeICStruct *call_data); + + /** + * delete a X11IC struct according to its icid. + */ + void delete_ic (CARD16 icid); + +public: + void new_connection (IMOpenStruct *call_data); + void delete_connection (IMCloseStruct *call_data); + + String get_connection_locale (CARD16 connect_id); + + /** + * Create a new X11IC struct and set its attributes. + * @return a bitsets indicates which attributes are set. + */ + uint32 create_ic (IMChangeICStruct *call_data, int siid); + + X11IC * find_ic (CARD16 icid); + X11IC * find_ic_by_siid (int siid); + + void destroy_ic (IMDestroyICStruct *call_data); + + /** + * load the attributes of ic into call_data + * @return a bitsets indicates which attributes are loaded. + */ + uint32 get_ic_values (IMChangeICStruct *call_data); + + /** + * store the attributes in call_data to rec. + * @return a bitsets indicates which attributes are set. + */ + uint32 set_ic_values (IMChangeICStruct *call_data); +}; + +#endif // _SCIM_X11_IC_H + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/imengine/Makefile.am b/ism/modules/imengine/Makefile.am new file mode 100644 index 0000000..062c413 --- /dev/null +++ b/ism/modules/imengine/Makefile.am @@ -0,0 +1,59 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.bak +EXTRA_DIST = imengine.version-script + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(top_srcdir)/ism/utils \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" \ + -DSCIM_TEMPDIR=\"@SCIM_TEMPDIR@\" + +if SCIM_BUILD_IMENGINE_SOCKET +CONFIG_IMENGINE_SOCKET_MODULE = socket.la +endif + +if SCIM_LD_VERSION_SCRIPT +LD_VERSION_SCRIPT_OPTION="-Wl,--version-script=$(srcdir)/imengine.version-script" +endif + +noinst_HEADERS = scim_socket_imengine.h + +moduledir = @SCIM_MODULE_PATH@/$(SCIM_BINARY_VERSION)/IMEngine +module_LTLIBRARIES = $(CONFIG_IMENGINE_SOCKET_MODULE) + +socket_la_SOURCES = scim_socket_imengine.cpp + +socket_la_LDFLAGS = -avoid-version \ + -rpath $(moduledir) \ + -module \ + $(LD_VERSION_SCRIPT_OPTION) \ + @LIBTOOL_EXPORT_OPTIONS@ \ + @LTLIBINTL@ + +socket_la_LIBADD = $(top_builddir)/ism/src/libscim@SCIM_EPOCH@.la + diff --git a/ism/modules/imengine/imengine.version-script b/ism/modules/imengine/imengine.version-script new file mode 100755 index 0000000..d697104 --- /dev/null +++ b/ism/modules/imengine/imengine.version-script @@ -0,0 +1,16 @@ +SCIM_IMENGINE_1.0 { + global: + extern "C" { + *scim_imengine_module_create_factory*; + *scim_imengine_module_init*; + *scim_module_exit*; + *scim_module_init*; + }; + + local: + extern "C++" { + scim::*; + std::*; + __gnu_cxx::*; + }; +}; diff --git a/ism/modules/imengine/scim_socket_imengine.cpp b/ism/modules/imengine/scim_socket_imengine.cpp new file mode 100644 index 0000000..7a90411 --- /dev/null +++ b/ism/modules/imengine/scim_socket_imengine.cpp @@ -0,0 +1,1251 @@ +/** @file scim_socket_imengine.cpp + * implementation of class SocketFactory and SocketInstance. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Use ISE cache file + * 2. Add new interface APIs for keyboard ISE + * a. select_aux (), set_prediction_allow () and set_layout () + * b. update_candidate_item_layout (), update_cursor_position () and update_displayed_candidate_number () + * c. candidate_more_window_show (), candidate_more_window_hide () and longpress_candidate () + * d. set_imdata () and reset_option () + * 3. Add get_option () in SocketFactory + * + * $Id: scim_socket_imengine.cpp,v 1.21 2005/07/06 03:57:04 suzhe Exp $ + * + */ + +#define Uses_SCIM_IMENGINE +#define Uses_SCIM_CONFIG_BASE +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_SOCKET +#define Uses_SCIM_TRANSACTION +#define Uses_C_STDLIB +#define Uses_SCIM_PANEL_AGENT + + +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "scim_socket_imengine.h" +#include "scim_stl_map.h" +#include "isf_query_utility.h" + + +#define scim_module_init socket_LTX_scim_module_init +#define scim_module_exit socket_LTX_scim_module_exit +#define scim_imengine_module_init socket_LTX_scim_imengine_module_init +#define scim_imengine_module_create_factory socket_LTX_scim_imengine_module_create_factory + +#define SCIM_CONFIG_IMENGINE_SOCKET_TIMEOUT "/IMEngine/Socket/Timeout" +#define SCIM_CONFIG_IMENGINE_SOCKET_ADDRESS "/IMEngine/Socket/Address" + +#define SCIM_SOCKET_FRONTEND_DEF_ADDRESS "local:/tmp/scim-socket-frontend" + +#ifndef SCIM_TEMPDIR + #define SCIM_TEMPDIR "/tmp" +#endif + +using namespace scim; + + +class scim::SocketIMEngineGlobal +{ +#if SCIM_USE_STL_EXT_HASH_MAP +typedef __gnu_cxx::hash_map IconRepository; +#elif SCIM_USE_STL_HASH_MAP +typedef std::hash_map IconRepository; +#else +typedef std::map IconRepository; +#endif + + SocketClient m_socket_client; + SocketAddress m_socket_address; + uint32 m_socket_magic_key; + int m_socket_timeout; + + std::vector m_peer_factories; + + IconRepository m_icon_repository; + + Signal0 m_signal_reconnect; + +public: + SocketIMEngineGlobal (); + ~SocketIMEngineGlobal (); + + bool create_connection (); + unsigned int number_of_factories (); + SocketFactory * create_factory (unsigned int index); + + void init_transaction (Transaction &trans); + bool send_transaction (Transaction &trans); + bool receive_transaction (Transaction &trans); + + void get_ise_info_map (const char *filename); + String load_icon (const String &icon); + + Connection connect_reconnect_signal (Slot0 *slot_reconnect); + +private: + void init (); + void destroy (); + + void destroy_all_icons (); +}; + +static SocketIMEngineGlobal *global = 0; +static std::map ise_info_repository; + +extern "C" { + void scim_module_init (void) + { + if (!global) + global = new SocketIMEngineGlobal; + } + + void scim_module_exit (void) + { + if (global) { + delete global; + global = 0; + } + } + + unsigned int scim_imengine_module_init (const ConfigPointer &config) + { + if (global) + return global->number_of_factories (); + return 0; + } + + IMEngineFactoryPointer scim_imengine_module_create_factory (unsigned int index) + { + if (!global) + return 0; + + SocketFactory *sf = global->create_factory (index); + + if (!sf || !sf->valid ()) { + delete sf; + sf = 0; + } + + return sf; + } +} + +namespace scim { + +SocketIMEngineGlobal::SocketIMEngineGlobal () + : m_socket_magic_key (0), + m_socket_timeout (-1) +{ + init (); +} + +SocketIMEngineGlobal::~SocketIMEngineGlobal () +{ + destroy (); +} + +void +SocketIMEngineGlobal::init () +{ + SCIM_DEBUG_IMENGINE(1) << "Init SocketIMEngine Global.\n"; + + String address = scim_get_default_socket_imengine_address (); + + m_socket_timeout = scim_get_default_socket_timeout (); + m_socket_address.set_address (address); + + if (!m_socket_address.valid ()) + return; + + // Connect to SocketFrontEnd. + if (!create_connection ()) { + SCIM_DEBUG_IMENGINE(2) << " Cannot connect to SocketFrontEnd (" << address << ").\n"; + return; + } + + SCIM_DEBUG_IMENGINE(2) << " Connected to SocketFrontEnd (" << address + << ") MagicKey (" << m_socket_magic_key << ").\n"; + + // Get IMEngineFactory list. + String user_file_name = String (USER_ENGINE_FILE_NAME); + + ise_info_repository.clear (); + m_peer_factories.clear (); + get_ise_info_map (user_file_name.c_str ()); +} + +bool +SocketIMEngineGlobal::create_connection () +{ + SCIM_DEBUG_IMENGINE(1) << __FUNCTION__ << "...\n"; + + // Connect to SocketFrontEnd. + if (!m_socket_client.connect (m_socket_address)) + return false; + + if (!scim_socket_open_connection (m_socket_magic_key, + String ("SocketIMEngine"), + String ("SocketFrontEnd"), + m_socket_client, + m_socket_timeout)) { + m_socket_client.close (); + return false; + } + + m_signal_reconnect.emit (); + + return true; +} + +void +SocketIMEngineGlobal::destroy () +{ + SCIM_DEBUG_IMENGINE(1) << "Destroy SocketIMEngine Global.\n"; + + m_socket_client.close (); + + destroy_all_icons (); +} + +unsigned int +SocketIMEngineGlobal::number_of_factories () +{ + return m_peer_factories.size (); +} + +SocketFactory * +SocketIMEngineGlobal::create_factory (unsigned int index) +{ + if (index < m_peer_factories.size ()) { + return new SocketFactory (m_peer_factories [index]); + } + return 0; +} + +void +SocketIMEngineGlobal::init_transaction (Transaction &trans) +{ + trans.clear (); + trans.put_command (SCIM_TRANS_CMD_REQUEST); + trans.put_data (m_socket_magic_key); +} + +bool +SocketIMEngineGlobal::send_transaction (Transaction &trans) +{ + return trans.write_to_socket (m_socket_client); +} + +bool +SocketIMEngineGlobal::receive_transaction (Transaction &trans) +{ + return trans.read_from_socket (m_socket_client, m_socket_timeout); +} + +void +SocketIMEngineGlobal::get_ise_info_map (const char *filename) +{ + FILE *engine_list_file = fopen (filename, "r"); + if (engine_list_file == NULL) { + std::cerr << __func__ << " Failed to open(" << filename << ")\n"; + return; + } + + char buf[MAXLINE]; + + while (fgets (buf, MAXLINE, engine_list_file) != NULL && strlen (buf) > 0) { + ISEINFO info; + isf_get_ise_info_from_string (buf, info); + + if (info.mode == TOOLBAR_KEYBOARD_MODE) { + m_peer_factories.push_back (info.uuid); + ise_info_repository[info.uuid] = info; + } + } + + fclose (engine_list_file); +} + +String +SocketIMEngineGlobal::load_icon (const String &icon) +{ + String local_icon = icon; + + IconRepository::const_iterator it = m_icon_repository.find (icon); + + // The icon has been loaded, just return the local copy filename. + if (it != m_icon_repository.end ()) + local_icon = it->second; + + // This icon is already available in local system, just return. + if (scim_load_file (local_icon, 0) != 0) + return local_icon; + + Transaction trans; + int cmd; + char *bufptr = 0; + size_t filesize = 0; + + local_icon = String (""); + + init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_LOAD_FILE); + trans.put_data (icon); + + // Load icon file from remote SocketFrontEnd. + if (send_transaction (trans) && receive_transaction (trans) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (&bufptr, filesize) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + + String tempfile; + String::size_type pos = icon.rfind (SCIM_PATH_DELIM); + + if (pos != String::npos) { + tempfile = icon.substr (pos + 1, String::npos); + } else { + tempfile = icon; + } + + char tmp [80]; + snprintf (tmp, 80, "%lu", (unsigned long) m_socket_magic_key); + + tempfile = String (SCIM_TEMPDIR) + String (SCIM_PATH_DELIM_STRING) + + String ("scim-") + String (tmp) + String ("-") + + tempfile; + + SCIM_DEBUG_IMENGINE(1) << "Creating temporary icon file: " << tempfile << "\n"; + + std::ofstream os (tempfile.c_str ()); + + if (os) { + os.write (bufptr, filesize); + os.close (); + + // Check if the file is written correctly. + if (scim_load_file (tempfile, 0) == filesize) { + m_icon_repository [icon] = tempfile; + local_icon = tempfile; + } else { + unlink (tempfile.c_str ()); + } + } + } + + delete [] bufptr; + + return local_icon; +} + +Connection +SocketIMEngineGlobal::connect_reconnect_signal (Slot0 *slot_reconnect) +{ + return m_signal_reconnect.connect (slot_reconnect); +} + +void +SocketIMEngineGlobal::destroy_all_icons () +{ + IconRepository::const_iterator it = m_icon_repository.begin (); + + for (; it != m_icon_repository.end (); ++ it) { + unlink (it->second.c_str ()); + } + + m_icon_repository.clear (); +} + +int +SocketFactory::create_peer_instance (const String &encoding) +{ + int cmd; + int si_peer_id = -1; + uint32 val; + Transaction trans; + + SCIM_DEBUG_IMENGINE(1) << "Create IMEngine Instance " << m_peer_uuid << ".\n"; + + global->init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_NEW_INSTANCE); + trans.put_data (m_peer_uuid); + trans.put_data (encoding); + if (global->send_transaction (trans)) { + if (global->receive_transaction (trans) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (val) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + + si_peer_id = (int) val; + } + } + + SCIM_DEBUG_IMENGINE(2) << " IMEngineInstance created (" << si_peer_id << ")\n"; + + return si_peer_id; +} + +SocketFactory::SocketFactory (const String &peer_uuid) + : m_name (utf8_mbstowcs (_("Unknown"))), + m_language (String ("")), + m_peer_uuid (peer_uuid), + m_icon_file (String ("")), + m_ok (false), + m_option (0) +{ + String locales; + String iconfile; + Transaction trans; + + SCIM_DEBUG_IMENGINE(1) << "Create SocketFactory " << peer_uuid << ".\n"; + + // Get factory name, locales, language and icon file. + std::map::iterator iter; + iter = ise_info_repository.find (m_peer_uuid); + if (iter != ise_info_repository.end ()) { + m_name = utf8_mbstowcs (iter->second.name); + set_locales (iter->second.locales); + m_language = iter->second.language; + //m_icon_file = global->load_icon (iter->second.icon); + m_ok = true; + m_option = iter->second.option; + } else { + m_language.clear (); + } +} + +SocketFactory::~SocketFactory () +{ +} + +WideString +SocketFactory::get_name () const +{ + return m_name; +} + +WideString +SocketFactory::get_authors () const +{ + int cmd; + WideString authors; + Transaction trans; + + SCIM_DEBUG_IMENGINE(1) << "Get Authors " << m_peer_uuid << ".\n"; + + // Get factory authors. + for (int retry = 0; retry < 3; ++retry) { + global->init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_FACTORY_AUTHORS); + trans.put_data (m_peer_uuid); + + if (global->send_transaction (trans) && global->receive_transaction (trans) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (authors) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + break; + + authors = utf8_mbstowcs (_("Unknown")); + + if (!global->create_connection ()) + break; + } + + return authors; +} + +WideString +SocketFactory::get_credits () const +{ + int cmd; + WideString credits; + Transaction trans; + + SCIM_DEBUG_IMENGINE(1) << "Get Credits " << m_peer_uuid << ".\n"; + + // Get factory credits. + for (int retry = 0; retry < 3; ++retry) { + global->init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_FACTORY_CREDITS); + trans.put_data (m_peer_uuid); + + if (global->send_transaction (trans) && global->receive_transaction (trans) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (credits) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + break; + + credits = utf8_mbstowcs (_("Unknown")); + + if (!global->create_connection ()) + break; + } + + return credits; +} + +WideString +SocketFactory::get_help () const +{ + int cmd; + WideString help; + Transaction trans; + + SCIM_DEBUG_IMENGINE(1) << "Get Help " << m_peer_uuid << ".\n"; + + // Get factory help. + for (int retry = 0; retry < 3; ++retry) { + global->init_transaction (trans); + trans.put_command (SCIM_TRANS_CMD_GET_FACTORY_HELP); + trans.put_data (m_peer_uuid); + + if (global->send_transaction (trans) && global->receive_transaction (trans) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + trans.get_data (help) && + trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) + break; + + help = utf8_mbstowcs (_("Unknown")); + + if (!global->create_connection ()) + break; + } + + return help; +} + +String +SocketFactory::get_uuid () const +{ + return m_peer_uuid; +} + +String +SocketFactory::get_icon_file () const +{ + return m_icon_file; +} + +String +SocketFactory::get_language () const +{ + if (m_language.length ()) + return m_language; + else + return IMEngineFactoryBase::get_language (); +} + +unsigned int +SocketFactory::get_option () const +{ + return m_option; +} + +IMEngineInstancePointer +SocketFactory::create_instance (const String& encoding, int id) +{ + int si_peer_id = create_peer_instance (encoding); + + SCIM_DEBUG_IMENGINE(2) << " IMEngineInstance created (" << si_peer_id << ")\n"; + + return new SocketInstance (this, encoding, id, si_peer_id); +} + +SocketInstance::SocketInstance (SocketFactory *factory, + const String& encoding, + int id, + int peer_id) + : IMEngineInstanceBase (factory, encoding, id), + m_factory (factory), + m_peer_id (peer_id) +{ + m_signal_reconnect_connection = global->connect_reconnect_signal (slot (this, &SocketInstance::reconnect_callback)); +} + +SocketInstance::~SocketInstance () +{ + Transaction trans; + + SCIM_DEBUG_IMENGINE(1) << "Destroy IMEngine Instance " << m_peer_id << ".\n"; + + m_signal_reconnect_connection.disconnect (); + + if (m_peer_id >= 0) { + global->init_transaction (trans); + + trans.put_command (SCIM_TRANS_CMD_DELETE_INSTANCE); + trans.put_data (m_peer_id); + + commit_transaction (trans); + } +} + +bool +SocketInstance::process_key_event (const KeyEvent& key) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "process_key_event (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_PROCESS_KEY_EVENT); + trans.put_data (m_peer_id); + trans.put_data (key); + + return commit_transaction (trans); +} + +void +SocketInstance::move_preedit_caret (unsigned int pos) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "move_preedit_caret (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_MOVE_PREEDIT_CARET); + trans.put_data (m_peer_id); + trans.put_data ((uint32) pos); + + commit_transaction (trans); +} + +void +SocketInstance::select_aux (unsigned int item) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "select_aux (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_SELECT_AUX); + trans.put_data (m_peer_id); + trans.put_data ((uint32) item); + + commit_transaction (trans); +} + +void +SocketInstance::select_candidate (unsigned int item) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "select_candidate (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_SELECT_CANDIDATE); + trans.put_data (m_peer_id); + trans.put_data ((uint32) item); + + commit_transaction (trans); +} + +void +SocketInstance::update_lookup_table_page_size (unsigned int page_size) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "update_lookup_table_page_size (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE); + trans.put_data (m_peer_id); + trans.put_data ((uint32) page_size); + + commit_transaction (trans); +} + +void +SocketInstance::lookup_table_page_up () +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "lookup_table_page_up (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::lookup_table_page_down () +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "lookup_table_page_up (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::set_prediction_allow (bool allow) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__<< " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_SET_PREDICTION_ALLOW); + trans.put_data (m_peer_id); + trans.put_data ((uint32) allow); + + commit_transaction (trans); +} + +void +SocketInstance::set_layout (unsigned int layout) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__<< " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_SET_LAYOUT); + trans.put_data (m_peer_id); + trans.put_data (layout); + + commit_transaction (trans); +} + +void +SocketInstance::update_candidate_item_layout (const std::vector &row_items) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__ << " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT); + trans.put_data (m_peer_id); + trans.put_data (row_items); + + commit_transaction (trans); +} + +void +SocketInstance::update_cursor_position (unsigned int cursor_pos) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__ << " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_UPDATE_CURSOR_POSITION); + trans.put_data (m_peer_id); + trans.put_data (cursor_pos); + + commit_transaction (trans); +} + +void +SocketInstance::update_displayed_candidate_number (unsigned int number) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__ << " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE); + trans.put_data (m_peer_id); + trans.put_data (number); + + commit_transaction (trans); +} + +void +SocketInstance::candidate_more_window_show (void) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__ << " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::candidate_more_window_hide (void) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__ << " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::longpress_candidate (unsigned int index) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__ << " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_LONGPRESS_CANDIDATE); + trans.put_data (m_peer_id); + trans.put_data (index); + + commit_transaction (trans); +} + +void +SocketInstance::set_imdata (const char *data, unsigned int len) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << __func__ << " (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_SET_ISE_IMDATA); + trans.put_data (m_peer_id); + trans.put_data (data, len); + + commit_transaction (trans); +} + +void +SocketInstance::reset_option () +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "reset_option (" << m_peer_id << ")\n"; + + trans.put_command (ISM_TRANS_CMD_RESET_ISE_OPTION); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::reset () +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "reset (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_RESET); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::focus_in () +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "focus_in (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_FOCUS_IN); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::focus_out () +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "focus_out (" << m_peer_id << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_FOCUS_OUT); + trans.put_data (m_peer_id); + + commit_transaction (trans); +} + +void +SocketInstance::trigger_property (const String &property) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "trigger_property (" << m_peer_id << ", " << property << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_TRIGGER_PROPERTY); + trans.put_data (m_peer_id); + trans.put_data (property); + + commit_transaction (trans); +} + +void +SocketInstance::process_helper_event (const String &helper_uuid, const Transaction &helper_trans) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "process_helper_event (" << m_peer_id << ", " << helper_uuid << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_PROCESS_HELPER_EVENT); + trans.put_data (m_peer_id); + trans.put_data (helper_uuid); + trans.put_data (helper_trans); + + commit_transaction (trans); +} + +void +SocketInstance::update_client_capabilities (unsigned int cap) +{ + Transaction trans; + + global->init_transaction (trans); + + SCIM_DEBUG_IMENGINE(1) << "update_client_capabilities (" << m_peer_id << ", " << cap << ")\n"; + + trans.put_command (SCIM_TRANS_CMD_UPDATE_CLIENT_CAPABILITIES); + trans.put_data (m_peer_id); + trans.put_data ((uint32) cap); + + commit_transaction (trans); +} + +bool +SocketInstance::commit_transaction (Transaction &trans) +{ + SCIM_DEBUG_IMENGINE(2) << " commit_transaction:\n"; + + bool ret = false; + + if (m_peer_id >= 0) { + if (global->send_transaction (trans)) { + while (1) { + if (!global->receive_transaction (trans)) break; + if (!do_transaction (trans, ret)) return ret; + } + } + } + + if (global->create_connection ()) + reset (); + + return ret; +} + +bool +SocketInstance::do_transaction (Transaction &trans, bool &ret) +{ + int cmd = -1; + bool cont = false; + + ret = false; + + SCIM_DEBUG_IMENGINE(2) << " Do transaction:\n"; + + if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY) { + while (trans.get_command (cmd)) { + switch (cmd) { + case SCIM_TRANS_CMD_SHOW_PREEDIT_STRING: + { + SCIM_DEBUG_IMENGINE(3) << " show_preedit_string ()\n"; + show_preedit_string (); + break; + } + case SCIM_TRANS_CMD_SHOW_AUX_STRING: + { + SCIM_DEBUG_IMENGINE(3) << " show_aux_string ()\n"; + show_aux_string (); + break; + } + case SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE: + { + SCIM_DEBUG_IMENGINE(3) << " show_lookup_table ()\n"; + show_lookup_table (); + break; + } + case SCIM_TRANS_CMD_HIDE_PREEDIT_STRING: + { + SCIM_DEBUG_IMENGINE(3) << " hide_preedit_string ()\n"; + hide_preedit_string (); + break; + } + case SCIM_TRANS_CMD_HIDE_AUX_STRING: + { + SCIM_DEBUG_IMENGINE(3) << " hide_aux_string ()\n"; + hide_aux_string (); + break; + } + case SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE: + { + SCIM_DEBUG_IMENGINE(3) << " hide_lookup_table ()\n"; + hide_lookup_table (); + break; + } + case SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET: + { + uint32 caret; + if (trans.get_data (caret)) { + SCIM_DEBUG_IMENGINE(3) << " update_preedit_caret (" << caret << ")\n"; + update_preedit_caret (caret); + } + break; + } + case SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING: + { + WideString str; + AttributeList attrs; + if (trans.get_data (str) && trans.get_data (attrs)) { + SCIM_DEBUG_IMENGINE(3) << " update_preedit_string ()\n"; + update_preedit_string (str, attrs); + } + break; + } + case SCIM_TRANS_CMD_UPDATE_AUX_STRING: + { + WideString str; + AttributeList attrs; + if (trans.get_data (str) && trans.get_data (attrs)) { + SCIM_DEBUG_IMENGINE(3) << " update_aux_string ()\n"; + update_aux_string (str, attrs); + } + break; + } + case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE: + { + CommonLookupTable table; + if (trans.get_data (table)) { + SCIM_DEBUG_IMENGINE(3) << " update_lookup_table ()\n"; + update_lookup_table (table); + } + break; + } + case SCIM_TRANS_CMD_COMMIT_STRING: + { + WideString str; + if (trans.get_data (str)) { + SCIM_DEBUG_IMENGINE(3) << " commit_string ()\n"; + commit_string (str); + } + break; + } + case SCIM_TRANS_CMD_FORWARD_KEY_EVENT: + { + KeyEvent key; + if (trans.get_data (key)) { + SCIM_DEBUG_IMENGINE(3) << " forward_key_event ()\n"; + forward_key_event (key); + } + break; + } + case SCIM_TRANS_CMD_REGISTER_PROPERTIES: + { + PropertyList proplist; + if (trans.get_data (proplist)) { + SCIM_DEBUG_IMENGINE(3) << " register_properties ()\n"; + + // Load icon files of these properties from remote SocketFrontEnd. + for (PropertyList::iterator it = proplist.begin (); it != proplist.end (); ++it) + it->set_icon (global->load_icon (it->get_icon ())); + + register_properties (proplist); + } + break; + } + case SCIM_TRANS_CMD_UPDATE_PROPERTY: + { + Property prop; + if (trans.get_data (prop)) { + SCIM_DEBUG_IMENGINE(3) << " update_property ()\n"; + + // Load the icon file of this property from remote SocketFrontEnd. + prop.set_icon (global->load_icon (prop.get_icon ())); + + update_property (prop); + } + break; + } + case SCIM_TRANS_CMD_BEEP: + { + SCIM_DEBUG_IMENGINE(3) << " beep ()\n"; + beep (); + break; + } + case SCIM_TRANS_CMD_START_HELPER: + { + String helper_uuid; + if (trans.get_data (helper_uuid)) { + SCIM_DEBUG_IMENGINE(3) << " start_helper (" << helper_uuid << ")\n"; + start_helper (helper_uuid); + } + break; + } + case SCIM_TRANS_CMD_STOP_HELPER: + { + String helper_uuid; + if (trans.get_data (helper_uuid)) { + SCIM_DEBUG_IMENGINE(3) << " stop_helper (" << helper_uuid << ")\n"; + stop_helper (helper_uuid); + } + break; + } + case SCIM_TRANS_CMD_SEND_HELPER_EVENT: + { + String helper_uuid; + Transaction temp_trans; + if (trans.get_data (helper_uuid) && trans.get_data (temp_trans)) { + SCIM_DEBUG_IMENGINE(3) << " send_helper_event (" << helper_uuid << ")\n"; + send_helper_event (helper_uuid, temp_trans); + } + break; + } + case SCIM_TRANS_CMD_OK: + { + SCIM_DEBUG_IMENGINE(3) << " ret = true\n"; + ret = true; + break; + } + case SCIM_TRANS_CMD_GET_SURROUNDING_TEXT: + { + WideString text; + int cursor; + uint32 maxlen_before; + uint32 maxlen_after; + Transaction temp_trans; + if (trans.get_data (maxlen_before) && trans.get_data (maxlen_after)) { + global->init_transaction (temp_trans); + if (get_surrounding_text (text, cursor, (int) maxlen_before, (int) maxlen_after)) { + temp_trans.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT); + temp_trans.put_data (text); + temp_trans.put_data ((uint32) cursor); + } else { + temp_trans.put_command (SCIM_TRANS_CMD_FAIL); + } + if (!global->send_transaction (temp_trans)) + std::cerr << "GET_SURROUNDING_TEXT: global->send_transaction () is failed!!!\n"; + } + cont = true; + break; + } + case SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT: + { + uint32 offset; + uint32 len; + Transaction temp_trans; + if (trans.get_data (offset) && trans.get_data (len)) { + global->init_transaction (temp_trans); + if (delete_surrounding_text ((int) offset, (int) len)) { + temp_trans.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT); + temp_trans.put_command (SCIM_TRANS_CMD_OK); + } else { + temp_trans.put_command (SCIM_TRANS_CMD_FAIL); + } + if (!global->send_transaction (temp_trans)) + std::cerr << "DELETE_SURROUNDING_TEXT: global->send_transaction () is failed!!!\n"; + } + cont = true; + break; + } + case ISM_TRANS_CMD_EXPAND_CANDIDATE: + { + SCIM_DEBUG_IMENGINE(3) << " expand_candidate ()\n"; + expand_candidate (); + break; + } + case ISM_TRANS_CMD_CONTRACT_CANDIDATE: + { + SCIM_DEBUG_IMENGINE(3) << " contract_candidate ()\n"; + contract_candidate (); + break; + } + case ISM_TRANS_CMD_SET_CANDIDATE_UI: + { + SCIM_DEBUG_IMENGINE(3) << " set_candidate_style ()\n"; + uint32 portrait_line, mode; + if (trans.get_data (portrait_line) && trans.get_data (mode)) + set_candidate_style ((ISF_CANDIDATE_PORTRAIT_LINE_T)portrait_line, (ISF_CANDIDATE_MODE_T)mode); + break; + } + default: + SCIM_DEBUG_IMENGINE(3) << " Strange cmd: " << cmd << "\n"; + } + } + } else { + SCIM_DEBUG_IMENGINE(3) << " Failed to get cmd: " << cmd << "\n"; + } + + SCIM_DEBUG_IMENGINE(2) << " End of Do transaction\n"; + + return cont; +} + +void +SocketInstance::reconnect_callback (void) +{ + m_peer_id = m_factory->create_peer_instance (get_encoding ()); +} + +} // namespace scim + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/modules/imengine/scim_socket_imengine.h b/ism/modules/imengine/scim_socket_imengine.h new file mode 100644 index 0000000..b8e711a --- /dev/null +++ b/ism/modules/imengine/scim_socket_imengine.h @@ -0,0 +1,135 @@ +/** @file scim_socket_imengine.h + * definition of SocketFactory related classes. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Use ISE cache file + * 2. Add new interface APIs for keyboard ISE + * a. select_aux (), set_prediction_allow () and set_layout () + * b. update_candidate_item_layout (), update_cursor_position () and update_displayed_candidate_number () + * c. candidate_more_window_show (), candidate_more_window_hide () and longpress_candidate () + * d. set_imdata () and reset_option () + * 3. Add get_option () in SocketFactory + * + * $Id: scim_socket_imengine.h,v 1.13 2005/07/06 03:57:05 suzhe Exp $ + */ + +#if !defined (__SCIM_SOCKET_IMENGINE_H) +#define __SCIM_SOCKET_IMENGINE_H + +namespace scim { + +class SocketFactory; + +class SocketFactory : public IMEngineFactoryBase +{ + WideString m_name; + + String m_language; + + String m_peer_uuid; + + String m_icon_file; + + bool m_ok; + + unsigned int m_option; + + friend class SocketInstance; + +public: + SocketFactory (const String &peer_uuid); + + bool valid () const { return m_ok; } + + virtual ~SocketFactory (); + + virtual WideString get_name () const; + virtual WideString get_authors () const; + virtual WideString get_credits () const; + virtual WideString get_help () const; + virtual String get_uuid () const; + virtual String get_icon_file () const; + virtual String get_language () const; + virtual unsigned int get_option () const; + + virtual IMEngineInstancePointer create_instance (const String& encoding, int id = -1); + +private: + int create_peer_instance (const String &encoding); +}; + +class SocketInstance : public IMEngineInstanceBase +{ + SocketFactory *m_factory; + int m_peer_id; + Connection m_signal_reconnect_connection; + +public: + SocketInstance (SocketFactory *factory, const String& encoding, int id, int peer_id); + virtual ~SocketInstance (); + + virtual bool process_key_event (const KeyEvent& key); + virtual void move_preedit_caret (unsigned int pos); + virtual void select_aux (unsigned int item); + virtual void select_candidate (unsigned int item); + virtual void update_lookup_table_page_size (unsigned int page_size); + virtual void lookup_table_page_up (); + virtual void lookup_table_page_down (); + virtual void set_prediction_allow (bool allow); + virtual void set_layout (unsigned int layout); + virtual void reset_option (); + virtual void reset (); + virtual void focus_in (); + virtual void focus_out (); + virtual void trigger_property (const String &property); + virtual void process_helper_event (const String &helper_uuid, const Transaction &trans); + virtual void update_client_capabilities (unsigned int cap); + virtual void update_candidate_item_layout (const std::vector &row_items); + virtual void update_cursor_position (unsigned int cursor_pos); + virtual void update_displayed_candidate_number (unsigned int number); + virtual void candidate_more_window_show (void); + virtual void candidate_more_window_hide (void); + virtual void longpress_candidate (unsigned int index); + virtual void set_imdata (const char *data, unsigned int len); + +private: + bool commit_transaction (Transaction &trans); + bool do_transaction (Transaction &trans, bool &ret); + void reconnect_callback (void); +}; + +// Forward declaration +class SocketIMEngineGlobal; + +} // namespace scim + +#endif +/* +vi:ts=4:nowrap:ai:expandtab +*/ + diff --git a/ism/src/Makefile.am b/ism/src/Makefile.am new file mode 100644 index 0000000..f36da12 --- /dev/null +++ b/ism/src/Makefile.am @@ -0,0 +1,189 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +## Copyright (C) 2002 James Su +## +## 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +MAINTAINERCLEANFILES = Makefile.in scim_types.h +CLEANFILES = libltdlc.la libscim.la *.bak +DISTCLEANFILES = scim_types.h +EXTRA_DIST = libscim.version-script + +INCLUDES = -I$(top_builddir) \ + -I$(top_builddir)/ism/src \ + -I$(top_srcdir) \ + -I$(top_srcdir)/ism/src \ + -I$(top_srcdir)/ism/intl \ + -I$(includedir) \ + -DISF_VERSION=\"@ISF_VERSION@\" \ + -DSCIM_BINDIR=\"@SCIM_BINDIR@\" \ + -DSCIM_DATADIR=\"@SCIM_DATADIR@\" \ + -DSCIM_LOCALEDIR=\"@SCIM_LOCALEDIR@\" \ + -DSCIM_SYSCONFDIR=\"@SCIM_SYSCONFDIR@\" \ + -DSCIM_LIBEXECDIR=\"@SCIM_LIBEXECDIR@\" \ + -DSCIM_ICONDIR=\"@SCIM_ICONDIR@\" \ + -DSCIM_MODULE_PATH=\"@SCIM_MODULE_PATH@\" + + +noinst_HEADERS = ltdl.h \ + scim_private.h \ + scim_compose_key_data.h \ + scim_keyboard_layout_data.h \ + scim_keyevent_data.h \ + scim_stl_map.h \ + isf_query_utility.h + +libscimincludedir = $(includedir)/scim@SCIM_EPOCH@ + +libsciminclude_HEADERS = scim.h \ + scim_attribute.h \ + scim_backend.h \ + scim_bind.h \ + scim_compose_key.h \ + scim_config_base.h \ + scim_config_module.h \ + scim_config_path.h \ + scim_connection.h \ + scim_debug.h \ + scim_event.h \ + scim_exception.h \ + scim_filter.h \ + scim_filter_module.h \ + scim_filter_manager.h \ + scim_frontend.h \ + scim_frontend_module.h \ + scim_global_config.h \ + scim_helper.h \ + scim_helper_manager.h \ + scim_helper_module.h \ + scim_hotkey.h \ + scim_iconv.h \ + scim_imengine.h \ + scim_imengine_module.h \ + scim_lookup_table.h \ + scim_module.h \ + scim_object.h \ + scim_panel_agent.h \ + scim_panel_client.h \ + scim_panel_common.h \ + scim_pointer.h \ + scim_property.h \ + scim_signals.h \ + scim_slot.h \ + scim_socket.h \ + scim_trans_commands.h \ + scim_transaction.h \ + scim_types.h \ + scim_utility.h \ + isf_control.h \ + isf_imcontrol_client.h \ + ise_context.h + +noinst_LTLIBRARIES = libltdlc.la + +libltdlc_la_SOURCES = ltdl.cpp +libltdlc_la_LIBADD = $(LIBADD_DL) + +if SCIM_LD_VERSION_SCRIPT +LD_VERSION_SCRIPT_OPTION="-Wl,--version-script=$(srcdir)/libscim.version-script" +endif + +lib_LTLIBRARIES = libscim@SCIM_EPOCH@.la + +libscim@SCIM_EPOCH@_la_SOURCES = scim_backend.cpp \ + scim_chartraits.cpp \ + scim_compose_key.cpp \ + scim_config_base.cpp \ + scim_config_module.cpp \ + scim_connection.cpp \ + scim_debug.cpp \ + scim_event.cpp \ + scim_filter.cpp \ + scim_filter_module.cpp \ + scim_filter_manager.cpp \ + scim_frontend.cpp \ + scim_frontend_module.cpp \ + scim_global_config.cpp \ + scim_helper.cpp \ + scim_helper_manager.cpp \ + scim_helper_module.cpp \ + scim_hotkey.cpp \ + scim_iconv.cpp \ + scim_imengine.cpp \ + scim_imengine_module.cpp \ + scim_lookup_table.cpp \ + scim_module.cpp \ + scim_object.cpp \ + scim_panel_agent.cpp \ + scim_panel_client.cpp \ + scim_private.cpp \ + scim_signals.cpp \ + scim_slot.cpp \ + scim_socket.cpp \ + scim_transaction.cpp \ + scim_utility.cpp \ + isf_control.cpp \ + isf_imcontrol_client.cpp \ + isf_query_utility.cpp + +libscim@SCIM_EPOCH@_la_CXXFLAGS = @GTK2_CFLAGS@ @DLOG_CFLAGS@ + +libscim@SCIM_EPOCH@_la_LDFLAGS = -version-info $(SCIM_CURRENT):$(SCIM_REVISION):$(SCIM_AGE) \ + -export-dynamic \ + -rpath $(libdir) \ + $(LD_VERSION_SCRIPT_OPTION) \ + @DLOG_LIBS@ \ + @LIBTOOL_EXPORT_OPTIONS@ \ + @LIBICONV@ \ + @LTLIBINTL@ \ + -lstdc++ + +libscim@SCIM_EPOCH@_la_LIBADD = libltdlc.la + + +bin_PROGRAMS = scim isf-log isf-query-engines + +scim_SOURCES = scim.cpp +scim_LDADD = libscim@SCIM_EPOCH@.la +scim_LDFLAGS = @LTLIBINTL@ + +isf_log_SOURCES = isf_log.cpp +isf_log_LDADD = libscim@SCIM_EPOCH@.la +if SCIM_BUILD_GTK_UTILS +isf_log_CXXFLAGS = @GTK2_CFLAGS@ +isf_log_LDFLAGS = @LTLIBINTL@ -rpath $(libdir) -L@GTK_LIBDIR@ -lgtk-x11-2.0 -lgdk-x11-2.0 -lglib-2.0 -lgobject-2.0 +else +isf_log_LDFLAGS = @LTLIBINTL@ -rpath $(libdir) -lglib-2.0 -lgobject-2.0 +endif + +isf_query_engines_SOURCES = isf_query_engines.cpp +isf_query_engines_CXXFLAGS = @VCONF_CFLAGS@ @PRIVILEGE_CONTROL_CFLAGS@ +isf_query_engines_LDADD = libscim@SCIM_EPOCH@.la +isf_query_engines_LDFLAGS = @LTLIBINTL@ @VCONF_LIBS@ @PRIVILEGE_CONTROL_LIBS@ + +libexecdir = $(libdir)/scim@SCIM_EPOCH@ +libexec_PROGRAMS = scim-launcher scim-helper-launcher + +scim_launcher_SOURCES = scim_launcher.cpp +scim_launcher_LDADD = libscim@SCIM_EPOCH@.la +scim_launcher_CXXFLAGS = @PRIVILEGE_CONTROL_CFLAGS@ +scim_launcher_LDFLAGS = @LTLIBINTL@ @PRIVILEGE_CONTROL_LIBS@ + +scim_helper_launcher_SOURCES = scim_helper_launcher.cpp +scim_helper_launcher_CXXFLAGS = @PRIVILEGE_CONTROL_CFLAGS@ +scim_helper_launcher_LDADD = libscim@SCIM_EPOCH@.la +scim_helper_launcher_LDFLAGS = @LTLIBINTL@ @PRIVILEGE_CONTROL_LIBS@ + + + diff --git a/ism/src/TIZEN_ISF_PG.h b/ism/src/TIZEN_ISF_PG.h new file mode 100644 index 0000000..0270c10 --- /dev/null +++ b/ism/src/TIZEN_ISF_PG.h @@ -0,0 +1,1366 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +/** + * @ingroup TIZEN_PG + * @defgroup InputServiceFramework_PG InputServiceFW + * @{ + +

Introduction

+The Input Service Framework (ISF) is based on the open source project SCIM-1.4.7. The Input Service Framework is capable of supporting advanced input methods like full touch input, voice input, handwriting etc. + +

Purpose

+This document is aimed to describe how to develop application using TIZEN ISE (Input Service Engine) based on the ISF (Input Service Framework). The contents include: the introduction which is whole of the TIZEN ISE sample screen followed in GUI, the introduction of type and interface function of TIZEN ISE developing, and use from some sample application programs. + +

Scope

+The intention is that this document will provide a guide to enable the application programmer to be familiar with using TIZEN ISE as soon as possible. In this document it will only cover part of TIZEN ISE APIs, which are close to the development of ISF and other ISE. + +

Intended Readers

+This document is intended for the TIZEN ISE application programmer and the related project managers. (Actually, this document is focused on application developer who uses TIZEN ISE). + +

Abbreviations

+- ISF - Input Service Framework +- ISE - Input Service Engine + +

Abstract

+ISF is to monitor and handle all the input events and provide the input service to meet the requirement of applications. Then how does the application to get the input service of ISEs. For KeyboardISE and TouchISE, the interface is the ISF implementation of STKImControl. So the application programmer can easily program to the interface of STKImControl to get the service. +The application programmer who wants to use the traditional input service (like keyboard, soft-keyboard) does not need to change any code. +@} + +@defgroup ISF_Architecture Architecture +@ingroup InputServiceFramework_PG +@{ +

Architecture

+@image html TIZEN_ISF_PG_architecture.png +
Figure. UI Framework Architecture Diagram
+ +

UI Framework

+The UI framework is a middleware that consists of several modules like UI toolkit and Document-View framework (for building work-based application user interface), UI Contention manager (which implements various UI policies regarding screen state management), resource manager (which manages application and system resources), , font system, Flash engine (which takes care of 3D screens in applications), Input service framework, and windowing and graphics (including Vector, and raster graphics) system. + +@image html TIZEN_ISF_PG_isf_diagram.png +
Figure. UI Framework Architecture Diagram
+ +

ISF

+The Input Service Framework (ISF) is an abstraction layer with a well defined interface to allow text editor widgets to utilize the input methods. It is the responsibility of the widgets to request the assistance of the ISF, through the exported interface layer (Ecore IMF/GtkIM). + +The Input Service Framework (ISF) monitors and handles all the input events from kernel which means ISF should manage all kinds of input events and dispatch them. On the other hand, as a service provider, ISF provides the input service to fulfill the requirement of applications and users in platform, which means ISF is a container for loading Input Service Engine (ISE) to provide services. + +ISF consists of following components +-# ISF-IMF API Layer +-# ISM +-# Panel (UI) + +

ISM

+- Registration/Load/Unload/Running/Pause/Resume/Mutually exclusive for ISEs +- Interfaces among applications/ISE +- The program of ISM is highly modular. All ISEs are required to program according to specific interface and each ISE will be compiled into individual dynamic library and be placed into the predefine directory. So when ISE module run, ISF will search the predefine directory and dynamically load the ISE module. + +@image html TIZEN_ISF_PG_ism_ise_interaction_diagram.png +
Figure. ISM-ISE interaction Diagram
+ +

Panel (UI)

+- Provide the ISF control panel, enable the user configure ISF and ISE, providing the help information, providing the switch of active ISEs. +- Provide the visual feedback from the user, such as candidates, associated phrases. + +

ISE

+- Helper ISE is based on HelperAgent. HelperAgent is responsible for the communication between Helper ISE and ISF. +- Keyboard ISE is the traditional ISE, and it is running in ISM process. +@} + +@defgroup ISF_Use_Cases1 App Dev Guide for EFL +@brief Application Guide for EFL + +@defgroup ISF_Use_Cases1_1 How to show soft keyboard as soon as application is launched. +@ingroup ISF_Use_Cases1 +@{ +

How to show soft keyboard as soon as application is launched.

+Call elm_object_focus_set() API to let entry have a focus. +@code +void create_entry(struct appdata *ad) +{ + ad->eb = elm_entry_add(ad->eb_layout); + elm_object_part_content_set(ad->eb_layout, "btn_text", ad->eb); + + // Set the layout of soft keyboard when entry has a focus or is clicked. + elm_entry_input_panel_layout_set(ad->eb, ELM_INPUT_PANEL_LAYOUT_URL); + elm_object_focus_set(ad->eb, EINA_TRUE); //give focus to the entry and then soft keyboard will be shown automatically +} +@endcode +@} +@defgroup ISF_Use_Cases1_2 Example of Applications to be hidden soft keyboard +@ingroup ISF_Use_Cases1 +@{ + +

Example of Applications that must avoid showing soft keyboard even though entry has a focus or is clicked

+To avoid showing soft keyboard automatically, use elm_entry_input_panel_enabled_set(Evas_Object *obj, Eina_Bool enabled) API. +@code +Evas_Object *eo; + +eo = elm_entry_add(ad->win_main); + +//avoid showing soft keyboard automatically +elm_entry_input_panel_enabled_set(eo, EINA_FALSE); +@endcode +@} +@defgroup ISF_Use_Cases1_3 How to show soft keyboard manually +@ingroup ISF_Use_Cases1 +@{ + +

How to show the current active soft keyboard manually

+ + + + +
+ Note: If you use elm_entry widget, you don't need to call this API.
+ Please give a focus to entry widget using elm_object_focus_set() if you want to show a soft keyboard. +
+@code +static void entry_application(struct appdata *ad) +{ + Evas_Object *en; + Ecore_IMF_Context *imf_context = NULL; + + en = elm_entry_add(ad->win_main); + imf_context = elm_entry_imf_context_get(en); + ecore_imf_context_input_panel_show(imf_context); +} +@endcode +@} +@defgroup ISF_Use_Cases1_4 How to hide soft keyboard manually +@ingroup ISF_Use_Cases1 +@{ + +

How to hide the current active soft keyboard manually

+ + + + +
+ Note: If you use elm_entry widget, you don't need to call this API.
+ Soft keyboard will be hidden when entry widget loses a focus. +
+@code +static void entry_application(struct appdata * ad) +{ + Evas_Object *bt; + bt = elm_button_add(ad->win_main); + evas_object_smart_callback_add(bt, "clicked", button_cb, ad); +} + +static void button_cb(void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + Ecore_IMF_Context *imf_context = NULL; + imf_context = elm_entry_imf_context_get(ad->entry); + + if (imf_context) + ecore_imf_context_input_panel_hide(imf_context); +} +@endcode +@} +@defgroup ISF_Use_Cases1_5 How to set ISE Specific data +@ingroup ISF_Use_Cases1 +@{ + +

How to set ISE Specific data before show ISE

+Use ecore_imf_context_input_panel_imdata_set() API when application wants to deliver specific data to ISE.
+In this case, application and ISE negotiate the data format. +@code +#include + +void create_entry(struct appdata *ad) +{ + char *im_data = "application sample imdata"; + Ecore_IMF_Context *imf_context = NULL; + ad->entry = elm_entry_add(ad->layout_main); + imf_context = elm_entry_imf_context_get(ad->entry); + + if (imf_context) + { + ecore_imf_context_input_panel_imdata_set(imf_context, im_data, strlen(im_data)+1); + } +} +@endcode +@} +@defgroup ISF_Use_Cases1_6 How to get ISE specific data +@ingroup ISF_Use_Cases1 +@{ + +

How to get ISE specific data of current active ISE.

+@code +#include + +void get_imdata(struct appdata *ad) +{ + int len = 256; + char *im_data = (char*) malloc(len); + Ecore_IMF_Context *imf_context = NULL; + imf_context = elm_entry_imf_context_get(ad->entry); + if (imf_context) + ecore_imf_context_input_panel_imdata_get(imf_context, im_data, &len); + + free(im_data); +} +@endcode +@} +@defgroup ISF_Use_Cases1_7 How to detect whether soft keyboard is shown or hidden +@ingroup ISF_Use_Cases1 +@{ + +

Example code to detect whether soft keyboard is shown or hidden

+@code +void _input_panel_event_callback(void *data, Ecore_IMF_Context *imf_context, int value) +{ + int x, y, w, h; + if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) { + // ISE state has changed to INPUT_PANEL_STATE_SHOW status + // Get ISE position of current active ISE + ecore_imf_context_input_panel_geometry_get(imf_context, &x, &y, &w, &h); + printf("keypad is shown\n"); + printf("The coordination of input panel. x : %d, y : %d, w : %d, h : %d\n", x, y, w, h); + } else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + // ISE state has changed to INPUT_PANEL_STATE_HIDE status + printf("keypad is hidden\n"); + } +} + +static void create_entry(struct appdata *ad) +{ + Evas_Object *en; + Ecore_IMF_Context *imf_context = NULL; + en = elm_entry_add(ad->layout_main); + elm_object_part_content_set(ad->layout_main, "entry", en); + + imf_context = elm_entry_imf_context_get(en); + + if (imf_context) + { + ecore_imf_context_input_panel_event_callback_add(imf_context, ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, data); + } +} +@endcode +@} +@defgroup ISF_Use_Cases1_91 How to set the layout of soft keyboard ISE Layout +@ingroup ISF_Use_Cases1 +@{ + +

How to set the layout of soft keyboard

+The layouts that are currently supported by ISEs are
+ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL
+ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER (in qwerty mode)
+ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL (in qwerty mode)
+ECORE_IMF_INPUT_PANEL_LAYOUT_URL (in qwerty mode)
+ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER (in 4x4 modes)
+ECORE_IMF_INPUT_PANEL_LAYOUT_IP (including IPv4, IPv6)
+ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH (in 3x4 mode)
+ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY (in 3x4 mode)

+Sample code: Refer to the example of ecore_imf_context_input_panel_layout_set () API
+The snapshots of common layouts supported in Korean ISE are shown below + + + + + + + + + + + + + + +
NORMAL layoutNUMBER layoutEMAIL layoutURL layout
@image html TIZEN_ISF_PG_normal_layout.png@image html TIZEN_ISF_PG_number_layout.png@image html TIZEN_ISF_PG_email_layout.png@image html TIZEN_ISF_PG_url_layout.png
+ + + + + + + + + + + + + + +
PHONENUMBER layoutIP layoutMONTH layoutNUMBERONLY layout
@image html TIZEN_ISF_PG_phonenumber_layout.png@image html TIZEN_ISF_PG_ip_layout.png@image html TIZEN_ISF_PG_month_layout.png@image html TIZEN_ISF_PG_numberonly_layout.png
+@code +static void entry_application(struct appdata * ad) +{ + Evas_Object *en; + en = elm_entry_add(ad->win_main); + elm_entry_input_panel_layout_set(en, ELM_INPUT_PANEL_LAYOUT_URL); +} +@endcode +@} +@defgroup ISF_Use_Cases1_92 Get ISE Layout of current active ISE +@ingroup ISF_Use_Cases1 +@{ + +

Get ISE Layout of current active ISE

+@code +void get_layout(struct appdata *ad) +{ + Evas_Object *en; + Elm_Input_Panel_Layout layout ; + + en = elm_entry_add(ad->win_main); + elm_entry_input_panel_layout_set(en, ELM_INPUT_PANEL_LAYOUT_URL); + layout = elm_entry_input_panel_layout_get(en); + //here you can see what the current layout is + printf("the current layout is %d", layout); +} +@endcode +@} +@defgroup ISF_Use_Cases1_93 How to set the return key type of soft keyboard +@ingroup ISF_Use_Cases1 +@{ + +

How to set the return key type of soft keyboard

+The return key types that are currently supported by ISEs are
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH
+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND

+ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN

+Sample code: Refer to the example of ecore_imf_context_input_panel_return_key_type_set () API + + + + + + + + + + + + +
DEFAULT typeDONE typeGO type
@image html TIZEN_ISF_PG_return_default.png@image html TIZEN_ISF_PG_return_done.png@image html TIZEN_ISF_PG_return_go.png
+ + + + + + + + + + + + +
JOIN typeLOGIN typeNEXT type
@image html TIZEN_ISF_PG_return_join.png@image html TIZEN_ISF_PG_return_login.png@image html TIZEN_ISF_PG_return_next.png
+ + + + + + + + + + + + +
SEARCH typeSEND typeSIGNIN type
@image html TIZEN_ISF_PG_return_search.png@image html TIZEN_ISF_PG_return_send.png@image html TIZEN_ISF_PG_return_signin.png
+@code +static void entry_application(struct appdata * ad) +{ + Evas_Object *en; + en = elm_entry_add(ad->win_main); + + elm_entry_input_panel_return_key_type_set(en, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE); +} +@endcode +@} + +@defgroup ISF_Use_Cases1_94 How to register a callback for any change in ISE values +@ingroup ISF_Use_Cases1 +@{ + +

How to register a callback for any change in ISE values

+@code +void _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value) +{ + if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) { + // ISE state has changed to ECORE_IMF_INPUT_PANEL_STATE_SHOW status + } else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { + // ISE state has changed to ECORE_IMF_INPUT_PANEL_STATE_HIDE status + } + printf("value: %d\n", value); +} + +static void create_entry(struct appdata *ad) +{ + Evas_Object *en; + en = elm_entry_add(ad->layout_main); + elm_object_part_content_set(ad->layout_main, "entry", en); + + Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(en); // Get the input context in the entry + + if (imf_context) + { + ecore_imf_context_input_panel_event_callback_add(imf_context, ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, data); + } +} +@endcode +@} +@defgroup ISF_Use_Cases1_95 Unregister a callback for any change in ISE values +@ingroup ISF_Use_Cases1 +@{ + +

Unregister a callback for any change in ISE values.

+@code +static void deregister_callback(struct appdata *ad) +{ + Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(ad->entry); // Get the input context in the entry + + if (imf_context) + { + ecore_imf_context_input_panel_event_callback_del(imf_context, ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback); + } +} +@endcode +@} + +

Sample codes

+

Sample 1 - How application uses IMControl APIs (European ISE Launch)

+@code +static int init(struct appdata *ad) +{ + Evas_Object *en; + + en = elm_entry_add(ad->win_main); + elm_object_part_content_set(ad->layout_main, "entry", en); + elm_entry_input_panel_layout_set(en, ELM_INPUT_PANEL_LAYOUT_NUMBER); +} +@endcode +@} +@defgroup ISF_Use_Cases1_96 How Application gets ISE Input String +@ingroup ISF_Use_Cases1 +@{ + +

Sample 2 - How Application gets ISE Input String

+@code +static Eina_Bool _imf_event_commit_cb(void *data, int type, void *event) +{ + Ecore_IMF_Event_Commit *ev = event; + printf("input string from ISE is %s \n", ev->str); //here you get the Input String from ISE + + return ECORE_CALLBACK_PASS_ON; +} + +Ecore_IMF_Context *imf_context_create(Evas_Object *obj) +{ + Ecore_IMF_Context *imf_context = NULL; + const char *ctx_id = ecore_imf_context_default_id_get(); + Evas *evas = evas_object_evas_get(obj); + if (ctx_id) + { + imf_context = ecore_imf_context_add(ctx_id); + if (obj) + { + ecore_imf_context_client_window_set(imf_context, (void *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas))); + // the canvas information is used for supporting the auto rotation of input panel + ecore_imf_context_client_canvas_set(imf_context, evas); + } + } + + return imf_context; +} + +void test_ise_show(void *data, Evas_Object *obj, void *event_info) +{ + Ecore_IMF_Context *imf_context = NULL; + imf_context = imf_context_create(NULL); + if (imf_context) + { + ecore_imf_context_reset(imf_context); + ecore_imf_context_focus_in(imf_context); + ecore_imf_context_input_panel_show(imf_context); + } + + ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, NULL); + //please use ECORE_IMF_EVENT_PREEDIT_CHANGED if want preedit string + //ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, _imf_event_changed_cb, NULL); +} + +static void my_win_main(void) +{ + ... + elm_list_item_append(li, "ISE SHOW", NULL, NULL, test_ise_show, NULL); + ... +} +@endcode +@} +@defgroup ISF_Use_Cases1_97 How Application gets ISE-Specific Key Event +@ingroup ISF_Use_Cases1 +@{ + +

Sample 3 - How Application gets ISE-Specific Key Event

+@code +static Eina_Bool _imf_event_commit_cb(void *data, int type, void *event) +{ + Ecore_IMF_Event_Commit *ev = event; + printf("input string from ISE is %s \n", ev->str); //here you get the Input String from ISE + + return ECORE_CALLBACK_PASS_ON; +}; + +Ecore_IMF_Context *imf_context_create(Evas_Object *obj) +{ + Ecore_IMF_Context *imf_context = NULL; + const char *ctx_id = ecore_imf_context_default_id_get(); + Evas_Object *evas = evas_object_evas_get(obj); + + if (ctx_id) + { + imf_context = ecore_imf_context_add(ctx_id); + if (obj) + { + ecore_imf_context_client_window_set(imf_context, (void *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas))); + // the canvas information is used for supporting the auto rotation of input panel + ecore_imf_context_client_canvas_set(imf_context, evas_object_evas_get(obj)); + } + } + + return imf_context; +} + +void test_ise_show(void *data, Evas_Object *obj, void *event_info) +{ + Ecore_IMF_Context *imf_context = NULL; + imf_context = imf_context_create(NULL); + + if (imf_context) + { + ecore_imf_context_reset(imf_context); + ecore_imf_context_focus_in(imf_context); + ecore_imf_context_input_panel_show(imf_context); + } + ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, NULL); + //please use ECORE_IMF_EVENT_PREEDIT_CHANGED if want preedit string + //ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, _imf_event_changed_cb, NULL); +} + +static void my_win_main(void) +{ + ... + elm_list_item_append(li, "ISE SHOW", NULL, NULL, test_ise_show, NULL); + ... +} +@endcode +@code +static void +_edje_key_down_cb(void *data, Evas *e , Evas_Object *obj, void *event_info) +{ + Evas_Event_Key_Down *ev = event_info; + //if (!strcmp(ev->key, "BackSpace")) + printf("Key Event from ISE is %s \n", ev->key); //here you can get the Key Event from ISE +} + +Ecore_IMF_Context *imf_context_create(Evas_Object *obj) +{ + Ecore_IMF_Context *imf_context = NULL; + const char *ctx_id = ecore_imf_context_default_id_get(); + Evas *evas = evas_object_evas_get(obj); + + if (ctx_id) + { + imf_context = ecore_imf_context_add(ctx_id); + if (obj) + { + ecore_imf_context_client_window_set(imf_context, (void *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas))); + // the canvas information is used for supporting the auto rotation of input panel + ecore_imf_context_client_canvas_set(imf_context, evas); + } + } + + return imf_context; +} + +void test_ise_show(void *data, Evas_Object *obj, void *event_info) +{ + Ecore_IMF_Context *imf_context = NULL; + + imf_context = imf_context_create(obj); + //printf("imf_context = %d\n", imf_context); + + if (imf_context) + ecore_imf_context_input_panel_show(imf_context); + + evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb, NULL); + evas_object_focus_set(obj, EINA_TRUE); +} + +static void my_win_main(void) +{ + ... + elm_list_item_append(li, "ISE SHOW", NULL, NULL, test_ise_show, NULL); + ... +} +@endcode +@} +@defgroup ISF_Use_Cases1_98 How to get key event +@ingroup ISF_Use_Cases1 +@{ + +

Sample 4 - How to get key event

+- How to get key event and identify entry + -# Register the event EVAS_CALLBACK_KEY_UP callback function for each entry which needs to process key up event. + @code +evas_object_event_callback_add(_entry1, EVAS_CALLBACK_KEY_UP, _evas_key_up_cb, (void *)NULL); + @endcode + -# Make callback function like below to identify which entry received key event + @code +static void +_evas_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + static char str [100]; + Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info; + + if (obj == _entry1) + sprintf (str, "entry 1 get keyEvent: %s", ev->keyname); + else if (obj == _entry2) + sprintf (str, "entry 2 get keyEvent: %s", ev->keyname); + else + sprintf (str, ""); + + elm_object_text_set(_key_event_label, str); +} + @endcode + +- How to use Ecore event handlers + -# The ECORE_IMF_EVENT_PREEDIT_CHANGED and ECORE_IMF_EVENT_COMMIT are not bound to object. However ISF always sends the preedit string and commit string to the focused entry. So in the callback functions for the two events, we can determine which entry receives the preedit string and commit string by checking which entry gets the focus. The function to determine which widget gets the focus is elm_object_focus_get(). + -# For preedit string, we need call ecore_imf_context_preedit_string_get() to get the preedit string in its callback function. + -# For commit string, the third parameter ev of _ecore_imf_event_commit_cb contain the commit string. + +- How to get pre-edit string and identify entry + -# Register the event ECORE_IMF_EVENT_PREEDIT_CHANGED callback function for each entry which needs to process pre-edit. + @code +ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, _ecore_imf_event_changed_cb, NULL); + @endcode + -# Make callback function like below + @code +static Eina_Bool _ecore_imf_event_changed_cb(void *data, int type, void *event) +{ + static char str [100]; + char *preedit_string; + int len; + Ecore_IMF_Context *imf_context = NULL; + + if (elm_object_focus_get(_entry1)) + { + imf_context = elm_entry_imf_context_get(_entry1); + ecore_imf_context_preedit_string_get(imf_context, &preedit_string, &len); + + sprintf(str, "entry 1 get preedit string: %s", preedit_string); + } + else if (elm_object_focus_get(_entry2)) + { + imf_context = elm_entry_imf_context_get(_entry2); + ecore_imf_context_preedit_string_get(imf_context, &preedit_string, &len); + + sprintf(str, "entry 1 get preedit string: %s", preedit_string); + } + else + sprintf(str, ""); + + free(preedit_string); + + elm_object_text_set(_preedit_event_label,str); + + return ECORE_CALLBACK_PASS_ON; +} + @endcode + +- How to get commit string and identify entry + -# Register the event ECORE_IMF_EVENT_COMMIT callback function for each entry which needs to process pre-edit. + @code +ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _ecore_imf_event_commit_cb, NULL); + @endcode + -# Make callback function like below + @code +static Eina_Bool _ecore_imf_event_commit_cb(void *data, int type, void *event) +{ + static char str [100]; + Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event; + + if (elm_object_focus_get(_entry1)) + sprintf(str, "entry 1 get commit string: %s", ev->str); + else if (elm_object_focus_get(_entry2)) + sprintf (str, "entry 2 get commit string: %s", ev->str); + else + sprintf (str, ""); + + elm_object_text_set(_commit_event_label,str); + + return ECORE_CALLBACK_PASS_ON; +} + @endcode +- How to use Ecore event handlers + -# The ECORE_IMF_EVENT_PREEDIT_CHANGED and ECORE_IMF_EVENT_COMMIT are not bound to object. But ISF always send the preedit string and commit string to the focused entry. So in the callback functions for the two events, we can determine which entry receive the preedit string and commit string by checking which entry get the focus. The function to determine which widget gets the focus is elm_object_focus_get(). + -# For preedit string, we need call ecore_imf_context_preedit_string_get() to get the preedit string in its callback function. After getting preedit_string, you should deallocate memory by using free(). + -# For commit string, the third parameter ev of _ecore_imf_event_commit_cb contain the commit string. + +- Example - In case the application does not use an Entry + -# We use elm_label as the sample for showing how to get the key event, commit string and preedit string in case the application does not use an entry. Most part is similar to the application using entry except the following b) and c). + -# Creating an imcontext instance. +@code +Evas_Object *label; + +...... +static Eina_Bool _ecore_imf_event_changed_cb(void *data, int type, void *event) +{ + //example how to get preedit string + static char str [100]; + char *preedit_string; + int len; + Ecore_IMF_Context * imf_context = (Ecore_IMF_Context *)data; + + ecore_imf_context_preedit_string_get(imf_context, &preedit_string, &len); + sprint(str, "preedit string : %s\n", preedit_string); + + elm_object_text_set(label, str); + free(preedit_string); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool _ecore_imf_event_commit_cb(void *data, int type, void *event) +{ + //example how to get commit string + Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event; + + sprint(str, "commit string : %s\n", ev->str); + elm_object_text_set(label, ev->str); + + return ECORE_CALLBACK_PASS_ON; +} + +void +isf_label_event_demo_bt(void *data, Evas_Object *obj, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + Ecore_IMF_Context * _imf_context; + Evas *evas = evas_object_evas_get(obj); + + if (ad == NULL) return; + + label = elm_label_add(ad->win_main); + + const char *ctx_id = ecore_imf_context_default_id_get(); + _imf_context = ecore_imf_context_add(ctx_id); + + ecore_imf_context_client_window_set(imf_context, (void *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas))); + // the canvas information is used for supporting the auto rotation of input panel + ecore_imf_context_client_canvas_set(imf_context, evas); + + ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _ecore_imf_event_commit_cb, _imf_context); + ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, _ecore_imf_event_changed_cb, _imf_context); +} +@endcode +@} + +@defgroup ISF_Use_Cases3 ISE Dev Guide +@ingroup ISF_Use_Cases +@{ +

ISE Development Guide

+

Purpose

+This document aimed at ISE (Input Service Engine) developers to make their own keyboard (i.e. ISE) quickly, with using of ISF (Input Service Framework) in TIZEN. +The contents include: +- Making ISE step by step +- How to install ISE on target +- An example +- Other you may be interested + +

Let's get started

+ISF in TIZEN is designed to support a variety of ISEs, including soft keyboard, hand-writing recognizers, and hard keyboard. In this document our focus will be on soft keyboards, since this is most often developing ISE in support TIZEN text input. For more detail about other ISE types, you can refer to "ISF User Manual" for getting more information. +With ISE of soft keyboard, the life-cycle of input flow looks like below: + +@image html TIZEN_ISF_PG_lifecycle_of_input_flow.png +
Figure. Life Cycle of Input Flow
+@} + +@defgroup ISF_Use_Cases3_1 Step1 : Define and Include +@ingroup ISF_Use_Cases3 +@{ + +

For generating a new ISE with soft keyboard, let's follow 6 steps to make it.

+

Step 1 : Define and Include

+@code +#define Uses_SCIM_HELPER +#define Uses_SCIM_CONFIG_BASE +#include +using namespace scim; + +#define YOUR_ISE_UUID "ff119040-4062-b8f0-9ff6-3575c0a84f4f" +#define YOUR_ISE_NAME "Your ISE Name" +#define YOUR_ISE_ICON (SCIM_ICONDIR "/your_ise_icon.png") +#define YOUR_ISE_DESCRIPTION "Your ISE Description" +@endcode +Here, HELPER mainly means ISEs with using touch screen device. +@} + +@defgroup ISF_Use_Cases3_2 Step2 : Implement 2 objects +@ingroup ISF_Use_Cases3 +@{ + +

Step 2 : Implement 2 objects

+@code +static HelperInfo helper_info (YOUR_ISE_UUID, + YOUR_ISE_NAME, + String (YOUR_ISE_ICON), + YOUR_ISE_DESCRIPTION, + SCIM_HELPER_STAND_ALONE|SCIM_HELPER_AUTO_RESTART); +@endcode + +Structure helper_info collects basic information of your ISE. UUID is the unique ID for your ISE, also the NAME and ICON. + +The most often using helper_info options: + + + + +
OptionDescription
SCIM_HELPER_STAND_ALONEcompulsory option
SCIM_HELPER_AUTO_RESTARTOption indicates ISE will be restarted when it exits abnormally. We strongly recommend you use this option only in your release version, for not hiding abnormal cases.
+ +@code +HelperAgent _helper_agent; +@endcode + +Class HelperAgent is an accessory class to write a Helper object. This class implements all Socket transaction protocol between Helper object and Panel. Helper objects and Panel communicate with each other via the Socket created by Panel. Helper object could use command and signal through Panel Socket to do some operations with Application, Hard Keyboard ISE and Configure Module. + +About detailed description of HelperAgent, please refer to "ISF User Manual", and the most often using methods of HelperAgent object are listed here. +@} + +@defgroup ISF_Use_Cases3_3 Step3 : Implement 6 interfaces +@ingroup ISF_Use_Cases3 +@{ + +

Step 3 : Implement 6 interfaces

+First of all, you need implement scim_module_init and scim_module_exit, for your ISE will be a module loaded by ISF. +scim_module_init will be called by ISF when the ISE module is loaded. You can do your general module initialization work in it. + +scim_module_exit will be called by ISF when the ISE module is unloaded. You can do the general module cleaning work in it. +@code +void scim_module_init(void) +{ + bindtextdomain(GETTEXT_PACKAGE, SCIM_INPUT_PAD_LOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + ... + Do your initializing work here + ... +} + +void scim_module_exit(void) +{ + ... + Do your finalizing work here + ... +} +@endcode + +Then you will implement the information collection interfaces for your Helper. +scim_helper_module_number_of_helpers gets the number of Helpers in this module. Because a Helper module can have multiple Helpers in it, and each Helper should run in its own process space. +scim_helper_module_get_helper_info gets the basic information of a Helper. +scim_helper_module_get_helper_language gets supported language for the specific Helper ISE. + +@code +unsigned int scim_helper_module_number_of_helpers(void) +{ + return 1; //1 for common use +} + +bool scim_helper_module_get_helper_info(unsigned int idx, HelperInfo &info) +{ + if (idx == 0) + { + info = _helper_info; + return true; + } + return false; +} + +String scim_helper_module_get_helper_language(unsigned int idx) +{ + if (idx == 0) + { + String strLanguage("en,de_DE,fr_FR,es,pt,it_IT,nl_NL,ar,ru_RU"); + return strLanguage; + } + return "other"; +} +@endcode + +Then, you need implement scim_helper_module_run_helper. + +This interface is the last but the most important one, because most of your real implementation of your ISE will be here. + +@code +void scim_helper_module_run_helper(const String &uuid, const ConfigPointer &config, const String &display) +{ + _config = config; + if (uuid == YOUR_ISE_UUID) + { + ... + Read your configure here + ... + run(display); + } +} +@endcode + +@code +void run(const String &display) +{ + char **argv = new char * [4]; + int argc = 3; + argv [0] = const_cast ("input-pad"); + argv [1] = const_cast ("--display"); + argv [2] = const_cast (display.c_str ()); + argv [3] = 0; + setenv("DISPLAY", display.c_str(), 1); + + elm_init(argc, argv); + + _helper_agent.signal_connect_exit(slot(slot_exit)); + ... + Do your signal connection work here + ... + + int id, fd; + id = _helper_agent.open_connection(_helper_info, display); + if (id == -1) + { + std::cerr << " open_connection failed!!!!!!\n"; + goto ise_exit; + } + + fd = _helper_agent.get_connection_number(); + if (fd >= 0) + { + _read_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, helper_agent_input_handler, NULL, NULL, NULL); + } + + elm_run(); + elm_shutdown(); + +ise_exit: + if (argv) + delete []argv; + +} +@endcode + +In scim_helper_module_run_helper, you should implement a set of signal connection for combination the signal with your real implemented functions (slots), which we'll describe in step 4. +@} + +@defgroup ISF_Use_Cases3_4 Step4 : Implement main signal/slots +@ingroup ISF_Use_Cases3 +@{ + +

Step 4 : Implement main signal/slots

+ +- Introduction of signal/slot +ISF adopts Signal/Slot to implement some callback function mechanism. It defines one-to-many relationship between a signal object and any number of slot objects, so that when the signal is emitted, all its slots will be called automatically. +The class diagram of Signal/Slot shown like this: + +@image html TIZEN_ISF_PG_slot_and_signal.png + +SignalN +- Knows the prototype of its slots +- Can hold any number of slots +- Provide a interface to attach slot object at run time +SlotN +- Provides a call interface to let signal object call. +FunctionSlotN +- Derived from SlotN +- Implement the call operation. + +- Implementation of signal/slot +ISE can receive many signals from ISF by HelperAgent, and you should implement those slot functions for concerned signals, then call signal connection function to connect those slots functions. About all slot functions interface and parameters, please reference to scim_helper.h and Input-pad ISE demo. Normally below slot functions should be implemented.

+_helper_agent.signal_connect_exit(slot(slot_exit));
+_helper_agent.signal_connect_focus_out(slot(slot_focus_out));
+_helper_agent.signal_connect_focus_in(slot(slot_focus_in));
+_helper_agent.signal_connect_reload_config(slot(slot_reload_config));
+ +The mapping of EFLIMFControl APIs and HelperAgent signals: + + + + + + + + + + + + + + + + + + + + + + + + + + +
EFLIMFControl APISignal
ecore_imf_context_input_panel_showsignal_ise_show
ecore_imf_context_input_panel_hidesignal_ise_hide
ecore_imf_context_input_panel_imdata_setsignal_set_imdata
ecore_imf_context_input_panel_imdata_getsignal_get_imdata
ecore_imf_context_input_panel_layout_setsignal_set_layout
ecore_imf_context_input_panel_layout_getsignal_get_layout
ecore_imf_context_input_panel_geometry_getsignal_get_size
+@} + +@defgroup ISF_Use_Cases3_5 Step5 : Interacting with window manager +@ingroup ISF_Use_Cases3 +@{ + +

Step 5 : Interacting with window manager

+In TIZEN, window manager should treat soft keyboard window differently from other normal application windows. When an ISE creates its soft keyboard window, it should notify the window manager that the created window's type is a soft keyboard type, by calling following function. + +@code +elm_win_keyboard_win_set(main_window, EINA_TRUE); +@endcode + +And when an application rotates its window, the window manager sends a X Client Message to a soft keyboard to let it know the state change of target application window. To handle the X client message, the following handler function should be implemented inside ISE. +@code +static int _client_message_cb(void *data, int type, void *event) +{ + Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event; + int angle; + + if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE) { + angle = ev->data.l[0]; + ... + Do your keyboard rotation work here + ... + } + + return ECORE_CALLBACK_RENEW; +} +@endcode + +And the handler function should be registered as a handler function to ECORE_X_EVENT_CLIENT_MESSAGE when initializing, as shown below. + +@code +Ecore_Event_Handler *handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _client_message_cb, NULL); +@endcode +@} + +@defgroup ISF_Use_Cases3_6 Step6 : How to install ISE on target +@ingroup ISF_Use_Cases3 +@{ + +

Step 6 : How to install ISE on target

+To integrate an ISE into ISF, you should build ISE module as a dynamic library and install it into the predefined directory \$(TOP_INSTALL_DIR)/lib/scim-1.0/1.4.0/\$(ISE_TYPE)/. Then ISF will search the predefined directory to find the ISE module.
+The TOP_INSTALL_DIR is the top-level ISF installation directory. By default its value is "/usr".
+The ISE_TYPE is "IMEngine" (KeyboardISE) or "Helper" (HelperISE). The ISE developer should select one value according to the ISE type.
+If the ISE has one setup UI module, this setup UI module should be installed into "\$(TOP_INSTALL_DIR)/lib/scim-1.0/1.4.0/SetupUI" directory.
+The setup UI module's name should be defined as ISE file name + "-imengine-setup.so".
+For example, Input-pad ISE file name is "input-pad.so", its setup UI module's name is "input-pad-imengine-setup.so". + +Below are the repository directories for three modules:
+- KeyboardISE
+\$(TOP_INSTALL_DIR)/lib/scim-1.0/1.4.0/IMEngine. +- HelperISE
+\$(TOP_INSTALL_DIR)/lib/scim-1.0/1.4.0/Helper +- ISE Setup Module
+\$(TOP_INSTALL_DIR)/lib/scim-1.0/1.4.0/SetupUI +@} + +@defgroup ISF_Ref References +@ingroup InputServiceFramework_PG +@{ + +

Demo for Softkeyboard ISE

+The HelperISE uses an object of accessory class HelperAgent to deal with all Socket Transaction between HelperISE objects and PanelAgent.
+It needs to implement the necessary slot functions and connect the slots to the corresponding signals if they want to accept the specific events. +@code +static HelperAgent helper_agent; +static HelperInfo helper_info( + String ("ff110940-b8f0-4062-9ff6-a84f4f3575c0"), + "Input Pad", + String (SCIM_INPUT_PAD_ICON), + "", + SCIM_HELPER_STAND_ALONE|SCIM_HELPER_NEED_SCREEN_INFO); + +void scim_module_init(void) +{ + bindtextdomain(GETTEXT_PACKAGE, SCIM_INPUT_PAD_LOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + + _helper_info.name = String (_("Input Pad")); + _helper_info.description = String (_("An On Screen Input Pad to input characters easily.")); +} + +void scim_module_exit(void) +{ +} + +unsigned int scim_helper_module_number_of_helpers(void) +{ + return 1; +} + +bool scim_helper_module_get_helper_info(unsigned int idx, HelperInfo &info) +{ + if (idx == 0) { + info = helper_info; + return true; + } + return false; +} + +String scim_helper_module_get_helper_language(unsigned int idx) +{ + if (idx == 0) + { + String + strLanguage ("en,de_DE,fr_FR,es,pt,tr_TR,el_GR,it_IT,nl_NL,ar,ru_RU," + "az_AZ,bn,bg_BG,ca_ES,cs_CZ,cy_GB,da_DK,et_EE," + "eu_ES,fi_FI,ga_IE,gl_ES,gu_IN,he_IL,hi_IN,hu_HU," + "is_IS,ka_GE,kk_KZ,km,kn_IN,lt_LT,lv_LV,mk_MK," + "ml_IN,mn_MN,Marathi,ms_MY,no_NO,pa_IN,pl_PL," + "ro_RO,si_LK,sk_SK,sl_SI,sq_AL,sr_CS,sv,ta_IN," + "te_IN,th_TH,uk_UA,ur_PK,z_UZ,vi_VN," + "zh_CN,zh_TW,zh_HK,zh_SG"); + + return strLanguage; + } + return "other"; +} + +void scim_helper_module_run_helper(const String &uuid, const ConfigPointer &config, const String &display) +{ + char **argv = new char * [4]; + int argc = 3; + + argv [0] = const_cast ("input-pad"); + argv [1] = const_cast ("--display"); + argv [2] = const_cast (display.c_str ()); + argv [3] = 0; + + setenv("DISPLAY", display.c_str(), 1); + + elm_init(argc, argv); + ...... + helper_agent.signal_connect_exit(slot(slot_exit)); + helper_agent.signal_connect_focus_out(slot(slot_focus_out)); + helper_agent.signal_connect_focus_in(slot(slot_focus_in)); + ...... + int id, fd; + id = _helper_agent.open_connection(_helper_info, display); + if (id == -1) + { + std::cerr << " open_connection failed!!!!!!\n"; + goto ise_exit; + } + + fd = _helper_agent.get_connection_number(); + if (fd >= 0) + { + _read_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, + helper_agent_input_handler, NULL, NULL, NULL); + //ecore_main_fd_handler_active_set(_read_handler, ECORE_FD_READ); + } + + create_ise_window(); + init_candidate_table_labels(); + ...... + _helper_agent.get_keyboard_ise_list(_helper_info.uuid); + _helper_agent.get_candidate_ui(_helper_info.uuid); + _helper_agent.get_candidate_window_rect(_helper_info.uuid); + _helper_agent.get_keyboard_ise(_helper_info.uuid); + + _helper_agent.set_candidate_position(-1, -1); + elm_run(); + elm_shutdown(); + +ise_exit: + if (argv) + delete []argv; + ...... +} +@endcode + +Here, we will use the skeleton of InputPad ISE as an example. InputPad is a software keyboard ISE. By studying the code segment example, you can see: +-# As mentioned in step 3, the HelperISE should at least implement the six interfaces "scim_module_init()", "scim_module_exit()", "scim_helper_module_number_of_helpers()", "scim_helper_module_get_helper_info()", "scim_helper_module_get_helper_language()" and "scim_helper_module_run_helper()" +-# How to send the result to the target input widget +HelperAgent class provides two member functions to do this job, helper_agent.commit_string() and helper_agent.send_key_event(). As indicated by the function name, commit_string() is to send a string to the target input widget while send_key_event() is to send a key event to the target input widget. + -# helper_agent.commit_string(-1, "", scim::utf8_mbstowcs(str)); + -# helper_agent.send_key_event(-1, "", key); +In InputPad, the first parameters of commit_string and send_key_event are assigned with -1 and "", then the result will be sent to the last focused widget. +-# How to receive the ISF events +Here, we adopt Signal/Slot to connect the callback functions (Slot) to the corresponding events (Signal). In InputPad, helper_agent.signal_connect_exit(), helper_agent.signal_connect_update_screen() etc will do the connection. Currently, the InputPad will emit the following signals: + -# signal_exit + -# signal_ise_show + -# signal_ise_hide + -# signal_get_size + -# signal_set_layout + -# signal_update_candidate_ui + -# signal_update_keyboard_ise + +Most often HelperAgent Methods + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodDescription
int open_connection(const HelperInfo &info, const String &display);Open socket connection to the Panel. +- Param info: The information of this Helper object. +- Param display: The display which this Helper object should run on. +Return the connection socket id. -1 means failed to create the connection +
void close_connection();Close the socket connection to Panel.
int get_connection_number() const;Get the connection id previously returned by open_connection().
bool is_connected() const;Return whether this HelperAgent has been connected to a Panel. +Return true if there are any events available. +
bool has_pending_event() const;Check if there are any events available to be processed. If it returns true then Helper object should call HelperAgent::filter_event() to process them.
bool filter_event();Process the pending events. This function will emit the corresponding signals according to the events. +Return false if the connection is broken, otherwise return true. +
void reload_config() const;Request ISF to reload all configurations. This function should only be used by Setup Helper to request ISF's reloading the configuration.
void send_imengine_event(int ic, const String &ic_uuid, const Transaction &trans) const;Send a set of events to a Hard Keyboard ISE Instance. All events should be put into a Transaction. And the events can only be received by one IMEngineInstance (Hard keyboard ISE) object. +- Param ic: The handle of the Input Context to receive the events. +- Param ic_uuid: The UUID of the Input Context. +- Param trans: The Transaction object holds the events. +
void send_key_event(int ic, const String &ic_uuid, const KeyEvent &key) const;Send a KeyEvent to an IMEngineInstance. +- Param ic: The handle of the IMEngineInstance to receive the event. -1 means the currently focused IMEngineInstance. +- Param ic_uuid: The UUID of the IMEngineInstance. Empty means don't match. +- Param key: The KeyEvent to be sent. +
void forward_key_event(int ic, const String &ic_uuid, const KeyEvent &key) const;Forward a KeyEvent to client application directly. +- Param ic: The handle of the IMEngineInstance to receive the event. -1 means the currently focused IMEngineInstance. +- Param ic_uuid: The UUID of the IMEngineInstance. Empty means don't match. +
void commit_string(int ic, const String &ic_uuid, const WideString &wstr) const;Commit a WideString to client application directly. +- Param ic: The handle of the client Input Context to receive the WideString. -1 means the currently focused Input Context. +- Param ic_uuid: The UUID of the IMEngine used by the Input Context. Empty means don't match. +- Param wstr: The WideString to be committed. +
void update_input_context(uint32 type, uint32 value) const;When the input context of ISE is changed, ISE can call this function to notify application. +- Param type: type of event. The type of event may differ in different project. It is an engagement between ISE and the applications. One example definition is ECORE_IMF_INPUT_PANEL_EVENT in Ecore_IMF.h in TIZEN project. +- Param value: value of event. +
void set_candidate_ui(const ISF_CANDIDATE_STYLE_T style, const ISF_CANDIDATE_MODE_T mode) const;Set the style and mode for candidate window. +- Param style: The candidate window style. +ISF_CANDIDATE_STYLE_T may differ in different project. Please refer the latest definition in scim_utility.h. +- Param mode: The candidate window mode. +ISF_CANDIDATE_MODE_T may differ in different project. Please refer the latest definition in scim_utility.h. +
void get_candidate_ui(const String &uuid) const;Send request to get the candidate window's style and mode.
void set_candidate_position(int left, int top) const;Set the position for candidate window. +- Param left: The candidate window's left position. +- Param top: The candidate window's top position. +- If both Params set <0, the candidate will be default set to cursor following mode. +
void candidate_hide(void) const;Send request to hide the candidate window, including Aux, Candidate and Associate area
void get_candidate_window_rect(const String &uuid) const;Send request to get the candidate window's size and position. +- Param uuid: The Helper ISE's uuid. +
void set_keyboard_ise_by_uuid(const String &uuid) const;Set the keyboard ISE by ISE's uuid. +- Param uuid: The keyboard ISE's uuid. +
void get_keyboard_ise(const String &uuid) const;Send request to get the current keyboard ISE. +- Param uuid: The Helper ISE's uuid. +
+@} +*/ + +/** +* @addtogroup InputServiceFramework_PG Input Service FW + @{ +* @defgroup ISF_Use_Cases Use Cases + @{ +* @defgroup ISF_Use_Cases1 +* @defgroup ISF_Use_Cases2 +* @defgroup ISF_Use_Cases3 + @brief For generating a new ISE with soft keyboard, let's follow 6 steps to make it. + @} + @} +*/ diff --git a/ism/src/image/TIZEN_ISF_PG_architecture.png b/ism/src/image/TIZEN_ISF_PG_architecture.png new file mode 100644 index 0000000..e301b81 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_architecture.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_email_layout.png b/ism/src/image/TIZEN_ISF_PG_email_layout.png new file mode 100644 index 0000000..c662636 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_email_layout.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_ip_layout.png b/ism/src/image/TIZEN_ISF_PG_ip_layout.png new file mode 100644 index 0000000..d9c5c71 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_ip_layout.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_isf_diagram.png b/ism/src/image/TIZEN_ISF_PG_isf_diagram.png new file mode 100644 index 0000000..f389c2d Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_isf_diagram.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_ism_ise_interaction_diagram.png b/ism/src/image/TIZEN_ISF_PG_ism_ise_interaction_diagram.png new file mode 100644 index 0000000..013ad0c Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_ism_ise_interaction_diagram.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_lifecycle_of_input_flow.png b/ism/src/image/TIZEN_ISF_PG_lifecycle_of_input_flow.png new file mode 100644 index 0000000..d3f6488 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_lifecycle_of_input_flow.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_month_layout.png b/ism/src/image/TIZEN_ISF_PG_month_layout.png new file mode 100644 index 0000000..b75ebdd Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_month_layout.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_normal_layout.png b/ism/src/image/TIZEN_ISF_PG_normal_layout.png new file mode 100644 index 0000000..36b196c Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_normal_layout.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_number_layout.png b/ism/src/image/TIZEN_ISF_PG_number_layout.png new file mode 100644 index 0000000..b298e3c Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_number_layout.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_numberonly_layout.png b/ism/src/image/TIZEN_ISF_PG_numberonly_layout.png new file mode 100644 index 0000000..ed13cdc Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_numberonly_layout.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_phonenumber_layout.png b/ism/src/image/TIZEN_ISF_PG_phonenumber_layout.png new file mode 100644 index 0000000..9037112 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_phonenumber_layout.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_default.png b/ism/src/image/TIZEN_ISF_PG_return_default.png new file mode 100644 index 0000000..7eb60a7 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_default.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_done.png b/ism/src/image/TIZEN_ISF_PG_return_done.png new file mode 100644 index 0000000..9870b5e Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_done.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_go.png b/ism/src/image/TIZEN_ISF_PG_return_go.png new file mode 100644 index 0000000..7f26916 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_go.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_join.png b/ism/src/image/TIZEN_ISF_PG_return_join.png new file mode 100644 index 0000000..934856c Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_join.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_login.png b/ism/src/image/TIZEN_ISF_PG_return_login.png new file mode 100644 index 0000000..faf8586 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_login.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_next.png b/ism/src/image/TIZEN_ISF_PG_return_next.png new file mode 100644 index 0000000..0448861 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_next.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_search.png b/ism/src/image/TIZEN_ISF_PG_return_search.png new file mode 100644 index 0000000..e1fe622 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_search.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_send.png b/ism/src/image/TIZEN_ISF_PG_return_send.png new file mode 100644 index 0000000..8e4bcfb Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_send.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_return_signin.png b/ism/src/image/TIZEN_ISF_PG_return_signin.png new file mode 100644 index 0000000..d43deb9 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_return_signin.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_slot_and_signal.png b/ism/src/image/TIZEN_ISF_PG_slot_and_signal.png new file mode 100644 index 0000000..f95058e Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_slot_and_signal.png differ diff --git a/ism/src/image/TIZEN_ISF_PG_url_layout.png b/ism/src/image/TIZEN_ISF_PG_url_layout.png new file mode 100644 index 0000000..62c3dc8 Binary files /dev/null and b/ism/src/image/TIZEN_ISF_PG_url_layout.png differ diff --git a/ism/src/ise_context.h b/ism/src/ise_context.h new file mode 100644 index 0000000..2d4bf08 --- /dev/null +++ b/ism/src/ise_context.h @@ -0,0 +1,49 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Jihoon Kim , Haifeng Deng + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISE_CONTEXT_H +#define __ISE_CONTEXT_H + +#include +#include + +typedef struct { + Ecore_IMF_Input_Panel_Lang language; + Ecore_IMF_Input_Panel_Layout layout; + Ecore_IMF_Input_Panel_Return_Key_Type return_key_type; + Ecore_X_Window client_window; + int imdata_size; + int cursor_pos; + Eina_Bool return_key_disabled; + Eina_Bool prediction_allow; + Eina_Bool password_mode; + Eina_Bool caps_mode; + int reserved[249]; +} Ise_Context; + +#endif /* __ISE_CONTEXT_H */ + +/* +vi:ts=4:expandtab:nowrap +*/ diff --git a/ism/src/isf_control.cpp b/ism/src/isf_control.cpp new file mode 100644 index 0000000..b43d5ad --- /dev/null +++ b/ism/src/isf_control.cpp @@ -0,0 +1,118 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_TRANSACTION +#define Uses_ISF_IMCONTROL_CLIENT + + +#include +#include "scim.h" +#include "isf_control.h" + + +namespace scim +{ + +int isf_control_set_active_ise_by_uuid (const char *uuid) +{ + if (uuid == NULL) + return -1; + + IMControlClient imcontrol_client; + imcontrol_client.open_connection (); + imcontrol_client.prepare (); + imcontrol_client.set_active_ise_by_uuid (uuid); + imcontrol_client.close_connection (); + return 0; +} + +int isf_control_get_active_ise (char **uuid) +{ + if (uuid == NULL) + return -1; + + String strUuid; + IMControlClient imcontrol_client; + imcontrol_client.open_connection (); + imcontrol_client.prepare (); + imcontrol_client.get_active_ise (strUuid); + imcontrol_client.close_connection (); + + *uuid = strUuid.length () ? strdup (strUuid.c_str ()) : strdup (""); + + return strUuid.length (); +} + +int isf_control_get_ise_list (char ***uuid_list) +{ + if (uuid_list == NULL) + return -1; + + int count; + IMControlClient imcontrol_client; + imcontrol_client.open_connection (); + imcontrol_client.prepare (); + imcontrol_client.get_ise_list (&count, uuid_list); + imcontrol_client.close_connection (); + return count; +} + +int isf_control_get_ise_info (const char *uuid, char** name, char** language, ISE_TYPE_T &type, int &option) +{ + if (uuid == NULL || name == NULL || language == NULL) + return -1; + + int nType = 0; + int nOption = 0; + String strName, strLanguage; + + IMControlClient imcontrol_client; + imcontrol_client.open_connection (); + imcontrol_client.prepare (); + imcontrol_client.get_ise_info (uuid, strName, strLanguage, nType, nOption); + imcontrol_client.close_connection (); + + *name = strName.length () ? strdup (strName.c_str ()) : strdup (""); + *language = strLanguage.length () ? strdup (strLanguage.c_str ()) : strdup (""); + type = (ISE_TYPE_T)nType; + option = nOption; + + return 0; +} + +int isf_control_reset_ise_option (void) +{ + IMControlClient imcontrol_client; + imcontrol_client.open_connection (); + imcontrol_client.prepare (); + imcontrol_client.reset_ise_option (); + imcontrol_client.close_connection (); + return 0; +} + +}; + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/isf_control.h b/ism/src/isf_control.h new file mode 100644 index 0000000..3c03492 --- /dev/null +++ b/ism/src/isf_control.h @@ -0,0 +1,98 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_CONTROL_H +#define __ISF_CONTROL_H + +namespace scim +{ +///////////////////////////////////////////////////////////////////////////// +// Declaration of global data types. +///////////////////////////////////////////////////////////////////////////// +typedef enum +{ + HARDWARE_KEYBOARD_ISE = 0, /* Hardware keyboard ISE */ + SOFTWARE_KEYBOARD_ISE /* Software keyboard ISE */ +} ISE_TYPE_T; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of global functions. +///////////////////////////////////////////////////////////////////////////// +/** + * @brief Set active ISE by UUID. + * + * @param uuid The active ISE's UUID. + * + * @return 0 if successfully, otherwise return -1; + */ +int isf_control_set_active_ise_by_uuid (const char *uuid); + +/** + * @brief Get active ISE's UUID. + * + * @param uuid The parameter is used to store active ISE's UUID. + * Applcation need free *uuid if it is not used. + * + * @return the length of UUID if successfully, otherwise return -1; + */ +int isf_control_get_active_ise (char **uuid); + +/** + * @brief Get the list of all ISEs' UUID. + * + * @param uuid_list The list is used to store all ISEs' UUID. + * Applcation need free **uuid_list if it is not used. + * + * @return the count of UUID list if successfully, otherwise return -1; + */ +int isf_control_get_ise_list (char ***uuid_list); + +/** + * @brief Get ISE's information according to ISE's UUID. + * + * @param uuid The ISE's UUID. + * @param name The parameter is used to store ISE's name. Applcation need free *name if it is not used. + * @param language The parameter is used to store ISE's language. Applcation need free *language if it is not used. + * @param type The parameter is used to store ISE's type. + * @param option The parameter is used to store ISE's option. + * + * @return 0 if successfully, otherwise return -1; + */ +int isf_control_get_ise_info (const char *uuid, char** name, char** language, ISE_TYPE_T &type, int &option); + +/** + * @brief Reset all ISEs' options. + * + * @return 0 if successfully, otherwise return -1; + */ +int isf_control_reset_ise_option (void); + +} + +#endif /* __ISF_CONTROL_H */ + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/isf_imcontrol_client.cpp b/ism/src/isf_imcontrol_client.cpp new file mode 100644 index 0000000..e17238a --- /dev/null +++ b/ism/src/isf_imcontrol_client.cpp @@ -0,0 +1,653 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_TRANSACTION +#define Uses_ISF_IMCONTROL_CLIENT + + +#include +#include +#include "scim.h" + +#define LOG_TAG "immodule" + +#define IMCONTROLDBG(str...) +#define IMCONTROLERR(str...) LOGW(str) + +namespace scim +{ + +typedef Signal1 IMControlClientSignalVoid; + +class IMControlClient::IMControlClientImpl +{ + SocketClient m_socket_imclient2panel; + SocketClient m_socket_panel2imclient; + int m_socket_timeout; + uint32 m_socket_i2p_magic_key; + uint32 m_socket_p2i_magic_key; + Transaction m_trans; + + IMControlClientSignalVoid m_signal_show_ise; + IMControlClientSignalVoid m_signal_hide_ise; + +public: + IMControlClientImpl () + : m_socket_timeout (scim_get_default_socket_timeout ()), + m_socket_i2p_magic_key (0), + m_socket_p2i_magic_key (0) { + } + + int open_connection (void) { + String config = ""; + String display = String(getenv ("DISPLAY")); + + SocketAddress addr (scim_get_default_panel_socket_address (display)); + + if (m_socket_imclient2panel.is_connected ()) close_connection (); + + bool ret=false, ret2=false; + int count = 0; + + /* Try three times. */ + while (1) { + ret = m_socket_imclient2panel.connect (addr); + ret2 = m_socket_panel2imclient.connect (addr); + if (!ret) { + scim_usleep (100000); + scim_launch_panel (true, config, display, NULL); + for (int i = 0; i < 200; ++i) { + if (m_socket_imclient2panel.connect (addr)) { + ret = true; + break; + } + scim_usleep (100000); + } + } + + if (ret && scim_socket_open_connection (m_socket_i2p_magic_key, String ("IMControl_Active"), String ("Panel"), m_socket_imclient2panel, m_socket_timeout)) { + if (ret2 && scim_socket_open_connection (m_socket_p2i_magic_key, String ("IMControl_Passive"), String ("Panel"), m_socket_panel2imclient, m_socket_timeout)) + break; + } + m_socket_imclient2panel.close (); + m_socket_panel2imclient.close (); + + if (count++ >= 3) break; + + scim_usleep (100000); + } + + return m_socket_imclient2panel.get_id (); + } + + void close_connection (void) { + m_socket_imclient2panel.close (); + m_socket_panel2imclient.close (); + m_socket_i2p_magic_key = 0; + m_socket_p2i_magic_key = 0; + } + + bool is_connected (void) const { + return (m_socket_imclient2panel.is_connected () && m_socket_panel2imclient.is_connected ()); + } + + int get_panel2imclient_connection_number (void) const { + return m_socket_panel2imclient.get_id (); + } + + bool prepare (void) { + if (!m_socket_imclient2panel.is_connected ()) return false; + + m_trans.clear (); + m_trans.put_command (SCIM_TRANS_CMD_REQUEST); + m_trans.put_data (m_socket_i2p_magic_key); + + return true; + } + + bool send (void) { + if (!m_socket_imclient2panel.is_connected ()) return false; + if (m_trans.get_data_type () != SCIM_TRANS_DATA_UNKNOWN) + return m_trans.write_to_socket (m_socket_imclient2panel, 0x4d494353); + return false; + } + + + void show_ise (int client_id, int context, void *data, int length, int *input_panel_show) { + int cmd; + uint32 temp; + m_trans.put_command (ISM_TRANS_CMD_SHOW_ISE_PANEL); + m_trans.put_data ((uint32)client_id); + m_trans.put_data ((uint32)context); + m_trans.put_data ((const char *)data, (size_t)length); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (temp)) { + if (input_panel_show) + *input_panel_show = temp; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + if (input_panel_show) + *input_panel_show = false; + } + } + + void hide_ise (int client_id, int context) { + m_trans.put_command (ISM_TRANS_CMD_HIDE_ISE_PANEL); + m_trans.put_data ((uint32)client_id); + m_trans.put_data ((uint32)context); + } + + void show_control_panel (void) { + m_trans.put_command (ISM_TRANS_CMD_SHOW_ISF_CONTROL); + } + + void hide_control_panel (void) { + m_trans.put_command (ISM_TRANS_CMD_HIDE_ISF_CONTROL); + } + + void set_mode (int mode) { + m_trans.put_command (ISM_TRANS_CMD_SET_ISE_MODE); + m_trans.put_data (mode); + } + + void set_imdata (const char* data, int len) { + m_trans.put_command (ISM_TRANS_CMD_SET_ISE_IMDATA); + m_trans.put_data (data, len); + } + + void get_imdata (char* data, int* len) { + int cmd; + size_t datalen = 0; + char* data_temp = NULL; + + m_trans.put_command (ISM_TRANS_CMD_GET_ISE_IMDATA); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (&data_temp, datalen)) { + memcpy (data, data_temp, datalen); + *len = datalen; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + delete [] data_temp; + } + + void get_ise_window_geometry (int* x, int* y, int* width, int* height) { + int cmd; + uint32 x_temp = 0; + uint32 y_temp = 0; + uint32 w_temp = 0; + uint32 h_temp = 0; + + m_trans.put_command (ISM_TRANS_CMD_GET_ACTIVE_ISE_GEOMETRY); + m_trans.write_to_socket (m_socket_imclient2panel); + + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (x_temp) && + m_trans.get_data (y_temp) && + m_trans.get_data (w_temp) && + m_trans.get_data (h_temp)) { + *x = x_temp; + *y = y_temp; + *width = w_temp; + *height = h_temp; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + } + + void get_candidate_window_geometry (int* x, int* y, int* width, int* height) { + int cmd; + uint32 x_temp = 0; + uint32 y_temp = 0; + uint32 w_temp = 0; + uint32 h_temp = 0; + + m_trans.put_command (ISM_TRANS_CMD_GET_CANDIDATE_GEOMETRY); + m_trans.write_to_socket (m_socket_imclient2panel); + + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s::read_from_socket () may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (x_temp) && + m_trans.get_data (y_temp) && + m_trans.get_data (w_temp) && + m_trans.get_data (h_temp)) { + *x = x_temp; + *y = y_temp; + *width = w_temp; + *height = h_temp; + } else { + IMCONTROLERR ("%s::get_command () or get_data () is failed!!!\n", __FUNCTION__); + } + } + + void get_ise_language_locale (char **locale) { + int cmd; + size_t datalen = 0; + char *data = NULL; + + m_trans.put_command (ISM_TRANS_CMD_GET_ISE_LANGUAGE_LOCALE); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s::read_from_socket () may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (&data, datalen)) { + if (locale) + *locale = strndup (data, datalen); + } else { + IMCONTROLERR ("%s::get_command () or get_data () is failed!!!\n", __FUNCTION__); + if (locale) + *locale = strdup (""); + } + if (data) + delete [] data; + } + + void set_return_key_type (int type) { + m_trans.put_command (ISM_TRANS_CMD_SET_RETURN_KEY_TYPE); + m_trans.put_data (type); + } + + void get_return_key_type (int &type) { + int cmd; + uint32 temp; + + m_trans.put_command (ISM_TRANS_CMD_GET_RETURN_KEY_TYPE); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (temp)) { + type = temp; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + } + + void set_return_key_disable (int disabled) { + m_trans.put_command (ISM_TRANS_CMD_SET_RETURN_KEY_DISABLE); + m_trans.put_data (disabled); + } + + void get_return_key_disable (int &disabled) { + int cmd; + uint32 temp; + + m_trans.put_command (ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (temp)) { + disabled = temp; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + } + + void set_layout (int layout) { + m_trans.put_command (ISM_TRANS_CMD_SET_LAYOUT); + m_trans.put_data (layout); + } + + void get_layout (int* layout) { + int cmd; + uint32 layout_temp; + + m_trans.put_command (ISM_TRANS_CMD_GET_LAYOUT); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (layout_temp)) { + *layout = layout_temp; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + } + + void set_ise_language (int language) { + m_trans.put_command (ISM_TRANS_CMD_SET_ISE_LANGUAGE); + m_trans.put_data (language); + } + + void set_active_ise_by_uuid (const char* uuid) { + int cmd; + m_trans.put_command (ISM_TRANS_CMD_SET_ACTIVE_ISE_BY_UUID); + m_trans.put_data (uuid, strlen(uuid)+1); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + } + + void get_active_ise (String &uuid) { + int cmd; + String strTemp; + + m_trans.put_command (ISM_TRANS_CMD_GET_ACTIVE_ISE); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (strTemp)) { + uuid = strTemp; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + } + + void get_ise_list (int* count, char*** iselist) { + int cmd; + uint32 count_temp = 0; + char **buf = NULL; + size_t len; + char * buf_temp = NULL; + + m_trans.put_command (ISM_TRANS_CMD_GET_ISE_LIST); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (count_temp) ) { + *count = count_temp; + } else { + *count = 0; + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + + if (count_temp > 0) { + buf = (char**)malloc (count_temp * sizeof (char*)); + if (buf) { + memset (buf, 0, count_temp * sizeof (char*)); + for (uint32 i = 0; i < count_temp; i++) { + if (m_trans.get_data (&buf_temp, len)) + buf[i] = buf_temp; + } + } + } + *iselist = buf; + } + + void get_ise_info (const char* uuid, String &name, String &language, int &type, int &option) + { + int cmd; + uint32 tmp_type, tmp_option; + String tmp_name, tmp_language; + + m_trans.put_command (ISM_TRANS_CMD_GET_ISE_INFORMATION); + m_trans.put_data (String (uuid)); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK && + m_trans.get_data (tmp_name) && m_trans.get_data (tmp_language) && + m_trans.get_data (tmp_type) && m_trans.get_data (tmp_option)) { + name = tmp_name; + language = tmp_language; + type = tmp_type; + option = tmp_option; + } else { + IMCONTROLERR ("%s:: get_command() or get_data() may fail!!!\n", __FUNCTION__); + } + } + + void reset_ise_option (void) { + int cmd; + + m_trans.put_command (ISM_TRANS_CMD_RESET_ISE_OPTION); + m_trans.write_to_socket (m_socket_imclient2panel); + if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) + IMCONTROLERR ("%s:: read_from_socket() may be timeout \n", __FUNCTION__); + + if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY && + m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) { + ; + } else { + IMCONTROLERR ("%s:: get_command() is failed!!!\n", __FUNCTION__); + } + } + + void set_caps_mode (int mode) { + m_trans.put_command (ISM_TRANS_CMD_SET_CAPS_MODE); + m_trans.put_data (mode); + } + + void focus_in (void) { + m_trans.put_command (SCIM_TRANS_CMD_FOCUS_IN); + } + + void focus_out (void) { + m_trans.put_command (SCIM_TRANS_CMD_FOCUS_OUT); + } +}; + +IMControlClient::IMControlClient () + : m_impl (new IMControlClientImpl ()) +{ +} + +IMControlClient::~IMControlClient () +{ + delete m_impl; +} + +int +IMControlClient::open_connection (void) +{ + return m_impl->open_connection (); +} + +void +IMControlClient::close_connection (void) +{ + m_impl->close_connection (); +} + +bool IMControlClient::is_connected (void) const +{ + return m_impl->is_connected (); +} + +int IMControlClient::get_panel2imclient_connection_number (void) const +{ + return m_impl->get_panel2imclient_connection_number (); +} + +bool +IMControlClient::prepare (void) +{ + return m_impl->prepare (); +} + +bool +IMControlClient::send (void) +{ + return m_impl->send (); +} + +void IMControlClient::show_ise (int client_id, int context, void *data, int length, int *input_panel_show) +{ + m_impl->show_ise (client_id, context, data,length, input_panel_show); +} + +void IMControlClient::hide_ise (int client_id, int context) +{ + m_impl->hide_ise (client_id, context); +} + +void IMControlClient::show_control_panel (void) +{ + m_impl->show_control_panel (); +} + +void IMControlClient::hide_control_panel (void) +{ + m_impl->hide_control_panel (); +} + +void IMControlClient::set_mode (int mode) +{ + m_impl->set_mode (mode); +} + +void IMControlClient::set_imdata (const char* data, int len) +{ + m_impl->set_imdata (data, len); +} + +void IMControlClient::get_imdata (char* data, int* len) +{ + m_impl->get_imdata (data, len); +} + +void IMControlClient::get_ise_window_geometry (int* x, int* y, int* width, int* height) +{ + m_impl->get_ise_window_geometry (x, y, width, height); +} + +void IMControlClient::get_candidate_window_geometry (int* x, int* y, int* width, int* height) +{ + m_impl->get_candidate_window_geometry (x, y, width, height); +} + +void IMControlClient::get_ise_language_locale (char **locale) +{ + m_impl->get_ise_language_locale (locale); +} + +void IMControlClient::set_return_key_type (int type) +{ + m_impl->set_return_key_type (type); +} + +void IMControlClient::get_return_key_type (int &type) +{ + m_impl->get_return_key_type (type); +} + +void IMControlClient::set_return_key_disable (int disabled) +{ + m_impl->set_return_key_disable (disabled); +} + +void IMControlClient::get_return_key_disable (int &disabled) +{ + m_impl->get_return_key_disable (disabled); +} + +void IMControlClient::set_layout (int layout) +{ + m_impl->set_layout (layout); +} + +void IMControlClient::get_layout (int* layout) +{ + m_impl->get_layout (layout); +} + +void IMControlClient::set_ise_language (int language) +{ + m_impl->set_ise_language (language); +} + +void IMControlClient::set_active_ise_by_uuid (const char* uuid) +{ + m_impl->set_active_ise_by_uuid (uuid); +} + +void IMControlClient::get_active_ise (String &uuid) +{ + m_impl->get_active_ise (uuid); +} + +void IMControlClient::get_ise_list (int* count, char*** iselist) +{ + m_impl->get_ise_list (count, iselist); +} + +void IMControlClient::get_ise_info (const char* uuid, String &name, String &language, int &type, int &option) +{ + m_impl->get_ise_info (uuid, name, language, type, option); +} + +void IMControlClient::reset_ise_option (void) +{ + m_impl->reset_ise_option (); +} + +void IMControlClient::set_caps_mode (int mode) +{ + m_impl->set_caps_mode (mode); +} + +void IMControlClient::focus_in (void) +{ + m_impl->focus_in (); +} + +void IMControlClient::focus_out (void) +{ + m_impl->focus_out (); +} + +}; + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/isf_imcontrol_client.h b/ism/src/isf_imcontrol_client.h new file mode 100644 index 0000000..1807594 --- /dev/null +++ b/ism/src/isf_imcontrol_client.h @@ -0,0 +1,87 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_IMCONTROL_CLIENT_H +#define __ISF_IMCONTROL_CLIENT_H + +namespace scim +{ + +typedef Slot1 IMControlClientSlotVoid; + + +class IMControlClient +{ + class IMControlClientImpl; + IMControlClientImpl *m_impl; + + IMControlClient (const IMControlClient &); + const IMControlClient & operator = (const IMControlClient &); + +public: + IMControlClient (); + ~IMControlClient (); + + int open_connection (void); + void close_connection (void); + bool is_connected (void) const; + int get_panel2imclient_connection_number (void) const; + bool prepare (void); + bool send (void); + + void show_ise (int client_id, int context, void *data, int length, int *input_panel_show); + void hide_ise (int client_id, int context); + void show_control_panel (void); + void hide_control_panel (void); + void set_mode (int mode); + + void set_imdata (const char* data, int len); + void get_imdata (char* data, int* len); + void get_ise_window_geometry (int* x, int* y, int* width, int* height); + void get_candidate_window_geometry (int* x, int* y, int* width, int* height); + void get_ise_language_locale (char **locale); + void set_return_key_type (int type); + void get_return_key_type (int &type); + void set_return_key_disable (int disabled); + void get_return_key_disable (int &disabled); + void set_layout (int layout); + void get_layout (int* layout); + void set_ise_language (int language); + void set_active_ise_by_uuid (const char* uuid); + void get_active_ise (String &uuid); + void get_ise_list (int* count, char*** iselist); + void get_ise_info (const char* uuid, String &name, String &language, int &type, int &option); + void reset_ise_option (void); + void set_caps_mode (int mode); + void focus_in (void); + void focus_out (void); +}; + +} + +#endif /* __ISF_IMCONTROL_CLIENT_H */ + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/isf_log.cpp b/ism/src/isf_log.cpp new file mode 100644 index 0000000..49784ae --- /dev/null +++ b/ism/src/isf_log.cpp @@ -0,0 +1,119 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_HELPER_MANAGER +#define Uses_SCIM_PANEL_CLIENT + +#include "scim.h" +#include "scim_private.h" + +#undef GDK_WINDOWING_X11 + +#if GDK_MULTIHEAD_SAFE +#include +#include +#include +#endif + +#include +#include + + +using namespace scim; + +static void _enable_panel_agent_log (bool _enable_debug) +{ + String display_name; + String config_name ("socket"); + int id = 0; + + { +#if GDK_MULTIHEAD_SAFE + const char *p = gdk_display_get_name (gdk_display_get_default ()); +#else + const char *p = getenv ("DISPLAY"); +#endif + if (p) display_name = String (p); + } + + String address = scim_get_default_panel_socket_address (display_name); + + SocketAddress m_socket_address; + SocketClient m_socket_client; + m_socket_address.set_address (address); + + if (!m_socket_address.valid ()) { + printf ("m_socket_address is not valid!!!\n"); + return; + } + + PanelClient panel_client; + if (panel_client.open_connection (config_name, display_name) >= 0) { + panel_client.prepare (id); + panel_client.turn_on_log (id, _enable_debug); + panel_client.send (); + } +} + +static void _enable_frontend_log (bool _enable_debug) +{ + HelperManager m_helper_manager; + + m_helper_manager.turn_on_log (_enable_debug); +} + +int main (int argc, char **argv) +{ + bool _enable_debug; + + if (argc != 2) { + printf ("usage: isf_log [on/off]\n"); + return -1; + } + + if (!strcmp (argv[1], "on")) + _enable_debug = true; + else if (!strcmp (argv[1], "off")) + _enable_debug = false; + else { + printf ("usage: isf_log [on/off]\n"); + return -1; + } + +#if GDK_MULTIHEAD_SAFE + gtk_init (&argc, &argv); +#endif + + try { + _enable_panel_agent_log (_enable_debug); + _enable_frontend_log (_enable_debug); + } catch (...) { + printf ("exception happen...\n"); + } + return 0; +} + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/isf_query_engines.cpp b/ism/src/isf_query_engines.cpp new file mode 100644 index 0000000..0093864 --- /dev/null +++ b/ism/src/isf_query_engines.cpp @@ -0,0 +1,152 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_DEBUG +#define Uses_SCIM_CONFIG +#define Uses_SCIM_CONFIG_MODULE +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_UTILITY +#define Uses_SCIM_PANEL_AGENT + + +#include +#include +#include +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "isf_query_utility.h" +#include + + +using namespace scim; + + +static void print_help (void) +{ + std::cout << "Usage: isf-query-engines [option] ISE_MODULE_NAME\n\n" + << "The options are: \n" + << " -u, --uninstall If this option is not specified, the default action is to install.\n" + << " -t, --type isetype If this option is not specified, the default type is 0(keyboardISE).\n" + << " -h, --help Show this help message.\n"; +} + +int main (int argc, char *argv[]) +{ + char *isename = NULL; + int isetype = 0; + int uninstall = 0; + + set_app_privilege ("isf", NULL, NULL); + + int i = 1; + while (i < argc) { + if (String ("-t") == String (argv[i]) || String ("--type") == String (argv[i])) { + if (++i >= argc) { + std::cerr << "No argument for option " << argv [i-1] << "\n"; + return -1; + } + isetype = atoi (argv[i]); + i++; + continue; + } + + if (String ("-u") == String (argv[i]) || String ("--uninstall") == String (argv[i])) { + i++; + uninstall = 1; + continue; + } + + if (String ("-h") == String (argv[i]) || String ("--help") == String (argv[i])) { + print_help (); + return 0; + } + + isename = argv[i]; + i++; + } + + String sys_file_name = String (SYS_ENGINE_FILE_NAME); + String user_file_name = String (USER_ENGINE_FILE_NAME); + String engine_file_name = sys_file_name; + + if (access (engine_file_name.c_str (), F_OK | W_OK) != 0) { + FILE *filp = fopen (engine_file_name.c_str (), "a"); + if (filp == NULL) { + engine_file_name = user_file_name; + // Create folder for saving engine list + scim_make_dir (USER_ENGINE_LIST_PATH); + } else { + fclose (filp); + } + } + + if (uninstall == 1) { + isf_remove_ise_info_from_file (engine_file_name.c_str (), isename); + return 0; + } + + ConfigModule *_config_module = 0; + ConfigPointer _config; + + _config_module = new ConfigModule ("simple"); + if (_config_module != NULL && _config_module->valid ()) + _config = _config_module->create_config (); + if (_config.null ()) { + std::cerr << "Config module cannot be loaded, using dummy Config.\n"; + + if (_config_module) delete _config_module; + _config_module = NULL; + + _config = new DummyConfig (); + } + + char *lang_str = vconf_get_str (VCONFKEY_LANGSET); + + if (strlen (lang_str)) { + setenv ("LANG", lang_str, 1); + setlocale (LC_MESSAGES, lang_str); + free(lang_str); + } else { + setenv ("LANG", "en_US.utf8", 1); + setlocale (LC_MESSAGES, "en_US.utf8"); + } + + if (argc == 1) { + isf_update_ise_info_to_file (engine_file_name.c_str (), _config); + return 0; + } + + if (isetype == 0) + isf_add_keyboard_info_to_file (engine_file_name.c_str (), isename, _config); + else + isf_add_helper_info_to_file (engine_file_name.c_str (), isename); + + return 0; +} + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/isf_query_utility.cpp b/ism/src/isf_query_utility.cpp new file mode 100644 index 0000000..9616e18 --- /dev/null +++ b/ism/src/isf_query_utility.cpp @@ -0,0 +1,309 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define Uses_SCIM_DEBUG +#define Uses_SCIM_IMENGINE +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_CONFIG +#define Uses_SCIM_CONFIG_MODULE +#define Uses_SCIM_CONFIG_PATH +#define Uses_C_LOCALE +#define Uses_SCIM_UTILITY +#define Uses_SCIM_PANEL_AGENT + + +#include +#include +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "isf_query_utility.h" + + +using namespace scim; + + +/** + * @brief Get normalized language name. + * + * @param src_str The language name before normalized. + * + * @return normalized language name. + */ +String isf_get_normalized_language (String src_str) +{ + std::vector str_list, dst_list; + scim_split_string_list (str_list, src_str); + + for (size_t i = 0; i < str_list.size (); i++) + dst_list.push_back (scim_get_normalized_language (str_list[i])); + + String dst_str = scim_combine_string_list (dst_list); + + return dst_str; +} + +void isf_get_ise_info_from_string (const char *str, ISEINFO &info) +{ + if (str == NULL || strlen (str) == 0) + return; + + char *buf = strdup (str); + if (buf == NULL) + return; + + int len = strlen (buf); + for (int i = 0; i < len; i++) { + if (buf[i] == ':' || buf[i] == '\n') + buf[i] = '\0'; + } + + int j = 0; + info.name = buf + j; + j += strlen (buf + j) + 1; + info.uuid = buf + j; + j += strlen (buf + j) + 1; + info.module = buf + j; + j += strlen (buf + j) + 1; + info.language = buf + j; + j += strlen (buf + j) + 1; + info.icon = buf + j; + j += strlen (buf + j) + 1; + info.mode = (TOOLBAR_MODE_T)atoi (buf + j); + j += strlen (buf + j) + 1; + info.option = (uint32)atoi (buf + j); + j += strlen (buf + j) + 1; + info.locales = buf + j; + + free (buf); +} + +String isf_combine_ise_info_string (String name, String uuid, String module, String language, + String icon, String mode, String option, String locales) +{ + String line = name + String (":") + uuid + String (":") + module + String (":") + language + String (":") + + icon + String (":") + mode + String (":") + option + String (":") + locales + String ("\n"); + return line; +} + +bool isf_read_ise_info_list (const char *filename, std::vector &info_list) +{ + info_list.clear (); + FILE *engine_list_file = fopen (filename, "r"); + if (engine_list_file == NULL) { + std::cerr << "failed to open " << filename << "\n"; + return false; + } + + char buf[MAXLINE]; + while (fgets (buf, MAXLINE, engine_list_file) != NULL && strlen (buf) > 0) { + ISEINFO info; + isf_get_ise_info_from_string (buf, info); + + info_list.push_back (info); + } + + fclose (engine_list_file); + return true; +} + +bool isf_write_ise_info_list (const char *filename, std::vector &info_list) +{ + if (info_list.size () <= 0) + return false; + + FILE *engine_list_file = fopen (filename, "w+"); + if (engine_list_file == NULL) { + std::cerr << __func__ << " Failed to open(" << filename << ")\n"; + return false; + } + + std::vector::iterator iter; + for (iter = info_list.begin (); iter != info_list.end (); iter++) { + char mode[12]; + char option[12]; + snprintf (mode, sizeof (mode), "%d", (int)iter->mode); + snprintf (option, sizeof (option), "%d", iter->option); + + String line = isf_combine_ise_info_string (iter->name, iter->uuid, iter->module, iter->language, + iter->icon, String (mode), String (option), iter->locales); + if (fputs (line.c_str (), engine_list_file) < 0) { + std::cerr << __func__ << " Failed to write(" << line << ")\n"; + break; + } + } + + fclose (engine_list_file); + return true; +} + +static void add_keyboard_info_to_list (std::vector &info_list, const char *module_name, const ConfigPointer &config) +{ + if (module_name == NULL) + return; + + IMEngineFactoryPointer factory; + IMEngineModule ime_module; + ime_module.load (module_name, config); + if (ime_module.valid ()) { + for (size_t j = 0; j < ime_module.number_of_factories (); ++j) { + try { + factory = ime_module.create_factory (j); + } catch (...) { + factory.reset (); + } + + if (!factory.null ()) { + ISEINFO info; + + info.name = utf8_wcstombs (factory->get_name ()); + info.uuid = factory->get_uuid (); + info.module = module_name; + info.language = isf_get_normalized_language (factory->get_language ()); + info.icon = factory->get_icon_file (); + info.mode = TOOLBAR_KEYBOARD_MODE; + info.option = factory->get_option (); + info.locales = factory->get_locales (); + + info_list.push_back (info); + factory.reset (); + } + } + ime_module.unload (); + } +} + +static void add_helper_info_to_list (std::vector &info_list, const char *module_name) +{ + if (module_name == NULL) + return; + + HelperModule helper_module; + HelperInfo helper_info; + helper_module.load (module_name); + if (helper_module.valid ()) { + for (size_t j = 0; j < helper_module.number_of_helpers (); ++j) { + ISEINFO info; + helper_module.get_helper_info (j, helper_info); + info.name = helper_info.name; + info.uuid = helper_info.uuid; + info.module = module_name; + info.language = isf_get_normalized_language (helper_module.get_helper_lang (j)); + info.icon = helper_info.icon; + info.mode = TOOLBAR_HELPER_MODE; + info.option = helper_info.option; + info.locales = String (""); + + info_list.push_back (info); + } + helper_module.unload (); + } +} + +static void remove_ise_info_from_list (std::vector &info_list, const char *module_name) +{ + if (module_name == NULL) + return; + + std::vector::iterator iter; + while (info_list.size () > 0) { + for (iter = info_list.begin (); iter != info_list.end (); iter++) { + if (iter->module == module_name) + break; + } + + if (iter != info_list.end ()) + info_list.erase (iter); + else + break; + } +} + +bool isf_add_keyboard_info_to_file (const char *filename, const char *module_name, const ConfigPointer &config) +{ + std::vector info_list; + std::vector::iterator iter; + isf_read_ise_info_list (filename, info_list); + + /* Firstly, remove the info of the specified modules from info_list */ + remove_ise_info_from_list (info_list, module_name); + + add_keyboard_info_to_list (info_list, module_name, config); + + return isf_write_ise_info_list (filename, info_list); +} + +bool isf_add_helper_info_to_file (const char *filename, const char *module_name) +{ + std::vector info_list; + std::vector::iterator iter; + isf_read_ise_info_list (filename, info_list); + + /* Firstly, remove the info of the specified modules from info_list */ + remove_ise_info_from_list (info_list, module_name); + + add_helper_info_to_list (info_list, module_name); + + return isf_write_ise_info_list (filename, info_list); +} + +void isf_remove_ise_info_from_file (const char *filename, const char *module_name) +{ + std::vector info_list; + std::vector::iterator iter; + isf_read_ise_info_list (filename, info_list); + + remove_ise_info_from_list (info_list, module_name); + + isf_write_ise_info_list (filename, info_list); +} + +void isf_update_ise_info_to_file (const char *filename, const ConfigPointer &config) +{ + if (filename == NULL) + return; + + std::vector info_list; + + std::vector imengine_list; + scim_get_imengine_module_list (imengine_list); + for (size_t i = 0; i < imengine_list.size (); ++i) { + if (imengine_list[i] != String ("socket")) + add_keyboard_info_to_list (info_list, imengine_list[i].c_str (), config); + } + + std::vector helper_list; + scim_get_helper_module_list (helper_list); + for (size_t i = 0; i < helper_list.size (); ++i) { + add_helper_info_to_list (info_list, helper_list[i].c_str ()); + } + + isf_write_ise_info_list (filename, info_list); +} + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/isf_query_utility.h b/ism/src/isf_query_utility.h new file mode 100644 index 0000000..9c8452d --- /dev/null +++ b/ism/src/isf_query_utility.h @@ -0,0 +1,71 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * Contact: Haifeng Deng , Hengliang Luo + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_QUERY_UTILITY_H +#define __ISF_QUERY_UTILITY_H + +using namespace scim; + + +///////////////////////////////////////////////////////////////////////////// +// Declaration of macro. +///////////////////////////////////////////////////////////////////////////// +#define MAXLINE 4096 +#define USER_ENGINE_LIST_PATH "/home/app/.scim" + +#ifndef SCIM_SYSCONFDIR + #define SCIM_SYSCONFDIR "/usr/etc" +#endif + +#define USER_ENGINE_FILE_NAME (USER_ENGINE_LIST_PATH "/engines_list") +#define SYS_ENGINE_FILE_NAME (SCIM_SYSCONFDIR "/scim/engines_list") + + +typedef struct { + String name; + String uuid; + String module; + String language; + String icon; + TOOLBAR_MODE_T mode; + uint32 option; + String locales; +} ISEINFO; + +String isf_get_normalized_language (String src_str); +String isf_combine_ise_info_string (String name, String uuid, String module, String language, + String icon, String mode, String option, String locales); +void isf_get_ise_info_from_string (const char *str, ISEINFO &info); +bool isf_read_ise_info_list (const char *filename, std::vector &info_list); +bool isf_write_ise_info_list (const char *filename, std::vector &info_list); +bool isf_add_keyboard_info_to_file (const char *filename, const char *module_name, const ConfigPointer &config); +bool isf_add_helper_info_to_file (const char *filename, const char *module_name); +void isf_remove_ise_info_from_file (const char *filename, const char *module_name); +void isf_update_ise_info_to_file (const char *filename, const ConfigPointer &config); + +#endif /* __ISF_QUERY_UTILITY_H */ + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/src/libscim.version-script b/ism/src/libscim.version-script new file mode 100755 index 0000000..6681c12 --- /dev/null +++ b/ism/src/libscim.version-script @@ -0,0 +1,9 @@ +LIBSCIM_1.0 { + global: + extern "C++" { + *scim::*; + }; + + local: + *; +}; diff --git a/ism/src/ltdl.cpp b/ism/src/ltdl.cpp new file mode 100644 index 0000000..58832bb --- /dev/null +++ b/ism/src/ltdl.cpp @@ -0,0 +1,4440 @@ +/* ltdl.c -- system independent dlopen wrapper + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA + +*/ + +#if HAVE_CONFIG_H +# include +#endif + +#if HAVE_UNISTD_H +# include +#endif + +#if HAVE_STDIO_H +# include +#endif + +/* Include the header defining malloc. On K&R C compilers, + that's , on ANSI C and ISO C compilers, that's . */ +#if HAVE_STDLIB_H +# include +#else +# if HAVE_MALLOC_H +# include +# endif +#endif + +#if HAVE_STRING_H +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif + +#if HAVE_CTYPE_H +# include +#endif + +#if HAVE_MEMORY_H +# include +#endif + +#if HAVE_ERRNO_H +# include +#endif + + +#ifndef __WINDOWS__ +# ifdef __WIN32__ +# define __WINDOWS__ +# endif +#endif + + +#undef LT_USE_POSIX_DIRENT +#ifdef HAVE_CLOSEDIR +# ifdef HAVE_OPENDIR +# ifdef HAVE_READDIR +# ifdef HAVE_DIRENT_H +# define LT_USE_POSIX_DIRENT +# endif /* HAVE_DIRENT_H */ +# endif /* HAVE_READDIR */ +# endif /* HAVE_OPENDIR */ +#endif /* HAVE_CLOSEDIR */ + + +#undef LT_USE_WINDOWS_DIRENT_EMULATION +#ifndef LT_USE_POSIX_DIRENT +# ifdef __WINDOWS__ +# define LT_USE_WINDOWS_DIRENT_EMULATION +# endif /* __WINDOWS__ */ +#endif /* LT_USE_POSIX_DIRENT */ + + +#ifdef LT_USE_POSIX_DIRENT +# include +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +#else +# ifdef LT_USE_WINDOWS_DIRENT_EMULATION +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +# else +# define dirent direct +# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen) +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# endif +#endif + +#if HAVE_ARGZ_H +# include +#endif + +#if HAVE_ASSERT_H +# include +#else +# define assert(arg) ((void) 0) +#endif + +#include "ltdl.h" + +#if WITH_DMALLOC +# include +#endif + + + + +/* --- WINDOWS SUPPORT --- */ + + +#ifdef DLL_EXPORT +# define LT_GLOBAL_DATA __declspec(dllexport) +#else +# define LT_GLOBAL_DATA +#endif + +/* fopen() mode flags for reading a text file */ +#undef LT_READTEXT_MODE +#ifdef __WINDOWS__ +# define LT_READTEXT_MODE "rt" +#else +# define LT_READTEXT_MODE "r" +#endif + +#ifdef LT_USE_WINDOWS_DIRENT_EMULATION + +#include + +#define dirent lt_dirent +#define DIR lt_DIR + +struct dirent +{ + char d_name[2048]; + int d_namlen; +}; + +typedef struct _DIR +{ + HANDLE hSearch; + WIN32_FIND_DATA Win32FindData; + BOOL firsttime; + struct dirent file_info; +} DIR; + +#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */ + +namespace scim { + + +/* --- MANIFEST CONSTANTS --- */ + + +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" + +/* Standard libtool archive file extension. */ +#undef LTDL_ARCHIVE_EXT +#define LTDL_ARCHIVE_EXT ".la" + +#ifndef LTDL_OBJDIR +# ifdef LT_OBJDIR +# define LTDL_OBJDIR LT_OBJDIR +# endif +#endif + +#ifndef LTDL_SHLIBPATH_VAR +# ifdef LT_MODULE_PATH_VAR +# define LTDL_SHLIBPATH_VAR LT_MODULE_PATH_VAR +# endif +#endif + +#ifndef LTDL_SHLIB_EXT +# ifdef LT_MODULE_EXT +# define LTDL_SHLIB_EXT LT_MODULE_EXT +# endif +#endif + +#ifndef LTDL_SYSSEARCHPATH +# ifdef LT_DLSEARCH_PATH +# define LTDL_SYSSEARCHPATH LT_DLSEARCH_PATH +# endif +#endif + +/* max. filename length */ +#ifndef LT_FILENAME_MAX +# define LT_FILENAME_MAX 1024 +#endif + +/* This is the maximum symbol size that won't require malloc/free */ +#undef LT_SYMBOL_LENGTH +#define LT_SYMBOL_LENGTH 128 + +/* This accounts for the _LTX_ separator */ +#undef LT_SYMBOL_OVERHEAD +#define LT_SYMBOL_OVERHEAD 5 + + + + +/* --- MEMORY HANDLING --- */ + + +/* These are the functions used internally. In addition to making + use of the associated function pointers above, they also perform + error handling. */ +static char *lt_estrdup LT_PARAMS((const char *str)); +static lt_ptr lt_emalloc LT_PARAMS((size_t size)); +static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size)); + +/* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */ +#define rpl_realloc realloc + +/* These are the pointers that can be changed by the caller: */ +LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)) + = (lt_ptr (*) LT_PARAMS((size_t))) malloc; +LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)) + = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc; +LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)) + = (void (*) LT_PARAMS((lt_ptr))) free; + +/* The following macros reduce the amount of typing needed to cast + assigned memory. */ +#if WITH_DMALLOC + +#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) { xfree (p); (p) = 0; } } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) + +#else + +#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) { lt_dlfree (p); (p) = 0; } } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) + +#endif + +#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ + if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \ + } LT_STMT_END + + +/* --- REPLACEMENT FUNCTIONS --- */ + + +#undef strdup +#define strdup rpl_strdup + +static char *strdup LT_PARAMS((const char *str)); + +static char * +strdup(const char *str) +{ + char *tmp = 0; + + if (str) + { + tmp = LT_DLMALLOC (char, 1+ strlen (str)); + if (tmp) + { + strcpy(tmp, str); + } + } + + return tmp; +} + + +#if ! HAVE_STRCMP + +#undef strcmp +#define strcmp rpl_strcmp + +static int strcmp LT_PARAMS((const char *str1, const char *str2)); + +static int +strcmp (const char *str1, const char *str2) +{ + if (str1 == str2) + return 0; + if (str1 == 0) + return -1; + if (str2 == 0) + return 1; + + for (;*str1 && *str2; ++str1, ++str2) + { + if (*str1 != *str2) + break; + } + + return (int)(*str1 - *str2); +} +#endif + + +#if ! HAVE_STRCHR + +# if HAVE_INDEX +# define strchr index +# else +# define strchr rpl_strchr + +static const char *strchr LT_PARAMS((const char *str, int ch)); + +static const char* +strchr(const char *str, int ch) +{ + const char *p; + + for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p) + /*NOWORK*/; + + return (*p == (char)ch) ? p : 0; +} + +# endif +#endif /* !HAVE_STRCHR */ + + +#if ! HAVE_STRRCHR + +# if HAVE_RINDEX +# define strrchr rindex +# else +# define strrchr rpl_strrchr + +static const char *strrchr LT_PARAMS((const char *str, int ch)); + +static const char* +strrchr(const char *str, int ch) +{ + const char *p, *q = 0; + + for (p = str; *p != LT_EOS_CHAR; ++p) + { + if (*p == (char) ch) + { + q = p; + } + } + + return q; +} + +# endif +#endif + +/* NOTE: Neither bcopy nor the memcpy implementation below can + reliably handle copying in overlapping areas of memory. Use + memmove (for which there is a fallback implmentation below) + if you need that behaviour. */ +#if ! HAVE_MEMCPY + +# if HAVE_BCOPY +# define memcpy(dest, src, size) bcopy (src, dest, size) +# else +# define memcpy rpl_memcpy + +static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +static lt_ptr +memcpy (lt_ptr dest, const lt_ptr src, size_t size) +{ + size_t i = 0; + + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + + return dest; +} + +# endif /* !HAVE_BCOPY */ +#endif /* !HAVE_MEMCPY */ + +#if ! HAVE_MEMMOVE +# define memmove rpl_memmove + +static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +static lt_ptr +memmove (lt_ptr dest, const lt_ptr src, size_t size) +{ + size_t i; + + if (dest < src) + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + else if (dest > src) + for (i = size -1; i >= 0; --i) + { + dest[i] = src[i]; + } + + return dest; +} + +#endif /* !HAVE_MEMMOVE */ + +#ifdef LT_USE_WINDOWS_DIRENT_EMULATION + +static void closedir LT_PARAMS((DIR *entry)); + +static void +closedir(DIR *entry) +{ + assert(entry != (DIR *) NULL); + FindClose(entry->hSearch); + lt_dlfree((lt_ptr)entry); +} + + +static DIR * opendir LT_PARAMS((const char *path)); + +static DIR* +opendir (const char *path) +{ + char file_specification[LT_FILENAME_MAX]; + DIR *entry; + + assert(path != (char *) NULL); + (void) strncpy(file_specification,path,LT_FILENAME_MAX-1); + (void) strcat(file_specification,"\\"); + entry = LT_DLMALLOC (DIR,sizeof(DIR)); + if (entry != (DIR *) 0) + { + entry->firsttime = TRUE; + entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData); + } + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + (void) strcat(file_specification,"\\*.*"); + entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData); + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + LT_DLFREE (entry); + return (DIR *) 0; + } + } + return(entry); +} + + +static struct dirent *readdir LT_PARAMS((DIR *entry)); + +static struct dirent *readdir(DIR *entry) +{ + int + status; + + if (entry == (DIR *) 0) + return((struct dirent *) 0); + if (!entry->firsttime) + { + status = FindNextFile(entry->hSearch,&entry->Win32FindData); + if (status == 0) + return((struct dirent *) 0); + } + entry->firsttime = FALSE; + (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName, + LT_FILENAME_MAX-1); + entry->file_info.d_namlen = strlen(entry->file_info.d_name); + return(&entry->file_info); +} + +#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */ + +/* According to Alexandre Oliva , + ``realloc is not entirely portable'' + In any case we want to use the allocator supplied by the user without + burdening them with an lt_dlrealloc function pointer to maintain. + Instead implement our own version (with known boundary conditions) + using lt_dlmalloc and lt_dlfree. */ + +/* #undef realloc + #define realloc rpl_realloc +*/ +#if 0 + /* You can't (re)define realloc unless you also (re)define malloc. + Right now, this code uses the size of the *destination* to decide + how much to copy. That's not right, but you can't know the size + of the source unless you know enough about, or wrote malloc. So + this code is disabled... */ + +static lt_ptr +realloc (ptr, size) + lt_ptr ptr; + size_t size; +{ + if (size == 0) + { + /* For zero or less bytes, free the original memory */ + if (ptr != 0) + { + lt_dlfree (ptr); + } + + return (lt_ptr) 0; + } + else if (ptr == 0) + { + /* Allow reallocation of a NULL pointer. */ + return lt_dlmalloc (size); + } + else + { + /* Allocate a new block, copy and free the old block. */ + lt_ptr mem = lt_dlmalloc (size); + + if (mem) + { + memcpy (mem, ptr, size); + lt_dlfree (ptr); + } + + /* Note that the contents of PTR are not damaged if there is + insufficient memory to realloc. */ + return mem; + } +} +#endif + + +#if ! HAVE_ARGZ_APPEND +# define argz_append rpl_argz_append + +static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len, + const char *buf, size_t buf_len)); + +static error_t +argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len) +{ + size_t argz_len; + char *argz; + + assert (pargz); + assert (pargz_len); + assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); + + /* If nothing needs to be appended, no more work is required. */ + if (buf_len == 0) + return 0; + + /* Ensure there is enough room to append BUF_LEN. */ + argz_len = *pargz_len + buf_len; + argz = LT_DLREALLOC (char, *pargz, argz_len); + if (!argz) + return ENOMEM; + + /* Copy characters from BUF after terminating '\0' in ARGZ. */ + memcpy (argz + *pargz_len, buf, buf_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_APPEND */ + + +#if ! HAVE_ARGZ_CREATE_SEP +# define argz_create_sep rpl_argz_create_sep + +static error_t argz_create_sep LT_PARAMS((const char *str, int delim, + char **pargz, size_t *pargz_len)); + +static error_t +argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len) +{ + size_t argz_len; + char *argz = 0; + + assert (str); + assert (pargz); + assert (pargz_len); + + /* Make a copy of STR, but replacing each occurence of + DELIM with '\0'. */ + argz_len = 1+ LT_STRLEN (str); + if (argz_len) + { + const char *p; + char *q; + + argz = LT_DLMALLOC (char, argz_len); + if (!argz) + return ENOMEM; + + for (p = str, q = argz; *p != LT_EOS_CHAR; ++p) + { + if (*p == delim) + { + /* Ignore leading delimiters, and fold consecutive + delimiters in STR into a single '\0' in ARGZ. */ + if ((q > argz) && (q[-1] != LT_EOS_CHAR)) + *q++ = LT_EOS_CHAR; + else + --argz_len; + } + else + *q++ = *p; + } + /* Copy terminating LT_EOS_CHAR. */ + *q = *p; + } + + /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ + if (!argz_len) + LT_DLFREE (argz); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_CREATE_SEP */ + + +#if ! HAVE_ARGZ_INSERT +# define argz_insert rpl_argz_insert + +static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, + char *before, const char *entry)); + +static error_t +argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry) +{ + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + /* No BEFORE address indicates ENTRY should be inserted after the + current last element. */ + if (!before) + return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry)); + + /* This probably indicates a programmer error, but to preserve + semantics, scan back to the start of an entry if BEFORE points + into the middle of it. */ + while ((before > *pargz) && (before[-1] != LT_EOS_CHAR)) + --before; + + { + size_t entry_len = 1+ LT_STRLEN (entry); + size_t argz_len = *pargz_len + entry_len; + size_t offset = before - *pargz; + char *argz = LT_DLREALLOC (char, *pargz, argz_len); + + if (!argz) + return ENOMEM; + + /* Make BEFORE point to the equivalent offset in ARGZ that it + used to have in *PARGZ incase realloc() moved the block. */ + before = argz + offset; + + /* Move the ARGZ entries starting at BEFORE up into the new + space at the end -- making room to copy ENTRY into the + resulting gap. */ + memmove (before + entry_len, before, *pargz_len - offset); + memcpy (before, entry, entry_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + } + + return 0; +} +#endif /* !HAVE_ARGZ_INSERT */ + + +#if ! HAVE_ARGZ_NEXT +# define argz_next rpl_argz_next + +static char *argz_next LT_PARAMS((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next (char *argz, size_t argz_len, const char *entry) +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (entry) + { + /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address + within the ARGZ vector. */ + assert ((!argz && !argz_len) + || ((argz <= entry) && (entry < (argz + argz_len)))); + + /* Move to the char immediately after the terminating + '\0' of ENTRY. */ + entry = 1+ strchr (entry, LT_EOS_CHAR); + + /* Return either the new ENTRY, or else NULL if ARGZ is + exhausted. */ + return (entry >= argz + argz_len) ? 0 : (char *) entry; + } + else + { + /* This should probably be flagged as a programmer error, + since starting an argz_next loop with the iterator set + to ARGZ is safer. To preserve semantics, handle the NULL + case by returning the start of ARGZ (if any). */ + if (argz_len > 0) + return argz; + else + return 0; + } +} +#endif /* !HAVE_ARGZ_NEXT */ + + + +#if ! HAVE_ARGZ_STRINGIFY +# define argz_stringify rpl_argz_stringify + +static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, + int sep)); + +static void +argz_stringify (char *argz, size_t argz_len, int sep) +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (sep) + { + --argz_len; /* don't stringify the terminating EOS */ + while (--argz_len > 0) + { + if (argz[argz_len] == LT_EOS_CHAR) + argz[argz_len] = sep; + } + } +} +#endif /* !HAVE_ARGZ_STRINGIFY */ + + + + +/* --- TYPE DEFINITIONS -- */ + + +/* This type is used for the array of caller data sets in each handler. */ +typedef struct { + lt_dlcaller_id key; + lt_ptr data; +} lt_caller_data; + + + + +/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */ + + +/* Extract the diagnostic strings from the error table macro in the same + order as the enumerated indices in ltdl.h. */ + +static const char *lt_dlerror_strings[] = + { +#define LT_ERROR(name, diagnostic) (diagnostic), + lt_dlerror_table +#undef LT_ERROR + + 0 + }; + +/* This structure is used for the list of registered loaders. */ +struct lt_dlloader { + struct lt_dlloader *next; + const char *loader_name; /* identifying name for each loader */ + const char *sym_prefix; /* prefix for symbols */ + lt_module_open *module_open; + lt_module_close *module_close; + lt_find_sym *find_sym; + lt_dlloader_exit *dlloader_exit; + lt_user_data dlloader_data; +}; + +struct lt_dlhandle_struct { + struct lt_dlhandle_struct *next; + lt_dlloader *loader; /* dlopening interface */ + lt_dlinfo info; + int depcount; /* number of dependencies */ + lt_dlhandle *deplibs; /* dependencies */ + lt_module module; /* system module handle */ + lt_ptr system; /* system specific data */ + lt_caller_data *caller_data; /* per caller associated data */ + int flags; /* various boolean stats */ +}; + +/* Various boolean flags can be stored in the flags field of an + lt_dlhandle_struct... */ +#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag)) +#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag)) + +#define LT_DLRESIDENT_FLAG (0x01 << 0) +/* ...add more flags here... */ + +#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) + + +#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] + +static const char objdir[] = LTDL_OBJDIR; +static const char archive_ext[] = LTDL_ARCHIVE_EXT; +#ifdef LTDL_SHLIB_EXT +static const char shlib_ext[] = LTDL_SHLIB_EXT; +#endif +#ifdef LTDL_SYSSEARCHPATH +static const char sys_search_path[] = LTDL_SYSSEARCHPATH; +#endif + + + + +/* --- MUTEX LOCKING --- */ + + +/* Macros to make it easier to run the lock functions only if they have + been registered. The reason for the complicated lock macro is to + ensure that the stored error message from the last error is not + accidentally erased if the current function doesn't generate an + error of its own. */ +#define LT_DLMUTEX_LOCK() LT_STMT_START { \ + if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \ + } LT_STMT_END +#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \ + if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\ + } LT_STMT_END +#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_seterror_func) \ + (*lt_dlmutex_seterror_func) (errormsg); \ + else lt_dllast_error = (errormsg); } LT_STMT_END +#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_seterror_func) \ + (errormsg) = (*lt_dlmutex_geterror_func) (); \ + else (errormsg) = lt_dllast_error; } LT_STMT_END + +/* The mutex functions stored here are global, and are necessarily the + same for all threads that wish to share access to libltdl. */ +static lt_dlmutex_lock *lt_dlmutex_lock_func = 0; +static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0; +static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0; +static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0; +static const char *lt_dllast_error = 0; + + +/* Either set or reset the mutex functions. Either all the arguments must + be valid functions, or else all can be NULL to turn off locking entirely. + The registered functions should be manipulating a static global lock + from the lock() and unlock() callbacks, which needs to be reentrant. */ +int +lt_dlmutex_register ( + lt_dlmutex_lock *lock, + lt_dlmutex_unlock *unlock, + lt_dlmutex_seterror *seterror, + lt_dlmutex_geterror *geterror) +{ + lt_dlmutex_unlock *old_unlock = unlock; + int errors = 0; + + /* Lock using the old lock() callback, if any. */ + LT_DLMUTEX_LOCK (); + + if ((lock && unlock && seterror && geterror) + || !(lock || unlock || seterror || geterror)) + { + lt_dlmutex_lock_func = lock; + lt_dlmutex_unlock_func = unlock; + lt_dlmutex_geterror_func = geterror; + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS)); + ++errors; + } + + /* Use the old unlock() callback we saved earlier, if any. Otherwise + record any errors using internal storage. */ + if (old_unlock) + (*old_unlock) (); + + /* Return the number of errors encountered during the execution of + this function. */ + return errors; +} + + + + +/* --- ERROR HANDLING --- */ + + +static const char **user_error_strings = 0; +static int errorcount = LT_ERROR_MAX; + +int +lt_dladderror (const char *diagnostic) +{ + int errindex = 0; + int result = -1; + const char **temp = (const char **) 0; + + assert (diagnostic); + + LT_DLMUTEX_LOCK (); + + errindex = errorcount - LT_ERROR_MAX; + temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex); + if (temp) + { + user_error_strings = temp; + user_error_strings[errindex] = diagnostic; + result = errorcount++; + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +int +lt_dlseterror (int errindex) +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + if (errindex >= errorcount || errindex < 0) + { + /* Ack! Error setting the error message! */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE)); + ++errors; + } + else if (errindex < LT_ERROR_MAX) + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]); + } + else + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static lt_ptr +lt_emalloc (size_t size) +{ + lt_ptr mem = lt_dlmalloc (size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static lt_ptr +lt_erealloc (lt_ptr addr, size_t size) +{ + lt_ptr mem = lt_dlrealloc (addr, size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static char * +lt_estrdup (const char *str) +{ + char *copy = strdup (str); + if (LT_STRLEN (str) && !copy) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return copy; +} + + + + +/* --- DLOPEN() INTERFACE LOADER --- */ + + +#if HAVE_LIBDL + +/* dynamic linking with dlopen/dlsym */ + +#if HAVE_DLFCN_H +# include +#endif + +#if HAVE_SYS_DL_H +# include +#endif + +#ifdef RTLD_GLOBAL +# define LT_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_GLOBAL DL_GLOBAL +# endif +#endif /* !RTLD_GLOBAL */ +#ifndef LT_GLOBAL +# define LT_GLOBAL 0 +#endif /* !LT_GLOBAL */ + +/* We may have to define LT_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_LAZY_OR_NOW DL_LAZY +# endif +# endif /* !RTLD_LAZY */ +#endif +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_NOW +# define LT_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_LAZY_OR_NOW DL_NOW +# endif +# endif /* !RTLD_NOW */ +#endif +#ifndef LT_LAZY_OR_NOW +# define LT_LAZY_OR_NOW 0 +#endif /* !LT_LAZY_OR_NOW */ + +#if HAVE_DLERROR +# define DLERROR(arg) dlerror () +#else +# define DLERROR(arg) LT_DLSTRERROR (arg) +#endif + +static lt_module +sys_dl_open (lt_user_data loader_data, const char *filename) +{ + lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW); + + if (!module) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN)); + } + + return module; +} + +static int +sys_dl_close (lt_user_data loader_data, lt_module module) +{ + int errors = 0; + + if (dlclose (module) != 0) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_dl_sym ( + lt_user_data loader_data, + lt_module module, + const char *symbol) +{ + lt_ptr address = dlsym (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_dl = + { +# ifdef NEED_USCORE + "_", +# else + 0, +# endif + sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 }; + + +#endif /* HAVE_LIBDL */ + + + +/* --- SHL_LOAD() INTERFACE LOADER --- */ + +#if HAVE_SHL_LOAD + +/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */ + +#ifdef HAVE_DL_H +# include +#endif + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * + * Mandatory: + * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. + * BIND_DEFERRED - Delay code symbol resolution until actual reference. + * + * Optionally: + * BIND_FIRST - Place the library at the head of the symbol search + * order. + * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all + * unsatisfied symbols as fatal. This flag allows + * binding of unsatisfied code symbols to be deferred + * until use. + * [Perl: For certain libraries, like DCE, deferred + * binding often causes run time problems. Adding + * BIND_NONFATAL to BIND_IMMEDIATE still allows + * unresolved references in situations like this.] + * BIND_NOSTART - Do not call the initializer for the shared library + * when the library is loaded, nor on a future call to + * shl_unload(). + * BIND_VERBOSE - Print verbose messages concerning possible + * unsatisfied symbols. + * + * hp9000s700/hp9000s800: + * BIND_RESTRICTED - Restrict symbols visible by the library to those + * present at library load time. + * DYNAMIC_PATH - Allow the loader to dynamically search for the + * library specified by the path argument. + */ + +#ifndef DYNAMIC_PATH +# define DYNAMIC_PATH 0 +#endif +#ifndef BIND_RESTRICTED +# define BIND_RESTRICTED 0 +#endif + +#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) + +static lt_module +sys_shl_open (lt_user_data loader_data, const char *filename) +{ + static shl_t self = (shl_t) 0; + lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); + + /* Since searching for a symbol against a NULL module handle will also + look in everything else that was already loaded and exported with + the -E compiler flag, we always cache a handle saved before any + modules are loaded. */ + if (!self) + { + lt_ptr address; + shl_findsym (&self, "main", TYPE_UNDEFINED, &address); + } + + if (!filename) + { + module = self; + } + else + { + module = shl_load (filename, LT_BIND_FLAGS, 0L); + + if (!module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + } + } + + return module; +} + +static int +sys_shl_close (lt_user_data loader_data, lt_module module) +{ + int errors = 0; + + if (module && (shl_unload ((shl_t) (module)) != 0)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_shl_sym ( + lt_user_data loader_data, + lt_module module, + const char *symbol) +{ + lt_ptr address = 0; + + /* sys_shl_open should never return a NULL module handle */ + if (module == (lt_module) 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + } + else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address)) + { + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + } + + return address; +} + +static struct lt_user_dlloader sys_shl = { + 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 +}; + +#endif /* HAVE_SHL_LOAD */ + + + + +/* --- LOADLIBRARY() INTERFACE LOADER --- */ + +#ifdef __WINDOWS__ + +/* dynamic linking for Win32 */ + +#include + +/* Forward declaration; required to implement handle search below. */ +static lt_dlhandle handles; + +static lt_module +sys_wll_open (lt_user_data loader_data, const char *filename) +{ + lt_dlhandle cur; + lt_module module = 0; + const char *errormsg = 0; + char *searchname = 0; + char *ext; + char self_name_buf[MAX_PATH]; + + if (!filename) + { + /* Get the name of main module */ + *self_name_buf = 0; + GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); + filename = ext = self_name_buf; + } + else + { + ext = strrchr (filename, '.'); + } + + if (ext) + { + /* FILENAME already has an extension. */ + searchname = lt_estrdup (filename); + } + else + { + /* Append a `.' to stop Windows from adding an + implicit `.dll' extension. */ + searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); + if (searchname) + sprintf (searchname, "%s.", filename); + } + if (!searchname) + return 0; + +#if __CYGWIN__ + { + char wpath[MAX_PATH]; + cygwin_conv_to_full_win32_path(searchname, wpath); + module = LoadLibrary(wpath); + } +#else + module = LoadLibrary (searchname); +#endif + LT_DLFREE (searchname); + + /* libltdl expects this function to fail if it is unable + to physically load the library. Sadly, LoadLibrary + will search the loaded libraries for a match and return + one of them if the path search load fails. + + We check whether LoadLibrary is returning a handle to + an already loaded module, and simulate failure if we + find one. */ + LT_DLMUTEX_LOCK (); + cur = handles; + while (cur) + { + if (!cur->module) + { + cur = 0; + break; + } + + if (cur->module == module) + { + break; + } + + cur = cur->next; + } + LT_DLMUTEX_UNLOCK (); + + if (cur || !module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + module = 0; + } + + return module; +} + +static int +sys_wll_close (lt_user_data loader_data, lt_module module) +{ + int errors = 0; + + if (FreeLibrary(module) == 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_wll_sym ( + lt_user_data loader_data, + lt_module module, + const char *symbol) +{ + lt_ptr address = GetProcAddress (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_wll = { + 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 +}; + +#endif /* __WINDOWS__ */ + + + + +/* --- LOAD_ADD_ON() INTERFACE LOADER --- */ + + +#ifdef __BEOS__ + +/* dynamic linking for BeOS */ + +#include + +static lt_module +sys_bedl_open (lt_user_data loader_data, const char *filename) +{ + image_id image = 0; + + if (filename) + { + image = load_add_on (filename); + } + else + { + image_info info; + int32 cookie = 0; + if (get_next_image_info (0, &cookie, &info) == B_OK) + image = load_add_on (info.name); + } + + if (image <= 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + image = 0; + } + + return (lt_module) image; +} + +static int +sys_bedl_close (lt_user_data loader_data, lt_module module) +{ + int errors = 0; + + if (unload_add_on ((image_id) module) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_bedl_sym ( + lt_user_data loader_data, + lt_module module, + const char *symbol) +{ + lt_ptr address = 0; + image_id image = (image_id) module; + + if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + address = 0; + } + + return address; +} + +static struct lt_user_dlloader sys_bedl = { + 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 +}; + +#endif /* __BEOS__ */ + + + + +/* --- DLD_LINK() INTERFACE LOADER --- */ + + +#if HAVE_DLD + +/* dynamic linking with dld */ + +#if HAVE_DLD_H +#include +#endif + +static lt_module +sys_dld_open (lt_user_data loader_data, const char *filename) +{ + lt_module module = strdup (filename); + + if (dld_link (filename) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLFREE (module); + module = 0; + } + + return module; +} + +static int +sys_dld_close (lt_user_data loader_data, lt_module module) +{ + int errors = 0; + + if (dld_unlink_by_file ((char*)(module), 1) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + else + { + LT_DLFREE (module); + } + + return errors; +} + +static lt_ptr +sys_dld_sym ( + lt_user_data loader_data, + lt_module module, + const char *symbol) +{ + lt_ptr address = dld_get_func (symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_dld = { + 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 +}; + +#endif /* HAVE_DLD */ + +/* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */ +#if HAVE_DYLD + + +#if HAVE_MACH_O_DYLD_H +#if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__) +/* Is this correct? Does it still function properly? */ +#define __private_extern__ extern +#endif +# include +#endif +#include + +/* We have to put some stuff here that isn't in older dyld.h files */ +#ifndef ENUM_DYLD_BOOL +# define ENUM_DYLD_BOOL +# undef FALSE +# undef TRUE + enum DYLD_BOOL { + FALSE, + TRUE + }; +#endif +#ifndef LC_REQ_DYLD +# define LC_REQ_DYLD 0x80000000 +#endif +#ifndef LC_LOAD_WEAK_DYLIB +# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) +#endif +static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0; +static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0; +static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0; +static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0; + +#ifndef NSADDIMAGE_OPTION_NONE +#define NSADDIMAGE_OPTION_NONE 0x0 +#endif +#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR +#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 +#endif +#ifndef NSADDIMAGE_OPTION_WITH_SEARCHING +#define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2 +#endif +#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 +#endif +#ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME +#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR +#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 +#endif + + +static const char * +lt_int_dyld_error(char* othererror) +{ +/* return the dyld error string, or the passed in error string if none */ + NSLinkEditErrors ler; + int lerno; + const char *errstr; + const char *file; + NSLinkEditError(&ler,&lerno,&file,&errstr); + if (!errstr || !strlen(errstr)) errstr = othererror; + return errstr; +} + +static const struct mach_header * +lt_int_dyld_get_mach_header_from_nsmodule(NSModule module) +{ +/* There should probably be an apple dyld api for this */ + int i=_dyld_image_count(); + int j; + const char *modname=NSNameOfModule(module); + const struct mach_header *mh=NULL; + if (!modname) return NULL; + for (j = 0; j < i; j++) + { + if (!strcmp(_dyld_get_image_name(j),modname)) + { + mh=_dyld_get_image_header(j); + break; + } + } + return mh; +} + +static const char* lt_int_dyld_lib_install_name(const struct mach_header *mh) +{ +/* NSAddImage is also used to get the loaded image, but it only works if the lib + is installed, for uninstalled libs we need to check the install_names against + each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a + different lib was loaded as a result +*/ + int j; + struct load_command *lc; + unsigned long offset = sizeof(struct mach_header); + const char* retStr=NULL; + for (j = 0; j < mh->ncmds; j++) + { + lc = (struct load_command*)(((unsigned long)mh) + offset); + if (LC_ID_DYLIB == lc->cmd) + { + retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc); + } + offset += lc->cmdsize; + } + return retStr; +} + +static const struct mach_header * +lt_int_dyld_match_loaded_lib_by_install_name(const char *name) +{ + int i=_dyld_image_count(); + int j; + const struct mach_header *mh=NULL; + const char *id=NULL; + for (j = 0; j < i; j++) + { + id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j)); + if ((id) && (!strcmp(id,name))) + { + mh=_dyld_get_image_header(j); + break; + } + } + return mh; +} + +static NSSymbol +lt_int_dyld_NSlookupSymbolInLinkedLibs(const char *symbol, const struct mach_header *mh) +{ + /* Safe to assume our mh is good */ + int j; + struct load_command *lc; + unsigned long offset = sizeof(struct mach_header); + NSSymbol retSym = 0; + const struct mach_header *mh1; + if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) ) + { + for (j = 0; j < mh->ncmds; j++) + { + lc = (struct load_command*)(((unsigned long)mh) + offset); + if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd)) + { + mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc)); + if (!mh1) + { + /* Maybe NSAddImage can find it */ + mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc), + NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED + + NSADDIMAGE_OPTION_WITH_SEARCHING + + NSADDIMAGE_OPTION_RETURN_ON_ERROR ); + } + if (mh1) + { + retSym = ltdl_NSLookupSymbolInImage(mh1, + symbol, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR + ); + if (retSym) break; + } + } + offset += lc->cmdsize; + } + } + return retSym; +} + +static int +sys_dyld_init() +{ + int retCode = 0; + int err = 0; + if (!_dyld_present()) { + retCode=1; + } + else { + err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage); + err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage); + err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage); + err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic); + } + return retCode; +} + +static lt_module +sys_dyld_open (lt_user_data loader_data, const char *filename) +{ + lt_module module = 0; + NSObjectFileImage ofi = 0; + NSObjectFileImageReturnCode ofirc; + + if (!filename) + return (lt_module)-1; + ofirc = NSCreateObjectFileImageFromFile(filename, &ofi); + switch (ofirc) + { + case NSObjectFileImageSuccess: + module = NSLinkModule(ofi, filename, + NSLINKMODULE_OPTION_RETURN_ON_ERROR + | NSLINKMODULE_OPTION_PRIVATE + | NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage(ofi); + if (module) + ltdl_NSMakePrivateModulePublic(module); + break; + case NSObjectFileImageInappropriateFile: + if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) + { + module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + break; + } + default: + LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); + return 0; + } + if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); + return module; +} + +static int +sys_dyld_close (lt_user_data loader_data, lt_module module) +{ + int retCode = 0; + int flags = 0; + if (module == (lt_module)-1) return 0; +#ifdef __BIG_ENDIAN__ + if (((struct mach_header *)module)->magic == MH_MAGIC) +#else + if (((struct mach_header *)module)->magic == MH_CIGAM) +#endif + { + LT_DLMUTEX_SETERROR("Can not close a dylib"); + retCode = 1; + } + else + { +#if 1 +/* Currently, if a module contains c++ static destructors and it is unloaded, we + get a segfault in atexit(), due to compiler and dynamic loader differences of + opinion, this works around that. +*/ + if ((const struct section *)NULL != + getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module), + "__DATA","__mod_term_func")) + { + flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; + } +#endif +#ifdef __ppc__ + flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; +#endif + if (!NSUnLinkModule(module,flags)) + { + retCode=1; + LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE))); + } + } + + return retCode; +} + +static lt_ptr +sys_dyld_sym ( + lt_user_data loader_data, + lt_module module, + const char *symbol) +{ + lt_ptr address = 0; + NSSymbol *nssym = 0; + void *unused; + const struct mach_header *mh=NULL; + char saveError[256] = "Symbol not found"; + if (module == (lt_module)-1) + { + _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused); + return address; + } +#ifdef __BIG_ENDIAN__ + if (((struct mach_header *)module)->magic == MH_MAGIC) +#else + if (((struct mach_header *)module)->magic == MH_CIGAM) +#endif + { + if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) + { + mh=module; + if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol)) + { + nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module, + symbol, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR + ); + } + } + + } + else { + nssym = NSLookupSymbolInModule(module, symbol); + } + if (!nssym) + { + strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255); + saveError[255] = 0; + if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module); + nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh); + } + if (!nssym) + { + LT_DLMUTEX_SETERROR (saveError); + return NULL; + } + return NSAddressOfSymbol(nssym); +} + +static struct lt_user_dlloader sys_dyld = + { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 }; + + +#endif /* HAVE_DYLD */ + + +/* --- DLPREOPEN() INTERFACE LOADER --- */ + + +/* emulate dynamic linking using preloaded_symbols */ + +typedef struct lt_dlsymlists_t +{ + struct lt_dlsymlists_t *next; + const lt_dlsymlist *syms; +} lt_dlsymlists_t; + +static const lt_dlsymlist *default_preloaded_symbols = 0; +static lt_dlsymlists_t *preloaded_symbols = 0; + +static int +presym_init (lt_user_data loader_data) +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + preloaded_symbols = 0; + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +presym_free_symlists () +{ + lt_dlsymlists_t *lists; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + lt_dlsymlists_t *tmp = lists; + + lists = lists->next; + LT_DLFREE (tmp); + } + preloaded_symbols = 0; + + LT_DLMUTEX_UNLOCK (); + + return 0; +} + +static int +presym_exit (lt_user_data loader_data) +{ + presym_free_symlists (); + return 0; +} + +static int +presym_add_symlist (const lt_dlsymlist *preloaded) +{ + lt_dlsymlists_t *tmp; + lt_dlsymlists_t *lists; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + if (lists->syms == preloaded) + { + goto done; + } + lists = lists->next; + } + + tmp = LT_EMALLOC (lt_dlsymlists_t, 1); + if (tmp) + { + memset (tmp, 0, sizeof(lt_dlsymlists_t)); + tmp->syms = preloaded; + tmp->next = preloaded_symbols; + preloaded_symbols = tmp; + } + else + { + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static lt_module +presym_open (lt_user_data loader_data, const char *filename) +{ + lt_dlsymlists_t *lists; + lt_module module = (lt_module) 0; + + LT_DLMUTEX_LOCK (); + lists = preloaded_symbols; + + if (!lists) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); + goto done; + } + + /* Can't use NULL as the reflective symbol header, as NULL is + used to mark the end of the entire symbol list. Self-dlpreopened + symbols follow this magic number, chosen to be an unlikely + clash with a real module name. */ + if (!filename) + { + filename = "@PROGRAM@"; + } + + while (lists) + { + const lt_dlsymlist *syms = lists->syms; + + while (syms->name) + { + if (!syms->address && strcmp(syms->name, filename) == 0) + { + module = (lt_module) syms; + goto done; + } + ++syms; + } + + lists = lists->next; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + + done: + LT_DLMUTEX_UNLOCK (); + return module; +} + +static int +presym_close (lt_user_data loader_data, lt_module module) +{ + /* Just to silence gcc -Wall */ + module = 0; + return 0; +} + +static lt_ptr +presym_sym ( + lt_user_data loader_data, + lt_module module, + const char *symbol) +{ + lt_dlsymlist *syms = (lt_dlsymlist*) module; + + ++syms; + while (syms->address) + { + if (strcmp(syms->name, symbol) == 0) + { + return syms->address; + } + + ++syms; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + + return 0; +} + +static struct lt_user_dlloader presym = { + 0, presym_open, presym_close, presym_sym, presym_exit, 0 +}; + + + + + +/* --- DYNAMIC MODULE LOADING --- */ + + +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + +static int foreach_dirinpath LT_PARAMS((const char *search_path, + const char *base_name, + foreach_callback_func *func, + lt_ptr data1, lt_ptr data2)); + +static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + + +static int canonicalize_path LT_PARAMS((const char *path, + char **pcanonical)); +static int argzize_path LT_PARAMS((const char *path, + char **pargz, + size_t *pargz_len)); +static FILE *find_file LT_PARAMS((const char *search_path, + const char *base_name, + char **pdir)); +static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, + const char *base_name, + lt_dlhandle *handle)); +static int find_module LT_PARAMS((lt_dlhandle *handle, + const char *dir, + const char *libdir, + const char *dlname, + const char *old_name, + int installed)); +static int free_vars LT_PARAMS((char *dlname, char *oldname, + char *libdir, char *deplibs)); +static int load_deplibs LT_PARAMS((lt_dlhandle handle, + char *deplibs)); +static int trim LT_PARAMS((char **dest, + const char *str)); +static int try_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); +static int lt_argz_insert LT_PARAMS((char **pargz, + size_t *pargz_len, + char *before, + const char *entry)); +static int lt_argz_insertinorder LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *entry)); +static int lt_argz_insertdir LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *dirnam, + struct dirent *dp)); +static int lt_dlpath_insertdir LT_PARAMS((char **ppath, + char *before, + const char *dir)); +static int list_files_by_dir LT_PARAMS((const char *dirnam, + char **pargz, + size_t *pargz_len)); +static int file_not_found LT_PARAMS((void)); + +static char *user_search_path= 0; +static lt_dlloader *loaders = 0; +static lt_dlhandle handles = 0; +static int initialized = 0; + +/* Initialize libltdl. */ +int +lt_dlinit () +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* Initialize only at first call. */ + if (++initialized == 1) + { + handles = 0; + user_search_path = 0; /* empty search path */ + +#if HAVE_LIBDL + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); +#endif +#if HAVE_SHL_LOAD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen"); +#endif +#ifdef __WINDOWS__ + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen"); +#endif +#ifdef __BEOS__ + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen"); +#endif +#if HAVE_DLD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld"); +#endif +#if HAVE_DYLD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld"); + errors += sys_dyld_init(); +#endif + errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload"); + + if (presym_init (presym.dlloader_data)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); + ++errors; + } + else if (errors != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); + ++errors; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +lt_dlpreload (const lt_dlsymlist *preloaded) +{ + int errors = 0; + + if (preloaded) + { + errors = presym_add_symlist (preloaded); + } + else + { + presym_free_symlists(); + + LT_DLMUTEX_LOCK (); + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlpreload_default (const lt_dlsymlist *preloaded) +{ + LT_DLMUTEX_LOCK (); + default_preloaded_symbols = preloaded; + LT_DLMUTEX_UNLOCK (); + return 0; +} + +int +lt_dlexit () +{ + /* shut down libltdl */ + lt_dlloader *loader; + int errors = 0; + + LT_DLMUTEX_LOCK (); + loader = loaders; + + if (!initialized) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); + ++errors; + goto done; + } + + /* shut down only at last call. */ + if (--initialized == 0) + { + int level; + + while (handles && LT_DLIS_RESIDENT (handles)) + { + handles = handles->next; + } + + /* close all modules */ + for (level = 1; handles; ++level) + { + lt_dlhandle cur = handles; + int saw_nonresident = 0; + + while (cur) + { + lt_dlhandle tmp = cur; + cur = cur->next; + if (!LT_DLIS_RESIDENT (tmp)) + saw_nonresident = 1; + if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level) + { + if (lt_dlclose (tmp)) + { + ++errors; + } + } + } + /* done if only resident modules are left */ + if (!saw_nonresident) + break; + } + + /* close all loaders */ + while (loader) + { + lt_dlloader *next = loader->next; + lt_user_data data = loader->dlloader_data; + if (loader->dlloader_exit && loader->dlloader_exit (data)) + { + ++errors; + } + + LT_DLMEM_REASSIGN (loader, next); + } + loaders = 0; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static int +tryall_dlopen (lt_dlhandle *handle, const char *filename) +{ + lt_dlhandle cur; + lt_dlloader *loader; + const char *saved_error; + int errors = 0; + + LT_DLMUTEX_GETERROR (saved_error); + LT_DLMUTEX_LOCK (); + + cur = handles; + loader = loaders; + + /* check whether the module was already opened */ + while (cur) + { + /* try to dlopen the program itself? */ + if (!cur->info.filename && !filename) + { + break; + } + + if (cur->info.filename && filename + && strcmp (cur->info.filename, filename) == 0) + { + break; + } + + cur = cur->next; + } + + if (cur) + { + ++cur->info.ref_count; + *handle = cur; + goto done; + } + + cur = *handle; + if (filename) + { + /* Comment out the check of file permissions using access. + This call seems to always return -1 with error EACCES. + */ + /* We need to catch missing file errors early so that + file_not_found() can detect what happened. + if (access (filename, R_OK) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto done; + } */ + + cur->info.filename = lt_estrdup (filename); + if (!cur->info.filename) + { + ++errors; + goto done; + } + } + else + { + cur->info.filename = 0; + } + + while (loader) + { + lt_user_data data = loader->dlloader_data; + + cur->module = loader->module_open (data, filename); + + if (cur->module != 0) + { + break; + } + loader = loader->next; + } + + if (!loader) + { + LT_DLFREE (cur->info.filename); + ++errors; + goto done; + } + + cur->loader = loader; + LT_DLMUTEX_SETERROR (saved_error); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +tryall_dlopen_module ( + lt_dlhandle *handle, + const char *prefix, + const char *dirname, + const char *dlname) +{ + int error = 0; + char *filename = 0; + size_t filename_len = 0; + size_t dirname_len = LT_STRLEN (dirname); + + assert (handle); + assert (dirname); + assert (dlname); +#ifdef LT_DIRSEP_CHAR + /* Only canonicalized names (i.e. with DIRSEP chars already converted) + should make it into this function: */ + assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); +#endif + + if (dirname_len > 0) + if (dirname[dirname_len -1] == '/') + --dirname_len; + filename_len = dirname_len + 1 + LT_STRLEN (dlname); + + /* Allocate memory, and combine DIRNAME and MODULENAME into it. + The PREFIX (if any) is handled below. */ + filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1); + if (!filename) + return 1; + + sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname); + + /* Now that we have combined DIRNAME and MODULENAME, if there is + also a PREFIX to contend with, simply recurse with the arguments + shuffled. Otherwise, attempt to open FILENAME as a module. */ + if (prefix) + { + error += tryall_dlopen_module (handle, + (const char *) 0, prefix, filename); + } + else if (tryall_dlopen (handle, filename) != 0) + { + ++error; + } + + LT_DLFREE (filename); + return error; +} + +static int +find_module ( + lt_dlhandle *handle, + const char *dir, + const char *libdir, + const char *dlname, + const char *old_name, + int installed) +{ + /* Try to open the old library first; if it was dlpreopened, + we want the preopened version of it, even if a dlopenable + module is available. */ + if (old_name && tryall_dlopen (handle, old_name) == 0) + { + return 0; + } + + /* Try to open the dynamic library. */ + if (dlname) + { + /* try to open the installed module */ + if (installed && libdir) + { + if (tryall_dlopen_module (handle, + (const char *) 0, libdir, dlname) == 0) + return 0; + } + + /* try to open the not-installed module */ + if (!installed) + { + if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) + return 0; + } + + /* maybe it was moved to another directory */ + { + if (tryall_dlopen_module (handle, + (const char *) 0, dir, dlname) == 0) + return 0; + } + } + + return 1; +} + + +static int +canonicalize_path ( + const char *path, + char **pcanonical) +{ + char *canonical = 0; + + assert (path && *path); + assert (pcanonical); + + canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path)); + if (!canonical) + return 1; + + { + size_t dest = 0; + size_t src; + for (src = 0; path[src] != LT_EOS_CHAR; ++src) + { + /* Path separators are not copied to the beginning or end of + the destination, or if another separator would follow + immediately. */ + if (path[src] == LT_PATHSEP_CHAR) + { + if ((dest == 0) + || (path[1+ src] == LT_PATHSEP_CHAR) + || (path[1+ src] == LT_EOS_CHAR)) + continue; + } + + /* Anything other than a directory separator is copied verbatim. */ + if ((path[src] != '/') +#ifdef LT_DIRSEP_CHAR + && (path[src] != LT_DIRSEP_CHAR) +#endif + ) + { + canonical[dest++] = path[src]; + } + /* Directory separators are converted and copied only if they are + not at the end of a path -- i.e. before a path separator or + NULL terminator. */ + else if ((path[1+ src] != LT_PATHSEP_CHAR) + && (path[1+ src] != LT_EOS_CHAR) +#ifdef LT_DIRSEP_CHAR + && (path[1+ src] != LT_DIRSEP_CHAR) +#endif + && (path[1+ src] != '/')) + { + canonical[dest++] = '/'; + } + } + + /* Add an end-of-string marker at the end. */ + canonical[dest] = LT_EOS_CHAR; + } + + /* Assign new value. */ + *pcanonical = canonical; + + return 0; +} + +static int +argzize_path ( + const char *path, + char **pargz, + size_t *pargz_len) +{ + error_t error; + + assert (path); + assert (pargz); + assert (pargz_len); + + if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + + return 1; + } + + return 0; +} + +/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element + of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns + non-zero or all elements are exhausted. If BASE_NAME is non-NULL, + it is appended to each SEARCH_PATH element before FUNC is called. */ +static int +foreach_dirinpath ( + const char *search_path, + const char *base_name, + foreach_callback_func *func, + lt_ptr data1, + lt_ptr data2) +{ + int result = 0; + int filenamesize = 0; + size_t lenbase = LT_STRLEN (base_name); + size_t argz_len = 0; + char *argz = 0; + char *filename = 0; + char *canonical = 0; + + LT_DLMUTEX_LOCK (); + + if (!search_path || !*search_path) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + goto cleanup; + } + + if (canonicalize_path (search_path, &canonical) != 0) + goto cleanup; + + if (argzize_path (canonical, &argz, &argz_len) != 0) + goto cleanup; + + { + char *dir_name = 0; + while ((dir_name = argz_next (argz, argz_len, dir_name))) + { + size_t lendir = LT_STRLEN (dir_name); + + if (lendir +1 +lenbase >= filenamesize) + { + LT_DLFREE (filename); + filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ + filename = LT_EMALLOC (char, filenamesize); + if (!filename) + goto cleanup; + } + + assert (filenamesize > lendir); + strcpy (filename, dir_name); + + if (base_name && *base_name) + { + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, base_name); + } + + if ((result = (*func) (filename, data1, data2))) + { + break; + } + } + } + + cleanup: + LT_DLFREE (argz); + LT_DLFREE (canonical); + LT_DLFREE (filename); + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +/* If FILEPATH can be opened, store the name of the directory component + in DATA1, and the opened FILE* structure address in DATA2. Otherwise + DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ +static int +find_file_callback ( + char *filename, + lt_ptr data1, + lt_ptr data2) +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + assert (filename && *filename); + assert (pdir); + assert (pfile); + + if ((*pfile = fopen (filename, LT_READTEXT_MODE))) + { + char *dirend = strrchr (filename, '/'); + + if (dirend > filename) + *dirend = LT_EOS_CHAR; + + LT_DLFREE (*pdir); + *pdir = lt_estrdup (filename); + is_done = (*pdir == 0) ? -1 : 1; + } + + return is_done; +} + +static FILE * +find_file ( + const char *search_path, + const char *base_name, + char **pdir) +{ + FILE *file = 0; + + foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); + + return file; +} + +static int +find_handle_callback ( + char *filename, + lt_ptr data, + lt_ptr ignored) +{ + lt_dlhandle *handle = (lt_dlhandle *) data; + int notfound = access (filename, R_OK); + + /* Bail out if file cannot be read... */ + if (notfound) + return 0; + + /* Try to dlopen the file, but do not continue searching in any + case. */ + if (tryall_dlopen (handle, filename) != 0) + *handle = 0; + + return 1; +} + +/* If HANDLE was found return it, otherwise return 0. If HANDLE was + found but could not be opened, *HANDLE will be set to 0. */ +static lt_dlhandle * +find_handle ( + const char *search_path, + const char *base_name, + lt_dlhandle *handle) +{ + if (!search_path) + return 0; + + if (!foreach_dirinpath (search_path, base_name, find_handle_callback, + handle, 0)) + return 0; + + return handle; +} + +static int +load_deplibs ( + lt_dlhandle handle, + char *deplibs) +{ +#if LTDL_DLOPEN_DEPLIBS + char *p, *save_search_path = 0; + int depcount = 0; + int i; + char **names = 0; +#endif + int errors = 0; + + handle->depcount = 0; + +#if LTDL_DLOPEN_DEPLIBS + if (!deplibs) + { + return errors; + } + ++errors; + + LT_DLMUTEX_LOCK (); + if (user_search_path) + { + save_search_path = lt_estrdup (user_search_path); + if (!save_search_path) + goto cleanup; + } + + /* extract search paths and count deplibs */ + p = deplibs; + while (*p) + { + if (!isspace ((int) *p)) + { + char *end = p+1; + while (*end && !isspace((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) + { + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (lt_dladdsearchdir(p+2)) + { + goto cleanup; + } + *end = save; + } + else + { + ++depcount; + } + + p = end; + } + else + { + ++p; + } + } + + /* restore the old search path */ + LT_DLFREE (user_search_path); + user_search_path = save_search_path; + + LT_DLMUTEX_UNLOCK (); + + if (!depcount) + { + errors = 0; + goto cleanup; + } + + names = LT_EMALLOC (char *, depcount * sizeof (char*)); + if (!names) + goto cleanup; + + /* now only extract the actual deplibs */ + depcount = 0; + p = deplibs; + while (*p) + { + if (isspace ((int) *p)) + { + ++p; + } + else + { + char *end = p+1; + while (*end && !isspace ((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) + { + char *name; + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (strncmp(p, "-l", 2) == 0) + { + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = LT_EMALLOC (char, 1+ name_len); + if (name) + sprintf (name, "lib%s", p+2); + } + else + name = lt_estrdup(p); + + if (!name) + goto cleanup_names; + + names[depcount++] = name; + *end = save; + } + p = end; + } + } + + /* load the deplibs (in reverse order) + At this stage, don't worry if the deplibs do not load correctly, + they may already be statically linked into the loading application + for instance. There will be a more enlightening error message + later on if the loaded module cannot resolve all of its symbols. */ + if (depcount) + { + int j = 0; + + handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount); + if (!handle->deplibs) + goto cleanup; + + for (i = 0; i < depcount; ++i) + { + handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]); + if (handle->deplibs[j]) + { + ++j; + } + } + + handle->depcount = j; /* Number of successfully loaded deplibs */ + errors = 0; + } + + cleanup_names: + for (i = 0; i < depcount; ++i) + { + LT_DLFREE (names[i]); + } + + cleanup: + LT_DLFREE (names); +#endif + + return errors; +} + +static int +unload_deplibs ( + lt_dlhandle handle) +{ + int i; + int errors = 0; + + if (handle->depcount) + { + for (i = 0; i < handle->depcount; ++i) + { + if (!LT_DLIS_RESIDENT (handle->deplibs[i])) + { + errors += lt_dlclose (handle->deplibs[i]); + } + } + } + + return errors; +} + +static int +trim ( + char **dest, + const char *str) +{ + /* remove the leading and trailing "'" from str + and store the result in dest */ + const char *end = strrchr (str, '\''); + size_t len = LT_STRLEN (str); + char *tmp; + + LT_DLFREE (*dest); + + if (len > 3 && str[0] == '\'') + { + tmp = LT_EMALLOC (char, end - str); + if (!tmp) + return 1; + + strncpy(tmp, &str[1], (end - str) - 1); + tmp[len-3] = LT_EOS_CHAR; + *dest = tmp; + } + else + { + *dest = 0; + } + + return 0; +} + +static int +free_vars ( + char *dlname, + char *oldname, + char *libdir, + char *deplibs) +{ + LT_DLFREE (dlname); + LT_DLFREE (oldname); + LT_DLFREE (libdir); + LT_DLFREE (deplibs); + + return 0; +} + +static int +try_dlopen ( + lt_dlhandle *phandle, + const char *filename) +{ + const char * ext = 0; + const char * saved_error = 0; + char * canonical = 0; + char * base_name = 0; + char * dir = 0; + char * name = 0; + int errors = 0; + lt_dlhandle newhandle; + + assert (phandle); + assert (*phandle == 0); + + LT_DLMUTEX_GETERROR (saved_error); + + /* dlopen self? */ + if (!filename) + { + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + return 1; + + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + newhandle = *phandle; + + /* lt_dlclose()ing yourself is very bad! Disallow it. */ + LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); + + if (tryall_dlopen (&newhandle, 0) != 0) + { + LT_DLFREE (*phandle); + return 1; + } + + goto register_handle; + } + + assert (filename && *filename); + + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (canonicalize_path (filename, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + /* If the canonical module name is a path (relative or absolute) + then split it into a directory part and a name part. */ + base_name = strrchr (canonical, '/'); + if (base_name) + { + size_t dirlen = (1+ base_name) - canonical; + + dir = LT_EMALLOC (char, 1+ dirlen); + if (!dir) + { + ++errors; + goto cleanup; + } + + strncpy (dir, canonical, dirlen); + dir[dirlen] = LT_EOS_CHAR; + + ++base_name; + } + else + { + LT_DLMEM_REASSIGN (base_name, canonical); + canonical = base_name; + } + + assert (base_name && *base_name); + + /* Check whether we are opening a libtool module (.la extension). */ + ext = strrchr (base_name, '.'); + if (ext && strcmp (ext, archive_ext) == 0) + { + /* this seems to be a libtool module */ + FILE * file = 0; + char * dlname = 0; + char * old_name = 0; + char * libdir = 0; + char * deplibs = 0; + char * line = 0; + size_t line_len; + + /* if we can't find the installed flag, it is probably an + installed libtool archive, produced with an old version + of libtool */ + int installed = 1; + + /* extract the module name from the file name */ + name = LT_EMALLOC (char, ext - base_name + 1); + if (!name) + { + ++errors; + goto cleanup; + } + + /* canonicalize the module name */ + { + size_t i; + for (i = 0; i < ext - base_name; ++i) + { + if (isalnum ((int)(base_name[i]))) + { + name[i] = base_name[i]; + } + else + { + name[i] = '_'; + } + } + name[ext - base_name] = LT_EOS_CHAR; + } + + /* Now try to open the .la file. If there is no directory name + component, try to find it first in user_search_path and then other + prescribed paths. Otherwise (or in any case if the module was not + yet found) try opening just the module name as passed. */ + if (!dir) + { + const char *search_path; + + LT_DLMUTEX_LOCK (); + search_path = user_search_path; + if (search_path) + file = find_file (user_search_path, base_name, &dir); + LT_DLMUTEX_UNLOCK (); + + if (!file) + { + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!file) + { + search_path = getenv (LTDL_SHLIBPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!file && sys_search_path) + { + file = find_file (sys_search_path, base_name, &dir); + } +#endif + } + if (!file) + { + file = fopen (filename, LT_READTEXT_MODE); + } + + /* If we didn't find the file by now, it really isn't there. Set + the status flag, and bail out. */ + if (!file) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto cleanup; + } + + line_len = LT_FILENAME_MAX; + line = LT_EMALLOC (char, line_len); + if (!line) + { + fclose (file); + ++errors; + goto cleanup; + } + + /* read the .la file */ + while (!feof (file)) + { + if (!fgets (line, (int) line_len, file)) + { + break; + } + + /* Handle the case where we occasionally need to read a line + that is longer than the initial buffer size. */ + while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file))) + { + line = LT_DLREALLOC (char, line, line_len *2); + if (!fgets (&line[line_len -1], (int) line_len +1, file)) + { + break; + } + line_len *= 2; + } + + if (line[0] == '\n' || line[0] == '#') + { + continue; + } + +#undef STR_DLNAME +#define STR_DLNAME "dlname=" + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) + { + errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); + } + +#undef STR_OLD_LIBRARY +#define STR_OLD_LIBRARY "old_library=" + else if (strncmp (line, STR_OLD_LIBRARY, + sizeof (STR_OLD_LIBRARY) - 1) == 0) + { + errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + } +#undef STR_LIBDIR +#define STR_LIBDIR "libdir=" + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) + { + errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); + } + +#undef STR_DL_DEPLIBS +#define STR_DL_DEPLIBS "dependency_libs=" + else if (strncmp (line, STR_DL_DEPLIBS, + sizeof (STR_DL_DEPLIBS) - 1) == 0) + { + errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + } + else if (strcmp (line, "installed=yes\n") == 0) + { + installed = 1; + } + else if (strcmp (line, "installed=no\n") == 0) + { + installed = 0; + } + +#undef STR_LIBRARY_NAMES +#define STR_LIBRARY_NAMES "library_names=" + else if (! dlname && strncmp (line, STR_LIBRARY_NAMES, + sizeof (STR_LIBRARY_NAMES) - 1) == 0) + { + char *last_libname; + errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && dlname + && (last_libname = strrchr (dlname, ' ')) != 0) + { + last_libname = lt_estrdup (last_libname + 1); + if (!last_libname) + { + ++errors; + goto cleanup; + } + LT_DLMEM_REASSIGN (dlname, last_libname); + } + } + + if (errors) + break; + } + + fclose (file); + LT_DLFREE (line); + + /* allocate the handle */ + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + ++errors; + + if (errors) + { + free_vars (dlname, old_name, libdir, deplibs); + LT_DLFREE (*phandle); + goto cleanup; + } + + assert (*phandle); + + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + if (load_deplibs (*phandle, deplibs) == 0) + { + newhandle = *phandle; + /* find_module may replace newhandle */ + if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) + { + unload_deplibs (*phandle); + ++errors; + } + } + else + { + ++errors; + } + + free_vars (dlname, old_name, libdir, deplibs); + if (errors) + { + LT_DLFREE (*phandle); + goto cleanup; + } + + if (*phandle != newhandle) + { + unload_deplibs (*phandle); + } + } + else + { + /* not a libtool module */ + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + { + ++errors; + goto cleanup; + } + + memset (*phandle, 0, sizeof (struct lt_dlhandle_struct)); + newhandle = *phandle; + + /* If the module has no directory name component, try to find it + first in user_search_path and then other prescribed paths. + Otherwise (or in any case if the module was not yet found) try + opening just the module name as passed. */ + if ((dir || (!find_handle (user_search_path, base_name, &newhandle) + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, + &newhandle) +#ifdef LTDL_SHLIBPATH_VAR + && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, + &newhandle) +#endif +#ifdef LTDL_SYSSEARCHPATH + && !find_handle (sys_search_path, base_name, &newhandle) +#endif + ))) + { + if (tryall_dlopen (&newhandle, filename) != 0) + { + newhandle = NULL; + } + } + + if (!newhandle) + { + LT_DLFREE (*phandle); + ++errors; + goto cleanup; + } + } + + register_handle: + LT_DLMEM_REASSIGN (*phandle, newhandle); + + if ((*phandle)->info.ref_count == 0) + { + (*phandle)->info.ref_count = 1; + LT_DLMEM_REASSIGN ((*phandle)->info.name, name); + + LT_DLMUTEX_LOCK (); + (*phandle)->next = handles; + handles = *phandle; + LT_DLMUTEX_UNLOCK (); + } + + LT_DLMUTEX_SETERROR (saved_error); + + cleanup: + LT_DLFREE (dir); + LT_DLFREE (name); + LT_DLFREE (canonical); + + return errors; +} + +lt_dlhandle +lt_dlopen ( + const char *filename) +{ + lt_dlhandle handle = 0; + + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgets to reset handle... */ + if (try_dlopen (&handle, filename) != 0) + return 0; + + return handle; +} + +/* If the last error messge store was `FILE_NOT_FOUND', then return + non-zero. */ +static int +file_not_found () +{ + const char *error = 0; + + LT_DLMUTEX_GETERROR (error); + if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) + return 1; + + return 0; +} + +/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with SHLIB_EXT appended + instead. */ +lt_dlhandle +lt_dlopenext ( + const char *filename) +{ + lt_dlhandle handle = 0; + char * tmp = 0; + char * ext = 0; + size_t len; + int errors = 0; + + if (!filename) + { + return lt_dlopen (filename); + } + + assert (filename); + + len = LT_STRLEN (filename); + ext = strrchr ((char *)filename, '.'); + + /* If FILENAME already bears a suitable extension, there is no need + to try appending additional extensions. */ + if (ext && ((strcmp (ext, archive_ext) == 0) +#ifdef LTDL_SHLIB_EXT + || (strcmp (ext, shlib_ext) == 0) +#endif + )) + { + return lt_dlopen (filename); + } + + /* First try appending ARCHIVE_EXT. */ + tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + strcat (tmp, archive_ext); + errors = try_dlopen (&handle, tmp); + + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && !file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } + +#ifdef LTDL_SHLIB_EXT + /* Try appending SHLIB_EXT. */ + if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) + { + LT_DLFREE (tmp); + tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + } + else + { + tmp[len] = LT_EOS_CHAR; + } + + strcat(tmp, shlib_ext); + errors = try_dlopen (&handle, tmp); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && !file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } +#endif + + /* Still here? Then we really did fail to locate any of the file + names we tried. */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT_DLFREE (tmp); + return 0; +} + + +static int +lt_argz_insert ( + char **pargz, + size_t *pargz_len, + char *before, + const char *entry) +{ + error_t error; + + if ((error = argz_insert (pargz, pargz_len, before, entry))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + return 1; + } + + return 0; +} + +static int +lt_argz_insertinorder ( + char **pargz, + size_t *pargz_len, + const char *entry) +{ + char *before = 0; + + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + if (*pargz) + while ((before = argz_next (*pargz, *pargz_len, before))) + { + int cmp = strcmp (entry, before); + + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ + } + + return lt_argz_insert (pargz, pargz_len, before, entry); +} + +static int +lt_argz_insertdir ( + char **pargz, + size_t *pargz_len, + const char *dirnam, + struct dirent *dp) +{ + char *buf = 0; + size_t buf_len = 0; + char *end = 0; + size_t end_offset = 0; + size_t dir_len = 0; + int errors = 0; + + assert (pargz); + assert (pargz_len); + assert (dp); + + dir_len = LT_STRLEN (dirnam); + end = dp->d_name + LT_D_NAMLEN(dp); + + /* Ignore version numbers. */ + { + char *p; + for (p = end; p -1 > dp->d_name; --p) + if (strchr (".0123456789", p[-1]) == 0) + break; + + if (*p == '.') + end = p; + } + + /* Ignore filename extension. */ + { + char *p; + for (p = end -1; p > dp->d_name; --p) + if (*p == '.') + { + end = p; + break; + } + } + + /* Prepend the directory name. */ + end_offset = end - dp->d_name; + buf_len = dir_len + 1+ end_offset; + buf = LT_EMALLOC (char, 1+ buf_len); + if (!buf) + return ++errors; + + assert (buf); + + strcpy (buf, dirnam); + strcat (buf, "/"); + strncat (buf, dp->d_name, end_offset); + buf[buf_len] = LT_EOS_CHAR; + + /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ + if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) + ++errors; + + LT_DLFREE (buf); + + return errors; +} + +static int +list_files_by_dir ( + const char *dirnam, + char **pargz, + size_t *pargz_len) +{ + DIR *dirp = 0; + int errors = 0; + + assert (dirnam && *dirnam); + assert (pargz); + assert (pargz_len); + assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); + + dirp = opendir (dirnam); + if (dirp) + { + struct dirent *dp = 0; + + while ((dp = readdir (dirp))) + if (dp->d_name[0] != '.') + if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) + { + ++errors; + break; + } + + closedir (dirp); + } + else + ++errors; + + return errors; +} + + +/* If there are any files in DIRNAME, call the function passed in + DATA1 (with the name of each file and DATA2 as arguments). */ +static int +foreachfile_callback ( + char *dirname, + lt_ptr data1, + lt_ptr data2) +{ + int (*func) LT_PARAMS((const char *filename, lt_ptr data)) + = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; + + int is_done = 0; + char *argz = 0; + size_t argz_len = 0; + + if (list_files_by_dir (dirname, &argz, &argz_len) != 0) + goto cleanup; + if (!argz) + goto cleanup; + + { + char *filename = 0; + while ((filename = argz_next (argz, argz_len, filename))) + if ((is_done = (*func) (filename, data2))) + break; + } + + cleanup: + LT_DLFREE (argz); + + return is_done; +} + + +/* Call FUNC for each unique extensionless file in SEARCH_PATH, along + with DATA. The filenames passed to FUNC would be suitable for + passing to lt_dlopenext. The extensions are stripped so that + individual modules do not generate several entries (e.g. libfoo.la, + libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, + then the same directories that lt_dlopen would search are examined. */ +int +lt_dlforeachfile ( + const char *search_path, + int (*func) LT_PARAMS ((const char *filename, lt_ptr data)), + lt_ptr data) +{ + int is_done = 0; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, + foreachfile_callback, (void*)func, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, + foreachfile_callback, (void*)func, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, + foreachfile_callback, (void*)func, data); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, + foreachfile_callback, (void*)func, data); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, + foreachfile_callback, (void*)func, data); + } +#endif + } + + return is_done; +} + +int +lt_dlclose ( + lt_dlhandle handle) +{ + lt_dlhandle cur, last; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* check whether the handle is valid */ + last = cur = handles; + while (cur && handle != cur) + { + last = cur; + cur = cur->next; + } + + if (!cur) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + goto done; + } + + handle->info.ref_count--; + + /* Note that even with resident modules, we must track the ref_count + correctly incase the user decides to reset the residency flag + later (even though the API makes no provision for that at the + moment). */ + if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle)) + { + lt_user_data data = handle->loader->dlloader_data; + + if (handle != handles) + { + last->next = handle->next; + } + else + { + handles = handle->next; + } + + errors += handle->loader->module_close (data, handle->module); + errors += unload_deplibs(handle); + + /* It is up to the callers to free the data itself. */ + LT_DLFREE (handle->caller_data); + + LT_DLFREE (handle->info.filename); + LT_DLFREE (handle->info.name); + LT_DLFREE (handle); + + goto done; + } + + if (LT_DLIS_RESIDENT (handle)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE)); + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_ptr +lt_dlsym ( + lt_dlhandle handle, + const char *symbol) +{ + size_t lensym; + char lsym[LT_SYMBOL_LENGTH]; + char *sym; + lt_ptr address; + lt_user_data data; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + if (!symbol) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + return 0; + } + + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix) + + LT_STRLEN (handle->info.name); + + if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) + { + sym = lsym; + } + else + { + sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); + if (!sym) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW)); + return 0; + } + } + + data = handle->loader->dlloader_data; + if (handle->info.name) + { + const char *saved_error; + + LT_DLMUTEX_GETERROR (saved_error); + + /* this is a libtool module */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, handle->info.name); + } + else + { + strcpy(sym, handle->info.name); + } + + strcat(sym, "_LTX_"); + strcat(sym, symbol); + + /* try "modulename_LTX_symbol" */ + address = handle->loader->find_sym (data, handle->module, sym); + if (address) + { + if (sym != lsym) + { + LT_DLFREE (sym); + } + return address; + } + LT_DLMUTEX_SETERROR (saved_error); + } + + /* otherwise try "symbol" */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, symbol); + } + else + { + strcpy(sym, symbol); + } + + address = handle->loader->find_sym (data, handle->module, sym); + if (sym != lsym) + { + LT_DLFREE (sym); + } + + return address; +} + +const char * +lt_dlerror () +{ + const char *error; + + LT_DLMUTEX_GETERROR (error); + LT_DLMUTEX_SETERROR (0); + + return error ? error : NULL; +} + +static int +lt_dlpath_insertdir ( + char **ppath, + char *before, + const char *dir) +{ + int errors = 0; + char *canonical = 0; + char *argz = 0; + size_t argz_len = 0; + + assert (ppath); + assert (dir && *dir); + + if (canonicalize_path (dir, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + assert (canonical && *canonical); + + /* If *PPATH is empty, set it to DIR. */ + if (*ppath == 0) + { + assert (!before); /* BEFORE cannot be set without PPATH. */ + assert (dir); /* Without DIR, don't call this function! */ + + *ppath = lt_estrdup (dir); + if (*ppath == 0) + ++errors; + + return errors; + } + + assert (ppath && *ppath); + + if (argzize_path (*ppath, &argz, &argz_len) != 0) + { + ++errors; + goto cleanup; + } + + /* Convert BEFORE into an equivalent offset into ARGZ. This only works + if *PPATH is already canonicalized, and hence does not change length + with respect to ARGZ. We canonicalize each entry as it is added to + the search path, and don't call this function with (uncanonicalized) + user paths, so this is a fair assumption. */ + if (before) + { + assert (*ppath <= before); + assert (before - *ppath <= strlen (*ppath)); + + before = before - *ppath + argz; + } + + if (lt_argz_insert (&argz, &argz_len, before, dir) != 0) + { + ++errors; + goto cleanup; + } + + argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); + LT_DLMEM_REASSIGN (*ppath, argz); + + cleanup: + LT_DLFREE (canonical); + LT_DLFREE (argz); + + return errors; +} + +int +lt_dladdsearchdir ( + const char *search_dir) +{ + int errors = 0; + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlinsertsearchdir ( + const char *before, + const char *search_dir) +{ + int errors = 0; + + if (before) + { + LT_DLMUTEX_LOCK (); + if ((before < user_search_path) + || (before >= user_search_path + LT_STRLEN (user_search_path))) + { + LT_DLMUTEX_UNLOCK (); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION)); + return 1; + } + LT_DLMUTEX_UNLOCK (); + } + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, + (char *) before, search_dir) != 0) + { + ++errors; + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlsetsearchpath ( + const char *search_path) +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + LT_DLFREE (user_search_path); + LT_DLMUTEX_UNLOCK (); + + if (!search_path || !LT_STRLEN (search_path)) + { + return errors; + } + + LT_DLMUTEX_LOCK (); + if (canonicalize_path (search_path, &user_search_path) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +const char * +lt_dlgetsearchpath () +{ + const char *saved_path; + + LT_DLMUTEX_LOCK (); + saved_path = user_search_path; + LT_DLMUTEX_UNLOCK (); + + return saved_path; +} + +int +lt_dlmakeresident ( + lt_dlhandle handle) +{ + int errors = 0; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + } + else + { + LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + } + + return errors; +} + +int +lt_dlisresident ( + lt_dlhandle handle) +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return -1; + } + + return LT_DLIS_RESIDENT (handle); +} + + + + +/* --- MODULE INFORMATION --- */ + +const lt_dlinfo * +lt_dlgetinfo ( + lt_dlhandle handle) +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + return &(handle->info); +} + +lt_dlhandle +lt_dlhandle_next ( + lt_dlhandle place) +{ + return place ? place->next : handles; +} + +int +lt_dlforeach ( + int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data)), + lt_ptr data) +{ + int errors = 0; + lt_dlhandle cur; + + LT_DLMUTEX_LOCK (); + + cur = handles; + while (cur) + { + lt_dlhandle tmp = cur; + + cur = cur->next; + if ((*func) (tmp, data)) + { + ++errors; + break; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_dlcaller_id +lt_dlcaller_register () +{ + static lt_dlcaller_id last_caller_id = 0; + int result; + + LT_DLMUTEX_LOCK (); + result = ++last_caller_id; + LT_DLMUTEX_UNLOCK (); + + return result; +} + +lt_ptr +lt_dlcaller_set_data ( + lt_dlcaller_id key, + lt_dlhandle handle, + lt_ptr data) +{ + int n_elements = 0; + lt_ptr stale = (lt_ptr) 0; + int i; + + /* This needs to be locked so that the caller data can be updated + simultaneously by different threads. */ + LT_DLMUTEX_LOCK (); + + if (handle->caller_data) + while (handle->caller_data[n_elements].key) + ++n_elements; + + for (i = 0; i < n_elements; ++i) + { + if (handle->caller_data[i].key == key) + { + stale = handle->caller_data[i].data; + break; + } + } + + /* Ensure that there is enough room in this handle's caller_data + array to accept a new element (and an empty end marker). */ + if (i == n_elements) + { + lt_caller_data *temp + = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements); + + if (!temp) + { + stale = 0; + goto done; + } + + handle->caller_data = temp; + + /* We only need this if we needed to allocate a new caller_data. */ + handle->caller_data[i].key = key; + handle->caller_data[1+ i].key = 0; + } + + handle->caller_data[i].data = data; + + done: + LT_DLMUTEX_UNLOCK (); + + return stale; +} + +lt_ptr +lt_dlcaller_get_data ( + lt_dlcaller_id key, + lt_dlhandle handle) +{ + lt_ptr result = (lt_ptr) 0; + + /* This needs to be locked so that the caller data isn't updated by + another thread part way through this function. */ + LT_DLMUTEX_LOCK (); + + /* Locate the index of the element with a matching KEY. */ + { + int i; + for (i = 0; handle->caller_data[i].key; ++i) + { + if (handle->caller_data[i].key == key) + { + result = handle->caller_data[i].data; + break; + } + } + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + + + +/* --- USER MODULE LOADER API --- */ + + +int +lt_dlloader_add ( + lt_dlloader *place, + const struct lt_user_dlloader *dlloader, + const char *loader_name) +{ + int errors = 0; + lt_dlloader *node = 0, *ptr = 0; + + if ((dlloader == 0) /* diagnose null parameters */ + || (dlloader->module_open == 0) + || (dlloader->module_close == 0) + || (dlloader->find_sym == 0)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + /* Create a new dlloader node with copies of the user callbacks. */ + node = LT_EMALLOC (lt_dlloader, 1); + if (!node) + return 1; + + node->next = 0; + node->loader_name = loader_name; + node->sym_prefix = dlloader->sym_prefix; + node->dlloader_exit = dlloader->dlloader_exit; + node->module_open = dlloader->module_open; + node->module_close = dlloader->module_close; + node->find_sym = dlloader->find_sym; + node->dlloader_data = dlloader->dlloader_data; + + LT_DLMUTEX_LOCK (); + if (!loaders) + { + /* If there are no loaders, NODE becomes the list! */ + loaders = node; + } + else if (!place) + { + /* If PLACE is not set, add NODE to the end of the + LOADERS list. */ + for (ptr = loaders; ptr->next; ptr = ptr->next) + { + /*NOWORK*/; + } + + ptr->next = node; + } + else if (loaders == place) + { + /* If PLACE is the first loader, NODE goes first. */ + node->next = place; + loaders = node; + } + else + { + /* Find the node immediately preceding PLACE. */ + for (ptr = loaders; ptr->next != place; ptr = ptr->next) + { + /*NOWORK*/; + } + + if (ptr->next != place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + ++errors; + } + else + { + /* Insert NODE between PTR and PLACE. */ + node->next = place; + ptr->next = node; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +lt_dlloader_remove ( + const char *loader_name) +{ + lt_dlloader *place = lt_dlloader_find (loader_name); + lt_dlhandle handle; + int errors = 0; + + if (!place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + LT_DLMUTEX_LOCK (); + + /* Fail if there are any open modules which use this loader. */ + for (handle = handles; handle; handle = handle->next) + { + if (handle->loader == place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER)); + ++errors; + goto done; + } + } + + if (place == loaders) + { + /* PLACE is the first loader in the list. */ + loaders = loaders->next; + } + else + { + /* Find the loader before the one being removed. */ + lt_dlloader *prev; + for (prev = loaders; prev->next; prev = prev->next) + { + if (!strcmp (prev->next->loader_name, loader_name)) + { + break; + } + } + + place = prev->next; + if (prev->next) prev->next = prev->next->next; + } + + if (place && place->dlloader_exit) + { + errors = place->dlloader_exit (place->dlloader_data); + } + + LT_DLFREE (place); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_dlloader * +lt_dlloader_next ( + lt_dlloader *place) +{ + lt_dlloader *next; + + LT_DLMUTEX_LOCK (); + next = place ? place->next : loaders; + LT_DLMUTEX_UNLOCK (); + + return next; +} + +const char * +lt_dlloader_name ( + lt_dlloader *place) +{ + const char *name = 0; + + if (place) + { + LT_DLMUTEX_LOCK (); + name = place ? place->loader_name : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return name; +} + +lt_user_data * +lt_dlloader_data ( + lt_dlloader *place) +{ + lt_user_data *data = 0; + + if (place) + { + LT_DLMUTEX_LOCK (); + data = place ? &(place->dlloader_data) : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return data; +} + +lt_dlloader * +lt_dlloader_find ( + const char *loader_name) +{ + lt_dlloader *place = 0; + + LT_DLMUTEX_LOCK (); + for (place = loaders; place; place = place->next) + { + if (strcmp (place->loader_name, loader_name) == 0) + { + break; + } + } + LT_DLMUTEX_UNLOCK (); + + return place; +} + +} // namespace scim diff --git a/ism/src/ltdl.h b/ism/src/ltdl.h new file mode 100644 index 0000000..87ba067 --- /dev/null +++ b/ism/src/ltdl.h @@ -0,0 +1,369 @@ +/* ltdl.h -- generic dlopen functions + Copyright (C) 1998-2000 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA +*/ + +/* Only include this header file once. */ +#ifndef LTDL_H +#define LTDL_H 1 + +#include /* for size_t declaration */ +namespace scim { + + +/* --- MACROS FOR PORTABILITY --- */ + + +/* Saves on those hard to debug '\0' typos.... */ +#define LT_EOS_CHAR '\0' + +/* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, + so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at + the end of C declarations. */ +#ifdef __cplusplus +# define LT_BEGIN_C_DECLS extern "C" { +# define LT_END_C_DECLS } +#else +# define LT_BEGIN_C_DECLS /* empty */ +# define LT_END_C_DECLS /* empty */ +#endif + +//LT_BEGIN_C_DECLS + + +/* LT_PARAMS is a macro used to wrap function prototypes, so that compilers + that don't understand ANSI C prototypes still work, and ANSI C + compilers can issue warnings about type mismatches. */ +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus) +# define LT_PARAMS(protos) protos +# define lt_ptr void* +#else +# define LT_PARAMS(protos) () +# define lt_ptr char* +#endif + +/* LT_STMT_START/END are used to create macros which expand to a + a single compound statement in a portable way. */ +#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) +# define LT_STMT_START (void)( +# define LT_STMT_END ) +#else +# if (defined (sun) || defined (__sun__)) +# define LT_STMT_START if (1) +# define LT_STMT_END else (void)0 +# else +# define LT_STMT_START do +# define LT_STMT_END while (0) +# endif +#endif + +/* LT_CONC creates a new concatenated symbol for the compiler + in a portable way. */ +#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER) +# define LT_CONC(s,t) s##t +#else +# define LT_CONC(s,t) s/**/t +#endif + +/* LT_STRLEN can be used safely on NULL pointers. */ +#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) + + + +/* --- WINDOWS SUPPORT --- */ + + +/* Canonicalise Windows and Cygwin recognition macros. */ +#ifdef __CYGWIN32__ +# ifndef __CYGWIN__ +# define __CYGWIN__ __CYGWIN32__ +# endif +#endif +#if defined(_WIN32) || defined(WIN32) +# ifndef __WINDOWS__ +# ifdef _WIN32 +# define __WINDOWS__ _WIN32 +# else +# ifdef WIN32 +# define __WINDOWS__ WIN32 +# endif +# endif +# endif +#endif + + +#ifdef __WINDOWS__ +# ifndef __CYGWIN__ +/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory + separator when it is set. */ +# define LT_DIRSEP_CHAR '\\' +# define LT_PATHSEP_CHAR ';' +# endif +#endif +#ifndef LT_PATHSEP_CHAR +# define LT_PATHSEP_CHAR ':' +#endif + +/* DLL building support on win32 hosts; mostly to workaround their + ridiculous implementation of data symbol exporting. */ +#ifndef LT_SCOPE +# ifdef __WINDOWS__ +# ifdef DLL_EXPORT /* defined by libtool (if required) */ +# define LT_SCOPE __declspec(dllexport) +# endif +# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */ +# define LT_SCOPE extern __declspec(dllimport) +# endif +# endif +# ifndef LT_SCOPE /* static linking or !__WINDOWS__ */ +# define LT_SCOPE extern +# endif +#endif + + +#if defined(_MSC_VER) /* Visual Studio */ +# define R_OK 4 +#endif + + + +/* --- DYNAMIC MODULE LOADING API --- */ + + +typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */ + +/* Initialisation and finalisation functions for libltdl. */ +LT_SCOPE int lt_dlinit LT_PARAMS((void)); +LT_SCOPE int lt_dlexit LT_PARAMS((void)); + +/* Module search path manipulation. */ +LT_SCOPE int lt_dladdsearchdir LT_PARAMS((const char *search_dir)); +LT_SCOPE int lt_dlinsertsearchdir LT_PARAMS((const char *before, + const char *search_dir)); +LT_SCOPE int lt_dlsetsearchpath LT_PARAMS((const char *search_path)); +LT_SCOPE const char *lt_dlgetsearchpath LT_PARAMS((void)); +LT_SCOPE int lt_dlforeachfile LT_PARAMS(( + const char *search_path, + int (*func) (const char *filename, lt_ptr data), + lt_ptr data)); + +/* Portable libltdl versions of the system dlopen() API. */ +LT_SCOPE lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); +LT_SCOPE lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename)); +LT_SCOPE lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle, + const char *name)); +LT_SCOPE const char *lt_dlerror LT_PARAMS((void)); +LT_SCOPE int lt_dlclose LT_PARAMS((lt_dlhandle handle)); + +/* Module residency management. */ +LT_SCOPE int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE int lt_dlisresident LT_PARAMS((lt_dlhandle handle)); + + + + +/* --- MUTEX LOCKING --- */ + + +typedef void lt_dlmutex_lock LT_PARAMS((void)); +typedef void lt_dlmutex_unlock LT_PARAMS((void)); +typedef void lt_dlmutex_seterror LT_PARAMS((const char *errmsg)); +typedef const char *lt_dlmutex_geterror LT_PARAMS((void)); + +LT_SCOPE int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock, + lt_dlmutex_unlock *unlock, + lt_dlmutex_seterror *seterror, + lt_dlmutex_geterror *geterror)); + + + + +/* --- MEMORY HANDLING --- */ + + +/* By default, the realloc function pointer is set to our internal + realloc implementation which iself uses lt_dlmalloc and lt_dlfree. + libltdl relies on a featureful realloc, but if you are sure yours + has the right semantics then you can assign it directly. Generally, + it is safe to assign just a malloc() and a free() function. */ +LT_SCOPE lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)); +LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)); +LT_SCOPE void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)); + + + + +/* --- PRELOADED MODULE SUPPORT --- */ + + +/* A preopened symbol. Arrays of this type comprise the exported + symbols for a dlpreopened module. */ +typedef struct { + const char *name; + lt_ptr address; +} lt_dlsymlist; + +LT_SCOPE int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded)); +LT_SCOPE int lt_dlpreload_default + LT_PARAMS((const lt_dlsymlist *preloaded)); + +#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ + extern const lt_dlsymlist lt_preloaded_symbols[]; \ + lt_dlpreload_default(lt_preloaded_symbols); \ + }LT_STMT_END + + + + +/* --- MODULE INFORMATION --- */ + + +/* Read only information pertaining to a loaded module. */ +typedef struct { + char *filename; /* file name */ + char *name; /* module name */ + int ref_count; /* number of times lt_dlopened minus + number of times lt_dlclosed. */ +} lt_dlinfo; + +LT_SCOPE const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place)); +LT_SCOPE int lt_dlforeach LT_PARAMS(( + int (*func) (lt_dlhandle handle, lt_ptr data), + lt_ptr data)); + +/* Associating user data with loaded modules. */ +typedef unsigned lt_dlcaller_id; + +LT_SCOPE lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void)); +LT_SCOPE lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key, + lt_dlhandle handle, + lt_ptr data)); +LT_SCOPE lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key, + lt_dlhandle handle)); + + + +/* --- USER MODULE LOADER API --- */ + + +typedef struct lt_dlloader lt_dlloader; +typedef lt_ptr lt_user_data; +typedef lt_ptr lt_module; + +/* Function pointer types for creating user defined module loaders. */ +typedef lt_module lt_module_open LT_PARAMS((lt_user_data loader_data, + const char *filename)); +typedef int lt_module_close LT_PARAMS((lt_user_data loader_data, + lt_module handle)); +typedef lt_ptr lt_find_sym LT_PARAMS((lt_user_data loader_data, + lt_module handle, + const char *symbol)); +typedef int lt_dlloader_exit LT_PARAMS((lt_user_data loader_data)); + +struct lt_user_dlloader { + const char *sym_prefix; + lt_module_open *module_open; + lt_module_close *module_close; + lt_find_sym *find_sym; + lt_dlloader_exit *dlloader_exit; + lt_user_data dlloader_data; +}; + +LT_SCOPE lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place)); +LT_SCOPE lt_dlloader *lt_dlloader_find LT_PARAMS(( + const char *loader_name)); +LT_SCOPE const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place)); +LT_SCOPE lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place)); +LT_SCOPE int lt_dlloader_add LT_PARAMS((lt_dlloader *place, + const struct lt_user_dlloader *dlloader, + const char *loader_name)); +LT_SCOPE int lt_dlloader_remove LT_PARAMS(( + const char *loader_name)); + + + +/* --- ERROR MESSAGE HANDLING --- */ + + +/* Defining error strings alongside their symbolic names in a macro in + this way allows us to expand the macro in different contexts with + confidence that the enumeration of symbolic names will map correctly + onto the table of error strings. */ +#define lt_dlerror_table \ + LT_ERROR(UNKNOWN, "unknown error") \ + LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \ + LT_ERROR(INVALID_LOADER, "invalid loader") \ + LT_ERROR(INIT_LOADER, "loader initialization failed") \ + LT_ERROR(REMOVE_LOADER, "loader removal failed") \ + LT_ERROR(FILE_NOT_FOUND, "file not found") \ + LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \ + LT_ERROR(NO_SYMBOLS, "no symbols defined") \ + LT_ERROR(CANNOT_OPEN, "can't open the module") \ + LT_ERROR(CANNOT_CLOSE, "can't close the module") \ + LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \ + LT_ERROR(NO_MEMORY, "not enough memory") \ + LT_ERROR(INVALID_HANDLE, "invalid module handle") \ + LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \ + LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \ + LT_ERROR(SHUTDOWN, "library already shutdown") \ + LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \ + LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \ + LT_ERROR(INVALID_POSITION, "invalid search path insert position") + +/* Enumerate the symbolic error names. */ +enum { +#define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name), + lt_dlerror_table +#undef LT_ERROR + + LT_ERROR_MAX +}; + +/* These functions are only useful from inside custom module loaders. */ +LT_SCOPE int lt_dladderror LT_PARAMS((const char *diagnostic)); +LT_SCOPE int lt_dlseterror LT_PARAMS((int errorcode)); + + + + +/* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */ + + +#ifdef LT_NON_POSIX_NAMESPACE +# define lt_ptr_t lt_ptr +# define lt_module_t lt_module +# define lt_module_open_t lt_module_open +# define lt_module_close_t lt_module_close +# define lt_find_sym_t lt_find_sym +# define lt_dlloader_exit_t lt_dlloader_exit +# define lt_dlloader_t lt_dlloader +# define lt_dlloader_data_t lt_user_data +#endif + +//LT_END_C_DECLS + +} // namespace scim + +#endif /* !LTDL_H */ diff --git a/ism/src/scim.cpp b/ism/src/scim.cpp new file mode 100644 index 0000000..1687b30 --- /dev/null +++ b/ism/src/scim.cpp @@ -0,0 +1,347 @@ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim.cpp,v 1.51 2005/06/15 00:19:08 suzhe Exp $ + * + */ + +#define Uses_SCIM_FRONTEND_MODULE +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_HELPER_MODULE +#define Uses_SCIM_BACKEND +#define Uses_SCIM_CONFIG_PATH +#define Uses_SCIM_TRANSACTION +#define Uses_C_LOCALE +#define Uses_SCIM_UTILITY +#include "scim_private.h" +#include +#include +#include +#include +#include +#include + +using namespace scim; +using std::cout; +using std::cerr; +using std::endl; + +static bool check_socket_frontend (void) +{ + SocketAddress address; + SocketClient client; + + uint32 magic; + + address.set_address (scim_get_default_socket_frontend_address ()); + + if (!client.connect (address)) + return false; + + if (!scim_socket_open_connection (magic, + String ("ConnectionTester"), + String ("SocketFrontEnd"), + client, + 1000)) { + return false; + } + + return true; +} + +int main (int argc, char *argv []) +{ + struct tms tiks_buf; + clock_t clock_start = times (&tiks_buf); + + BackEndPointer backend; + + std::vector frontend_list; + std::vector config_list; + std::vector engine_list; + std::vector helper_list; + std::vector exclude_engine_list; + std::vector load_engine_list; + std::vector all_engine_list; + + std::vector::iterator it; + + String def_frontend ("socket"); + String def_config ("simple"); + + int i; + bool daemon = false; + bool socket = true; + bool manual = false; + + int new_argc = 0; + char *new_argv [80]; + + /* Display version info */ + cout << "Input Service Manager " << ISF_VERSION << "\n\n"; + + /* Get modules list */ + scim_get_frontend_module_list (frontend_list); + config_list.push_back ("simple"); + config_list.push_back ("socket"); + + scim_get_imengine_module_list (engine_list); + scim_get_helper_module_list (helper_list); + + for (it = engine_list.begin (); it != engine_list.end (); it++) { + all_engine_list.push_back (*it); + if (*it != "socket") + load_engine_list.push_back (*it); + } + for (it = helper_list.begin (); it != helper_list.end (); it++) { + all_engine_list.push_back (*it); + load_engine_list.push_back (*it); + } + + /* Use x11 FrontEnd as default if available. */ + if (frontend_list.size ()) { + def_frontend = String ("x11"); + if (std::find (frontend_list.begin (), + frontend_list.end (), + def_frontend) == frontend_list.end ()) + def_frontend = frontend_list [0]; + } + + /* Use simple Config module as default if available. */ + def_config = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE, String ("simple")); + if (std::find (config_list.begin (), + config_list.end (), + def_config) == config_list.end ()) + def_config = config_list [0]; + + /* If no Socket Config/IMEngine/FrontEnd modules */ + /* then do not try to start a SocketFrontEnd. */ + if (std::find (frontend_list.begin (), frontend_list.end (), "socket") == frontend_list.end () || + std::find (config_list.begin (), config_list.end (), "socket") == config_list.end () || + std::find (engine_list.begin (), engine_list.end (), "socket") == engine_list.end ()) + socket = false; + + /* parse command options */ + i = 0; + while (i < argc) { + if (++i >= argc) break; + + if (String ("-l") == argv [i] || + String ("--list") == argv [i]) { + + cout << endl; + cout << "Available FrontEnd module:\n"; + for (it = frontend_list.begin (); it != frontend_list.end (); it++) + cout << " " << *it << endl; + + cout << endl; + cout << "Available Config module:\n"; + for (it = config_list.begin (); it != config_list.end (); it++) { + if (*it != "dummy") + cout << " " << *it << endl; + } + + cout << endl; + cout << "Available ISEngine module:\n"; + for (it = all_engine_list.begin (); it != all_engine_list.end (); it++) + cout << " " << *it << endl; + + return 0; + } + + if (String ("-f") == argv [i] || + String ("--frontend") == argv [i]) { + if (++i >= argc) { + cerr << "No argument for option " << argv [i-1] << endl; + return -1; + } + def_frontend = argv [i]; + continue; + } + + if (String ("-c") == argv [i] || + String ("--config") == argv [i]) { + if (++i >= argc) { + cerr << "No argument for option " << argv [i-1] << endl; + return -1; + } + def_config = argv [i]; + continue; + } + + if (String ("-h") == argv [i] || + String ("--help") == argv [i]) { + cout << "Usage: " << argv [0] << " [option]...\n\n" + << "The options are: \n" + << " -l, --list List all of available modules.\n" + << " -f, --frontend name Use specified FrontEnd module.\n" + << " -c, --config name Use specified Config module.\n" + << " -e, --engines name Load specified set of ISEngines.\n" + << " -ne,--no-engines name Do not load those set of ISEngines.\n" + << " -d, --daemon Run as a daemon.\n" + << " --no-socket Do not try to start a SocketFrontEnd daemon.\n" + << " -h, --help Show this help message.\n"; + return 0; + } + + if (String ("-d") == argv [i] || + String ("--daemon") == argv [i]) { + daemon = true; + continue; + } + + if (String ("-e") == argv [i] || String ("-s") == argv [i] || + String ("--engines") == argv [i] || String ("--servers") == argv [i]) { + if (++i >= argc) { + cerr << "No argument for option " << argv [i-1] << endl; + return -1; + } + load_engine_list.clear (); + scim_split_string_list (load_engine_list, String (argv [i]), ','); + manual = true; + continue; + } + + if (String ("-ne") == argv [i] || String ("-ns") == argv [i] || + String ("--no-engines") == argv [i] || String ("-no-servers") == argv [i]) { + if (++i >= argc) { + cerr << "No argument for option " << argv [i-1] << endl; + return -1; + } + scim_split_string_list (exclude_engine_list, String (argv [i]), ','); + manual = true; + continue; + } + + if (String ("--no-socket") == argv [i]) { + socket = false; + continue; + } + + if (String ("--") == argv [i]) + break; + + cerr << "Invalid command line option: " << argv [i] << "\n"; + return -1; + } /* End of command line parsing. */ + + /* Store the rest argvs into new_argv. */ + for (++i; i < argc; ++i) { + new_argv [new_argc ++] = argv [i]; + } + + new_argv [new_argc] = 0; + + /* Get the imengine module list which should be loaded. */ + if (exclude_engine_list.size ()) { + load_engine_list.clear (); + for (i = 0; i < (int)all_engine_list.size (); ++i) { + if (std::find (exclude_engine_list.begin (), + exclude_engine_list.end (), + all_engine_list [i]) == exclude_engine_list.end () && + all_engine_list [i] != "socket") + load_engine_list.push_back (all_engine_list [i]); + } + } + + if (!def_frontend.length ()) { + cerr << "No FrontEnd module is available!\n"; + return -1; + } + + if (!def_config.length ()) { + cerr << "No Config module is available!\n"; + return -1; + } + + /* If you try to use the socket feature manually, + then let you do it by yourself. */ + if (def_frontend == "socket" || def_config == "socket" || + std::find (load_engine_list.begin (), load_engine_list.end (), "socket") != load_engine_list.end ()) + socket = false; + + /* If the socket address of SocketFrontEnd and SocketIMEngine/SocketConfig are different, + then do not try to start the SocketFrontEnd instance automatically. */ + if (scim_get_default_socket_frontend_address () != scim_get_default_socket_imengine_address () || + scim_get_default_socket_frontend_address () != scim_get_default_socket_config_address ()) + socket = false; + + /* Try to start a SocketFrontEnd daemon first. */ + if (socket) { + /* If no Socket FrontEnd is running, then launch one. + And set manual to false. */ + if (!check_socket_frontend ()) { + cerr << "Launching a daemon with Socket FrontEnd...\n"; + char *argv [] = { const_cast ("--stay"), 0 }; + scim_launch (true, + def_config, + (load_engine_list.size () ? scim_combine_string_list (load_engine_list, ',') : "none"), + "socket", + argv); + manual = false; + } + + /* If there is one Socket FrontEnd running and it's not manual mode, + then just use this Socket Frontend. */ + if (!manual) { + for (int i = 0; i < 100; ++i) { + if (check_socket_frontend ()) { + def_config = "socket"; + load_engine_list.clear (); + load_engine_list.push_back ("socket"); + break; + } + scim_usleep (100000); + } + } + } + + cerr << "Launching a process with " << def_frontend << " FrontEnd...\n"; + + /* Launch the scim process. */ + if (scim_launch (daemon, + def_config, + (load_engine_list.size () ? scim_combine_string_list (load_engine_list, ',') : "none"), + def_frontend, + new_argv) == 0) { + if (daemon) + cerr << "ISM has been successfully launched.\n"; + else + cerr << "ISM has exited successfully.\n"; + + gettime (clock_start, "ISM launch time"); + + return 0; + } + + if (daemon) + cerr << "Failed to launch ISM.\n"; + else + cerr << "ISM has exited abnormally.\n"; + + return 1; +} + +/* +vi:ts=4:ai:nowrap:expandtab +*/ diff --git a/ism/src/scim.h b/ism/src/scim.h new file mode 100644 index 0000000..1fff6e2 --- /dev/null +++ b/ism/src/scim.h @@ -0,0 +1,442 @@ +/** @file scim.h + * + * all of the header files are included within this file. + * source files may include this file instead of others headers. + * + * @defgroup InputServiceFramework Input Service Framework + * The Input Service Framework (ISF) is based on the open source project SCIM-1.4.7.
+ * The Input Service Framework is capable of supporting advanced input methods like full touch input, voice input, handwriting etc. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim.h,v 1.38 2005/05/17 06:45:14 suzhe Exp $ + */ + +/* Define the macros */ +#define Uses_SCIM_TYPES +#define Uses_SCIM_UTILITY +#define Uses_SCIM_GLOBAL_CONFIG +#define Uses_SCIM_EXCEPTION +#define Uses_SCIM_DEBUG +#define Uses_SCIM_OBJECT +#define Uses_SCIM_SIGNALS +#define Uses_SCIM_SLOT +#define Uses_SCIM_CONNECTION +#define Uses_SCIM_BIND +#define Uses_SCIM_POINTER +#define Uses_STL_STRING +#define Uses_STL_VECTOR +#define Uses_STL_ALGORITHM +#define Uses_STL_NEW + +#ifdef Uses_SCIM_FILTER_MANAGER + #define Uses_SCIM_FILTER +#endif + +#ifdef Uses_SCIM_FILTER_MODULE + #define Uses_SCIM_MODULE + #define Uses_SCIM_CONFIG_BASE + #define Uses_SCIM_BACKEND + #define Uses_SCIM_FILTER +#endif + +#ifdef Uses_SCIM_FILTER + #define Uses_SCIM_IMENGINE +#endif + +#ifdef Uses_SCIM_PANEL + #define Uses_SCIM_PANEL_AGENT + #define Uses_SCIM_PANEL_CLIENT +#endif + +#ifdef Uses_SCIM_PANEL_AGENT + #define Uses_SCIM_HELPER_MANAGER + #define Uses_SCIM_TRANSACTION +#endif + +#ifdef Uses_SCIM_PANEL_CLIENT + #define Uses_SCIM_TRANSACTION +#endif + +#ifdef Uses_SCIM_HELPER_MANAGER + #define Uses_SCIM_HELPER +#endif + +#ifdef Uses_SCIM_HELPER_MODULE + #define Uses_SCIM_HELPER + #define Uses_SCIM_MODULE + #define Uses_SCIM_CONFIG_BASE +#endif + +#ifdef Uses_SCIM_HELPER + #define Uses_SCIM_TRANSACTION + #define Uses_SCIM_EVENT +#endif + +#ifdef Uses_SCIM_COMPOSE_KEY + #define Uses_SCIM_IMENGINE +#endif + +#ifdef Uses_SCIM_TRANSACTION + #define Uses_SCIM_EVENT + #define Uses_SCIM_LOOKUP_TABLE + #define Uses_SCIM_SOCKET + #define Uses_SCIM_ATTRIBUTE + #define Uses_SCIM_PROPERTY + #define Uses_SCIM_TRANS_COMMANDS +#endif + +#ifdef Uses_SCIM_CONFIG_MODULE + #define Uses_SCIM_MODULE + #define Uses_SCIM_CONFIG_BASE +#endif + +#ifdef Uses_SCIM_IMENGINE_MODULE + #define Uses_SCIM_MODULE + #define Uses_SCIM_CONFIG_BASE + #define Uses_SCIM_IMENGINE +#endif + +#ifdef Uses_SCIM_FRONTEND_MODULE + #define Uses_SCIM_MODULE + #define Uses_SCIM_CONFIG_BASE + #define Uses_SCIM_FRONTEND +#endif + +#ifdef Uses_SCIM_ICONV + #define Uses_C_ICONV +#endif + +#ifdef Uses_SCIM_FRONTEND + #define Uses_SCIM_BACKEND + #define Uses_SCIM_IMENGINE + #define Uses_SCIM_EVENT + #define Uses_SCIM_LOOKUP_TABLE + #define Uses_STL_MAP + #define Uses_C_STDIO + #define Uses_SCIM_ATTRIBUTE + #define Uses_SCIM_PROPERTY + #define Uses_SCIM_TRANSACTION + #define Uses_SCIM_SOCKET +#endif + +#ifdef Uses_SCIM_BACKEND + #define Uses_SCIM_IMENGINE + #define Uses_SCIM_CONFIG_BASE + #define Uses_SCIM_COMPOSE_KEY +#endif + +#ifdef Uses_SCIM_IMENGINE + #define Uses_SCIM_EVENT + #define Uses_SCIM_LOOKUP_TABLE + #define Uses_SCIM_ATTRIBUTE + #define Uses_SCIM_PROPERTY + #define Uses_SCIM_TRANSACTION + #define Uses_SCIM_SOCKET +#endif + +#ifdef Uses_SCIM_LOOKUP_TABLE + #define Uses_SCIM_EVENT + #define Uses_SCIM_ATTRIBUTE +#endif + +#ifdef Uses_SCIM_CONFIG_BASE + #define Uses_SCIM_MODULE + #define Uses_SCIM_CONFIG_MODULE + #define Uses_STL_LIST +#endif + +#ifdef Uses_SCIM_EXCEPTION + #define Uses_STL_EXCEPTION +#endif + +#ifdef Uses_SCIM_DEBUG + #define Uses_STL_IOSTREAM + #define Uses_STL_FSTREAM +#endif + +#ifdef Uses_SCIM_UTILITY + #define Uses_STL_IOSTREAM +#endif + +#ifdef Uses_SCIM_HOTKEY + #define Uses_SCIM_EVENT + #define Uses_SCIM_CONFIG_BASE + #define Uses_SCIM_CONFIG_PATH +#endif + +/* Include Standard headers */ +#ifdef Uses_STL_EXCEPTION + #include +#endif + +#ifdef Uses_STL_NEW + #include +#endif + +#ifdef Uses_STL_IOSTREAM + #include +#endif + +#ifdef Uses_STL_FSTREAM + #include +#endif + +#ifdef Uses_STL_FUNCTIONAL + #include +#endif + +#ifdef Uses_STL_IOMANIP + #include +#endif + +#ifdef Uses_STL_MEMORY + #include +#endif + +#ifdef Uses_STL_VECTOR + #include +#endif + +#ifdef Uses_STL_LIST + #include +#endif + +#ifdef Uses_STL_MAP + #include +#endif + +#ifdef Uses_STL_QUEUE + #include +#endif + +#ifdef Uses_STL_ALGORITHM + #include +#endif + +#ifdef Uses_STL_UTILITY + #include +#endif + +#ifdef Uses_STL_STRING + #include +#endif + +#ifdef Uses_STL_STRSTREAM + #include +#endif + +#ifdef Uses_C_STDIO + #include +#endif + +#ifdef Uses_C_STDLIB + #include +#endif + +#ifdef Uses_C_LOCALE + #include +#endif + +#ifdef Uses_C_CTYPE + #include +#endif + +#ifdef Uses_C_WCTYPE + #include +#endif + +#ifdef Uses_C_STRING + #include +#endif + +#ifdef Uses_C_LIMITS + #include +#endif + +#ifdef Uses_C_ICONV + #include +#endif + +/* Include SCIM Headers */ +#ifdef Uses_SCIM_TYPES + #include +#endif + +#ifdef Uses_SCIM_DEBUG + #include +#endif + +#ifdef Uses_SCIM_EXCEPTION + #include +#endif + +#ifdef Uses_SCIM_EVENT + #include +#endif + +#ifdef Uses_SCIM_UTILITY + #include +#endif + +#ifdef Uses_SCIM_GLOBAL_CONFIG + #include +#endif + +#ifdef Uses_SCIM_OBJECT + #include +#endif + +#ifdef Uses_SCIM_POINTER + #include +#endif + +#ifdef Uses_SCIM_SLOT + #include +#endif + +#ifdef Uses_SCIM_CONNECTION + #include +#endif + +#ifdef Uses_SCIM_SIGNALS + #include +#endif + +#ifdef Uses_SCIM_BIND + #include +#endif + +#ifdef Uses_SCIM_CONFIG_BASE + #include +#endif + +#ifdef Uses_SCIM_ATTRIBUTE + #include +#endif + +#ifdef Uses_SCIM_PROPERTY + #include +#endif + +#ifdef Uses_SCIM_LOOKUP_TABLE + #include +#endif + +#ifdef Uses_SCIM_ICONV + #include +#endif + +#ifdef Uses_SCIM_MODULE + #include +#endif + +#ifdef Uses_SCIM_SOCKET + #include +#endif + +#ifdef Uses_SCIM_TRANSACTION + #include +#endif + +#ifdef Uses_SCIM_IMENGINE + #include +#endif + +#ifdef Uses_SCIM_IMENGINE_MODULE + #include +#endif + +#ifdef Uses_SCIM_COMPOSE_KEY + #include +#endif + +#ifdef Uses_SCIM_BACKEND + #include +#endif + +#ifdef Uses_SCIM_FRONTEND + #include +#endif + +#ifdef Uses_SCIM_FRONTEND_MODULE + #include +#endif + +#ifdef Uses_SCIM_CONFIG_MODULE + #include +#endif + +#ifdef Uses_SCIM_CONFIG_PATH + #include +#endif + +#ifdef Uses_SCIM_TRANS_COMMANDS + #include +#endif + +#ifdef Uses_SCIM_HELPER + #include +#endif + +#ifdef Uses_SCIM_HELPER_MODULE + #include +#endif + +#ifdef Uses_SCIM_HELPER_MANAGER + #include +#endif + +#ifdef Uses_SCIM_PANEL_AGENT + #include +#endif + +#ifdef Uses_SCIM_PANEL_CLIENT + #include +#endif + +#ifdef Uses_ISF_IMCONTROL_CLIENT + #include +#endif + +#ifdef Uses_SCIM_HOTKEY + #include +#endif + +#ifdef Uses_SCIM_FILTER + #include +#endif + +#ifdef Uses_SCIM_FILTER_MODULE + #include +#endif + +#ifdef Uses_SCIM_FILTER_MANAGER + #include +#endif + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/scim_attribute.h b/ism/src/scim_attribute.h new file mode 100644 index 0000000..995743a --- /dev/null +++ b/ism/src/scim_attribute.h @@ -0,0 +1,206 @@ +/** @file scim_attribute.h + * @brief Definition of scim::Attribute and scim::AttributeList + * + * Provide class scim::Attribute to control the + * drawing effect of strings. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_attribute.h,v 1.7 2005/08/05 16:12:31 suzhe Exp $ + */ + + +#ifndef __SCIM_ATTRIBUTE_H +#define __SCIM_ATTRIBUTE_H + +namespace scim { + +/** + * @addtogroup Accessories + * @ingroup InputServiceFramework + * + * The accessorial classes and functions, including Attribute, IConvert, LookupTable etc. + * + * @{ + */ + +/** + * @brief Enum values of the valid attribute type. + */ +enum AttributeType +{ + SCIM_ATTR_NONE, ///< No attribute. + SCIM_ATTR_DECORATE, ///< A decorate attribute, eg. underline etc. + SCIM_ATTR_FOREGROUND, ///< A foreground color attribute, in RGB format. + SCIM_ATTR_BACKGROUND ///< A background color attribute, in RGB format. +}; + +const unsigned int SCIM_ATTR_DECORATE_NONE = 0; ///< No decorate +const unsigned int SCIM_ATTR_DECORATE_UNDERLINE = 1; ///< Draw a line under the text +const unsigned int SCIM_ATTR_DECORATE_HIGHLIGHT = 2; ///< Draw the text in highlighted color +const unsigned int SCIM_ATTR_DECORATE_REVERSE = 4; ///< Draw the text in reverse color mode +const unsigned int SCIM_ATTR_DECORATE_BGCOLOR1 = 5; ///< Draw the text in underline background 1 mode +const unsigned int SCIM_ATTR_DECORATE_BGCOLOR2 = 6; ///< Draw the text in underline background 2 mode +const unsigned int SCIM_ATTR_DECORATE_BGCOLOR3 = 7; ///< Draw the text in underline background 3 mode +const unsigned int SCIM_ATTR_DECORATE_BGCOLOR4 = 8; ///< Draw the text in underline background 4 mode + +#define SCIM_RGB_COLOR(RED,GREEN,BLUE) ((unsigned int)(((RED)<<16) + ((GREEN)<<8) + (BLUE))) +#define SCIM_RGB_COLOR_RED(COLOR) ((unsigned int)((COLOR>>16) & 0x00ff)) +#define SCIM_RGB_COLOR_GREEN(COLOR) ((unsigned int)((COLOR>>8) & 0x00ff)) +#define SCIM_RGB_COLOR_BLUE(COLOR) ((unsigned int)((COLOR) & 0x00ff)) + +/** + * @brief Class to store the string attributes. + * + * The string attributes control the effect of the string + * drawn by FrontEnds. There are currently four valid types. + * + * A attribute could be one of the following types: + * - SCIM_ATTR_NONE No attribute + * - SCIM_ATTR_DECORATE Decorate attribute, eg. underline, highlight etc. + * - SCIM_ATTR_FOREGROUND Foreground color attribute, in RGB format. + * - SCIM_ATTR_BACKGROUND Background color attribute, in RGB format. + * + * For a DECORATE attribute, it can be one of the following values: + * - SCIM_ATTR_DECORATE_NONE No decorate + * - SCIM_ATTR_DECORATE_UNDERLINE Underline + * - SCIM_ATTR_DECORATE_HIGHLIGHT Highlight + * - SCIM_ATTR_DECORATE_REVERSE Reverse + * + * For a FOREGROUND or BACKGROUND attribute, it's a RGB color value generated with + * SCIM_RGB_COLOR (red,green,blue) macro. + * You may use SCIM_RGB_COLOR_RED, SCIM_RGB_COLOR_GREEN and SCIM_RGB_COLOR_BLUE to extract + * the RGB color later. + */ +class Attribute +{ + unsigned int m_start; + unsigned int m_length; + + AttributeType m_type; + unsigned int m_value; + +public: + /** + * @brief Constructor + * + * @param start - the start position in the string of this attribute. + * @param length - the length of this attribute, the range is [start,start+length). + * @param type - the type of this attribute. + * @param value - the value of this attribute. + */ + Attribute (unsigned int start = 0, + unsigned int length = 0, + AttributeType type = SCIM_ATTR_NONE, + unsigned int value = 0) : + m_start (start), m_length (length), m_type (type), m_value (value) + { } + + /** + * @brief Get the type of this attribute. + * + * @return The type of this attribute. + */ + AttributeType get_type () const { return m_type; } + + /** + * @brief Get the value of this attribute. + * + * @return The value of this attribute. + */ + unsigned int get_value () const { return m_value; } + + /** + * @brief Get the start position of this attribute. + * @return The start position of this attribute in the string. + */ + unsigned int get_start () const { return m_start; } + + /** + * @brief Get the length of this attribute. + * @return The length of this attribute in the string. + */ + unsigned int get_length () const { return m_length; } + + /** + * @brief Get the end position of this attribute. + * @return The end position of this attribute. + */ + unsigned int get_end () const { return m_start + m_length; } + + /** + * @brief Set the type of this attribute. + * @param type - the new attribute type to be set. + */ + void set_type (AttributeType type) { m_type = type; } + + /** + * @brief Set the value of this attribute. + * @param value - the new attribute value to be set. + */ + void set_value (unsigned int value) { m_value = value; } + + /** + * @brief Set the start position of this attribute. + * @param start - the new start position in the string. + */ + void set_start (unsigned int start) { m_start = start; } + + /** + * @brief Set the length of this attribute. + * @param length - the new length of this attribute. + */ + void set_length (unsigned int length) { m_length = length; } +}; + +inline bool +operator < (const Attribute &lhs, const Attribute &rhs) +{ + return lhs.get_start () < rhs.get_start () || + (lhs.get_start () == rhs.get_start () && + (lhs.get_length () < rhs.get_length () || + (lhs.get_length () == rhs.get_length () && + (lhs.get_type () < rhs.get_type () || + (lhs.get_type () == rhs.get_type () && + (lhs.get_value () < rhs.get_value ())))))); +} + +/** + * @typedef typedef std::vector AttributeList + * @brief The container to store a set of Attribute objects. + * + * You should use the STL container methods to manipulate its objects. + */ +typedef std::vector AttributeList; + +/** @} */ + +} // namespace scim + +#endif //__SCIM_ATTRIBUTE_H + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/scim_backend.cpp b/ism/src/scim_backend.cpp new file mode 100644 index 0000000..10dac78 --- /dev/null +++ b/ism/src/scim_backend.cpp @@ -0,0 +1,891 @@ +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Create and use ISE cache file + * 2. Dynamic load keyboard ISE + * + * $Id: scim_backend.cpp,v 1.38.2.1 2006/09/24 16:00:52 suzhe Exp $ + * + */ + +#define Uses_SCIM_FILTER_MANAGER +#define Uses_SCIM_BACKEND +#define Uses_SCIM_IMENGINE +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_CONFIG_PATH +#define Uses_STL_ALGORITHM +#define Uses_SCIM_PANEL_AGENT + + +#include +#include +#include "scim_private.h" +#include "scim.h" +#include "scim_stl_map.h" +#include "isf_query_utility.h" + + +namespace scim { + +#if SCIM_USE_STL_EXT_HASH_MAP +typedef __gnu_cxx::hash_map IMEngineFactoryRepository; +#elif SCIM_USE_STL_HASH_MAP +typedef std::hash_map IMEngineFactoryRepository; +#else +typedef std::map IMEngineFactoryRepository; +#endif + +typedef std::vector IMEngineFactoryPointerVector; + + +class LocaleEqual +{ + String m_lhs; +public: + LocaleEqual (const String &lhs) : m_lhs (lhs) { } + + bool operator () (const String &rhs) const { + if (m_lhs == rhs) return true; + if (scim_get_locale_language (m_lhs) == scim_get_locale_language (rhs) && + scim_get_locale_encoding (m_lhs) == scim_get_locale_encoding (rhs) && + m_lhs.find ('.') != String::npos && rhs.find ('.') != String::npos) + return true; + return false; + } +}; + +class IMEngineFactoryPointerLess +{ +public: + bool operator () (const IMEngineFactoryPointer &lhs, const IMEngineFactoryPointer &rhs) const { + return (lhs->get_language () < rhs->get_language ()) || + (lhs->get_language () == rhs->get_language () && lhs->get_name () < rhs->get_name ()); + } +}; + +class BackEndBase::BackEndBaseImpl +{ + IMEngineFactoryRepository m_factory_repository; + String m_supported_unicode_locales; + ConfigPointer m_config; + +public: + BackEndBaseImpl (const ConfigPointer &config) + : m_config (config) + { + String locales; + + /* Set the default supported locales. */ + locales = scim_global_config_read (SCIM_GLOBAL_CONFIG_SUPPORTED_UNICODE_LOCALES, String ("en_US.UTF-8")); + + std::vector locale_list; + std::vector real_list; + + scim_split_string_list (locale_list, locales); + + for (std::vector ::iterator i = locale_list.begin (); i!= locale_list.end (); ++i) { + *i = scim_validate_locale (*i); + if (i->length () && scim_get_locale_encoding (*i) == "UTF-8" && + std::find_if (real_list.begin (), real_list.end (), LocaleEqual (*i)) == real_list.end ()) + real_list.push_back (*i); + } + + m_supported_unicode_locales = scim_combine_string_list (real_list); + } + + void clear () + { + m_factory_repository.clear (); + } + + void dump_factories () + { + IMEngineFactoryRepository::const_iterator it; + std::cout << "Factories in backend:" << std::endl; + for (it = m_factory_repository.begin (); it != m_factory_repository.end (); ++it) { + if (it->second.null ()) + std::cout << "\t" << it->first << ": null" << std::endl; + else + std::cout << "\t" << it->first << ": valid" << std::endl; + } + } + + String get_all_locales () const + { + String locale; + + std::vector locale_list; + std::vector real_list; + + IMEngineFactoryRepository::const_iterator it; + + for (it = m_factory_repository.begin (); it != m_factory_repository.end (); ++it) { + if (locale.length () == 0) + locale += it->second->get_locales (); + else + locale += (String (",") + it->second->get_locales ()); + } + + if (m_supported_unicode_locales.length ()) + locale += (String (",") + m_supported_unicode_locales); + + scim_split_string_list (locale_list, locale); + + for (std::vector ::iterator i = locale_list.begin (); i!= locale_list.end (); i++) { + locale = scim_validate_locale (*i); + if (locale.length () && + std::find_if (real_list.begin (), real_list.end (), LocaleEqual (locale)) == real_list.end ()) + real_list.push_back (locale); + } + + return scim_combine_string_list (real_list); + } + + IMEngineFactoryPointer get_factory (const String &uuid) const + { + IMEngineFactoryRepository::const_iterator it = m_factory_repository.find (uuid); + + if (it != m_factory_repository.end ()) + return it->second; + + return IMEngineFactoryPointer (0); + } + + uint32 get_factories_for_encoding (std::vector &factories, + const String &encoding) const + { + IMEngineFactoryRepository::const_iterator it; + + factories.clear (); + + for (it = m_factory_repository.begin (); it != m_factory_repository.end (); ++it) { + if ((encoding.length () == 0 || it->second->validate_encoding (encoding))) + factories.push_back (it->second); + } + + sort_factories (factories); + + return factories.size (); + } + + uint32 get_factories_for_language (std::vector &factories, + const String &language) const + { + IMEngineFactoryRepository::const_iterator it; + + factories.clear (); + + for (it = m_factory_repository.begin (); it != m_factory_repository.end (); ++it) { + if ((language.length () == 0 || it->second->get_language () == language)) + factories.push_back (it->second); + } + + sort_factories (factories); + + return factories.size (); + } + + uint32 get_factory_list (std::vector &uuids) const + { + IMEngineFactoryRepository::const_iterator it; + for (it = m_factory_repository.begin (); it != m_factory_repository.end (); ++it) + uuids.push_back(it->first); + + return m_factory_repository.size (); + } + + IMEngineFactoryPointer get_default_factory (const String &language, const String &encoding) const + { + if (!language.length ()) return IMEngineFactoryPointer (); + + IMEngineFactoryPointerVector factories; + + if (get_factories_for_encoding (factories, encoding) > 0) { + IMEngineFactoryPointer lang_first; + IMEngineFactoryPointerVector::iterator it; + + String def_uuid; + + def_uuid = m_config->read (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + + String ("/") + String ("~other"), + String ("")); + + /* Match by Normalized language exactly. */ + for (it = factories.begin (); it != factories.end (); ++it) { + if (scim_get_normalized_language ((*it)->get_language ()) == language && lang_first.null ()) + lang_first = *it; + + if ((*it)->get_uuid () == def_uuid) + return *it; + } + + if (!lang_first.null ()) + return lang_first; + + /* Match by short language name. */ + for (it = factories.begin (); it != factories.end (); ++it) + if ((*it)->get_language () == language.substr (0,2)) + return *it; + + return factories [0]; + } + + return IMEngineFactoryPointer (); + } + + void set_default_factory (const String &language, const String &uuid) + { + if (!language.length () || !uuid.length ()) return; + + IMEngineFactoryPointerVector factories; + if (get_factories_for_encoding (factories, "") > 0) { + IMEngineFactoryPointerVector::iterator it; + for (it = factories.begin (); it != factories.end (); ++it) { + if ((*it)->get_uuid () == uuid) { + m_config->write (String (SCIM_CONFIG_DEFAULT_IMENGINE_FACTORY) + String ("/") + String ("~other"), uuid); + m_config->flush (); + m_config->reload (); + return; + } + } + } + } + + IMEngineFactoryPointer get_next_factory (const String &language, const String &encoding, const String &cur_uuid) const + { + IMEngineFactoryPointerVector factories; + + if (get_factories_for_encoding (factories, encoding) > 0) { + IMEngineFactoryPointer lang_first; + IMEngineFactoryPointerVector::iterator it, itl; + + for (it = factories.begin (); it != factories.end (); ++it) { + uint32 option = (*it)->get_option (); + if ((language.length () == 0 || (*it)->get_language () == language) && lang_first.null () && + !(option & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD)) + lang_first = *it; + + if ((*it)->get_uuid () == cur_uuid) { + for (itl = it + 1; itl != factories.end (); ++itl) { + option = (*itl)->get_option (); + if ((language.length () == 0 || (*itl)->get_language () == language) && + !(option & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD)) + return *itl; + } + if (!lang_first.null ()) return lang_first; + + return factories [0]; + } + } + } + + return IMEngineFactoryPointer (); + } + + IMEngineFactoryPointer get_previous_factory (const String &language, const String &encoding, const String &cur_uuid) const + { + IMEngineFactoryPointerVector factories; + + if (get_factories_for_encoding (factories, encoding) > 0) { + IMEngineFactoryPointer lang_last; + IMEngineFactoryPointerVector::iterator it, itl; + + uint32 option = 0; + for (it = factories.begin (); it != factories.end (); ++it) { + option = (*it)->get_option (); + if ((language.length () == 0 || (*it)->get_language () == language) && + !(option & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD)) + lang_last = *it; + } + + for (it = factories.begin (); it != factories.end (); ++it) { + if ((*it)->get_uuid () == cur_uuid) { + for (itl = it; itl != factories.begin (); --itl) { + option = (*(itl-1))->get_option (); + if ((language.length () == 0 || (*(itl-1))->get_language () == language) && + !(option & SCIM_IME_NOT_SUPPORT_HARDWARE_KEYBOARD)) + return *(itl-1); + } + + if (!lang_last.null ()) return lang_last; + + return factories [factories.size () - 1]; + } + } + } + + return IMEngineFactoryPointer (); + } + + bool add_factory (const IMEngineFactoryPointer &factory) + { + if (!factory.null ()) { + String uuid = factory->get_uuid (); + + if (uuid.length ()) { + m_factory_repository [uuid] = factory; + return true; + } + } + + return false; + } + + void add_specific_factory (const String &uuid, const IMEngineFactoryPointer &factory) + { + m_factory_repository [uuid] = factory; + return; + } + +private: + void sort_factories (std::vector &factories) const + { + std::sort (factories.begin (), factories.end (), IMEngineFactoryPointerLess ()); + } +}; + +BackEndBase::BackEndBase (const ConfigPointer &config) + : m_impl (new BackEndBase::BackEndBaseImpl (config)) +{ +} + +BackEndBase::~BackEndBase () +{ + delete m_impl; +} + +String +BackEndBase::get_all_locales () const +{ + return m_impl->get_all_locales (); +} + +IMEngineFactoryPointer +BackEndBase::get_factory (const String &uuid) const +{ + return m_impl->get_factory (uuid); +} + +uint32 +BackEndBase::get_factories_for_encoding (std::vector &factories, const String &encoding) const +{ + return m_impl->get_factories_for_encoding (factories, encoding); +} + +uint32 +BackEndBase::get_factories_for_language (std::vector &factories, const String &language) const +{ + return m_impl->get_factories_for_language (factories, language); +} + +uint32 +BackEndBase::get_factory_list (std::vector &uuids) const +{ + return m_impl->get_factory_list (uuids); +} + +IMEngineFactoryPointer +BackEndBase::get_default_factory (const String &language, const String &encoding) const +{ + return m_impl->get_default_factory (language, encoding); +} + +void +BackEndBase::set_default_factory (const String &language, const String &uuid) +{ + m_impl->set_default_factory (language, uuid); +} + +IMEngineFactoryPointer +BackEndBase::get_next_factory (const String &language, const String &encoding, const String &cur_uuid) const +{ + return m_impl->get_next_factory (language, encoding, cur_uuid); +} + +IMEngineFactoryPointer +BackEndBase::get_previous_factory (const String &language, const String &encoding, const String &cur_uuid) const +{ + return m_impl->get_previous_factory (language, encoding, cur_uuid); +} + +bool +BackEndBase::add_factory (const IMEngineFactoryPointer &factory) +{ + return m_impl->add_factory (factory); +} + +void +BackEndBase::add_specific_factory (const String &uuid, + const IMEngineFactoryPointer &factory) +{ + m_impl->add_specific_factory (uuid, factory); + return; +} + +void +BackEndBase::clear () +{ + m_impl->clear (); +} + +void +BackEndBase::dump_factories () +{ + m_impl->dump_factories (); +} + +/* Implementation of CommonBackEnd. */ +struct CommonBackEnd::CommonBackEndImpl { + std::vector m_engine_modules; + FilterManager *m_filter_manager; + std::vector m_disabled_factories; + std::vector m_modules; + std::map m_factory_module_repository; + + CommonBackEndImpl () : m_filter_manager (0) { } +}; + +CommonBackEnd::CommonBackEnd (const ConfigPointer &config, + const std::vector &modules) + : BackEndBase (config), + m_impl (new CommonBackEndImpl) +{ +} + +CommonBackEnd::~CommonBackEnd () +{ + clear (); + + for (unsigned int i = 0; i < m_impl->m_engine_modules.size (); i++) { + if (m_impl->m_engine_modules [i]) { + m_impl->m_engine_modules [i]->unload (); + delete m_impl->m_engine_modules [i]; + m_impl->m_engine_modules [i] = NULL; + } + } + delete m_impl->m_filter_manager; + delete m_impl; +} + +void +CommonBackEnd::initialize (const ConfigPointer &config, + const std::vector &modules, + const bool is_load_resource, + const bool is_load_info) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << "...\n"; + + IMEngineFactoryPointer factory; + std::vector new_modules = modules; + + int all_factories_count = 0; + int module_factories_count = 0; + + if (config.null ()) return; + + /* Get disabled factories list. */ + m_impl->m_disabled_factories = scim_global_config_read (SCIM_GLOBAL_CONFIG_DISABLED_IMENGINE_FACTORIES, m_impl->m_disabled_factories); + + /* Put socket module to the end of list. */ + if (new_modules.size () > 1) { + for (std::vector::iterator it = new_modules.begin (); it != new_modules.end (); ++it) { + if (*it == "socket") { + new_modules.erase (it); + new_modules.push_back ("socket"); + break; + } + } + } + + /* Try to load all IMEngine modules */ + try { + m_impl->m_filter_manager = new FilterManager (config); + } catch (const std::exception & err) { + std::cerr << err.what () << "\n"; + return; + } + + factory = new ComposeKeyFactory (); + + if (all_factories_count == 0 || + std::find (m_impl->m_disabled_factories.begin (), + m_impl->m_disabled_factories.end (), + factory->get_uuid ()) == m_impl->m_disabled_factories.end ()) { + factory = m_impl->m_filter_manager->attach_filters_to_factory (factory); + add_factory (factory); + } + + if (is_load_info) { + /*for (size_t i = 0; i < new_modules.size (); ++i) + add_module_info (config, new_modules [i]);*/ + add_module_info_from_cache_file (config, new_modules); + return; + } + + /* load IMEngine modules */ + for (size_t i = 0; i < new_modules.size (); ++i) { + module_factories_count = add_module (config, new_modules [i], is_load_resource); + all_factories_count += module_factories_count; + } +} + +int +CommonBackEnd::add_module (const ConfigPointer &config, + const String module, + bool is_load_resource) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << " : " << module << "\n"; + + IMEngineFactoryPointer factory; + IMEngineModule *engine_module = NULL; + int module_factories_count = 0; + bool first_load = false; + + if (config.null ()) return 0; + + if (module.length () > 0) { + /* Check if the module is already loaded */ + if (std::find (m_impl->m_modules.begin (), m_impl->m_modules.end (), module) == m_impl->m_modules.end ()) { + engine_module = new IMEngineModule; + m_impl->m_engine_modules.push_back (engine_module); + m_impl->m_modules.push_back (module); + engine_module->load (module, config); + first_load = true; + } else { + for (size_t i = 0; i < m_impl->m_modules.size (); i++) { + if (m_impl->m_modules [i] == module) { + engine_module = m_impl->m_engine_modules [i]; + break; + } + } + } + + if (engine_module && engine_module->valid ()) { + size_t number = engine_module->number_of_factories (); + for (size_t j = 0; j < number; ++j) { + + /* Try to load a IMEngine Factory. */ + try { + factory = engine_module->create_factory (j); + } catch (const std::exception & err) { + std::cerr << err.what () << "\n"; + factory.reset (); + } + + if (!factory.null ()) { + /* Check if it's disabled. */ + if (std::find (m_impl->m_disabled_factories.begin (), + m_impl->m_disabled_factories.end (), + factory->get_uuid ()) == m_impl->m_disabled_factories.end ()) { + + /* Add it into disabled list to prevent from loading again. */ + /*m_impl->m_disabled_factories.push_back (factory->get_uuid ());*/ + + if (is_load_resource) + factory->load_resource (); + + /* Only load filter for none socket IMEngines. */ + if (module != "socket") + factory = m_impl->m_filter_manager->attach_filters_to_factory (factory); + + add_factory (factory); + + module_factories_count ++; + + SCIM_DEBUG_BACKEND (1) << " Loading IMEngine Factory " << j << " : " << "OK\n"; + } else { + SCIM_DEBUG_BACKEND (1) << " Loading IMEngine Factory " << j << " : " << "Disabled\n"; + factory.reset (); + } + } else { + std::cerr << " Loading IMEngine Factory " << module << "(" << j << ") is Failed!!!\n"; + } + } + if (module_factories_count) { + SCIM_DEBUG_BACKEND (1) << module << " IMEngine module is successfully loaded.\n"; + } else { + std::cerr << "No Factory loaded from " << module << " IMEngine module!!!\n"; + if (first_load) + engine_module->unload (); + } + } else { + std::cerr << __func__ << ": Failed to load " << module << " IMEngine module!!!\n"; + } + } + + return module_factories_count; +} + +void +CommonBackEnd::add_module_info (const ConfigPointer &config, const String module_name) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << " : " << module_name << "\n"; + + if (module_name.length () <= 0 || module_name == "socket") + return; + + IMEngineFactoryPointer factory; + IMEngineModule ime_module; + + ime_module.load (module_name, config); + + if (ime_module.valid ()) { + for (size_t j = 0; j < ime_module.number_of_factories (); ++j) { + try { + factory = ime_module.create_factory (j); + } catch (...) { + factory.reset (); + } + + if (!factory.null ()) { + if (m_impl->m_factory_module_repository.find (factory->get_uuid ()) + == m_impl->m_factory_module_repository.end ()) { + add_specific_factory (factory->get_uuid (), IMEngineFactoryPointer (0)); + m_impl->m_factory_module_repository[factory->get_uuid ()] = module_name; + } + + factory.reset (); + } + } + } else { + std::cerr << __func__ << ": Failed to load " << module_name << " IMEngine module!!!\n"; + } + + ime_module.unload (); +} + +void +CommonBackEnd::add_factory_by_uuid (const ConfigPointer &config, const String uuid) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << " : " << uuid << "\n"; + + if (m_impl->m_factory_module_repository.find (uuid) == m_impl->m_factory_module_repository.end ()) + return; + + String module = m_impl->m_factory_module_repository[uuid]; + add_module (config, module, true); +} + +void +CommonBackEnd::release_module (const std::vector &use_uuids, const String del_uuid) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << " : " << del_uuid << "\n"; + + if (m_impl->m_factory_module_repository.find (del_uuid) == m_impl->m_factory_module_repository.end ()) + return; + + String module = m_impl->m_factory_module_repository[del_uuid]; + std::vector uuids; + std::map ::iterator it = m_impl->m_factory_module_repository.begin (); + + uuids.clear (); + for (; it != m_impl->m_factory_module_repository.end (); it++) { + if (it->second == module) + uuids.push_back (it->first); + } + + for (unsigned int i = 0; i < uuids.size (); i++) { + for (unsigned int j = 0; j < use_uuids.size (); j++) { + if (uuids[i] == use_uuids[j]) + return; + } + } + + /* unload the module */ + std::vector::iterator it2 = uuids.begin (); + for (; it2 != uuids.end (); it2++) + add_specific_factory (*it2, IMEngineFactoryPointer (0)); + + std::vector::iterator it3 = m_impl->m_modules.begin (); + for (; it3 != m_impl->m_modules.end (); it3++) { + if (*it3 == module) { + m_impl->m_modules.erase (it3); + break; + } + } + + std::vector::iterator it4 = m_impl->m_engine_modules.begin (); + for (; it4 != m_impl->m_engine_modules.end (); it4++) { + if ((*it4)->get_module_name () == module) { + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << " : " << module << "\n"; + (*it4)->unload (); + delete (*it4); + m_impl->m_engine_modules.erase (it4); + break; + } + } + malloc_trim (0); +} + +void +CommonBackEnd::add_module_info_from_cache_file (const ConfigPointer &config, std::vector &modules) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << "...\n"; + + FILE *engine_list_file = NULL; + FILE *user_engine_file = NULL; + char buf[MAXLINE]; + bool isFirst = false; + std::vector current_modules; + + current_modules.clear (); + + String user_file_name = String (USER_ENGINE_FILE_NAME); + String sys_file_name = String (SYS_ENGINE_FILE_NAME); + + engine_list_file = fopen (user_file_name.c_str (), "r"); + if (engine_list_file == NULL) { + std::cerr << user_file_name << " doesn't exist.\n"; + isFirst = true; + + engine_list_file = fopen (sys_file_name.c_str (), "r"); + if (engine_list_file == NULL) { + std::cerr << sys_file_name << " doesn't exist.\n"; + goto failed_open; + } + } + + /* + * If we start the system firstly, the engine list file in user directory + * doesn't exit, we should create it. + */ + if (isFirst) { + user_engine_file = fopen (user_file_name.c_str (), "a"); + if (user_engine_file == NULL) { + std::cerr << __func__ << " Failed to open(" << user_file_name << ")\n"; + } + } + + while (fgets (buf, MAXLINE, engine_list_file) != NULL) { + if (isFirst && user_engine_file != NULL) { + if (fputs (buf, user_engine_file) == EOF) + std::cerr << "failed to write " << user_file_name << "\n"; + } + + ISEINFO info; + isf_get_ise_info_from_string (buf, info); + std::vector::iterator iter = std::find (modules.begin (), modules.end (), info.module); + if (info.mode == TOOLBAR_KEYBOARD_MODE && iter != modules.end ()) { + if (m_impl->m_factory_module_repository.find (info.uuid) == m_impl->m_factory_module_repository.end ()) { + add_specific_factory (info.uuid, IMEngineFactoryPointer (0)); + m_impl->m_factory_module_repository[info.uuid] = info.module; + } + + std::vector::iterator iter2 = std::find (current_modules.begin (), current_modules.end (), info.module); + if (iter2 == current_modules.end ()) + current_modules.push_back (info.module); + } + } + + if (isFirst && user_engine_file != NULL) + fclose (user_engine_file); + fclose (engine_list_file); + +failed_open: + update_module_info (config, current_modules, modules); +} + +void +CommonBackEnd::update_module_info (const ConfigPointer &config, + std::vector ¤t_modules, + std::vector &modules) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << "...\n"; + + std::vector imengine_list; + scim_get_imengine_module_list (imengine_list); + for (size_t i = 0; i < imengine_list.size (); ++i) { + if (std::find (modules.begin (), modules.end (), imengine_list [i]) != modules.end () + && std::find (current_modules.begin (), current_modules.end (), imengine_list [i]) == current_modules.end ()) + add_imengine_module_info (imengine_list [i], config); + } +} + +void +CommonBackEnd::add_imengine_module_info (const String module_name, const ConfigPointer &config) +{ + SCIM_DEBUG_BACKEND (1) << __FUNCTION__ << " : " << module_name << "\n"; + + if (module_name.length () <= 0 || module_name == "socket") + return; + + IMEngineFactoryPointer factory; + IMEngineModule ime_module; + + String filename = String (USER_ENGINE_FILE_NAME); + FILE *engine_list_file = fopen (filename.c_str (), "a"); + if (engine_list_file == NULL) { + std::cerr << __func__ << " Failed to open(" << filename << ")\n"; + return; + } + + ime_module.load (module_name, config); + + if (ime_module.valid ()) { + for (size_t j = 0; j < ime_module.number_of_factories (); ++j) { + try { + factory = ime_module.create_factory (j); + } catch (...) { + factory.reset (); + } + + if (!factory.null ()) { + String uuid = factory->get_uuid (); + String name = utf8_wcstombs (factory->get_name ()); + String language = isf_get_normalized_language (factory->get_language ()); + String icon = factory->get_icon_file (); + char mode[12]; + char option[12]; + + snprintf (mode, sizeof (mode), "%d", (int)TOOLBAR_KEYBOARD_MODE); + snprintf (option, sizeof (option), "%d", factory->get_option ()); + + String line = isf_combine_ise_info_string (name, uuid, module_name, language, + icon, String (mode), String (option), factory->get_locales ()); + if (fputs (line.c_str (), engine_list_file) < 0) { + std::cerr << "write to ise cache file failed:" << line << "\n"; + break; + } + + add_specific_factory (uuid, IMEngineFactoryPointer (0)); + m_impl->m_factory_module_repository[uuid] = module_name; + + factory.reset (); + } + } + } else { + std::cerr << __func__ << ": Failed to load " << module_name << " IMEngine module!!!\n"; + } + + ime_module.unload (); + fclose (engine_list_file); +} + + +} /* namespace scim */ + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/scim_backend.h b/ism/src/scim_backend.h new file mode 100644 index 0000000..6ea2463 --- /dev/null +++ b/ism/src/scim_backend.h @@ -0,0 +1,270 @@ +/** @file scim_backend.h + * @brief definition of scim::BackEnd class. + * + * Class scim::BackEnd is used to load and manage IMEngine + * modules and IMEngineFactories. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * Modifications by Samsung Electronics Co., Ltd. + * 1. Create and use ISE cache file + * 2. Dynamic load keyboard ISE + * + * $Id: scim_backend.h,v 1.26 2005/10/06 18:02:06 liuspider Exp $ + */ + +#ifndef __SCIM_BACKEND_H +#define __SCIM_BACKEND_H + +namespace scim { + +/** + * @brief An exception class to hold BackEnd related errors. + * + * scim::BackEndBase and its derived classes must throw + * scim::BackEndError object when error. + */ +class BackEndError: public Exception +{ +public: + BackEndError (const String& what_arg) + : Exception (String("scim::BackEnd: ") + what_arg) { } +}; + +/** + * @brief The interface class to manage a set of IMEngineFactory + * and IMEngineInstance objects. + * + * This is mainly an accessory interface class used by scim::FrontEndBase. + * Its responsibility is to hold a set of IMEngineFactory instances + * and manage the locales list supported by them. + * + * Most developer should just use the default implementation + * scim::CommonBackEnd. + */ +class BackEndBase : public ReferencedObject +{ + class BackEndBaseImpl; + + BackEndBaseImpl *m_impl; + +protected: + /** + * @brief Default constructor. + * + * @param config Config object to be used. + */ + BackEndBase (const ConfigPointer &config); + + virtual ~BackEndBase (); + +public: + /** + * @brief Get a list of all locales supported by all IMEngineFactories. + * @return A comma separated locales list. + */ + String get_all_locales () const; + + /** + * @return Return the pointer of a Factory. + * + * @param uuid The uuid of the IMEngineFactory. + */ + IMEngineFactoryPointer get_factory (const String &uuid) const; + +public: + virtual void initialize (const ConfigPointer &config, + const std::vector &modules, + const bool is_load_resource, + const bool is_load_info) = 0; + + virtual int add_module (const ConfigPointer &config, + const String module, + bool is_load_resource) = 0; + + virtual void add_module_info (const ConfigPointer &config, + const String module_name) = 0; + + virtual void add_factory_by_uuid (const ConfigPointer &config, + const String uuid) = 0; + + virtual void release_module (const std::vector &use_uuids, + const String del_uuid) = 0; + +public: + /** + * @name Methods to manipulate IMEngine Factories. + * + * @{ + */ + + /** + * @brief Get the IMEngine factories list for specific encoding + * + * @param factories the vector to store the factories which + * support the encoding. + * @param encoding the encoding to be queried. If empty, + * all IMEngine factories will be returned. + * + * @return the number of IMEngine factories found. + */ + uint32 get_factories_for_encoding (std::vector &factories, const String &encoding = String ("")) const; + + /** + * @brief Get the IMEngine factories list for specific language + * + * @param factories the vector to store the factories which + * support the encoding. + * @param language the language to be queried. If empty, + * all IMEngine factories will be returned. + * + * @return the number of IMEngine factories found. + */ + uint32 get_factories_for_language (std::vector &factories, const String &language = String ("")) const; + + uint32 get_factory_list (std::vector &uuids) const; + + /** + * @brief Get the default IMEngineFactory for a specific language and encoding. + * + * @param language the language to be queried. + * @param encoding the encoding to be queried, if empty then don't match encoding. + * + * @return the pointer of the default IMEngineFactory for this language. + */ + IMEngineFactoryPointer get_default_factory (const String &language, const String &encoding) const; + + /** + * @brief Set the default IMEngineFactory for a specific language. + * + * @param language the language to be set. + * @param uuid the uuid of the default IMEngineFactory for this language. + */ + void set_default_factory (const String &language, const String &uuid); + + /** + * @brief Get the next IMEngineFactory for a specific language and encoding. + * + * @param language the language to be queried, if empty then don't match language. + * @param encoding the encoding to be queried, if empty then don't match encoding. + * @param cur_uuid the UUID of current IMEngineFactory. + * + * @return the pointer of the next IMEngineFactory for this language and encoding + * corresponding to the current IMEngineFactory. + */ + IMEngineFactoryPointer get_next_factory (const String &language, const String &encoding, const String &cur_uuid) const; + + /** + * @brief Get the previous IMEngineFactory for a specific language and encoding. + * + * @param language the language to be queried, if empty then don't match language. + * @param encoding the encoding to be queried, if empty then don't match encoding. + * @param cur_uuid the UUID of current IMEngineFactory. + * + * @return the pointer of the previous IMEngineFactory for this language and encoding + * corresponding to the current IMEngineFactory. + */ + IMEngineFactoryPointer get_previous_factory (const String &language, const String &encoding, const String &cur_uuid) const; + + /** + * @} + */ + +protected: + + bool add_factory (const IMEngineFactoryPointer &factory); + + void add_specific_factory (const String &uuid, const IMEngineFactoryPointer &factory); + + void clear (); + +public: + void dump_factories (); +}; + +/** + * @typedef typedef Pointer BackEndPointer; + * + * A smart pointer for scim::BackEndBase and its derived classes. + */ +typedef Pointer BackEndPointer; + +/** + * @brief The default implementation of scim::BackEndBase interface. + */ +class CommonBackEnd : public BackEndBase +{ + class CommonBackEndImpl; + CommonBackEndImpl *m_impl; + +public: + /** + * @brief Constructor + * + * @param config The pointer to the Config object. + * @param modules The list of the IMEngine modules to be loaded. + */ + CommonBackEnd (const ConfigPointer &config, + const std::vector &modules); + virtual ~CommonBackEnd (); + + virtual void initialize (const ConfigPointer &config, + const std::vector &modules, + const bool is_load_resource, + const bool is_load_info); + + virtual int add_module (const ConfigPointer &config, + const String module, + bool is_load_resource); + + virtual void add_module_info (const ConfigPointer &config, + const String module_name); + + virtual void add_factory_by_uuid (const ConfigPointer &config, + const String uuid); + + virtual void release_module (const std::vector &use_uuids, + const String del_uuid); + + void add_module_info_from_cache_file (const ConfigPointer &config, + std::vector &modules); + + void update_module_info (const ConfigPointer &config, + std::vector ¤t_modules, + std::vector &modules); + + void add_imengine_module_info (const String module_name, + const ConfigPointer &config); + +}; + +} /* namespace scim */ + +#endif /*__SCIM_BACKEND_H */ + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/scim_bind.h b/ism/src/scim_bind.h new file mode 100644 index 0000000..0057e6b --- /dev/null +++ b/ism/src/scim_bind.h @@ -0,0 +1,289 @@ +/** + * @file scim_bind.h + * @brief Binding adapters. + * + * A binding adaptor is an object that allows you to convert between slot types. + * Usually you wont use a BoundSlot directly but instead call the bind() factory + * function (similiar to the slot() factory function) which will create an + * appropriate bound slot for you, depending on the parameters passed. + * + * Most code of this file are came from Inti project. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * Copyright (c) 2002 The Inti Development Team. + * Copyright (c) 2000 Red Hat, Inc. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_bind.h,v 1.10 2005/01/10 08:30:52 suzhe Exp $ + */ + + +#ifndef __SCIM_BOUND_SLOT_H +#define __SCIM_BOUND_SLOT_H + +namespace scim { +/** + * @addtogroup SignalSlot + * @ingroup InputServiceFramework + * The classes for signal/slot mechanism. + * @{ + */ + +//! @name Bind functions returning a new BoundSlot. +//! @{ + +//! @class BoundSlot0_1 +//! @brief Converts a slot taking one argument into a slot taking no arguments. + +template +class BoundSlot0_1 : public Slot0 +{ + Pointer < Slot1 > original_slot; + P1 p; + +public: + BoundSlot0_1(Slot1 *slot, P1 p1) : original_slot(slot), p(p1) {} + //!< Constructor. + //!< @param slot - a pointer to a slot of type Slot1. + //!< @param p1 - a bound argument of type P1 + + virtual R call() const { return original_slot->call(p); } + //!< Calls the original slot passing it the bound argument p as the last parameter. +}; + +//! Overloaded bind() factory function. +//! @param s - a slot of type Slot1. +//! @param p1 - a value of type P1. +//! @return a new slot that stores the value p1. +//! +//!
When then returned slot is called it calls the original slot s, passing +//! it the arguments passed to it and the value p1, as the last parameter. If +//! the returned slot is connected to a signal it doesn't have to be unreferenced. The +//! signal it's connected to will unreference the slot when it is destroyed. Otherwise +//! the slot must be unreferenced by calling unref(). + +template +inline Slot0* +bind(Slot1 *s, P1 p1) +{ + return new BoundSlot0_1(s, p1); +} + +//! @class BoundSlot1_2 +//! @brief Converts a slot taking two arguments into a slot taking one argument. + +template +class BoundSlot1_2 : public Slot1 +{ + Pointer < Slot2 > original_slot; + P2 p; + +public: + BoundSlot1_2(Slot2 *slot, P2 p2) : original_slot(slot), p(p2) {} + //!< Constructor. + //!< @param slot - a pointer to a slot of type Slot1. + //!< @param p2 - a bound argument of type P2 + + virtual R call(P1 p1) const { return original_slot->call(p1, p); } + //!< Calls the original slot passing it argument p1 and the bound argument p as the last parameter. +}; + +//! Overloaded bind() factory function. +//! @param s - a slot of type Slot1. +//! @param p2 - a value of type P2. +//! @return a new slot that stores the value p2. +//! +//!
When then returned slot is called it calls the original slot s, passing +//! it the arguments passed to it and the value p2, as the last parameter. If +//! the returned slot is connected to a signal it doesn't have to be unreferenced. The +//! signal it's connected to will unreference the slot when it is destroyed. Otherwise +//! the slot must be unreferenced by calling unref(). + +template +inline Slot1* +bind(Slot2 *s, P2 p2) +{ + return new BoundSlot1_2(s, p2); +} + +//! @class BoundSlot2_3 +//! @brief Converts a slot taking three arguments into a slot taking two arguments. + +template +class BoundSlot2_3 : public Slot2 +{ + Pointer < Slot3 > original_slot; + P3 p; + +public: + BoundSlot2_3(Slot3 *slot, P3 p3) : original_slot(slot), p(p3) {} + //!< Constructor. + //!< @param slot - a pointer to a slot of type Slot1. + //!< @param p3 - a bound argument of type P3 + + virtual R call(P1 p1, P2 p2) const { return original_slot->call(p1, p2, p); } + //!< Calls the original slot passing it arguments p1 and p2, and the bound argument p as the last parameter. +}; + +//! Overloaded bind() factory function. +//! @param s - a slot of type Slot1. +//! @param p3 - a value of type P3. +//! @return a new slot that stores the value p3. +//! +//!
When then returned slot is called it calls the original slot s, passing +//! it the arguments passed to it and the value p3, as the last parameter. If +//! the returned slot is connected to a signal it doesn't have to be unreferenced. The +//! signal it's connected to will unreference the slot when it is destroyed. Otherwise +//! the slot must be unreferenced by calling unref(). + +template +inline Slot2* +bind(Slot3 *s, P3 p3) +{ + return new BoundSlot2_3(s, p3); +} + +//! @class BoundSlot3_4 +//! @brief Converts a slot taking four arguments into a slot taking three arguments. + +template +class BoundSlot3_4 : public Slot3 +{ + Pointer < Slot4 > original_slot; + P4 p; + +public: + BoundSlot3_4(Slot4 *slot, P4 p4) : original_slot(slot), p(p4) {} + //!< Constructor. + //!< @param slot - a pointer to a slot of type Slot1. + //!< @param p4 - a bound argument of type P4 + + virtual R call(P1 p1, P2 p2, P3 p3) const { return original_slot->call(p1, p2, p3, p); } + //!< Calls the original slot passing it arguments p1, p2 and p3, and the bound argument p as the last parameter. +}; + +//! Overloaded bind() factory function. +//! @param s - a slot of type Slot1. +//! @param p4 - a value of type P4. +//! @return a new slot that stores the value p4. +//! +//!
When then returned slot is called it calls the original slot s, passing +//! it the arguments passed to it and the value p4, as the last parameter. If +//! the returned slot is connected to a signal it doesn't have to be unreferenced. The +//! signal it's connected to will unreference the slot when it is destroyed. Otherwise +//! the slot must be unreferenced by calling unref(). + +template +inline Slot3* +bind(Slot4 *s, P4 p4) +{ + return new BoundSlot3_4(s, p4); +} + +//! @class BoundSlot4_5 +//! @brief Converts a slot taking five arguments into a slot taking four arguments. + +template +class BoundSlot4_5 : public Slot4 +{ + Pointer < Slot5 > original_slot; + P5 p; + +public: + BoundSlot4_5(Slot5 *slot, P5 p5) : original_slot(slot), p(p5) {} + //!< Constructor. + //!< @param slot - a pointer to a slot of type Slot1. + //!< @param p5 - a bound argument of type P5 + + virtual R call(P1 p1, P2 p2, P3 p3, P4 p4) const { return original_slot->call(p1, p2, p3, p4, p); } + //!< Calls the original slot passing it arguments p1, p2, p3 and p4, and the bound argument p as the last parameter. +}; + +//! Overloaded bind() factory function. +//! @param s - a slot of type Slot1. +//! @param p5 - a value of type P5. +//! @return a new slot that stores the value p5. +//! +//!
When then returned slot is called it calls the original slot s, passing +//! it the arguments passed to it and the value p5, as the last parameter. If +//! the returned slot is connected to a signal it doesn't have to be unreferenced. The +//! signal it's connected to will unreference the slot when it is destroyed. Otherwise +//! the slot must be unreferenced by calling unref(). + +template +inline Slot4* +bind(Slot5 *s, P5 p5) +{ + return new BoundSlot4_5(s, p5); +} + +//! @class BoundSlot5_6 +//! @brief Converts a slot taking six arguments into a slot taking five arguments. + +template +class BoundSlot5_6 : public Slot5 +{ + Pointer < Slot6 > original_slot; + P6 p; + +public: + BoundSlot5_6(Slot6 *slot, P6 p6) : original_slot(slot), p(p6) {} + //!< Constructor. + //!< @param slot - a pointer to a slot of type Slot1. + //!< @param p6 - a bound argument of type P6 + + virtual R call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return original_slot->call(p1, p2, p3, p4, p5, p); } + //!< Calls the original slot passing it arguments p1, p2, p3, p4 and p5, and the bound argument p as the last parameter. +}; + +//! Overloaded bind() factory function. +//! @param s - a slot of type Slot1. +//! @param p6 - a value of type P6. +//! @return a new slot that stores the value p6. +//! +//!
When then returned slot is called it calls the original slot s, passing +//! it the arguments passed to it and the value p6, as the last parameter. If +//! the returned slot is connected to a signal it doesn't have to be unreferenced. The +//! signal it's connected to will unreference the slot when it is destroyed. Otherwise +//! the slot must be unreferenced by calling unref(). + +template +inline Slot5* +bind(Slot6 *s, P6 p6) +{ + return new BoundSlot5_6(s, p6); +} + +//! @} + +/** @} */ + +} // namespace scim + +#endif //__SCIM_BOUND_SLOT_H + +/* +vi:ts=4:nowrap:ai:expandtab +*/ + diff --git a/ism/src/scim_chartraits.cpp b/ism/src/scim_chartraits.cpp new file mode 100644 index 0000000..2a01d1f --- /dev/null +++ b/ism/src/scim_chartraits.cpp @@ -0,0 +1,172 @@ +/** @file scim_chartraits.cpp + */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_chartraits.cpp,v 1.12 2005/07/05 16:18:17 suzhe Exp $ + */ + +#include +#include "scim_types.h" + +using namespace scim; + +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if !defined(__STDC_ISO_10646__) && GCC_VERSION >= 30200 + +namespace std +{ + +template<> +void +char_traits::assign(char_type& __c1, const char_type& __c2) +{ + __c1 = __c2; +} + +template<> +bool +char_traits::eq(const char_type& __c1, const char_type& __c2) +{ + return __c1 == __c2; +} + +template<> +bool +char_traits::lt(const char_type& __c1, const char_type& __c2) +{ + return __c1 < __c2; +} + +template<> +char_traits::char_type* +char_traits::assign(char_type* __s, size_t __n, char_type __a) +{ + char_type* dest = __s; + while (__n-- > 0) + *(dest++) = __a; + return __s; +} + +template<> +char_traits::char_type* +char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) +{ + char_type* dest = __s1; + const char_type* from = __s2; + while (__n-- > 0) + *(dest++) = *(from++); + return __s1; +} + +template<> +char_traits::char_type* +char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) +{ + if (__s1 + __n > __s2) { + char_type* dest = __s1 + __n - 1; + const char_type* from = __s2; + while (__n-- > 0) + *(dest--) = *(from++); + return __s1; + } else { + return copy(__s1, __s2, __n); + } +} + +template<> +size_t +char_traits::length(const char_type* __s) +{ + size_t __result = 0; + while ( *(__s++) != 0 ) + __result++; + return __result; +} + +template<> +int +char_traits::compare(const char_type* __s1, const char_type* __s2, size_t __n) +{ + while ( (*__s1 == *__s2++) && __n-- > 0 ) + if (*__s1++ == 0) + return (0); + if (__n <= 0) return (0); + return ( *__s1 - *(__s2 - 1) ); +} + +template<> +const char_traits::char_type* +char_traits::find(const char_type* __s, size_t __n, const char_type& __a) +{ + while (__n-- > 0) { + if (*__s == __a) + return __s; + ++__s; + } + return 0; +} + +template<> +char_traits::char_type +char_traits::to_char_type (const int_type& __c) +{ + return static_cast(__c); +} + +template<> +char_traits::int_type +char_traits::to_int_type (const char_type& __c) +{ + return static_cast(__c); +} + +template<> +bool +char_traits::eq_int_type(const int_type& __c1, const int_type& __c2) +{ + return __c1 == __c2; +} + +template<> +char_traits::int_type +char_traits::eof () +{ + return static_cast(EOF); +} + +template<> +char_traits::int_type +char_traits::not_eof (const int_type& __c) +{ + return (__c == eof()) ? 0 : __c; +} + +} +#endif + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/scim_compose_key.cpp b/ism/src/scim_compose_key.cpp new file mode 100644 index 0000000..3ca4b4f --- /dev/null +++ b/ism/src/scim_compose_key.cpp @@ -0,0 +1,306 @@ +/** @file scim_compose_key.cpp + * @brief Implementation of class ComposeKeyFactory and ComposeKeyInstance. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_compose_key.cpp,v 1.7 2005/08/16 07:26:54 suzhe Exp $ + * + */ + +#define Uses_SCIM_COMPOSE_KEY +#define Uses_C_CTYPE + +#include "scim_private.h" +#include "scim.h" + +namespace scim { + +#define SCIM_MAX_COMPOSE_LEN 5 + +struct ComposeSequence +{ + uint32 keys [SCIM_MAX_COMPOSE_LEN]; + ucs4_t unicode; +}; + +class ComposeSequenceLessByKeys +{ +public: + bool operator () (const ComposeSequence &lhs, const ComposeSequence &rhs) const { + for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) { + if (lhs.keys [i] < rhs.keys [i]) return true; + else if (lhs.keys [i] > rhs.keys [i]) return false; + } + return false; + } + + bool operator () (const ComposeSequence &lhs, const uint32 *rhs) const { + for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) { + if (lhs.keys [i] < rhs [i]) return true; + else if (lhs.keys [i] > rhs [i]) return false; + } + return false; + } + + bool operator () (const uint32 *lhs, const ComposeSequence &rhs) const { + for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) { + if (lhs [i] < rhs.keys [i]) return true; + else if (lhs [i] > rhs.keys [i]) return false; + } + return false; + } + + bool operator () (const uint32 *lhs, const uint32 *rhs) const { + for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) { + if (lhs [i] < rhs [i]) return true; + else if (lhs [i] > rhs [i]) return false; + } + return false; + } + +}; + +// Generated from /usr/X11R6/lib/X11/locale/en_US.UTF-8/Compose +// Get rid off all keys with unicode value. +// Merged with the table in gtk+2.x +static const ComposeSequence __scim_compose_seqs[] = { +#include "scim_compose_key_data.h" +}; + +#define SCIM_NUM_COMPOSE_SEQS (sizeof (__scim_compose_seqs) / sizeof (__scim_compose_seqs [0])) + +static uint16 __scim_compose_ignores [] = { + SCIM_KEY_Mode_switch, + SCIM_KEY_Shift_L, + SCIM_KEY_Shift_R, + SCIM_KEY_Control_L, + SCIM_KEY_Control_R, + SCIM_KEY_Caps_Lock, + SCIM_KEY_Shift_Lock, + SCIM_KEY_Meta_L, + SCIM_KEY_Meta_R, + SCIM_KEY_Alt_L, + SCIM_KEY_Alt_R, + SCIM_KEY_Super_L, + SCIM_KEY_Super_R, + SCIM_KEY_Hyper_L, + SCIM_KEY_Hyper_R +}; + +#define SCIM_NUM_COMPOSE_IGNORES (sizeof (__scim_compose_ignores) / sizeof (__scim_compose_ignores [0])) + +ComposeKeyFactory::ComposeKeyFactory () +{ + set_locales ("C"); +} + +ComposeKeyFactory::~ComposeKeyFactory () +{ +} + +WideString +ComposeKeyFactory::get_name () const +{ + return utf8_mbstowcs (_("English/Keyboard")); +} + +WideString +ComposeKeyFactory::get_authors () const +{ + return utf8_mbstowcs ("James Su "); +} + +WideString +ComposeKeyFactory::get_credits () const +{ + return WideString (); +} + +WideString +ComposeKeyFactory::get_help () const +{ + //return WideString (); + return utf8_mbstowcs (_("English input service")); +} + +String +ComposeKeyFactory::get_uuid () const +{ + return String (SCIM_COMPOSE_KEY_FACTORY_UUID); +} + +String +ComposeKeyFactory::get_icon_file () const +{ + return String (SCIM_KEYBOARD_ICON_FILE); +} + +bool +ComposeKeyFactory::validate_encoding (const String& encoding) const +{ + return true; +} + +bool +ComposeKeyFactory::validate_locale (const String& locale) const +{ + return true; +} + +IMEngineInstancePointer +ComposeKeyFactory::create_instance (const String& encoding, int id) +{ + return new ComposeKeyInstance (this, encoding, id); +} + +ComposeKeyInstance::ComposeKeyInstance (ComposeKeyFactory *factory, + const String& encoding, + int id) + : IMEngineInstanceBase (factory, encoding, id) +{ + m_compose_buffer [0] = m_compose_buffer [1] = m_compose_buffer [2] = m_compose_buffer [3] = 0; + m_compose_buffer [4] = m_compose_buffer [5] = m_compose_buffer [6] = m_compose_buffer [7] = 0; +} + +ComposeKeyInstance::~ComposeKeyInstance () +{ +} + +bool +ComposeKeyInstance::process_key_event (const KeyEvent& key) +{ + if (key.is_key_release ()) return false; + + // Ignore modifier key presses. + if (std::binary_search (__scim_compose_ignores, __scim_compose_ignores + SCIM_NUM_COMPOSE_IGNORES, (uint16) key.code)) + return false; + + // Ignore the key if ctrl or alt is down. + if (key.is_control_down () || key.is_alt_down ()) + return false; + + int n_compose = 0; + + while (m_compose_buffer [n_compose] != 0 && n_compose < SCIM_MAX_COMPOSE_LEN) + ++ n_compose; + + // The buffer is full, then reset the buffer first. + if (n_compose == SCIM_MAX_COMPOSE_LEN) { + reset (); + n_compose = 0; + } + + m_compose_buffer [n_compose] = (uint32) key.code; + + const ComposeSequence *it = std::lower_bound (__scim_compose_seqs, + __scim_compose_seqs + SCIM_NUM_COMPOSE_SEQS, + m_compose_buffer, + ComposeSequenceLessByKeys ()); + + // Not result found, reset the buffer and return false. + if (it == __scim_compose_seqs + SCIM_NUM_COMPOSE_SEQS) { + reset (); + return false; + } + + // Check if the compose sequence is match. + for (n_compose = 0; n_compose < SCIM_MAX_COMPOSE_LEN; ++ n_compose) { + if (m_compose_buffer [n_compose] == 0) + break; + + // Not match, reset the buffer and return. + // If it's the first key press, then return false to forward it. + // Otherwise return true to ignore it. + if (m_compose_buffer [n_compose] != it->keys [n_compose]) { + reset (); + return n_compose != 0; + } + } + + // Match exactly, commit the result. + if (n_compose == SCIM_MAX_COMPOSE_LEN || it->keys [n_compose] == 0) { + WideString wstr; + wstr.push_back (it->unicode); + commit_string (wstr); + reset (); + } + + return true; +} + +void +ComposeKeyInstance::move_preedit_caret (unsigned int /*pos*/) +{ +} + +void +ComposeKeyInstance::select_candidate (unsigned int /*item*/) +{ +} + +void +ComposeKeyInstance::update_lookup_table_page_size (unsigned int /*page_size*/) +{ +} + +void +ComposeKeyInstance::lookup_table_page_up () +{ +} + +void +ComposeKeyInstance::lookup_table_page_down () +{ +} + +void +ComposeKeyInstance::reset () +{ + m_compose_buffer [0] = m_compose_buffer [1] = m_compose_buffer [2] = m_compose_buffer [3] = 0; + m_compose_buffer [4] = m_compose_buffer [5] = m_compose_buffer [6] = m_compose_buffer [7] = 0; +} + +void +ComposeKeyInstance::focus_in () +{ + register_properties (PropertyList ()); + reset (); +} + +void +ComposeKeyInstance::focus_out () +{ +} + +void +ComposeKeyInstance::trigger_property (const String & /*property*/) +{ +} + +} // namespace scim + +/* +vi:ts=4:nowrap:ai:expandtab +*/ diff --git a/ism/src/scim_compose_key.h b/ism/src/scim_compose_key.h new file mode 100644 index 0000000..3acff00 --- /dev/null +++ b/ism/src/scim_compose_key.h @@ -0,0 +1,98 @@ +/** + * @file scim_compose_key.h + * @brief Defines scim::ComposeKeyFactory and scim::ComposeKeyInstance. + */ + +/* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */ + +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_compose_key.h,v 1.5 2005/08/16 07:26:54 suzhe Exp $ + */ + +#ifndef __SCIM_COMPOSE_KEY_H +#define __SCIM_COMPOSE_KEY_H + +namespace scim { +/** + * @addtogroup IMEngine + * @ingroup InputServiceFramework + * @{ + */ + +#define SCIM_COMPOSE_KEY_FACTORY_UUID "c6bebc27-6324-4b77-8ad4-6d41dcaf2e08" + +/** + * @brief A simple IMEngine to deal with the Compose keys. + */ +class ComposeKeyFactory : public IMEngineFactoryBase +{ +public: + ComposeKeyFactory (); + virtual ~ComposeKeyFactory (); + + virtual WideString get_name () const; + virtual String get_uuid () const; + virtual String get_icon_file () const; + virtual WideString get_authors () const; + virtual WideString get_credits () const; + virtual WideString get_help () const; + + virtual bool validate_encoding (const String& encoding) const; + virtual bool validate_locale (const String& locale) const; + + virtual IMEngineInstancePointer create_instance (const String& encoding, int id = -1); +}; + +class ComposeKeyInstance : public IMEngineInstanceBase +{ + uint32 m_compose_buffer [8]; + +public: + ComposeKeyInstance (ComposeKeyFactory *factory, + const String &encoding, + int id = -1); + + virtual ~ComposeKeyInstance (); + + virtual bool process_key_event (const KeyEvent& key); + virtual void move_preedit_caret (unsigned int pos); + virtual void select_candidate (unsigned int index); + virtual void update_lookup_table_page_size (unsigned int page_size); + virtual void lookup_table_page_up (); + virtual void lookup_table_page_down (); + virtual void reset (); + virtual void focus_in (); + virtual void focus_out (); + virtual void trigger_property (const String& property); +}; + +/** @} */ + +} // namespace scim + +#endif //__SCIM_COMPOSE_KEY_H + +/* +vi:ts=4:nowrap:ai:expandtab +*/ + diff --git a/ism/src/scim_compose_key_data.h b/ism/src/scim_compose_key_data.h new file mode 100644 index 0000000..e62015e --- /dev/null +++ b/ism/src/scim_compose_key_data.h @@ -0,0 +1,5918 @@ + {{SCIM_KEY_combining_tilde, SCIM_KEY_A, 0, 0, 0 }, 0x00C3}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_E, 0, 0, 0 }, 0x1EBC}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_I, 0, 0, 0 }, 0x0128}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_N, 0, 0, 0 }, 0x00D1}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_O, 0, 0, 0 }, 0x00D5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_U, 0, 0, 0 }, 0x0168}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_V, 0, 0, 0 }, 0x1E7C}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF8}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_a, 0, 0, 0 }, 0x00E3}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_e, 0, 0, 0 }, 0x1EBD}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_i, 0, 0, 0 }, 0x0129}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_n, 0, 0, 0 }, 0x00F1}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_o, 0, 0, 0 }, 0x00F5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_u, 0, 0, 0 }, 0x0169}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_v, 0, 0, 0 }, 0x1E7D}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_y, 0, 0, 0 }, 0x1EF9}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EAA}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EC4}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED6}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EAB}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EC5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED7}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EB4}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EB5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EE0}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EE1}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EEE}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EEF}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EAA}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EC4}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED6}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EAB}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EC5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED7}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EB4}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EB5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EE0}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EEE}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EE1}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EEF}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EE0}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEE}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EE1}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EEF}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB4}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EAA}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC4}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED6}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EAB}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC5}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED7}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB4}, + {{SCIM_KEY_combining_tilde, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB5}, + {{SCIM_KEY_combining_grave, SCIM_KEY_A, 0, 0, 0 }, 0x00C0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_E, 0, 0, 0 }, 0x00C8}, + {{SCIM_KEY_combining_grave, SCIM_KEY_I, 0, 0, 0 }, 0x00CC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_N, 0, 0, 0 }, 0x01F8}, + {{SCIM_KEY_combining_grave, SCIM_KEY_O, 0, 0, 0 }, 0x00D2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_U, 0, 0, 0 }, 0x00D9}, + {{SCIM_KEY_combining_grave, SCIM_KEY_W, 0, 0, 0 }, 0x1E80}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_a, 0, 0, 0 }, 0x00E0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_e, 0, 0, 0 }, 0x00E8}, + {{SCIM_KEY_combining_grave, SCIM_KEY_i, 0, 0, 0 }, 0x00EC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_n, 0, 0, 0 }, 0x01F9}, + {{SCIM_KEY_combining_grave, SCIM_KEY_o, 0, 0, 0 }, 0x00F2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_u, 0, 0, 0 }, 0x00F9}, + {{SCIM_KEY_combining_grave, SCIM_KEY_w, 0, 0, 0 }, 0x1E81}, + {{SCIM_KEY_combining_grave, SCIM_KEY_y, 0, 0, 0 }, 0x1EF3}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EA6}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EC0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Udiaeresis, 0, 0, 0 }, 0x01DB}, + {{SCIM_KEY_combining_grave, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EA7}, + {{SCIM_KEY_combining_grave, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EC1}, + {{SCIM_KEY_combining_grave, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED3}, + {{SCIM_KEY_combining_grave, SCIM_KEY_udiaeresis, 0, 0, 0 }, 0x01DC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EB0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EB1}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Emacron, 0, 0, 0 }, 0x1E14}, + {{SCIM_KEY_combining_grave, SCIM_KEY_emacron, 0, 0, 0 }, 0x1E15}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Omacron, 0, 0, 0 }, 0x1E50}, + {{SCIM_KEY_combining_grave, SCIM_KEY_omacron, 0, 0, 0 }, 0x1E51}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Cyrillic_ie, 0, 0, 0 }, 0x0450}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Cyrillic_i, 0, 0, 0 }, 0x045D}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Cyrillic_IE, 0, 0, 0 }, 0x0400}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Cyrillic_I, 0, 0, 0 }, 0x040D}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_iotadieresis, 0, 0, 0 }, 0x1FD2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_upsilondieresis, 0, 0, 0 }, 0x1FE2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x1FBA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_EPSILON, 0, 0, 0 }, 0x1FC8}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_ETA, 0, 0, 0 }, 0x1FCA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x1FDA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_OMICRON, 0, 0, 0 }, 0x1FF8}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x1FEA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_OMEGA, 0, 0, 0 }, 0x1FFA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1F70}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_epsilon, 0, 0, 0 }, 0x1F72}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x1F74}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1F76}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_omicron, 0, 0, 0 }, 0x1F78}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1F7A}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x1F7C}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EDC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EDD}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EEA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EEB}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EA6}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EC0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EA7}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EC1}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED3}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_macron, SCIM_KEY_E, 0, 0 }, 0x1E14}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_macron, SCIM_KEY_O, 0, 0 }, 0x1E50}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_macron, SCIM_KEY_e, 0, 0 }, 0x1E15}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_macron, SCIM_KEY_o, 0, 0 }, 0x1E51}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EB0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EB1}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0, 0 }, 0x01DB}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0, 0 }, 0x01DC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EDC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EEA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EDD}, + {{SCIM_KEY_combining_grave, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EEB}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01DB}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01DC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x1FD2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0B}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1B}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2B}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3B}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4B}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5B}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6B}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F03}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0 }, 0x1F13}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F23}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F33}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0 }, 0x1F43}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F53}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F63}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0A}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1A}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2A}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3A}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4A}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6A}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F02}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0 }, 0x1F12}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F22}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F32}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0 }, 0x1F42}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F52}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F62}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDC}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEA}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDD}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EEB}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB1}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA6}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED2}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA7}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC1}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED3}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_E, 0 }, 0x1E14}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_O, 0 }, 0x1E50}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_e, 0 }, 0x1E15}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x1E51}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB0}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB1}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_E, 0 }, 0x1E14}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_O, 0 }, 0x1E50}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_e, 0 }, 0x1E15}, + {{SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_o, 0 }, 0x1E51}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0A}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1A}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2A}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3A}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4A}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6A}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F02}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F12}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F22}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F32}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F42}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F52}, + {{SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F62}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0B}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1B}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2B}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3B}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4B}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1F5B}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6B}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F03}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F13}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F23}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F33}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F43}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F53}, + {{SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F63}, + {{SCIM_KEY_combining_grave, 0x1001f00, 0, 0, 0 }, 0x1F02}, + {{SCIM_KEY_combining_grave, 0x1001f01, 0, 0, 0 }, 0x1F03}, + {{SCIM_KEY_combining_grave, 0x1001f08, 0, 0, 0 }, 0x1F0A}, + {{SCIM_KEY_combining_grave, 0x1001f09, 0, 0, 0 }, 0x1F0B}, + {{SCIM_KEY_combining_grave, 0x1001f10, 0, 0, 0 }, 0x1F12}, + {{SCIM_KEY_combining_grave, 0x1001f11, 0, 0, 0 }, 0x1F13}, + {{SCIM_KEY_combining_grave, 0x1001f18, 0, 0, 0 }, 0x1F1A}, + {{SCIM_KEY_combining_grave, 0x1001f19, 0, 0, 0 }, 0x1F1B}, + {{SCIM_KEY_combining_grave, 0x1001f20, 0, 0, 0 }, 0x1F22}, + {{SCIM_KEY_combining_grave, 0x1001f21, 0, 0, 0 }, 0x1F23}, + {{SCIM_KEY_combining_grave, 0x1001f28, 0, 0, 0 }, 0x1F2A}, + {{SCIM_KEY_combining_grave, 0x1001f29, 0, 0, 0 }, 0x1F2B}, + {{SCIM_KEY_combining_grave, 0x1001f30, 0, 0, 0 }, 0x1F32}, + {{SCIM_KEY_combining_grave, 0x1001f31, 0, 0, 0 }, 0x1F33}, + {{SCIM_KEY_combining_grave, 0x1001f38, 0, 0, 0 }, 0x1F3A}, + {{SCIM_KEY_combining_grave, 0x1001f39, 0, 0, 0 }, 0x1F3B}, + {{SCIM_KEY_combining_grave, 0x1001f40, 0, 0, 0 }, 0x1F42}, + {{SCIM_KEY_combining_grave, 0x1001f41, 0, 0, 0 }, 0x1F43}, + {{SCIM_KEY_combining_grave, 0x1001f48, 0, 0, 0 }, 0x1F4A}, + {{SCIM_KEY_combining_grave, 0x1001f49, 0, 0, 0 }, 0x1F4B}, + {{SCIM_KEY_combining_grave, 0x1001f50, 0, 0, 0 }, 0x1F52}, + {{SCIM_KEY_combining_grave, 0x1001f51, 0, 0, 0 }, 0x1F53}, + {{SCIM_KEY_combining_grave, 0x1001f59, 0, 0, 0 }, 0x1F5B}, + {{SCIM_KEY_combining_grave, 0x1001f60, 0, 0, 0 }, 0x1F62}, + {{SCIM_KEY_combining_grave, 0x1001f61, 0, 0, 0 }, 0x1F63}, + {{SCIM_KEY_combining_grave, 0x1001f68, 0, 0, 0 }, 0x1F6A}, + {{SCIM_KEY_combining_grave, 0x1001f69, 0, 0, 0 }, 0x1F6B}, + {{SCIM_KEY_combining_acute, SCIM_KEY_A, 0, 0, 0 }, 0x00C1}, + {{SCIM_KEY_combining_acute, SCIM_KEY_C, 0, 0, 0 }, 0x0106}, + {{SCIM_KEY_combining_acute, SCIM_KEY_E, 0, 0, 0 }, 0x00C9}, + {{SCIM_KEY_combining_acute, SCIM_KEY_G, 0, 0, 0 }, 0x01F4}, + {{SCIM_KEY_combining_acute, SCIM_KEY_I, 0, 0, 0 }, 0x00CD}, + {{SCIM_KEY_combining_acute, SCIM_KEY_K, 0, 0, 0 }, 0x1E30}, + {{SCIM_KEY_combining_acute, SCIM_KEY_L, 0, 0, 0 }, 0x0139}, + {{SCIM_KEY_combining_acute, SCIM_KEY_M, 0, 0, 0 }, 0x1E3E}, + {{SCIM_KEY_combining_acute, SCIM_KEY_N, 0, 0, 0 }, 0x0143}, + {{SCIM_KEY_combining_acute, SCIM_KEY_O, 0, 0, 0 }, 0x00D3}, + {{SCIM_KEY_combining_acute, SCIM_KEY_P, 0, 0, 0 }, 0x1E54}, + {{SCIM_KEY_combining_acute, SCIM_KEY_R, 0, 0, 0 }, 0x0154}, + {{SCIM_KEY_combining_acute, SCIM_KEY_S, 0, 0, 0 }, 0x015A}, + {{SCIM_KEY_combining_acute, SCIM_KEY_U, 0, 0, 0 }, 0x00DA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_W, 0, 0, 0 }, 0x1E82}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Y, 0, 0, 0 }, 0x00DD}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Z, 0, 0, 0 }, 0x0179}, + {{SCIM_KEY_combining_acute, SCIM_KEY_a, 0, 0, 0 }, 0x00E1}, + {{SCIM_KEY_combining_acute, SCIM_KEY_c, 0, 0, 0 }, 0x0107}, + {{SCIM_KEY_combining_acute, SCIM_KEY_e, 0, 0, 0 }, 0x00E9}, + {{SCIM_KEY_combining_acute, SCIM_KEY_g, 0, 0, 0 }, 0x01F5}, + {{SCIM_KEY_combining_acute, SCIM_KEY_i, 0, 0, 0 }, 0x00ED}, + {{SCIM_KEY_combining_acute, SCIM_KEY_k, 0, 0, 0 }, 0x1E31}, + {{SCIM_KEY_combining_acute, SCIM_KEY_l, 0, 0, 0 }, 0x013A}, + {{SCIM_KEY_combining_acute, SCIM_KEY_m, 0, 0, 0 }, 0x1E3F}, + {{SCIM_KEY_combining_acute, SCIM_KEY_n, 0, 0, 0 }, 0x0144}, + {{SCIM_KEY_combining_acute, SCIM_KEY_o, 0, 0, 0 }, 0x00F3}, + {{SCIM_KEY_combining_acute, SCIM_KEY_p, 0, 0, 0 }, 0x1E55}, + {{SCIM_KEY_combining_acute, SCIM_KEY_r, 0, 0, 0 }, 0x0155}, + {{SCIM_KEY_combining_acute, SCIM_KEY_s, 0, 0, 0 }, 0x015B}, + {{SCIM_KEY_combining_acute, SCIM_KEY_u, 0, 0, 0 }, 0x00FA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_w, 0, 0, 0 }, 0x1E83}, + {{SCIM_KEY_combining_acute, SCIM_KEY_y, 0, 0, 0 }, 0x00FD}, + {{SCIM_KEY_combining_acute, SCIM_KEY_z, 0, 0, 0 }, 0x017A}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EA4}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Aring, 0, 0, 0 }, 0x01FA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_AE, 0, 0, 0 }, 0x01FC}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Ccedilla, 0, 0, 0 }, 0x1E08}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EBE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Idiaeresis, 0, 0, 0 }, 0x1E2E}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED0}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Otilde, 0, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Ooblique, 0, 0, 0 }, 0x01FE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Udiaeresis, 0, 0, 0 }, 0x01D7}, + {{SCIM_KEY_combining_acute, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EA5}, + {{SCIM_KEY_combining_acute, SCIM_KEY_aring, 0, 0, 0 }, 0x01FB}, + {{SCIM_KEY_combining_acute, SCIM_KEY_ae, 0, 0, 0 }, 0x01FD}, + {{SCIM_KEY_combining_acute, SCIM_KEY_ccedilla, 0, 0, 0 }, 0x1E09}, + {{SCIM_KEY_combining_acute, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EBF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_idiaeresis, 0, 0, 0 }, 0x1E2F}, + {{SCIM_KEY_combining_acute, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED1}, + {{SCIM_KEY_combining_acute, SCIM_KEY_otilde, 0, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_oslash, 0, 0, 0 }, 0x01FF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_udiaeresis, 0, 0, 0 }, 0x01D8}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EAE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EAF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Emacron, 0, 0, 0 }, 0x1E16}, + {{SCIM_KEY_combining_acute, SCIM_KEY_emacron, 0, 0, 0 }, 0x1E17}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Omacron, 0, 0, 0 }, 0x1E52}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Utilde, 0, 0, 0 }, 0x1E78}, + {{SCIM_KEY_combining_acute, SCIM_KEY_omacron, 0, 0, 0 }, 0x1E53}, + {{SCIM_KEY_combining_acute, SCIM_KEY_utilde, 0, 0, 0 }, 0x1E79}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Cyrillic_ghe, 0, 0, 0 }, 0x0453}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Cyrillic_ka, 0, 0, 0 }, 0x045C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Cyrillic_GHE, 0, 0, 0 }, 0x0403}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Cyrillic_KA, 0, 0, 0 }, 0x040C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_iotadieresis, 0, 0, 0 }, 0x0390}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_upsilondieresis, 0, 0, 0 }, 0x03B0}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x0386}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_EPSILON, 0, 0, 0 }, 0x0388}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_ETA, 0, 0, 0 }, 0x0389}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x038A}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_OMICRON, 0, 0, 0 }, 0x038C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x038E}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_OMEGA, 0, 0, 0 }, 0x038F}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x03AC}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_epsilon, 0, 0, 0 }, 0x03AD}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x03AE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x03AF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_omicron, 0, 0, 0 }, 0x03CC}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x03CD}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x03CE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_combining_tilde, SCIM_KEY_U, 0, 0 }, 0x1E78}, + {{SCIM_KEY_combining_acute, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_combining_tilde, SCIM_KEY_u, 0, 0 }, 0x1E79}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EDA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EDB}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EE8}, + {{SCIM_KEY_combining_acute, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EE9}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EA4}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EBE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED0}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EA5}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EBF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED1}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_tilde, SCIM_KEY_U, 0, 0 }, 0x1E78}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_tilde, SCIM_KEY_u, 0, 0 }, 0x1E79}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_macron, SCIM_KEY_E, 0, 0 }, 0x1E16}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_macron, SCIM_KEY_O, 0, 0 }, 0x1E52}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_macron, SCIM_KEY_e, 0, 0 }, 0x1E17}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_macron, SCIM_KEY_o, 0, 0 }, 0x1E53}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EAE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EAF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_I, 0, 0 }, 0x1E2E}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0, 0 }, 0x01D7}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_i, 0, 0 }, 0x1E2F}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0, 0 }, 0x01D8}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0, 0 }, 0x0390}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x03B0}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_abovering, SCIM_KEY_A, 0, 0 }, 0x01FA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_abovering, SCIM_KEY_a, 0, 0 }, 0x01FB}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_cedilla, SCIM_KEY_C, 0, 0 }, 0x1E08}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_cedilla, SCIM_KEY_c, 0, 0 }, 0x1E09}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EDA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EE8}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EDB}, + {{SCIM_KEY_combining_acute, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EE9}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_I, 0 }, 0x1E2E}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D7}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_i, 0 }, 0x1E2F}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01D8}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x0390}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x03B0}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F05}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0 }, 0x1F15}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F25}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F35}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0 }, 0x1F45}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F55}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F65}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F04}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0 }, 0x1F14}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F24}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F34}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0 }, 0x1F44}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F54}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F64}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EE8}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDB}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EE9}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_C, 0 }, 0x1E08}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_c, 0 }, 0x1E09}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA4}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EBE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED0}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA5}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EBF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED1}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_A, 0 }, 0x01FA}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_a, 0 }, 0x01FB}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0C}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1C}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2C}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3C}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4C}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6C}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F04}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F14}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F24}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F34}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F44}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F54}, + {{SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F64}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0D}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1D}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2D}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3D}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4D}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1F5D}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6D}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F05}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F15}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F25}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F35}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F45}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F55}, + {{SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F65}, + {{SCIM_KEY_combining_acute, 0x1001f00, 0, 0, 0 }, 0x1F04}, + {{SCIM_KEY_combining_acute, 0x1001f01, 0, 0, 0 }, 0x1F05}, + {{SCIM_KEY_combining_acute, 0x1001f08, 0, 0, 0 }, 0x1F0C}, + {{SCIM_KEY_combining_acute, 0x1001f09, 0, 0, 0 }, 0x1F0D}, + {{SCIM_KEY_combining_acute, 0x1001f10, 0, 0, 0 }, 0x1F14}, + {{SCIM_KEY_combining_acute, 0x1001f11, 0, 0, 0 }, 0x1F15}, + {{SCIM_KEY_combining_acute, 0x1001f18, 0, 0, 0 }, 0x1F1C}, + {{SCIM_KEY_combining_acute, 0x1001f19, 0, 0, 0 }, 0x1F1D}, + {{SCIM_KEY_combining_acute, 0x1001f20, 0, 0, 0 }, 0x1F24}, + {{SCIM_KEY_combining_acute, 0x1001f21, 0, 0, 0 }, 0x1F25}, + {{SCIM_KEY_combining_acute, 0x1001f28, 0, 0, 0 }, 0x1F2C}, + {{SCIM_KEY_combining_acute, 0x1001f29, 0, 0, 0 }, 0x1F2D}, + {{SCIM_KEY_combining_acute, 0x1001f30, 0, 0, 0 }, 0x1F34}, + {{SCIM_KEY_combining_acute, 0x1001f31, 0, 0, 0 }, 0x1F35}, + {{SCIM_KEY_combining_acute, 0x1001f38, 0, 0, 0 }, 0x1F3C}, + {{SCIM_KEY_combining_acute, 0x1001f39, 0, 0, 0 }, 0x1F3D}, + {{SCIM_KEY_combining_acute, 0x1001f40, 0, 0, 0 }, 0x1F44}, + {{SCIM_KEY_combining_acute, 0x1001f41, 0, 0, 0 }, 0x1F45}, + {{SCIM_KEY_combining_acute, 0x1001f48, 0, 0, 0 }, 0x1F4C}, + {{SCIM_KEY_combining_acute, 0x1001f49, 0, 0, 0 }, 0x1F4D}, + {{SCIM_KEY_combining_acute, 0x1001f50, 0, 0, 0 }, 0x1F54}, + {{SCIM_KEY_combining_acute, 0x1001f51, 0, 0, 0 }, 0x1F55}, + {{SCIM_KEY_combining_acute, 0x1001f59, 0, 0, 0 }, 0x1F5D}, + {{SCIM_KEY_combining_acute, 0x1001f60, 0, 0, 0 }, 0x1F64}, + {{SCIM_KEY_combining_acute, 0x1001f61, 0, 0, 0 }, 0x1F65}, + {{SCIM_KEY_combining_acute, 0x1001f68, 0, 0, 0 }, 0x1F6C}, + {{SCIM_KEY_combining_acute, 0x1001f69, 0, 0, 0 }, 0x1F6D}, + {{SCIM_KEY_combining_hook, SCIM_KEY_A, 0, 0, 0 }, 0x1EA2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_E, 0, 0, 0 }, 0x1EBA}, + {{SCIM_KEY_combining_hook, SCIM_KEY_I, 0, 0, 0 }, 0x1EC8}, + {{SCIM_KEY_combining_hook, SCIM_KEY_O, 0, 0, 0 }, 0x1ECE}, + {{SCIM_KEY_combining_hook, SCIM_KEY_U, 0, 0, 0 }, 0x1EE6}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF6}, + {{SCIM_KEY_combining_hook, SCIM_KEY_a, 0, 0, 0 }, 0x1EA3}, + {{SCIM_KEY_combining_hook, SCIM_KEY_e, 0, 0, 0 }, 0x1EBB}, + {{SCIM_KEY_combining_hook, SCIM_KEY_i, 0, 0, 0 }, 0x1EC9}, + {{SCIM_KEY_combining_hook, SCIM_KEY_o, 0, 0, 0 }, 0x1ECF}, + {{SCIM_KEY_combining_hook, SCIM_KEY_u, 0, 0, 0 }, 0x1EE7}, + {{SCIM_KEY_combining_hook, SCIM_KEY_y, 0, 0, 0 }, 0x1EF7}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EA8}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EC2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED4}, + {{SCIM_KEY_combining_hook, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EA9}, + {{SCIM_KEY_combining_hook, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EC3}, + {{SCIM_KEY_combining_hook, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED5}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EB2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EB3}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EDE}, + {{SCIM_KEY_combining_hook, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EDF}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EEC}, + {{SCIM_KEY_combining_hook, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EED}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EA8}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EC2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED4}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EA9}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EC3}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED5}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EB2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EB3}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EDE}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EEC}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EDF}, + {{SCIM_KEY_combining_hook, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EED}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDE}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEC}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDF}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EED}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB3}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA8}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED4}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA9}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC3}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED5}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB2}, + {{SCIM_KEY_combining_hook, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB3}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_A, 0, 0, 0 }, 0x1EA0}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_B, 0, 0, 0 }, 0x1E04}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_D, 0, 0, 0 }, 0x1E0C}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_E, 0, 0, 0 }, 0x1EB8}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_H, 0, 0, 0 }, 0x1E24}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_I, 0, 0, 0 }, 0x1ECA}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_K, 0, 0, 0 }, 0x1E32}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_L, 0, 0, 0 }, 0x1E36}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_M, 0, 0, 0 }, 0x1E42}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_N, 0, 0, 0 }, 0x1E46}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_O, 0, 0, 0 }, 0x1ECC}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_R, 0, 0, 0 }, 0x1E5A}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_S, 0, 0, 0 }, 0x1E62}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_T, 0, 0, 0 }, 0x1E6C}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_U, 0, 0, 0 }, 0x1EE4}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_V, 0, 0, 0 }, 0x1E7E}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_W, 0, 0, 0 }, 0x1E88}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF4}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Z, 0, 0, 0 }, 0x1E92}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_a, 0, 0, 0 }, 0x1EA1}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_b, 0, 0, 0 }, 0x1E05}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_d, 0, 0, 0 }, 0x1E0D}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_e, 0, 0, 0 }, 0x1EB9}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_h, 0, 0, 0 }, 0x1E25}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_i, 0, 0, 0 }, 0x1ECB}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_k, 0, 0, 0 }, 0x1E33}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_l, 0, 0, 0 }, 0x1E37}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_m, 0, 0, 0 }, 0x1E43}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_n, 0, 0, 0 }, 0x1E47}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_o, 0, 0, 0 }, 0x1ECD}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_r, 0, 0, 0 }, 0x1E5B}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_s, 0, 0, 0 }, 0x1E63}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_t, 0, 0, 0 }, 0x1E6D}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_u, 0, 0, 0 }, 0x1EE5}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_v, 0, 0, 0 }, 0x1E7F}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_w, 0, 0, 0 }, 0x1E89}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_y, 0, 0, 0 }, 0x1EF5}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_z, 0, 0, 0 }, 0x1E93}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EE2}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EE3}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EF0}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EF1}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EE2}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EF0}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EE3}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EF1}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EE2}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EF0}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EE3}, + {{SCIM_KEY_combining_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EF1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_space, 0, 0, 0 }, 0x0060}, + {{SCIM_KEY_dead_grave, SCIM_KEY_A, 0, 0, 0 }, 0x00C0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_E, 0, 0, 0 }, 0x00C8}, + {{SCIM_KEY_dead_grave, SCIM_KEY_I, 0, 0, 0 }, 0x00CC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_N, 0, 0, 0 }, 0x01F8}, + {{SCIM_KEY_dead_grave, SCIM_KEY_O, 0, 0, 0 }, 0x00D2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_U, 0, 0, 0 }, 0x00D9}, + {{SCIM_KEY_dead_grave, SCIM_KEY_W, 0, 0, 0 }, 0x1E80}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_grave, 0, 0, 0 }, 0x0060}, + {{SCIM_KEY_dead_grave, SCIM_KEY_a, 0, 0, 0 }, 0x00E0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_e, 0, 0, 0 }, 0x00E8}, + {{SCIM_KEY_dead_grave, SCIM_KEY_i, 0, 0, 0 }, 0x00EC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_n, 0, 0, 0 }, 0x01F9}, + {{SCIM_KEY_dead_grave, SCIM_KEY_o, 0, 0, 0 }, 0x00F2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_u, 0, 0, 0 }, 0x00F9}, + {{SCIM_KEY_dead_grave, SCIM_KEY_w, 0, 0, 0 }, 0x1E81}, + {{SCIM_KEY_dead_grave, SCIM_KEY_y, 0, 0, 0 }, 0x1EF3}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EA6}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EC0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Udiaeresis, 0, 0, 0 }, 0x01DB}, + {{SCIM_KEY_dead_grave, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EA7}, + {{SCIM_KEY_dead_grave, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EC1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED3}, + {{SCIM_KEY_dead_grave, SCIM_KEY_udiaeresis, 0, 0, 0 }, 0x01DC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EB0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EB1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Emacron, 0, 0, 0 }, 0x1E14}, + {{SCIM_KEY_dead_grave, SCIM_KEY_emacron, 0, 0, 0 }, 0x1E15}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Omacron, 0, 0, 0 }, 0x1E50}, + {{SCIM_KEY_dead_grave, SCIM_KEY_omacron, 0, 0, 0 }, 0x1E51}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Cyrillic_ie, 0, 0, 0 }, 0x0450}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Cyrillic_i, 0, 0, 0 }, 0x045D}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Cyrillic_IE, 0, 0, 0 }, 0x0400}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Cyrillic_I, 0, 0, 0 }, 0x040D}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_iotadieresis, 0, 0, 0 }, 0x1FD2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_upsilondieresis, 0, 0, 0 }, 0x1FE2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x1FBA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_EPSILON, 0, 0, 0 }, 0x1FC8}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_ETA, 0, 0, 0 }, 0x1FCA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x1FDA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_OMICRON, 0, 0, 0 }, 0x1FF8}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x1FEA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_OMEGA, 0, 0, 0 }, 0x1FFA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1F70}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_epsilon, 0, 0, 0 }, 0x1F72}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x1F74}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1F76}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_omicron, 0, 0, 0 }, 0x1F78}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1F7A}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x1F7C}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EDC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EDD}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EEA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EEB}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_grave, 0, 0, 0 }, 0x0060}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EA6}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EC0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EA7}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EC1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED3}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_macron, SCIM_KEY_E, 0, 0 }, 0x1E14}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_macron, SCIM_KEY_O, 0, 0 }, 0x1E50}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_macron, SCIM_KEY_e, 0, 0 }, 0x1E15}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_macron, SCIM_KEY_o, 0, 0 }, 0x1E51}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EB0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EB1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0, 0 }, 0x01DB}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0, 0 }, 0x01DC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EDC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EEA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EDD}, + {{SCIM_KEY_dead_grave, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EEB}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01DB}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01DC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x1FD2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0B}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1B}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2B}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3B}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4B}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5B}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6B}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F03}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0 }, 0x1F13}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F23}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F33}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0 }, 0x1F43}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F53}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F63}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0A}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1A}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2A}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3A}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4A}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6A}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F02}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0 }, 0x1F12}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F22}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F32}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0 }, 0x1F42}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F52}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F62}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDC}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEA}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDD}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EEB}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA6}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED2}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA7}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED3}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_E, 0 }, 0x1E14}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_O, 0 }, 0x1E50}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_e, 0 }, 0x1E15}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x1E51}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB0}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB1}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_E, 0 }, 0x1E14}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_O, 0 }, 0x1E50}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_e, 0 }, 0x1E15}, + {{SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_o, 0 }, 0x1E51}, + {{SCIM_KEY_dead_grave, 0x10001a0, 0, 0, 0 }, 0x1EDC}, + {{SCIM_KEY_dead_grave, 0x10001a1, 0, 0, 0 }, 0x1EDD}, + {{SCIM_KEY_dead_grave, 0x10001af, 0, 0, 0 }, 0x1EEA}, + {{SCIM_KEY_dead_grave, 0x10001b0, 0, 0, 0 }, 0x1EEB}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0A}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1A}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2A}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3A}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4A}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6A}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F02}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F12}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F22}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F32}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F42}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F52}, + {{SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F62}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0B}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1B}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2B}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3B}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4B}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1F5B}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6B}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F03}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F13}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F23}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F33}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F43}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F53}, + {{SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F63}, + {{SCIM_KEY_dead_grave, 0x1001f00, 0, 0, 0 }, 0x1F02}, + {{SCIM_KEY_dead_grave, 0x1001f01, 0, 0, 0 }, 0x1F03}, + {{SCIM_KEY_dead_grave, 0x1001f08, 0, 0, 0 }, 0x1F0A}, + {{SCIM_KEY_dead_grave, 0x1001f09, 0, 0, 0 }, 0x1F0B}, + {{SCIM_KEY_dead_grave, 0x1001f10, 0, 0, 0 }, 0x1F12}, + {{SCIM_KEY_dead_grave, 0x1001f11, 0, 0, 0 }, 0x1F13}, + {{SCIM_KEY_dead_grave, 0x1001f18, 0, 0, 0 }, 0x1F1A}, + {{SCIM_KEY_dead_grave, 0x1001f19, 0, 0, 0 }, 0x1F1B}, + {{SCIM_KEY_dead_grave, 0x1001f20, 0, 0, 0 }, 0x1F22}, + {{SCIM_KEY_dead_grave, 0x1001f21, 0, 0, 0 }, 0x1F23}, + {{SCIM_KEY_dead_grave, 0x1001f28, 0, 0, 0 }, 0x1F2A}, + {{SCIM_KEY_dead_grave, 0x1001f29, 0, 0, 0 }, 0x1F2B}, + {{SCIM_KEY_dead_grave, 0x1001f30, 0, 0, 0 }, 0x1F32}, + {{SCIM_KEY_dead_grave, 0x1001f31, 0, 0, 0 }, 0x1F33}, + {{SCIM_KEY_dead_grave, 0x1001f38, 0, 0, 0 }, 0x1F3A}, + {{SCIM_KEY_dead_grave, 0x1001f39, 0, 0, 0 }, 0x1F3B}, + {{SCIM_KEY_dead_grave, 0x1001f40, 0, 0, 0 }, 0x1F42}, + {{SCIM_KEY_dead_grave, 0x1001f41, 0, 0, 0 }, 0x1F43}, + {{SCIM_KEY_dead_grave, 0x1001f48, 0, 0, 0 }, 0x1F4A}, + {{SCIM_KEY_dead_grave, 0x1001f49, 0, 0, 0 }, 0x1F4B}, + {{SCIM_KEY_dead_grave, 0x1001f50, 0, 0, 0 }, 0x1F52}, + {{SCIM_KEY_dead_grave, 0x1001f51, 0, 0, 0 }, 0x1F53}, + {{SCIM_KEY_dead_grave, 0x1001f59, 0, 0, 0 }, 0x1F5B}, + {{SCIM_KEY_dead_grave, 0x1001f60, 0, 0, 0 }, 0x1F62}, + {{SCIM_KEY_dead_grave, 0x1001f61, 0, 0, 0 }, 0x1F63}, + {{SCIM_KEY_dead_grave, 0x1001f68, 0, 0, 0 }, 0x1F6A}, + {{SCIM_KEY_dead_grave, 0x1001f69, 0, 0, 0 }, 0x1F6B}, + {{SCIM_KEY_dead_acute, SCIM_KEY_space, 0, 0, 0 }, 0x0027}, + {{SCIM_KEY_dead_acute, SCIM_KEY_apostrophe, 0, 0, 0 }, 0x00B4}, + {{SCIM_KEY_dead_acute, SCIM_KEY_A, 0, 0, 0 }, 0x00C1}, + {{SCIM_KEY_dead_acute, SCIM_KEY_C, 0, 0, 0 }, 0x0106}, + {{SCIM_KEY_dead_acute, SCIM_KEY_E, 0, 0, 0 }, 0x00C9}, + {{SCIM_KEY_dead_acute, SCIM_KEY_G, 0, 0, 0 }, 0x01F4}, + {{SCIM_KEY_dead_acute, SCIM_KEY_I, 0, 0, 0 }, 0x00CD}, + {{SCIM_KEY_dead_acute, SCIM_KEY_K, 0, 0, 0 }, 0x1E30}, + {{SCIM_KEY_dead_acute, SCIM_KEY_L, 0, 0, 0 }, 0x0139}, + {{SCIM_KEY_dead_acute, SCIM_KEY_M, 0, 0, 0 }, 0x1E3E}, + {{SCIM_KEY_dead_acute, SCIM_KEY_N, 0, 0, 0 }, 0x0143}, + {{SCIM_KEY_dead_acute, SCIM_KEY_O, 0, 0, 0 }, 0x00D3}, + {{SCIM_KEY_dead_acute, SCIM_KEY_P, 0, 0, 0 }, 0x1E54}, + {{SCIM_KEY_dead_acute, SCIM_KEY_R, 0, 0, 0 }, 0x0154}, + {{SCIM_KEY_dead_acute, SCIM_KEY_S, 0, 0, 0 }, 0x015A}, + {{SCIM_KEY_dead_acute, SCIM_KEY_U, 0, 0, 0 }, 0x00DA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_W, 0, 0, 0 }, 0x1E82}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Y, 0, 0, 0 }, 0x00DD}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Z, 0, 0, 0 }, 0x0179}, + {{SCIM_KEY_dead_acute, SCIM_KEY_a, 0, 0, 0 }, 0x00E1}, + {{SCIM_KEY_dead_acute, SCIM_KEY_c, 0, 0, 0 }, 0x0107}, + {{SCIM_KEY_dead_acute, SCIM_KEY_e, 0, 0, 0 }, 0x00E9}, + {{SCIM_KEY_dead_acute, SCIM_KEY_g, 0, 0, 0 }, 0x01F5}, + {{SCIM_KEY_dead_acute, SCIM_KEY_i, 0, 0, 0 }, 0x00ED}, + {{SCIM_KEY_dead_acute, SCIM_KEY_k, 0, 0, 0 }, 0x1E31}, + {{SCIM_KEY_dead_acute, SCIM_KEY_l, 0, 0, 0 }, 0x013A}, + {{SCIM_KEY_dead_acute, SCIM_KEY_m, 0, 0, 0 }, 0x1E3F}, + {{SCIM_KEY_dead_acute, SCIM_KEY_n, 0, 0, 0 }, 0x0144}, + {{SCIM_KEY_dead_acute, SCIM_KEY_o, 0, 0, 0 }, 0x00F3}, + {{SCIM_KEY_dead_acute, SCIM_KEY_p, 0, 0, 0 }, 0x1E55}, + {{SCIM_KEY_dead_acute, SCIM_KEY_r, 0, 0, 0 }, 0x0155}, + {{SCIM_KEY_dead_acute, SCIM_KEY_s, 0, 0, 0 }, 0x015B}, + {{SCIM_KEY_dead_acute, SCIM_KEY_u, 0, 0, 0 }, 0x00FA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_w, 0, 0, 0 }, 0x1E83}, + {{SCIM_KEY_dead_acute, SCIM_KEY_y, 0, 0, 0 }, 0x00FD}, + {{SCIM_KEY_dead_acute, SCIM_KEY_z, 0, 0, 0 }, 0x017A}, + {{SCIM_KEY_dead_acute, SCIM_KEY_acute, 0, 0, 0 }, 0x00B4}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EA4}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Aring, 0, 0, 0 }, 0x01FA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_AE, 0, 0, 0 }, 0x01FC}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Ccedilla, 0, 0, 0 }, 0x1E08}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EBE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Idiaeresis, 0, 0, 0 }, 0x1E2E}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED0}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Otilde, 0, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Ooblique, 0, 0, 0 }, 0x01FE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Udiaeresis, 0, 0, 0 }, 0x01D7}, + {{SCIM_KEY_dead_acute, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EA5}, + {{SCIM_KEY_dead_acute, SCIM_KEY_aring, 0, 0, 0 }, 0x01FB}, + {{SCIM_KEY_dead_acute, SCIM_KEY_ae, 0, 0, 0 }, 0x01FD}, + {{SCIM_KEY_dead_acute, SCIM_KEY_ccedilla, 0, 0, 0 }, 0x1E09}, + {{SCIM_KEY_dead_acute, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EBF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_idiaeresis, 0, 0, 0 }, 0x1E2F}, + {{SCIM_KEY_dead_acute, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED1}, + {{SCIM_KEY_dead_acute, SCIM_KEY_otilde, 0, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_oslash, 0, 0, 0 }, 0x01FF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_udiaeresis, 0, 0, 0 }, 0x01D8}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EAE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EAF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Emacron, 0, 0, 0 }, 0x1E16}, + {{SCIM_KEY_dead_acute, SCIM_KEY_emacron, 0, 0, 0 }, 0x1E17}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Omacron, 0, 0, 0 }, 0x1E52}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Utilde, 0, 0, 0 }, 0x1E78}, + {{SCIM_KEY_dead_acute, SCIM_KEY_omacron, 0, 0, 0 }, 0x1E53}, + {{SCIM_KEY_dead_acute, SCIM_KEY_utilde, 0, 0, 0 }, 0x1E79}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Cyrillic_ghe, 0, 0, 0 }, 0x0453}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Cyrillic_ka, 0, 0, 0 }, 0x045C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Cyrillic_GHE, 0, 0, 0 }, 0x0403}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Cyrillic_KA, 0, 0, 0 }, 0x040C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_iotadieresis, 0, 0, 0 }, 0x0390}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_upsilondieresis, 0, 0, 0 }, 0x03B0}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x0386}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_EPSILON, 0, 0, 0 }, 0x0388}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_ETA, 0, 0, 0 }, 0x0389}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x038A}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_OMICRON, 0, 0, 0 }, 0x038C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x038E}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_OMEGA, 0, 0, 0 }, 0x038F}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x03AC}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_epsilon, 0, 0, 0 }, 0x03AD}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x03AE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x03AF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_omicron, 0, 0, 0 }, 0x03CC}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x03CD}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x03CE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_combining_tilde, SCIM_KEY_U, 0, 0 }, 0x1E78}, + {{SCIM_KEY_dead_acute, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_combining_tilde, SCIM_KEY_u, 0, 0 }, 0x1E79}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EDA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EDB}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EE8}, + {{SCIM_KEY_dead_acute, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EE9}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_acute, 0, 0, 0 }, 0x00B4}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EA4}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EBE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED0}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EA5}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EBF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED1}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_tilde, SCIM_KEY_U, 0, 0 }, 0x1E78}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_tilde, SCIM_KEY_u, 0, 0 }, 0x1E79}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_macron, SCIM_KEY_E, 0, 0 }, 0x1E16}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_macron, SCIM_KEY_O, 0, 0 }, 0x1E52}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_macron, SCIM_KEY_e, 0, 0 }, 0x1E17}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_macron, SCIM_KEY_o, 0, 0 }, 0x1E53}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EAE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EAF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_space, 0, 0 }, 0x0385}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_I, 0, 0 }, 0x1E2E}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0, 0 }, 0x01D7}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_i, 0, 0 }, 0x1E2F}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0, 0 }, 0x01D8}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0, 0 }, 0x0390}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x03B0}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_abovering, SCIM_KEY_A, 0, 0 }, 0x01FA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_abovering, SCIM_KEY_a, 0, 0 }, 0x01FB}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_cedilla, SCIM_KEY_C, 0, 0 }, 0x1E08}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_cedilla, SCIM_KEY_c, 0, 0 }, 0x1E09}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EDA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EE8}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EDB}, + {{SCIM_KEY_dead_acute, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EE9}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_I, 0 }, 0x1E2E}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D7}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_i, 0 }, 0x1E2F}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01D8}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x0390}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x03B0}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F05}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0 }, 0x1F15}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F25}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F35}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0 }, 0x1F45}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F55}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F65}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F04}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0 }, 0x1F14}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F24}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F34}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0 }, 0x1F44}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F54}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F64}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EE8}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDB}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EE9}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_C, 0 }, 0x1E08}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_c, 0 }, 0x1E09}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA4}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EBE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED0}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA5}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EBF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED1}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_A, 0 }, 0x01FA}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_a, 0 }, 0x01FB}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_dead_acute, 0x10001a0, 0, 0, 0 }, 0x1EDA}, + {{SCIM_KEY_dead_acute, 0x10001a1, 0, 0, 0 }, 0x1EDB}, + {{SCIM_KEY_dead_acute, 0x10001af, 0, 0, 0 }, 0x1EE8}, + {{SCIM_KEY_dead_acute, 0x10001b0, 0, 0, 0 }, 0x1EE9}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0C}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1C}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2C}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3C}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4C}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6C}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F04}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F14}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F24}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F34}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F44}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F54}, + {{SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F64}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0D}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F1D}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2D}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3D}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F4D}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1F5D}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6D}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F05}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F15}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F25}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F35}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F45}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F55}, + {{SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F65}, + {{SCIM_KEY_dead_acute, 0x1001f00, 0, 0, 0 }, 0x1F04}, + {{SCIM_KEY_dead_acute, 0x1001f01, 0, 0, 0 }, 0x1F05}, + {{SCIM_KEY_dead_acute, 0x1001f08, 0, 0, 0 }, 0x1F0C}, + {{SCIM_KEY_dead_acute, 0x1001f09, 0, 0, 0 }, 0x1F0D}, + {{SCIM_KEY_dead_acute, 0x1001f10, 0, 0, 0 }, 0x1F14}, + {{SCIM_KEY_dead_acute, 0x1001f11, 0, 0, 0 }, 0x1F15}, + {{SCIM_KEY_dead_acute, 0x1001f18, 0, 0, 0 }, 0x1F1C}, + {{SCIM_KEY_dead_acute, 0x1001f19, 0, 0, 0 }, 0x1F1D}, + {{SCIM_KEY_dead_acute, 0x1001f20, 0, 0, 0 }, 0x1F24}, + {{SCIM_KEY_dead_acute, 0x1001f21, 0, 0, 0 }, 0x1F25}, + {{SCIM_KEY_dead_acute, 0x1001f28, 0, 0, 0 }, 0x1F2C}, + {{SCIM_KEY_dead_acute, 0x1001f29, 0, 0, 0 }, 0x1F2D}, + {{SCIM_KEY_dead_acute, 0x1001f30, 0, 0, 0 }, 0x1F34}, + {{SCIM_KEY_dead_acute, 0x1001f31, 0, 0, 0 }, 0x1F35}, + {{SCIM_KEY_dead_acute, 0x1001f38, 0, 0, 0 }, 0x1F3C}, + {{SCIM_KEY_dead_acute, 0x1001f39, 0, 0, 0 }, 0x1F3D}, + {{SCIM_KEY_dead_acute, 0x1001f40, 0, 0, 0 }, 0x1F44}, + {{SCIM_KEY_dead_acute, 0x1001f41, 0, 0, 0 }, 0x1F45}, + {{SCIM_KEY_dead_acute, 0x1001f48, 0, 0, 0 }, 0x1F4C}, + {{SCIM_KEY_dead_acute, 0x1001f49, 0, 0, 0 }, 0x1F4D}, + {{SCIM_KEY_dead_acute, 0x1001f50, 0, 0, 0 }, 0x1F54}, + {{SCIM_KEY_dead_acute, 0x1001f51, 0, 0, 0 }, 0x1F55}, + {{SCIM_KEY_dead_acute, 0x1001f59, 0, 0, 0 }, 0x1F5D}, + {{SCIM_KEY_dead_acute, 0x1001f60, 0, 0, 0 }, 0x1F64}, + {{SCIM_KEY_dead_acute, 0x1001f61, 0, 0, 0 }, 0x1F65}, + {{SCIM_KEY_dead_acute, 0x1001f68, 0, 0, 0 }, 0x1F6C}, + {{SCIM_KEY_dead_acute, 0x1001f69, 0, 0, 0 }, 0x1F6D}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_space, 0, 0, 0 }, 0x005E}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_parenleft, 0, 0, 0 }, 0x207D}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_parenright, 0, 0, 0 }, 0x207E}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_plus, 0, 0, 0 }, 0x207A}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_minus, 0, 0, 0 }, 0x00AF}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_period, 0, 0, 0 }, 0x00B7}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_slash, 0, 0, 0 }, 0x007C}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_0, 0, 0, 0 }, 0x2070}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_1, 0, 0, 0 }, 0x00B9}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_2, 0, 0, 0 }, 0x00B2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_3, 0, 0, 0 }, 0x00B3}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_4, 0, 0, 0 }, 0x2074}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_5, 0, 0, 0 }, 0x2075}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_6, 0, 0, 0 }, 0x2076}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_7, 0, 0, 0 }, 0x2077}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_8, 0, 0, 0 }, 0x2078}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_9, 0, 0, 0 }, 0x2079}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_equal, 0, 0, 0 }, 0x207C}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0, 0 }, 0x00C2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_C, 0, 0, 0 }, 0x0108}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0, 0 }, 0x00CA}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_G, 0, 0, 0 }, 0x011C}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_H, 0, 0, 0 }, 0x0124}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_I, 0, 0, 0 }, 0x00CE}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_J, 0, 0, 0 }, 0x0134}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0, 0 }, 0x00D4}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_S, 0, 0, 0 }, 0x015C}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_U, 0, 0, 0 }, 0x00DB}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_W, 0, 0, 0 }, 0x0174}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Y, 0, 0, 0 }, 0x0176}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Z, 0, 0, 0 }, 0x1E90}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_asciicircum, 0, 0, 0 }, 0x005E}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_underscore, 0, 0, 0 }, 0x00AF}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0, 0 }, 0x00E2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_c, 0, 0, 0 }, 0x0109}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0, 0 }, 0x00EA}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_g, 0, 0, 0 }, 0x011D}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_h, 0, 0, 0 }, 0x0125}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_i, 0, 0, 0 }, 0x00EE}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_j, 0, 0, 0 }, 0x0135}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0, 0 }, 0x00F4}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_s, 0, 0, 0 }, 0x015D}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_u, 0, 0, 0 }, 0x00FB}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_w, 0, 0, 0 }, 0x0175}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_y, 0, 0, 0 }, 0x0177}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_z, 0, 0, 0 }, 0x1E91}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_combining_belowdot, SCIM_KEY_A, 0, 0 }, 0x1EAC}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_combining_belowdot, SCIM_KEY_E, 0, 0 }, 0x1EC6}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_combining_belowdot, SCIM_KEY_O, 0, 0 }, 0x1ED8}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_combining_belowdot, SCIM_KEY_a, 0, 0 }, 0x1EAD}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_combining_belowdot, SCIM_KEY_e, 0, 0 }, 0x1EC7}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_combining_belowdot, SCIM_KEY_o, 0, 0 }, 0x1ED9}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_dead_circumflex, 0, 0, 0 }, 0x005E}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_dead_belowdot, SCIM_KEY_A, 0, 0 }, 0x1EAC}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_dead_belowdot, SCIM_KEY_E, 0, 0 }, 0x1EC6}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_dead_belowdot, SCIM_KEY_O, 0, 0 }, 0x1ED8}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_dead_belowdot, SCIM_KEY_a, 0, 0 }, 0x1EAD}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_dead_belowdot, SCIM_KEY_e, 0, 0 }, 0x1EC7}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_dead_belowdot, SCIM_KEY_o, 0, 0 }, 0x1ED9}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_A, 0 }, 0x1EAC}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_E, 0 }, 0x1EC6}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_O, 0 }, 0x1ED8}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_a, 0 }, 0x1EAD}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_e, 0 }, 0x1EC7}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_o, 0 }, 0x1ED9}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_M, 0 }, 0x2120}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_T, SCIM_KEY_M, 0 }, 0x2122}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_a, 0 }, 0x00AA}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_h, 0 }, 0x02B0}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_i, 0 }, 0x2071}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_j, 0 }, 0x02B2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_l, 0 }, 0x02E1}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_n, 0 }, 0x207F}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x00BA}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_r, 0 }, 0x02B3}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_s, 0 }, 0x02E2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_w, 0 }, 0x02B7}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_x, 0 }, 0x02E3}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_y, 0 }, 0x02B8}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1000263, 0 }, 0x02E0}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1000266, 0 }, 0x02B1}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1000279, 0 }, 0x02B4}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x100027b, 0 }, 0x02B5}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1000281, 0 }, 0x02B6}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1000295, 0 }, 0x02E4}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_a, 0 }, 0x00AA}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_h, 0 }, 0x02B0}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_i, 0 }, 0x2071}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_j, 0 }, 0x02B2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_l, 0 }, 0x02E1}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_n, 0 }, 0x207F}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_o, 0 }, 0x00BA}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_r, 0 }, 0x02B3}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_s, 0 }, 0x02E2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_w, 0 }, 0x02B7}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_x, 0 }, 0x02E3}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_y, 0 }, 0x02B8}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, 0x1000263, 0 }, 0x02E0}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, 0x1000266, 0 }, 0x02B1}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, 0x1000279, 0 }, 0x02B4}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, 0x100027b, 0 }, 0x02B5}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, 0x1000281, 0 }, 0x02B6}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_Multi_key, SCIM_KEY_underbar, 0x1000295, 0 }, 0x02E4}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_Space, 0, 0, 0 }, 0x00B2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_Add, 0, 0, 0 }, 0x207A}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_0, 0, 0, 0 }, 0x2070}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_1, 0, 0, 0 }, 0x00B9}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_2, 0, 0, 0 }, 0x00B2}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_3, 0, 0, 0 }, 0x00B3}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_4, 0, 0, 0 }, 0x2074}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_5, 0, 0, 0 }, 0x2075}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_6, 0, 0, 0 }, 0x2076}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_7, 0, 0, 0 }, 0x2077}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_8, 0, 0, 0 }, 0x2078}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_9, 0, 0, 0 }, 0x2079}, + {{SCIM_KEY_dead_circumflex, SCIM_KEY_KP_Equal, 0, 0, 0 }, 0x207C}, + {{SCIM_KEY_dead_circumflex, 0x1001ea0, 0, 0, 0 }, 0x1EAC}, + {{SCIM_KEY_dead_circumflex, 0x1001ea1, 0, 0, 0 }, 0x1EAD}, + {{SCIM_KEY_dead_circumflex, 0x1001eb8, 0, 0, 0 }, 0x1EC6}, + {{SCIM_KEY_dead_circumflex, 0x1001eb9, 0, 0, 0 }, 0x1EC7}, + {{SCIM_KEY_dead_circumflex, 0x1001ecc, 0, 0, 0 }, 0x1ED8}, + {{SCIM_KEY_dead_circumflex, 0x1001ecd, 0, 0, 0 }, 0x1ED9}, + {{SCIM_KEY_dead_circumflex, 0x1002212, 0, 0, 0 }, 0x207B}, + {{SCIM_KEY_dead_circumflex, 0x1004e00, 0, 0, 0 }, 0x3192}, + {{SCIM_KEY_dead_circumflex, 0x1004e01, 0, 0, 0 }, 0x319C}, + {{SCIM_KEY_dead_circumflex, 0x1004e09, 0, 0, 0 }, 0x3194}, + {{SCIM_KEY_dead_circumflex, 0x1004e0a, 0, 0, 0 }, 0x3196}, + {{SCIM_KEY_dead_circumflex, 0x1004e0b, 0, 0, 0 }, 0x3198}, + {{SCIM_KEY_dead_circumflex, 0x1004e19, 0, 0, 0 }, 0x319B}, + {{SCIM_KEY_dead_circumflex, 0x1004e2d, 0, 0, 0 }, 0x3197}, + {{SCIM_KEY_dead_circumflex, 0x1004e59, 0, 0, 0 }, 0x319A}, + {{SCIM_KEY_dead_circumflex, 0x1004e8c, 0, 0, 0 }, 0x3193}, + {{SCIM_KEY_dead_circumflex, 0x1004eba, 0, 0, 0 }, 0x319F}, + {{SCIM_KEY_dead_circumflex, 0x10056db, 0, 0, 0 }, 0x3195}, + {{SCIM_KEY_dead_circumflex, 0x1005730, 0, 0, 0 }, 0x319E}, + {{SCIM_KEY_dead_circumflex, 0x1005929, 0, 0, 0 }, 0x319D}, + {{SCIM_KEY_dead_circumflex, 0x1007532, 0, 0, 0 }, 0x3199}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_space, 0, 0, 0 }, 0x007E}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_A, 0, 0, 0 }, 0x00C3}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_E, 0, 0, 0 }, 0x1EBC}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_I, 0, 0, 0 }, 0x0128}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_N, 0, 0, 0 }, 0x00D1}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_O, 0, 0, 0 }, 0x00D5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_U, 0, 0, 0 }, 0x0168}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_V, 0, 0, 0 }, 0x1E7C}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF8}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_a, 0, 0, 0 }, 0x00E3}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_e, 0, 0, 0 }, 0x1EBD}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_i, 0, 0, 0 }, 0x0129}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_n, 0, 0, 0 }, 0x00F1}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_o, 0, 0, 0 }, 0x00F5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_u, 0, 0, 0 }, 0x0169}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_v, 0, 0, 0 }, 0x1E7D}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_y, 0, 0, 0 }, 0x1EF9}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_asciitilde, 0, 0, 0 }, 0x007E}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EAA}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EC4}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EAB}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EC5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EB4}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EB5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Greek_iotadieresis, 0, 0, 0 }, 0x1FD7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Greek_upsilondieresis, 0, 0, 0 }, 0x1FE7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1FB6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x1FC6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1FD6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1FE6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x1FF6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EE0}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EE1}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EEE}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EEF}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EAA}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EC4}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EAB}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EC5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_tilde, 0, 0, 0 }, 0x007E}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EB4}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EB5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EE0}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EEE}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EE1}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EEF}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x1FD7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0F}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2F}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3F}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5F}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6F}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F07}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F27}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F37}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F57}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F67}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0E}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2E}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3E}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6E}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F06}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F26}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F36}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F56}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F66}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EE0}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEE}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EE1}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EEF}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB4}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EAA}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC4}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED6}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EAB}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC5}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED7}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB4}, + {{SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB5}, + {{SCIM_KEY_dead_tilde, 0x10001a0, 0, 0, 0 }, 0x1EE0}, + {{SCIM_KEY_dead_tilde, 0x10001a1, 0, 0, 0 }, 0x1EE1}, + {{SCIM_KEY_dead_tilde, 0x10001af, 0, 0, 0 }, 0x1EEE}, + {{SCIM_KEY_dead_tilde, 0x10001b0, 0, 0, 0 }, 0x1EEF}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0E}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2E}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3E}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6E}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F06}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F26}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F36}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F56}, + {{SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F66}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0F}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2F}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3F}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1F5F}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6F}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F07}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F27}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F37}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F57}, + {{SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F67}, + {{SCIM_KEY_dead_tilde, 0x1001f00, 0, 0, 0 }, 0x1F06}, + {{SCIM_KEY_dead_tilde, 0x1001f01, 0, 0, 0 }, 0x1F07}, + {{SCIM_KEY_dead_tilde, 0x1001f08, 0, 0, 0 }, 0x1F0E}, + {{SCIM_KEY_dead_tilde, 0x1001f09, 0, 0, 0 }, 0x1F0F}, + {{SCIM_KEY_dead_tilde, 0x1001f20, 0, 0, 0 }, 0x1F26}, + {{SCIM_KEY_dead_tilde, 0x1001f21, 0, 0, 0 }, 0x1F27}, + {{SCIM_KEY_dead_tilde, 0x1001f28, 0, 0, 0 }, 0x1F2E}, + {{SCIM_KEY_dead_tilde, 0x1001f29, 0, 0, 0 }, 0x1F2F}, + {{SCIM_KEY_dead_tilde, 0x1001f30, 0, 0, 0 }, 0x1F36}, + {{SCIM_KEY_dead_tilde, 0x1001f31, 0, 0, 0 }, 0x1F37}, + {{SCIM_KEY_dead_tilde, 0x1001f38, 0, 0, 0 }, 0x1F3E}, + {{SCIM_KEY_dead_tilde, 0x1001f39, 0, 0, 0 }, 0x1F3F}, + {{SCIM_KEY_dead_tilde, 0x1001f50, 0, 0, 0 }, 0x1F56}, + {{SCIM_KEY_dead_tilde, 0x1001f51, 0, 0, 0 }, 0x1F57}, + {{SCIM_KEY_dead_tilde, 0x1001f59, 0, 0, 0 }, 0x1F5F}, + {{SCIM_KEY_dead_tilde, 0x1001f60, 0, 0, 0 }, 0x1F66}, + {{SCIM_KEY_dead_tilde, 0x1001f61, 0, 0, 0 }, 0x1F67}, + {{SCIM_KEY_dead_tilde, 0x1001f68, 0, 0, 0 }, 0x1F6E}, + {{SCIM_KEY_dead_tilde, 0x1001f69, 0, 0, 0 }, 0x1F6F}, + {{SCIM_KEY_dead_macron, SCIM_KEY_space, 0, 0, 0 }, 0x00AF}, + {{SCIM_KEY_dead_macron, SCIM_KEY_A, 0, 0, 0 }, 0x0100}, + {{SCIM_KEY_dead_macron, SCIM_KEY_E, 0, 0, 0 }, 0x0112}, + {{SCIM_KEY_dead_macron, SCIM_KEY_G, 0, 0, 0 }, 0x1E20}, + {{SCIM_KEY_dead_macron, SCIM_KEY_I, 0, 0, 0 }, 0x012A}, + {{SCIM_KEY_dead_macron, SCIM_KEY_O, 0, 0, 0 }, 0x014C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_U, 0, 0, 0 }, 0x016A}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Y, 0, 0, 0 }, 0x0232}, + {{SCIM_KEY_dead_macron, SCIM_KEY_a, 0, 0, 0 }, 0x0101}, + {{SCIM_KEY_dead_macron, SCIM_KEY_e, 0, 0, 0 }, 0x0113}, + {{SCIM_KEY_dead_macron, SCIM_KEY_g, 0, 0, 0 }, 0x1E21}, + {{SCIM_KEY_dead_macron, SCIM_KEY_i, 0, 0, 0 }, 0x012B}, + {{SCIM_KEY_dead_macron, SCIM_KEY_o, 0, 0, 0 }, 0x014D}, + {{SCIM_KEY_dead_macron, SCIM_KEY_u, 0, 0, 0 }, 0x016B}, + {{SCIM_KEY_dead_macron, SCIM_KEY_y, 0, 0, 0 }, 0x0233}, + {{SCIM_KEY_dead_macron, SCIM_KEY_macron, 0, 0, 0 }, 0x00AF}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Adiaeresis, 0, 0, 0 }, 0x01DE}, + {{SCIM_KEY_dead_macron, SCIM_KEY_AE, 0, 0, 0 }, 0x01E2}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Otilde, 0, 0, 0 }, 0x022C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Odiaeresis, 0, 0, 0 }, 0x022A}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Udiaeresis, 0, 0, 0 }, 0x01D5}, + {{SCIM_KEY_dead_macron, SCIM_KEY_adiaeresis, 0, 0, 0 }, 0x01DF}, + {{SCIM_KEY_dead_macron, SCIM_KEY_ae, 0, 0, 0 }, 0x01E3}, + {{SCIM_KEY_dead_macron, SCIM_KEY_otilde, 0, 0, 0 }, 0x022D}, + {{SCIM_KEY_dead_macron, SCIM_KEY_odiaeresis, 0, 0, 0 }, 0x022B}, + {{SCIM_KEY_dead_macron, SCIM_KEY_udiaeresis, 0, 0, 0 }, 0x01D6}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Cyrillic_i, 0, 0, 0 }, 0x04E3}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Cyrillic_u, 0, 0, 0 }, 0x04EF}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Cyrillic_I, 0, 0, 0 }, 0x04E2}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Cyrillic_U, 0, 0, 0 }, 0x04EE}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x1FB9}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x1FD9}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x1FE9}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1FB1}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1FD1}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1FE1}, + {{SCIM_KEY_dead_macron, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0, 0 }, 0x022C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0, 0 }, 0x022D}, + {{SCIM_KEY_dead_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_L, 0, 0 }, 0x1E38}, + {{SCIM_KEY_dead_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_R, 0, 0 }, 0x1E5C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_l, 0, 0 }, 0x1E39}, + {{SCIM_KEY_dead_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_r, 0, 0 }, 0x1E5D}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0, 0 }, 0x022C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0, 0 }, 0x022D}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_macron, 0, 0, 0 }, 0x00AF}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_A, 0, 0 }, 0x01E0}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_O, 0, 0 }, 0x0230}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_a, 0, 0 }, 0x01E1}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_o, 0, 0 }, 0x0231}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_A, 0, 0 }, 0x01DE}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_O, 0, 0 }, 0x022A}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0, 0 }, 0x01D5}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_a, 0, 0 }, 0x01DF}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_o, 0, 0 }, 0x022B}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0, 0 }, 0x01D6}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_ogonek, SCIM_KEY_O, 0, 0 }, 0x01EC}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_ogonek, SCIM_KEY_o, 0, 0 }, 0x01ED}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_L, 0, 0 }, 0x1E38}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_R, 0, 0 }, 0x1E5C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_l, 0, 0 }, 0x1E39}, + {{SCIM_KEY_dead_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_r, 0, 0 }, 0x1E5D}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_L, 0 }, 0x1E38}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_R, 0 }, 0x1E5C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_l, 0 }, 0x1E39}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_r, 0 }, 0x1E5D}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_A, 0 }, 0x01DE}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_O, 0 }, 0x022A}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D5}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_a, 0 }, 0x01DF}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_o, 0 }, 0x022B}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01D6}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_A, 0 }, 0x01E0}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_O, 0 }, 0x0230}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_a, 0 }, 0x01E1}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_o, 0 }, 0x0231}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_O, 0 }, 0x01EC}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_o, 0 }, 0x01ED}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x022C}, + {{SCIM_KEY_dead_macron, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x022D}, + {{SCIM_KEY_dead_macron, 0x10001ea, 0, 0, 0 }, 0x01EC}, + {{SCIM_KEY_dead_macron, 0x10001eb, 0, 0, 0 }, 0x01ED}, + {{SCIM_KEY_dead_macron, 0x1000226, 0, 0, 0 }, 0x01E0}, + {{SCIM_KEY_dead_macron, 0x1000227, 0, 0, 0 }, 0x01E1}, + {{SCIM_KEY_dead_macron, 0x100022e, 0, 0, 0 }, 0x0230}, + {{SCIM_KEY_dead_macron, 0x100022f, 0, 0, 0 }, 0x0231}, + {{SCIM_KEY_dead_macron, 0x1001e36, 0, 0, 0 }, 0x1E38}, + {{SCIM_KEY_dead_macron, 0x1001e37, 0, 0, 0 }, 0x1E39}, + {{SCIM_KEY_dead_macron, 0x1001e5a, 0, 0, 0 }, 0x1E5C}, + {{SCIM_KEY_dead_macron, 0x1001e5b, 0, 0, 0 }, 0x1E5D}, + {{SCIM_KEY_dead_breve, SCIM_KEY_space, 0, 0, 0 }, 0x02D8}, + {{SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0, 0 }, 0x0102}, + {{SCIM_KEY_dead_breve, SCIM_KEY_E, 0, 0, 0 }, 0x0114}, + {{SCIM_KEY_dead_breve, SCIM_KEY_G, 0, 0, 0 }, 0x011E}, + {{SCIM_KEY_dead_breve, SCIM_KEY_I, 0, 0, 0 }, 0x012C}, + {{SCIM_KEY_dead_breve, SCIM_KEY_O, 0, 0, 0 }, 0x014E}, + {{SCIM_KEY_dead_breve, SCIM_KEY_U, 0, 0, 0 }, 0x016C}, + {{SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0, 0 }, 0x0103}, + {{SCIM_KEY_dead_breve, SCIM_KEY_e, 0, 0, 0 }, 0x0115}, + {{SCIM_KEY_dead_breve, SCIM_KEY_g, 0, 0, 0 }, 0x011F}, + {{SCIM_KEY_dead_breve, SCIM_KEY_i, 0, 0, 0 }, 0x012D}, + {{SCIM_KEY_dead_breve, SCIM_KEY_o, 0, 0, 0 }, 0x014F}, + {{SCIM_KEY_dead_breve, SCIM_KEY_u, 0, 0, 0 }, 0x016D}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_a, 0, 0, 0 }, 0x04D1}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_ie, 0, 0, 0 }, 0x04D7}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_i, 0, 0, 0 }, 0x0439}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_u, 0, 0, 0 }, 0x045E}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_zhe, 0, 0, 0 }, 0x04C2}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_A, 0, 0, 0 }, 0x04D0}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_IE, 0, 0, 0 }, 0x04D6}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_I, 0, 0, 0 }, 0x0419}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_U, 0, 0, 0 }, 0x040E}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Cyrillic_ZHE, 0, 0, 0 }, 0x04C1}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x1FB8}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x1FD8}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x1FE8}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1FB0}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1FD0}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1FE0}, + {{SCIM_KEY_dead_breve, SCIM_KEY_combining_belowdot, SCIM_KEY_A, 0, 0 }, 0x1EB6}, + {{SCIM_KEY_dead_breve, SCIM_KEY_combining_belowdot, SCIM_KEY_a, 0, 0 }, 0x1EB7}, + {{SCIM_KEY_dead_breve, SCIM_KEY_dead_breve, 0, 0, 0 }, 0x02D8}, + {{SCIM_KEY_dead_breve, SCIM_KEY_dead_cedilla, SCIM_KEY_E, 0, 0 }, 0x1E1C}, + {{SCIM_KEY_dead_breve, SCIM_KEY_dead_cedilla, SCIM_KEY_e, 0, 0 }, 0x1E1D}, + {{SCIM_KEY_dead_breve, SCIM_KEY_dead_belowdot, SCIM_KEY_A, 0, 0 }, 0x1EB6}, + {{SCIM_KEY_dead_breve, SCIM_KEY_dead_belowdot, SCIM_KEY_a, 0, 0 }, 0x1EB7}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_A, 0 }, 0x1EB6}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_a, 0 }, 0x1EB7}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_E, 0 }, 0x1E1C}, + {{SCIM_KEY_dead_breve, SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_e, 0 }, 0x1E1D}, + {{SCIM_KEY_dead_breve, 0x1000228, 0, 0, 0 }, 0x1E1C}, + {{SCIM_KEY_dead_breve, 0x1000229, 0, 0, 0 }, 0x1E1D}, + {{SCIM_KEY_dead_breve, 0x1001ea0, 0, 0, 0 }, 0x1EB6}, + {{SCIM_KEY_dead_breve, 0x1001ea1, 0, 0, 0 }, 0x1EB7}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_space, 0, 0, 0 }, 0x02D9}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_A, 0, 0, 0 }, 0x0226}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_B, 0, 0, 0 }, 0x1E02}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_C, 0, 0, 0 }, 0x010A}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_D, 0, 0, 0 }, 0x1E0A}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_E, 0, 0, 0 }, 0x0116}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_F, 0, 0, 0 }, 0x1E1E}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_G, 0, 0, 0 }, 0x0120}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_H, 0, 0, 0 }, 0x1E22}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_I, 0, 0, 0 }, 0x0130}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_M, 0, 0, 0 }, 0x1E40}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_N, 0, 0, 0 }, 0x1E44}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_O, 0, 0, 0 }, 0x022E}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_P, 0, 0, 0 }, 0x1E56}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_R, 0, 0, 0 }, 0x1E58}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_S, 0, 0, 0 }, 0x1E60}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_T, 0, 0, 0 }, 0x1E6A}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_W, 0, 0, 0 }, 0x1E86}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_X, 0, 0, 0 }, 0x1E8A}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Y, 0, 0, 0 }, 0x1E8E}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Z, 0, 0, 0 }, 0x017B}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_a, 0, 0, 0 }, 0x0227}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_b, 0, 0, 0 }, 0x1E03}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_c, 0, 0, 0 }, 0x010B}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_d, 0, 0, 0 }, 0x1E0B}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_e, 0, 0, 0 }, 0x0117}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_f, 0, 0, 0 }, 0x1E1F}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_g, 0, 0, 0 }, 0x0121}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_h, 0, 0, 0 }, 0x1E23}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_i, 0, 0, 0 }, 0x0131}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_m, 0, 0, 0 }, 0x1E41}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_n, 0, 0, 0 }, 0x1E45}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_o, 0, 0, 0 }, 0x022F}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_p, 0, 0, 0 }, 0x1E57}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_r, 0, 0, 0 }, 0x1E59}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_s, 0, 0, 0 }, 0x1E61}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_t, 0, 0, 0 }, 0x1E6B}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_w, 0, 0, 0 }, 0x1E87}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_x, 0, 0, 0 }, 0x1E8B}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_y, 0, 0, 0 }, 0x1E8F}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_z, 0, 0, 0 }, 0x017C}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Sacute, 0, 0, 0 }, 0x1E64}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Scaron, 0, 0, 0 }, 0x1E66}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_sacute, 0, 0, 0 }, 0x1E65}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_scaron, 0, 0, 0 }, 0x1E67}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_abovedot, 0, 0, 0 }, 0x02D9}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_combining_acute, SCIM_KEY_S, 0, 0 }, 0x1E64}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_combining_acute, SCIM_KEY_s, 0, 0 }, 0x1E65}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_combining_belowdot, SCIM_KEY_S, 0, 0 }, 0x1E68}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_combining_belowdot, SCIM_KEY_s, 0, 0 }, 0x1E69}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_dead_acute, SCIM_KEY_S, 0, 0 }, 0x1E64}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_dead_acute, SCIM_KEY_s, 0, 0 }, 0x1E65}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_dead_abovedot, 0, 0, 0 }, 0x02D9}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_dead_caron, SCIM_KEY_S, 0, 0 }, 0x1E66}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_dead_caron, SCIM_KEY_s, 0, 0 }, 0x1E67}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_dead_belowdot, SCIM_KEY_S, 0, 0 }, 0x1E68}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_dead_belowdot, SCIM_KEY_s, 0, 0 }, 0x1E69}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_S, 0 }, 0x1E68}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_s, 0 }, 0x1E69}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_S, 0 }, 0x1E64}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_s, 0 }, 0x1E65}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_S, 0 }, 0x1E66}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_s, 0 }, 0x1E67}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_S, 0 }, 0x1E64}, + {{SCIM_KEY_dead_abovedot, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_s, 0 }, 0x1E65}, + {{SCIM_KEY_dead_abovedot, 0x100017f, 0, 0, 0 }, 0x1E9B}, + {{SCIM_KEY_dead_abovedot, 0x1001e62, 0, 0, 0 }, 0x1E68}, + {{SCIM_KEY_dead_abovedot, 0x1001e63, 0, 0, 0 }, 0x1E69}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_space, 0, 0, 0 }, 0x0022}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_quotedbl, 0, 0, 0 }, 0x00A8}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_apostrophe, 0, 0, 0 }, 0x0344}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_A, 0, 0, 0 }, 0x00C4}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_E, 0, 0, 0 }, 0x00CB}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_H, 0, 0, 0 }, 0x1E26}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_I, 0, 0, 0 }, 0x00CF}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_O, 0, 0, 0 }, 0x00D6}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0, 0, 0 }, 0x00DC}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_W, 0, 0, 0 }, 0x1E84}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_X, 0, 0, 0 }, 0x1E8C}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Y, 0, 0, 0 }, 0x0178}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_a, 0, 0, 0 }, 0x00E4}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_e, 0, 0, 0 }, 0x00EB}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_h, 0, 0, 0 }, 0x1E27}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_i, 0, 0, 0 }, 0x00EF}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_o, 0, 0, 0 }, 0x00F6}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_t, 0, 0, 0 }, 0x1E97}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0, 0, 0 }, 0x00FC}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_w, 0, 0, 0 }, 0x1E85}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_x, 0, 0, 0 }, 0x1E8D}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_y, 0, 0, 0 }, 0x00FF}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_diaeresis, 0, 0, 0 }, 0x00A8}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_acute, 0, 0, 0 }, 0x0344}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Otilde, 0, 0, 0 }, 0x1E4E}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_otilde, 0, 0, 0 }, 0x1E4F}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Umacron, 0, 0, 0 }, 0x1E7A}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_umacron, 0, 0, 0 }, 0x1E7B}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Ukrainian_i, 0, 0, 0 }, 0x0457}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Ukrainian_I, 0, 0, 0 }, 0x0407}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_a, 0, 0, 0 }, 0x04D3}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_ie, 0, 0, 0 }, 0x0451}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_i, 0, 0, 0 }, 0x04E5}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_o, 0, 0, 0 }, 0x04E7}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_u, 0, 0, 0 }, 0x04F1}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_zhe, 0, 0, 0 }, 0x04DD}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_yeru, 0, 0, 0 }, 0x04F9}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_ze, 0, 0, 0 }, 0x04DF}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_e, 0, 0, 0 }, 0x04ED}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_che, 0, 0, 0 }, 0x04F5}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_A, 0, 0, 0 }, 0x04D2}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_IE, 0, 0, 0 }, 0x0401}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_I, 0, 0, 0 }, 0x04E4}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_O, 0, 0, 0 }, 0x04E6}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_U, 0, 0, 0 }, 0x04F0}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_ZHE, 0, 0, 0 }, 0x04DC}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_YERU, 0, 0, 0 }, 0x04F8}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_ZE, 0, 0, 0 }, 0x04DE}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_E, 0, 0, 0 }, 0x04EC}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Cyrillic_CHE, 0, 0, 0 }, 0x04F4}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x03AA}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x03AB}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x03CA}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x03CB}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0, 0 }, 0x1E4E}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0, 0 }, 0x1E4F}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_acute, SCIM_KEY_space, 0, 0 }, 0x0385}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_acute, SCIM_KEY_Greek_iota, 0, 0 }, 0x0390}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_acute, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x03B0}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0, 0 }, 0x1E4E}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0, 0 }, 0x1E4F}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_macron, SCIM_KEY_U, 0, 0 }, 0x1E7A}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_macron, SCIM_KEY_u, 0, 0 }, 0x1E7B}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_dead_diaeresis, 0, 0, 0 }, 0x00A8}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_U, 0 }, 0x1E7A}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_u, 0 }, 0x1E7B}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x1E4E}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x1E4F}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_U, 0 }, 0x1E7A}, + {{SCIM_KEY_dead_diaeresis, SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_u, 0 }, 0x1E7B}, + {{SCIM_KEY_dead_diaeresis, 0x10004d8, 0, 0, 0 }, 0x04DA}, + {{SCIM_KEY_dead_diaeresis, 0x10004d9, 0, 0, 0 }, 0x04DB}, + {{SCIM_KEY_dead_diaeresis, 0x10004e8, 0, 0, 0 }, 0x04EA}, + {{SCIM_KEY_dead_diaeresis, 0x10004e9, 0, 0, 0 }, 0x04EB}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_space, 0, 0, 0 }, 0x02DA}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_A, 0, 0, 0 }, 0x00C5}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_U, 0, 0, 0 }, 0x016E}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_a, 0, 0, 0 }, 0x00E5}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_u, 0, 0, 0 }, 0x016F}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_w, 0, 0, 0 }, 0x1E98}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_y, 0, 0, 0 }, 0x1E99}, + {{SCIM_KEY_dead_abovering, SCIM_KEY_dead_abovering, 0, 0, 0 }, 0x00B0}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_space, 0, 0, 0 }, 0x02DD}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_O, 0, 0, 0 }, 0x0150}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_U, 0, 0, 0 }, 0x0170}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_o, 0, 0, 0 }, 0x0151}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_u, 0, 0, 0 }, 0x0171}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_Cyrillic_u, 0, 0, 0 }, 0x04F3}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_Cyrillic_U, 0, 0, 0 }, 0x04F2}, + {{SCIM_KEY_dead_doubleacute, SCIM_KEY_dead_doubleacute, 0, 0, 0 }, 0x02DD}, + {{SCIM_KEY_dead_caron, SCIM_KEY_space, 0, 0, 0 }, 0x02C7}, + {{SCIM_KEY_dead_caron, SCIM_KEY_A, 0, 0, 0 }, 0x01CD}, + {{SCIM_KEY_dead_caron, SCIM_KEY_C, 0, 0, 0 }, 0x010C}, + {{SCIM_KEY_dead_caron, SCIM_KEY_D, 0, 0, 0 }, 0x010E}, + {{SCIM_KEY_dead_caron, SCIM_KEY_E, 0, 0, 0 }, 0x011A}, + {{SCIM_KEY_dead_caron, SCIM_KEY_G, 0, 0, 0 }, 0x01E6}, + {{SCIM_KEY_dead_caron, SCIM_KEY_H, 0, 0, 0 }, 0x021E}, + {{SCIM_KEY_dead_caron, SCIM_KEY_I, 0, 0, 0 }, 0x01CF}, + {{SCIM_KEY_dead_caron, SCIM_KEY_K, 0, 0, 0 }, 0x01E8}, + {{SCIM_KEY_dead_caron, SCIM_KEY_L, 0, 0, 0 }, 0x013D}, + {{SCIM_KEY_dead_caron, SCIM_KEY_N, 0, 0, 0 }, 0x0147}, + {{SCIM_KEY_dead_caron, SCIM_KEY_O, 0, 0, 0 }, 0x01D1}, + {{SCIM_KEY_dead_caron, SCIM_KEY_R, 0, 0, 0 }, 0x0158}, + {{SCIM_KEY_dead_caron, SCIM_KEY_S, 0, 0, 0 }, 0x0160}, + {{SCIM_KEY_dead_caron, SCIM_KEY_T, 0, 0, 0 }, 0x0164}, + {{SCIM_KEY_dead_caron, SCIM_KEY_U, 0, 0, 0 }, 0x01D3}, + {{SCIM_KEY_dead_caron, SCIM_KEY_Z, 0, 0, 0 }, 0x017D}, + {{SCIM_KEY_dead_caron, SCIM_KEY_a, 0, 0, 0 }, 0x01CE}, + {{SCIM_KEY_dead_caron, SCIM_KEY_c, 0, 0, 0 }, 0x010D}, + {{SCIM_KEY_dead_caron, SCIM_KEY_d, 0, 0, 0 }, 0x010F}, + {{SCIM_KEY_dead_caron, SCIM_KEY_e, 0, 0, 0 }, 0x011B}, + {{SCIM_KEY_dead_caron, SCIM_KEY_g, 0, 0, 0 }, 0x01E7}, + {{SCIM_KEY_dead_caron, SCIM_KEY_h, 0, 0, 0 }, 0x021F}, + {{SCIM_KEY_dead_caron, SCIM_KEY_i, 0, 0, 0 }, 0x01D0}, + {{SCIM_KEY_dead_caron, SCIM_KEY_j, 0, 0, 0 }, 0x01F0}, + {{SCIM_KEY_dead_caron, SCIM_KEY_k, 0, 0, 0 }, 0x01E9}, + {{SCIM_KEY_dead_caron, SCIM_KEY_l, 0, 0, 0 }, 0x013E}, + {{SCIM_KEY_dead_caron, SCIM_KEY_n, 0, 0, 0 }, 0x0148}, + {{SCIM_KEY_dead_caron, SCIM_KEY_o, 0, 0, 0 }, 0x01D2}, + {{SCIM_KEY_dead_caron, SCIM_KEY_r, 0, 0, 0 }, 0x0159}, + {{SCIM_KEY_dead_caron, SCIM_KEY_s, 0, 0, 0 }, 0x0161}, + {{SCIM_KEY_dead_caron, SCIM_KEY_t, 0, 0, 0 }, 0x0165}, + {{SCIM_KEY_dead_caron, SCIM_KEY_u, 0, 0, 0 }, 0x01D4}, + {{SCIM_KEY_dead_caron, SCIM_KEY_z, 0, 0, 0 }, 0x017E}, + {{SCIM_KEY_dead_caron, SCIM_KEY_Udiaeresis, 0, 0, 0 }, 0x01D9}, + {{SCIM_KEY_dead_caron, SCIM_KEY_udiaeresis, 0, 0, 0 }, 0x01DA}, + {{SCIM_KEY_dead_caron, SCIM_KEY_caron, 0, 0, 0 }, 0x02C7}, + {{SCIM_KEY_dead_caron, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0, 0 }, 0x01D9}, + {{SCIM_KEY_dead_caron, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0, 0 }, 0x01DA}, + {{SCIM_KEY_dead_caron, SCIM_KEY_dead_caron, 0, 0, 0 }, 0x02C7}, + {{SCIM_KEY_dead_caron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D9}, + {{SCIM_KEY_dead_caron, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01DA}, + {{SCIM_KEY_dead_caron, 0x10001b7, 0, 0, 0 }, 0x01EE}, + {{SCIM_KEY_dead_caron, 0x1000292, 0, 0, 0 }, 0x01EF}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_space, 0, 0, 0 }, 0x00B8}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_comma, 0, 0, 0 }, 0x00B8}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_minus, 0, 0, 0 }, 0x00AC}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_C, 0, 0, 0 }, 0x00C7}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_D, 0, 0, 0 }, 0x1E10}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_E, 0, 0, 0 }, 0x0228}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_G, 0, 0, 0 }, 0x0122}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_H, 0, 0, 0 }, 0x1E28}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_K, 0, 0, 0 }, 0x0136}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_L, 0, 0, 0 }, 0x013B}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_N, 0, 0, 0 }, 0x0145}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_R, 0, 0, 0 }, 0x0156}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_S, 0, 0, 0 }, 0x015E}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_T, 0, 0, 0 }, 0x0162}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_c, 0, 0, 0 }, 0x00E7}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_d, 0, 0, 0 }, 0x1E11}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_e, 0, 0, 0 }, 0x0229}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_g, 0, 0, 0 }, 0x0123}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_h, 0, 0, 0 }, 0x1E29}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_k, 0, 0, 0 }, 0x0137}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_l, 0, 0, 0 }, 0x013C}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_n, 0, 0, 0 }, 0x0146}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_r, 0, 0, 0 }, 0x0157}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_s, 0, 0, 0 }, 0x015F}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_t, 0, 0, 0 }, 0x0163}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_cedilla, 0, 0, 0 }, 0x00B8}, + {{SCIM_KEY_dead_cedilla, SCIM_KEY_dead_cedilla, 0, 0, 0 }, 0x00B8}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_space, 0, 0, 0 }, 0x02DB}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_A, 0, 0, 0 }, 0x0104}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_E, 0, 0, 0 }, 0x0118}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_I, 0, 0, 0 }, 0x012E}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_O, 0, 0, 0 }, 0x01EA}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_U, 0, 0, 0 }, 0x0172}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_a, 0, 0, 0 }, 0x0105}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_e, 0, 0, 0 }, 0x0119}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_i, 0, 0, 0 }, 0x012F}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_o, 0, 0, 0 }, 0x01EB}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_u, 0, 0, 0 }, 0x0173}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_ogonek, 0, 0, 0 }, 0x02DB}, + {{SCIM_KEY_dead_ogonek, SCIM_KEY_dead_ogonek, 0, 0, 0 }, 0x02DB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_alphaaccent, 0, 0, 0 }, 0x1FB4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_etaaccent, 0, 0, 0 }, 0x1FC4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_omegaaccent, 0, 0, 0 }, 0x1FF4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x1FBC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_ETA, 0, 0, 0 }, 0x1FCC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_OMEGA, 0, 0, 0 }, 0x1FFC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1FB3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x1FC3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x1FF3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f00, 0, 0 }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f01, 0, 0 }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f08, 0, 0 }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f09, 0, 0 }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f20, 0, 0 }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f21, 0, 0 }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f28, 0, 0 }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f29, 0, 0 }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f60, 0, 0 }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f61, 0, 0 }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f68, 0, 0 }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_grave, 0x1001f69, 0, 0 }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f00, 0, 0 }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f01, 0, 0 }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f08, 0, 0 }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f09, 0, 0 }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f20, 0, 0 }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f21, 0, 0 }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f28, 0, 0 }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f29, 0, 0 }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f60, 0, 0 }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f61, 0, 0 }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f68, 0, 0 }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_combining_acute, 0x1001f69, 0, 0 }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f00, 0, 0 }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f01, 0, 0 }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f08, 0, 0 }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f09, 0, 0 }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f20, 0, 0 }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f21, 0, 0 }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f28, 0, 0 }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f29, 0, 0 }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f60, 0, 0 }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f61, 0, 0 }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f68, 0, 0 }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_grave, 0x1001f69, 0, 0 }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f00, 0, 0 }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f01, 0, 0 }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f08, 0, 0 }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f09, 0, 0 }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f20, 0, 0 }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f21, 0, 0 }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f28, 0, 0 }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f29, 0, 0 }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f60, 0, 0 }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f61, 0, 0 }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f68, 0, 0 }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_acute, 0x1001f69, 0, 0 }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F9E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAE}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F86}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F96}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1FA6}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F9F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAF}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F87}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F97}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1FA7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f00, 0, 0 }, 0x1F86}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f01, 0, 0 }, 0x1F87}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f08, 0, 0 }, 0x1F8E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f09, 0, 0 }, 0x1F8F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f20, 0, 0 }, 0x1F96}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f21, 0, 0 }, 0x1F97}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f28, 0, 0 }, 0x1F9E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f29, 0, 0 }, 0x1F9F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f60, 0, 0 }, 0x1FA6}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f61, 0, 0 }, 0x1FA7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f68, 0, 0 }, 0x1FAE}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_tilde, 0x1001f69, 0, 0 }, 0x1FAF}, + {{SCIM_KEY_dead_iota, SCIM_KEY_dead_iota, 0, 0, 0 }, 0x037A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_alpha, 0 }, 0x1FB4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_eta, 0 }, 0x1FC4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_omega, 0 }, 0x1FF4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f00, 0 }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f01, 0 }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f08, 0 }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f09, 0 }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f20, 0 }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f21, 0 }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f28, 0 }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f29, 0 }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f60, 0 }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f61, 0 }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f68, 0 }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f69, 0 }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F89}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F99}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FA9}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F81}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F91}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1FA1}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F88}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F98}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FA8}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F80}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F90}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1FA0}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_alpha, 0 }, 0x1FB2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_eta, 0 }, 0x1FC2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_omega, 0 }, 0x1FF2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f00, 0 }, 0x1F82}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f01, 0 }, 0x1F83}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f08, 0 }, 0x1F8A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f09, 0 }, 0x1F8B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f20, 0 }, 0x1F92}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f21, 0 }, 0x1F93}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f28, 0 }, 0x1F9A}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f29, 0 }, 0x1F9B}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f60, 0 }, 0x1FA2}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f61, 0 }, 0x1FA3}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f68, 0 }, 0x1FAA}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f69, 0 }, 0x1FAB}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_alpha, 0 }, 0x1FB7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_eta, 0 }, 0x1FC7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_omega, 0 }, 0x1FF7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f00, 0 }, 0x1F86}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f01, 0 }, 0x1F87}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f08, 0 }, 0x1F8E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f09, 0 }, 0x1F8F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f20, 0 }, 0x1F96}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f21, 0 }, 0x1F97}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f28, 0 }, 0x1F9E}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f29, 0 }, 0x1F9F}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f60, 0 }, 0x1FA6}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f61, 0 }, 0x1FA7}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f68, 0 }, 0x1FAE}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f69, 0 }, 0x1FAF}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_alpha, 0 }, 0x1FB4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_eta, 0 }, 0x1FC4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_omega, 0 }, 0x1FF4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f00, 0 }, 0x1F84}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f01, 0 }, 0x1F85}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f08, 0 }, 0x1F8C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f09, 0 }, 0x1F8D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f20, 0 }, 0x1F94}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f21, 0 }, 0x1F95}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f28, 0 }, 0x1F9C}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f29, 0 }, 0x1F9D}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f60, 0 }, 0x1FA4}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f61, 0 }, 0x1FA5}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f68, 0 }, 0x1FAC}, + {{SCIM_KEY_dead_iota, SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f69, 0 }, 0x1FAD}, + {{SCIM_KEY_dead_iota, 0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F88}, + {{SCIM_KEY_dead_iota, 0x1000313, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F98}, + {{SCIM_KEY_dead_iota, 0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1FA8}, + {{SCIM_KEY_dead_iota, 0x1000313, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F80}, + {{SCIM_KEY_dead_iota, 0x1000313, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F90}, + {{SCIM_KEY_dead_iota, 0x1000313, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FA0}, + {{SCIM_KEY_dead_iota, 0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F89}, + {{SCIM_KEY_dead_iota, 0x1000314, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F99}, + {{SCIM_KEY_dead_iota, 0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1FA9}, + {{SCIM_KEY_dead_iota, 0x1000314, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F81}, + {{SCIM_KEY_dead_iota, 0x1000314, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F91}, + {{SCIM_KEY_dead_iota, 0x1000314, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FA1}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB7}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC7}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF7}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_dead_iota, 0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8E}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F9E}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAE}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F86}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F96}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1FA6}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F8F}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F9F}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FAF}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F87}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F97}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1FA7}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f00, 0, 0 }, 0x1F86}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f01, 0, 0 }, 0x1F87}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f08, 0, 0 }, 0x1F8E}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f09, 0, 0 }, 0x1F8F}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f20, 0, 0 }, 0x1F96}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f21, 0, 0 }, 0x1F97}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f28, 0, 0 }, 0x1F9E}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f29, 0, 0 }, 0x1F9F}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f60, 0, 0 }, 0x1FA6}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f61, 0, 0 }, 0x1FA7}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f68, 0, 0 }, 0x1FAE}, + {{SCIM_KEY_dead_iota, 0x1000342, 0x1001f69, 0, 0 }, 0x1FAF}, + {{SCIM_KEY_dead_iota, 0x1001f00, 0, 0, 0 }, 0x1F80}, + {{SCIM_KEY_dead_iota, 0x1001f01, 0, 0, 0 }, 0x1F81}, + {{SCIM_KEY_dead_iota, 0x1001f02, 0, 0, 0 }, 0x1F82}, + {{SCIM_KEY_dead_iota, 0x1001f03, 0, 0, 0 }, 0x1F83}, + {{SCIM_KEY_dead_iota, 0x1001f04, 0, 0, 0 }, 0x1F84}, + {{SCIM_KEY_dead_iota, 0x1001f05, 0, 0, 0 }, 0x1F85}, + {{SCIM_KEY_dead_iota, 0x1001f06, 0, 0, 0 }, 0x1F86}, + {{SCIM_KEY_dead_iota, 0x1001f07, 0, 0, 0 }, 0x1F87}, + {{SCIM_KEY_dead_iota, 0x1001f08, 0, 0, 0 }, 0x1F88}, + {{SCIM_KEY_dead_iota, 0x1001f09, 0, 0, 0 }, 0x1F89}, + {{SCIM_KEY_dead_iota, 0x1001f0a, 0, 0, 0 }, 0x1F8A}, + {{SCIM_KEY_dead_iota, 0x1001f0b, 0, 0, 0 }, 0x1F8B}, + {{SCIM_KEY_dead_iota, 0x1001f0c, 0, 0, 0 }, 0x1F8C}, + {{SCIM_KEY_dead_iota, 0x1001f0d, 0, 0, 0 }, 0x1F8D}, + {{SCIM_KEY_dead_iota, 0x1001f0e, 0, 0, 0 }, 0x1F8E}, + {{SCIM_KEY_dead_iota, 0x1001f0f, 0, 0, 0 }, 0x1F8F}, + {{SCIM_KEY_dead_iota, 0x1001f20, 0, 0, 0 }, 0x1F90}, + {{SCIM_KEY_dead_iota, 0x1001f21, 0, 0, 0 }, 0x1F91}, + {{SCIM_KEY_dead_iota, 0x1001f22, 0, 0, 0 }, 0x1F92}, + {{SCIM_KEY_dead_iota, 0x1001f23, 0, 0, 0 }, 0x1F93}, + {{SCIM_KEY_dead_iota, 0x1001f24, 0, 0, 0 }, 0x1F94}, + {{SCIM_KEY_dead_iota, 0x1001f25, 0, 0, 0 }, 0x1F95}, + {{SCIM_KEY_dead_iota, 0x1001f26, 0, 0, 0 }, 0x1F96}, + {{SCIM_KEY_dead_iota, 0x1001f27, 0, 0, 0 }, 0x1F97}, + {{SCIM_KEY_dead_iota, 0x1001f28, 0, 0, 0 }, 0x1F98}, + {{SCIM_KEY_dead_iota, 0x1001f29, 0, 0, 0 }, 0x1F99}, + {{SCIM_KEY_dead_iota, 0x1001f2a, 0, 0, 0 }, 0x1F9A}, + {{SCIM_KEY_dead_iota, 0x1001f2b, 0, 0, 0 }, 0x1F9B}, + {{SCIM_KEY_dead_iota, 0x1001f2c, 0, 0, 0 }, 0x1F9C}, + {{SCIM_KEY_dead_iota, 0x1001f2d, 0, 0, 0 }, 0x1F9D}, + {{SCIM_KEY_dead_iota, 0x1001f2e, 0, 0, 0 }, 0x1F9E}, + {{SCIM_KEY_dead_iota, 0x1001f2f, 0, 0, 0 }, 0x1F9F}, + {{SCIM_KEY_dead_iota, 0x1001f60, 0, 0, 0 }, 0x1FA0}, + {{SCIM_KEY_dead_iota, 0x1001f61, 0, 0, 0 }, 0x1FA1}, + {{SCIM_KEY_dead_iota, 0x1001f62, 0, 0, 0 }, 0x1FA2}, + {{SCIM_KEY_dead_iota, 0x1001f63, 0, 0, 0 }, 0x1FA3}, + {{SCIM_KEY_dead_iota, 0x1001f64, 0, 0, 0 }, 0x1FA4}, + {{SCIM_KEY_dead_iota, 0x1001f65, 0, 0, 0 }, 0x1FA5}, + {{SCIM_KEY_dead_iota, 0x1001f66, 0, 0, 0 }, 0x1FA6}, + {{SCIM_KEY_dead_iota, 0x1001f67, 0, 0, 0 }, 0x1FA7}, + {{SCIM_KEY_dead_iota, 0x1001f68, 0, 0, 0 }, 0x1FA8}, + {{SCIM_KEY_dead_iota, 0x1001f69, 0, 0, 0 }, 0x1FA9}, + {{SCIM_KEY_dead_iota, 0x1001f6a, 0, 0, 0 }, 0x1FAA}, + {{SCIM_KEY_dead_iota, 0x1001f6b, 0, 0, 0 }, 0x1FAB}, + {{SCIM_KEY_dead_iota, 0x1001f6c, 0, 0, 0 }, 0x1FAC}, + {{SCIM_KEY_dead_iota, 0x1001f6d, 0, 0, 0 }, 0x1FAD}, + {{SCIM_KEY_dead_iota, 0x1001f6e, 0, 0, 0 }, 0x1FAE}, + {{SCIM_KEY_dead_iota, 0x1001f6f, 0, 0, 0 }, 0x1FAF}, + {{SCIM_KEY_dead_iota, 0x1001f70, 0, 0, 0 }, 0x1FB2}, + {{SCIM_KEY_dead_iota, 0x1001f74, 0, 0, 0 }, 0x1FC2}, + {{SCIM_KEY_dead_iota, 0x1001f7c, 0, 0, 0 }, 0x1FF2}, + {{SCIM_KEY_dead_iota, 0x1001fb6, 0, 0, 0 }, 0x1FB7}, + {{SCIM_KEY_dead_iota, 0x1001fc6, 0, 0, 0 }, 0x1FC7}, + {{SCIM_KEY_dead_iota, 0x1001ff6, 0, 0, 0 }, 0x1FF7}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_WO, 0, 0, 0 }, 0x30FA}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_U, 0, 0, 0 }, 0x30F4}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_KA, 0, 0, 0 }, 0x30AC}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_KI, 0, 0, 0 }, 0x30AE}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_KU, 0, 0, 0 }, 0x30B0}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_KE, 0, 0, 0 }, 0x30B2}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_KO, 0, 0, 0 }, 0x30B4}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_SA, 0, 0, 0 }, 0x30B6}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_SHI, 0, 0, 0 }, 0x30B8}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_SU, 0, 0, 0 }, 0x30BA}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_SE, 0, 0, 0 }, 0x30BC}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_SO, 0, 0, 0 }, 0x30BE}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_TA, 0, 0, 0 }, 0x30C0}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_CHI, 0, 0, 0 }, 0x30C2}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_TSU, 0, 0, 0 }, 0x30C5}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_TE, 0, 0, 0 }, 0x30C7}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_TO, 0, 0, 0 }, 0x30C9}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_HA, 0, 0, 0 }, 0x30D0}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_HI, 0, 0, 0 }, 0x30D3}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_FU, 0, 0, 0 }, 0x30D6}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_HE, 0, 0, 0 }, 0x30D9}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_HO, 0, 0, 0 }, 0x30DC}, + {{SCIM_KEY_dead_voiced_sound, SCIM_KEY_kana_WA, 0, 0, 0 }, 0x30F7}, + {{SCIM_KEY_dead_voiced_sound, 0x1003046, 0, 0, 0 }, 0x3094}, + {{SCIM_KEY_dead_voiced_sound, 0x100304b, 0, 0, 0 }, 0x304C}, + {{SCIM_KEY_dead_voiced_sound, 0x100304d, 0, 0, 0 }, 0x304E}, + {{SCIM_KEY_dead_voiced_sound, 0x100304f, 0, 0, 0 }, 0x3050}, + {{SCIM_KEY_dead_voiced_sound, 0x1003051, 0, 0, 0 }, 0x3052}, + {{SCIM_KEY_dead_voiced_sound, 0x1003053, 0, 0, 0 }, 0x3054}, + {{SCIM_KEY_dead_voiced_sound, 0x1003055, 0, 0, 0 }, 0x3056}, + {{SCIM_KEY_dead_voiced_sound, 0x1003057, 0, 0, 0 }, 0x3058}, + {{SCIM_KEY_dead_voiced_sound, 0x1003059, 0, 0, 0 }, 0x305A}, + {{SCIM_KEY_dead_voiced_sound, 0x100305b, 0, 0, 0 }, 0x305C}, + {{SCIM_KEY_dead_voiced_sound, 0x100305d, 0, 0, 0 }, 0x305E}, + {{SCIM_KEY_dead_voiced_sound, 0x100305f, 0, 0, 0 }, 0x3060}, + {{SCIM_KEY_dead_voiced_sound, 0x1003061, 0, 0, 0 }, 0x3062}, + {{SCIM_KEY_dead_voiced_sound, 0x1003064, 0, 0, 0 }, 0x3065}, + {{SCIM_KEY_dead_voiced_sound, 0x1003066, 0, 0, 0 }, 0x3067}, + {{SCIM_KEY_dead_voiced_sound, 0x1003068, 0, 0, 0 }, 0x3069}, + {{SCIM_KEY_dead_voiced_sound, 0x100306f, 0, 0, 0 }, 0x3070}, + {{SCIM_KEY_dead_voiced_sound, 0x1003072, 0, 0, 0 }, 0x3073}, + {{SCIM_KEY_dead_voiced_sound, 0x1003075, 0, 0, 0 }, 0x3076}, + {{SCIM_KEY_dead_voiced_sound, 0x1003078, 0, 0, 0 }, 0x3079}, + {{SCIM_KEY_dead_voiced_sound, 0x100307b, 0, 0, 0 }, 0x307C}, + {{SCIM_KEY_dead_voiced_sound, 0x100309d, 0, 0, 0 }, 0x309E}, + {{SCIM_KEY_dead_voiced_sound, 0x10030f0, 0, 0, 0 }, 0x30F8}, + {{SCIM_KEY_dead_voiced_sound, 0x10030f1, 0, 0, 0 }, 0x30F9}, + {{SCIM_KEY_dead_voiced_sound, 0x10030fd, 0, 0, 0 }, 0x30FE}, + {{SCIM_KEY_dead_semivoiced_sound, SCIM_KEY_kana_HA, 0, 0, 0 }, 0x30D1}, + {{SCIM_KEY_dead_semivoiced_sound, SCIM_KEY_kana_HI, 0, 0, 0 }, 0x30D4}, + {{SCIM_KEY_dead_semivoiced_sound, SCIM_KEY_kana_FU, 0, 0, 0 }, 0x30D7}, + {{SCIM_KEY_dead_semivoiced_sound, SCIM_KEY_kana_HE, 0, 0, 0 }, 0x30DA}, + {{SCIM_KEY_dead_semivoiced_sound, SCIM_KEY_kana_HO, 0, 0, 0 }, 0x30DD}, + {{SCIM_KEY_dead_semivoiced_sound, 0x100306f, 0, 0, 0 }, 0x3071}, + {{SCIM_KEY_dead_semivoiced_sound, 0x1003072, 0, 0, 0 }, 0x3074}, + {{SCIM_KEY_dead_semivoiced_sound, 0x1003075, 0, 0, 0 }, 0x3077}, + {{SCIM_KEY_dead_semivoiced_sound, 0x1003078, 0, 0, 0 }, 0x307A}, + {{SCIM_KEY_dead_semivoiced_sound, 0x100307b, 0, 0, 0 }, 0x307D}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_A, 0, 0, 0 }, 0x1EA0}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_B, 0, 0, 0 }, 0x1E04}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_D, 0, 0, 0 }, 0x1E0C}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_E, 0, 0, 0 }, 0x1EB8}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_H, 0, 0, 0 }, 0x1E24}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_I, 0, 0, 0 }, 0x1ECA}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_K, 0, 0, 0 }, 0x1E32}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_L, 0, 0, 0 }, 0x1E36}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_M, 0, 0, 0 }, 0x1E42}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_N, 0, 0, 0 }, 0x1E46}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_O, 0, 0, 0 }, 0x1ECC}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_R, 0, 0, 0 }, 0x1E5A}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_S, 0, 0, 0 }, 0x1E62}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_T, 0, 0, 0 }, 0x1E6C}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_U, 0, 0, 0 }, 0x1EE4}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_V, 0, 0, 0 }, 0x1E7E}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_W, 0, 0, 0 }, 0x1E88}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF4}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Z, 0, 0, 0 }, 0x1E92}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_a, 0, 0, 0 }, 0x1EA1}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_b, 0, 0, 0 }, 0x1E05}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_d, 0, 0, 0 }, 0x1E0D}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_e, 0, 0, 0 }, 0x1EB9}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_h, 0, 0, 0 }, 0x1E25}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_i, 0, 0, 0 }, 0x1ECB}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_k, 0, 0, 0 }, 0x1E33}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_l, 0, 0, 0 }, 0x1E37}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_m, 0, 0, 0 }, 0x1E43}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_n, 0, 0, 0 }, 0x1E47}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_o, 0, 0, 0 }, 0x1ECD}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_r, 0, 0, 0 }, 0x1E5B}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_s, 0, 0, 0 }, 0x1E63}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_t, 0, 0, 0 }, 0x1E6D}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_u, 0, 0, 0 }, 0x1EE5}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_v, 0, 0, 0 }, 0x1E7F}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_w, 0, 0, 0 }, 0x1E89}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_y, 0, 0, 0 }, 0x1EF5}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_z, 0, 0, 0 }, 0x1E93}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EAC}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EC6}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED8}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EAD}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EC7}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED9}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EB6}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EB7}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EE2}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EE3}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EF0}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EF1}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EE2}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EF0}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EE3}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EF1}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EE2}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EF0}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EE3}, + {{SCIM_KEY_dead_belowdot, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EF1}, + {{SCIM_KEY_dead_belowdot, 0x10001a0, 0, 0, 0 }, 0x1EE2}, + {{SCIM_KEY_dead_belowdot, 0x10001a1, 0, 0, 0 }, 0x1EE3}, + {{SCIM_KEY_dead_belowdot, 0x10001af, 0, 0, 0 }, 0x1EF0}, + {{SCIM_KEY_dead_belowdot, 0x10001b0, 0, 0, 0 }, 0x1EF1}, + {{SCIM_KEY_dead_hook, SCIM_KEY_A, 0, 0, 0 }, 0x1EA2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_E, 0, 0, 0 }, 0x1EBA}, + {{SCIM_KEY_dead_hook, SCIM_KEY_I, 0, 0, 0 }, 0x1EC8}, + {{SCIM_KEY_dead_hook, SCIM_KEY_O, 0, 0, 0 }, 0x1ECE}, + {{SCIM_KEY_dead_hook, SCIM_KEY_U, 0, 0, 0 }, 0x1EE6}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Y, 0, 0, 0 }, 0x1EF6}, + {{SCIM_KEY_dead_hook, SCIM_KEY_a, 0, 0, 0 }, 0x1EA3}, + {{SCIM_KEY_dead_hook, SCIM_KEY_e, 0, 0, 0 }, 0x1EBB}, + {{SCIM_KEY_dead_hook, SCIM_KEY_i, 0, 0, 0 }, 0x1EC9}, + {{SCIM_KEY_dead_hook, SCIM_KEY_o, 0, 0, 0 }, 0x1ECF}, + {{SCIM_KEY_dead_hook, SCIM_KEY_u, 0, 0, 0 }, 0x1EE7}, + {{SCIM_KEY_dead_hook, SCIM_KEY_y, 0, 0, 0 }, 0x1EF7}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Acircumflex, 0, 0, 0 }, 0x1EA8}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Ecircumflex, 0, 0, 0 }, 0x1EC2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Ocircumflex, 0, 0, 0 }, 0x1ED4}, + {{SCIM_KEY_dead_hook, SCIM_KEY_acircumflex, 0, 0, 0 }, 0x1EA9}, + {{SCIM_KEY_dead_hook, SCIM_KEY_ecircumflex, 0, 0, 0 }, 0x1EC3}, + {{SCIM_KEY_dead_hook, SCIM_KEY_ocircumflex, 0, 0, 0 }, 0x1ED5}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Abreve, 0, 0, 0 }, 0x1EB2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_abreve, 0, 0, 0 }, 0x1EB3}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Ohorn, 0, 0, 0 }, 0x1EDE}, + {{SCIM_KEY_dead_hook, SCIM_KEY_ohorn, 0, 0, 0 }, 0x1EDF}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Uhorn, 0, 0, 0 }, 0x1EEC}, + {{SCIM_KEY_dead_hook, SCIM_KEY_uhorn, 0, 0, 0 }, 0x1EED}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0, 0 }, 0x1EA8}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0, 0 }, 0x1EC2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0, 0 }, 0x1ED4}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0, 0 }, 0x1EA9}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0, 0 }, 0x1EC3}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0, 0 }, 0x1ED5}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_breve, SCIM_KEY_A, 0, 0 }, 0x1EB2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_breve, SCIM_KEY_a, 0, 0 }, 0x1EB3}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0 }, 0x1EDE}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0 }, 0x1EEC}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0 }, 0x1EDF}, + {{SCIM_KEY_dead_hook, SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0 }, 0x1EED}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDE}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEC}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDF}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EED}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB3}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA8}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED4}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA9}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC3}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED5}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB2}, + {{SCIM_KEY_dead_hook, SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB3}, + {{SCIM_KEY_dead_hook, 0x10001a0, 0, 0, 0 }, 0x1EDE}, + {{SCIM_KEY_dead_hook, 0x10001a1, 0, 0, 0 }, 0x1EDF}, + {{SCIM_KEY_dead_hook, 0x10001af, 0, 0, 0 }, 0x1EEC}, + {{SCIM_KEY_dead_hook, 0x10001b0, 0, 0, 0 }, 0x1EED}, + {{SCIM_KEY_dead_horn, SCIM_KEY_O, 0, 0, 0 }, 0x01A0}, + {{SCIM_KEY_dead_horn, SCIM_KEY_U, 0, 0, 0 }, 0x01AF}, + {{SCIM_KEY_dead_horn, SCIM_KEY_o, 0, 0, 0 }, 0x01A1}, + {{SCIM_KEY_dead_horn, SCIM_KEY_u, 0, 0, 0 }, 0x01B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_space, 0, 0 }, 0x00A0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_apostrophe, 0, 0 }, 0x0027}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_parenleft, 0, 0 }, 0x02D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_comma, 0, 0 }, 0x00B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_minus, 0, 0 }, 0x007E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_period, 0, 0 }, 0x2008}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_less, 0, 0 }, 0x02C7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_greater, 0, 0 }, 0x005E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_asciicircum, 0, 0 }, 0x005E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_grave, 0, 0 }, 0x0060}, + {{SCIM_KEY_Multi_key, SCIM_KEY_space, SCIM_KEY_asciitilde, 0, 0 }, 0x007E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_exclam, 0, 0 }, 0x00A1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EE2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EF0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EE3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EF1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_A, 0, 0 }, 0x1EA0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_B, 0, 0 }, 0x1E04}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_D, 0, 0 }, 0x1E0C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_E, 0, 0 }, 0x1EB8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_H, 0, 0 }, 0x1E24}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_I, 0, 0 }, 0x1ECA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_K, 0, 0 }, 0x1E32}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_L, 0, 0 }, 0x1E36}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_M, 0, 0 }, 0x1E42}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_N, 0, 0 }, 0x1E46}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_O, 0, 0 }, 0x1ECC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_P, 0, 0 }, 0x00B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_R, 0, 0 }, 0x1E5A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_S, 0, 0 }, 0x1E62}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_T, 0, 0 }, 0x1E6C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_U, 0, 0 }, 0x1EE4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_V, 0, 0 }, 0x1E7E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_W, 0, 0 }, 0x1E88}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_Y, 0, 0 }, 0x1EF4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_Z, 0, 0 }, 0x1E92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_asciicircum, 0, 0 }, 0x00A6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_a, 0, 0 }, 0x1EA1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_b, 0, 0 }, 0x1E05}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_d, 0, 0 }, 0x1E0D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_e, 0, 0 }, 0x1EB9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_h, 0, 0 }, 0x1E25}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_i, 0, 0 }, 0x1ECB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_k, 0, 0 }, 0x1E33}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_l, 0, 0 }, 0x1E37}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_m, 0, 0 }, 0x1E43}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_n, 0, 0 }, 0x1E47}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_o, 0, 0 }, 0x1ECD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_p, 0, 0 }, 0x00B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_r, 0, 0 }, 0x1E5B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_s, 0, 0 }, 0x1E63}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_t, 0, 0 }, 0x1E6D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_u, 0, 0 }, 0x1EE5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_v, 0, 0 }, 0x1E7F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_w, 0, 0 }, 0x1E89}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_y, 0, 0 }, 0x1EF5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_z, 0, 0 }, 0x1E93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_Ohorn, 0, 0 }, 0x1EE2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_ohorn, 0, 0 }, 0x1EE3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_Uhorn, 0, 0 }, 0x1EF0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_uhorn, 0, 0 }, 0x1EF1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_dead_horn, SCIM_KEY_O, 0 }, 0x1EE2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_dead_horn, SCIM_KEY_U, 0 }, 0x1EF0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_dead_horn, SCIM_KEY_o, 0 }, 0x1EE3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_exclam, SCIM_KEY_dead_horn, SCIM_KEY_u, 0 }, 0x1EF1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_quotedbl, 0, 0 }, 0x00A8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_apostrophe, 0, 0 }, 0x0344}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_apostrophe, SCIM_KEY_space, 0 }, 0x0385}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_apostrophe, SCIM_KEY_Greek_iota, 0 }, 0x0390}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_apostrophe, SCIM_KEY_Greek_upsilon, 0 }, 0x03B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_comma, 0, 0 }, 0x201E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_slash, 0, 0 }, 0x301E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_less, 0, 0 }, 0x201C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_greater, 0, 0 }, 0x201D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_A, 0, 0 }, 0x00C4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_E, 0, 0 }, 0x00CB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_H, 0, 0 }, 0x1E26}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_I, 0, 0 }, 0x00CF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_O, 0, 0 }, 0x00D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_U, 0, 0 }, 0x00DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_W, 0, 0 }, 0x1E84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_X, 0, 0 }, 0x1E8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Y, 0, 0 }, 0x0178}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_backslash, 0, 0 }, 0x301D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_underscore, SCIM_KEY_U, 0 }, 0x1E7A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_underscore, SCIM_KEY_u, 0 }, 0x1E7B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_a, 0, 0 }, 0x00E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_e, 0, 0 }, 0x00EB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_h, 0, 0 }, 0x1E27}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_i, 0, 0 }, 0x00EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_o, 0, 0 }, 0x00F6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_t, 0, 0 }, 0x1E97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_u, 0, 0 }, 0x00FC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_w, 0, 0 }, 0x1E85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_x, 0, 0 }, 0x1E8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_y, 0, 0 }, 0x00FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x1E4E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x1E4F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_macron, SCIM_KEY_U, 0 }, 0x1E7A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_macron, SCIM_KEY_u, 0 }, 0x1E7B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_acute, 0, 0 }, 0x0344}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Otilde, 0, 0 }, 0x1E4E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_otilde, 0, 0 }, 0x1E4F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Umacron, 0, 0 }, 0x1E7A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_umacron, 0, 0 }, 0x1E7B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Ukrainian_i, 0, 0 }, 0x0457}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Ukrainian_I, 0, 0 }, 0x0407}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_a, 0, 0 }, 0x04D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_ie, 0, 0 }, 0x0451}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_i, 0, 0 }, 0x04E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_o, 0, 0 }, 0x04E7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_u, 0, 0 }, 0x04F1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_zhe, 0, 0 }, 0x04DD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_yeru, 0, 0 }, 0x04F9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_ze, 0, 0 }, 0x04DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_e, 0, 0 }, 0x04ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_che, 0, 0 }, 0x04F5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_A, 0, 0 }, 0x04D2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_IE, 0, 0 }, 0x0401}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_I, 0, 0 }, 0x04E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_O, 0, 0 }, 0x04E6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_U, 0, 0 }, 0x04F0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_ZHE, 0, 0 }, 0x04DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_YERU, 0, 0 }, 0x04F8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_ZE, 0, 0 }, 0x04DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_E, 0, 0 }, 0x04EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Cyrillic_CHE, 0, 0 }, 0x04F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x03AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x03AB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0, 0 }, 0x03CA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x03CB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0 }, 0x1E4E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0 }, 0x1E4F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_combining_acute, 0, 0 }, 0x0344}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_dead_acute, 0, 0 }, 0x0344}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0 }, 0x1E4E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0 }, 0x1E4F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_dead_macron, SCIM_KEY_U, 0 }, 0x1E7A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_dead_macron, SCIM_KEY_u, 0 }, 0x1E7B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, 0x10003d2, 0, 0 }, 0x03D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, 0x10004d8, 0, 0 }, 0x04DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, 0x10004d9, 0, 0 }, 0x04DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, 0x10004e8, 0, 0 }, 0x04EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, 0x10004e9, 0, 0 }, 0x04EB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_numbersign, SCIM_KEY_numbersign, 0, 0 }, 0x266F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_numbersign, SCIM_KEY_b, 0, 0 }, 0x266D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_numbersign, SCIM_KEY_f, 0, 0 }, 0x266E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_percent, SCIM_KEY_o, 0, 0 }, 0x2030}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_space, 0, 0 }, 0x0027}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_quotedbl, SCIM_KEY_space, 0 }, 0x0385}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_quotedbl, SCIM_KEY_I, 0 }, 0x1E2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_quotedbl, SCIM_KEY_i, 0 }, 0x1E2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x0390}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x03B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_apostrophe, 0, 0 }, 0x00B4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F05}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0 }, 0x1F15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F25}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F35}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0 }, 0x1F45}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F04}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0 }, 0x1F14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F24}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F34}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0 }, 0x1F44}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_comma, 0, 0 }, 0x201A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_comma, SCIM_KEY_C, 0 }, 0x1E08}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_comma, SCIM_KEY_c, 0 }, 0x1E09}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_slash, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_slash, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_less, 0, 0 }, 0x2018}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_greater, 0, 0 }, 0x2019}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_A, 0, 0 }, 0x00C1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_C, 0, 0 }, 0x0106}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_E, 0, 0 }, 0x00C9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_G, 0, 0 }, 0x01F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_I, 0, 0 }, 0x00CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_K, 0, 0 }, 0x1E30}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_L, 0, 0 }, 0x0139}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_M, 0, 0 }, 0x1E3E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_N, 0, 0 }, 0x0143}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_O, 0, 0 }, 0x00D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_P, 0, 0 }, 0x1E54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_R, 0, 0 }, 0x0154}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_S, 0, 0 }, 0x015A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_U, 0, 0 }, 0x00DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_W, 0, 0 }, 0x1E82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Y, 0, 0 }, 0x00DD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Z, 0, 0 }, 0x0179}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EBE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EBF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_underscore, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_underscore, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_underscore, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_a, 0, 0 }, 0x00E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_c, 0, 0 }, 0x0107}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_e, 0, 0 }, 0x00E9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_g, 0, 0 }, 0x01F5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_i, 0, 0 }, 0x00ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_k, 0, 0 }, 0x1E31}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_l, 0, 0 }, 0x013A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_m, 0, 0 }, 0x1E3F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_n, 0, 0 }, 0x0144}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_o, 0, 0 }, 0x00F3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_p, 0, 0 }, 0x1E55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_r, 0, 0 }, 0x0155}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_s, 0, 0 }, 0x015B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_u, 0, 0 }, 0x00FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_w, 0, 0 }, 0x1E83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_y, 0, 0 }, 0x00FD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_z, 0, 0 }, 0x017A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciitilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_asciitilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_macron, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_macron, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_macron, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_macron, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Acircumflex, 0, 0 }, 0x1EA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Aring, 0, 0 }, 0x01FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_AE, 0, 0 }, 0x01FC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Ccedilla, 0, 0 }, 0x1E08}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Ecircumflex, 0, 0 }, 0x1EBE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Idiaeresis, 0, 0 }, 0x1E2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Ocircumflex, 0, 0 }, 0x1ED0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Otilde, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Ooblique, 0, 0 }, 0x01FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Udiaeresis, 0, 0 }, 0x01D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_acircumflex, 0, 0 }, 0x1EA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_aring, 0, 0 }, 0x01FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_ae, 0, 0 }, 0x01FD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_ccedilla, 0, 0 }, 0x1E09}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_ecircumflex, 0, 0 }, 0x1EBF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_idiaeresis, 0, 0 }, 0x1E2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_ocircumflex, 0, 0 }, 0x1ED1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_otilde, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_oslash, 0, 0 }, 0x01FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_udiaeresis, 0, 0 }, 0x01D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Abreve, 0, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_abreve, 0, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Emacron, 0, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_emacron, 0, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Omacron, 0, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Utilde, 0, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_omacron, 0, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_utilde, 0, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Cyrillic_ghe, 0, 0 }, 0x0453}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Cyrillic_ka, 0, 0 }, 0x045C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Cyrillic_GHE, 0, 0 }, 0x0403}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Cyrillic_KA, 0, 0 }, 0x040C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_iotadieresis, 0, 0 }, 0x0390}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_upsilondieresis, 0, 0 }, 0x03B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x0386}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x0388}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_ETA, 0, 0 }, 0x0389}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x038A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x038C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x038E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x038F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_alpha, 0, 0 }, 0x03AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x03AD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_eta, 0, 0 }, 0x03AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_iota, 0, 0 }, 0x03AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_omicron, 0, 0 }, 0x03CC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x03CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Greek_omega, 0, 0 }, 0x03CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_combining_tilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_combining_tilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Ohorn, 0, 0 }, 0x1EDA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_ohorn, 0, 0 }, 0x1EDB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_Uhorn, 0, 0 }, 0x1EE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_uhorn, 0, 0 }, 0x1EE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0 }, 0x1EA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0 }, 0x1EBE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0 }, 0x1ED0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0 }, 0x1EA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0 }, 0x1EBF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0 }, 0x1ED1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_tilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_tilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_macron, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_macron, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_macron, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_macron, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_breve, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_breve, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_diaeresis, SCIM_KEY_I, 0 }, 0x1E2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0 }, 0x01D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_diaeresis, SCIM_KEY_i, 0 }, 0x1E2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0 }, 0x01D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0 }, 0x0390}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0 }, 0x03B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_abovering, SCIM_KEY_A, 0 }, 0x01FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_abovering, SCIM_KEY_a, 0 }, 0x01FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_cedilla, SCIM_KEY_C, 0 }, 0x1E08}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_cedilla, SCIM_KEY_c, 0 }, 0x1E09}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_horn, SCIM_KEY_O, 0 }, 0x1EDA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_horn, SCIM_KEY_U, 0 }, 0x1EE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_horn, SCIM_KEY_o, 0 }, 0x1EDB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_dead_horn, SCIM_KEY_u, 0 }, 0x1EE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_KP_Divide, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, SCIM_KEY_KP_Divide, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F2C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F04}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_epsilon, 0 }, 0x1F14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F24}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_iota, 0 }, 0x1F34}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_omicron, 0 }, 0x1F44}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_upsilon, 0 }, 0x1F54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1F64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F2D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F05}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_epsilon, 0 }, 0x1F15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F25}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_iota, 0 }, 0x1F35}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_omicron, 0 }, 0x1F45}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_upsilon, 0 }, 0x1F55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1F65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x10003d2, 0, 0 }, 0x03D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f00, 0, 0 }, 0x1F04}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f01, 0, 0 }, 0x1F05}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f08, 0, 0 }, 0x1F0C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f09, 0, 0 }, 0x1F0D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f10, 0, 0 }, 0x1F14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f11, 0, 0 }, 0x1F15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f18, 0, 0 }, 0x1F1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f19, 0, 0 }, 0x1F1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f20, 0, 0 }, 0x1F24}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f21, 0, 0 }, 0x1F25}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f28, 0, 0 }, 0x1F2C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f29, 0, 0 }, 0x1F2D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f30, 0, 0 }, 0x1F34}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f31, 0, 0 }, 0x1F35}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f38, 0, 0 }, 0x1F3C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f39, 0, 0 }, 0x1F3D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f40, 0, 0 }, 0x1F44}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f41, 0, 0 }, 0x1F45}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f48, 0, 0 }, 0x1F4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f49, 0, 0 }, 0x1F4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f50, 0, 0 }, 0x1F54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f51, 0, 0 }, 0x1F55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f59, 0, 0 }, 0x1F5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f60, 0, 0 }, 0x1F64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f61, 0, 0 }, 0x1F65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f68, 0, 0 }, 0x1F6C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_apostrophe, 0x1001f69, 0, 0 }, 0x1F6D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_space, 0, 0 }, 0x02D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_parenleft, 0, 0 }, 0x005B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_minus, 0, 0 }, 0x007B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_0, SCIM_KEY_parenright, 0 }, 0x24EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_parenright, 0 }, 0x2460}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_0, SCIM_KEY_parenright }, 0x2469}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_1, SCIM_KEY_parenright }, 0x246A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_2, SCIM_KEY_parenright }, 0x246B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_3, SCIM_KEY_parenright }, 0x246C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_4, SCIM_KEY_parenright }, 0x246D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_5, SCIM_KEY_parenright }, 0x246E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_6, SCIM_KEY_parenright }, 0x246F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_7, SCIM_KEY_parenright }, 0x2470}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_8, SCIM_KEY_parenright }, 0x2471}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_9, SCIM_KEY_parenright }, 0x2472}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x246B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x2469}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x246A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x246B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x246C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x246D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x246E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x246F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x2470}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x2471}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_1, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x2472}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_parenright, 0 }, 0x2461}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_0, SCIM_KEY_parenright }, 0x2473}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_1, SCIM_KEY_parenright }, 0x3251}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_2, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_3, SCIM_KEY_parenright }, 0x3253}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_4, SCIM_KEY_parenright }, 0x3254}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_5, SCIM_KEY_parenright }, 0x3255}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_6, SCIM_KEY_parenright }, 0x3256}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_7, SCIM_KEY_parenright }, 0x3257}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_8, SCIM_KEY_parenright }, 0x3258}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_9, SCIM_KEY_parenright }, 0x3259}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x2473}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x3251}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x3253}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x3254}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x3255}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x3256}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x3257}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x3258}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_2, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x3259}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_parenright, 0 }, 0x2462}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_0, SCIM_KEY_parenright }, 0x325A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_1, SCIM_KEY_parenright }, 0x325B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_2, SCIM_KEY_parenright }, 0x325C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_3, SCIM_KEY_parenright }, 0x325D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_4, SCIM_KEY_parenright }, 0x325E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_5, SCIM_KEY_parenright }, 0x325F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_6, SCIM_KEY_parenright }, 0x32B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_7, SCIM_KEY_parenright }, 0x32B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_8, SCIM_KEY_parenright }, 0x32B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_9, SCIM_KEY_parenright }, 0x32B4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x325C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x325A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x325B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x325C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x325D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x325E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x325F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x32B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x32B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x32B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_3, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x32B4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_parenright, 0 }, 0x2463}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_0, SCIM_KEY_parenright }, 0x32B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_1, SCIM_KEY_parenright }, 0x32B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_2, SCIM_KEY_parenright }, 0x32B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_3, SCIM_KEY_parenright }, 0x32B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_4, SCIM_KEY_parenright }, 0x32B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_5, SCIM_KEY_parenright }, 0x32BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_6, SCIM_KEY_parenright }, 0x32BB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_7, SCIM_KEY_parenright }, 0x32BC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_8, SCIM_KEY_parenright }, 0x32BD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_9, SCIM_KEY_parenright }, 0x32BE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x32B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x32B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x32B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x32B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x32B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x32B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x32BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x32BB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x32BC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x32BD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_4, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x32BE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_5, SCIM_KEY_parenright, 0 }, 0x2464}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_5, SCIM_KEY_0, SCIM_KEY_parenright }, 0x32BF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_5, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x32BF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_6, SCIM_KEY_parenright, 0 }, 0x2465}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_7, SCIM_KEY_parenright, 0 }, 0x2466}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_8, SCIM_KEY_parenright, 0 }, 0x2467}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_9, SCIM_KEY_parenright, 0 }, 0x2468}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_A, 0, 0 }, 0x0102}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_A, SCIM_KEY_parenright, 0 }, 0x24B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_B, SCIM_KEY_parenright, 0 }, 0x24B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_C, SCIM_KEY_parenright, 0 }, 0x24B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_D, SCIM_KEY_parenright, 0 }, 0x24B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_E, SCIM_KEY_parenright, 0 }, 0x24BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_F, SCIM_KEY_parenright, 0 }, 0x24BB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_G, 0, 0 }, 0x011E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_G, SCIM_KEY_parenright, 0 }, 0x24BC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_H, SCIM_KEY_parenright, 0 }, 0x24BD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_I, SCIM_KEY_parenright, 0 }, 0x24BE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_J, SCIM_KEY_parenright, 0 }, 0x24BF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_K, SCIM_KEY_parenright, 0 }, 0x24C0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_L, SCIM_KEY_parenright, 0 }, 0x24C1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_M, SCIM_KEY_parenright, 0 }, 0x24C2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_N, SCIM_KEY_parenright, 0 }, 0x24C3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_O, SCIM_KEY_parenright, 0 }, 0x24C4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_P, SCIM_KEY_parenright, 0 }, 0x24C5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Q, SCIM_KEY_parenright, 0 }, 0x24C6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_R, SCIM_KEY_parenright, 0 }, 0x24C7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_S, SCIM_KEY_parenright, 0 }, 0x24C8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_T, SCIM_KEY_parenright, 0 }, 0x24C9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_U, SCIM_KEY_parenright, 0 }, 0x24CA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_V, SCIM_KEY_parenright, 0 }, 0x24CB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_W, SCIM_KEY_parenright, 0 }, 0x24CC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_X, SCIM_KEY_parenright, 0 }, 0x24CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Y, SCIM_KEY_parenright, 0 }, 0x24CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Z, SCIM_KEY_parenright, 0 }, 0x24CF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_a, 0, 0 }, 0x0103}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_a, SCIM_KEY_parenright, 0 }, 0x24D0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_b, SCIM_KEY_parenright, 0 }, 0x24D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_c, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_c, SCIM_KEY_parenright, 0 }, 0x24D2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_d, SCIM_KEY_parenright, 0 }, 0x24D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_e, SCIM_KEY_parenright, 0 }, 0x24D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_f, SCIM_KEY_parenright, 0 }, 0x24D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_g, 0, 0 }, 0x011F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_g, SCIM_KEY_parenright, 0 }, 0x24D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_h, SCIM_KEY_parenright, 0 }, 0x24D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_i, SCIM_KEY_parenright, 0 }, 0x24D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_j, SCIM_KEY_parenright, 0 }, 0x24D9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_k, SCIM_KEY_parenright, 0 }, 0x24DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_l, SCIM_KEY_parenright, 0 }, 0x24DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_m, SCIM_KEY_parenright, 0 }, 0x24DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_n, SCIM_KEY_parenright, 0 }, 0x24DD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_o, SCIM_KEY_parenright, 0 }, 0x24DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_p, SCIM_KEY_parenright, 0 }, 0x24DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_q, SCIM_KEY_parenright, 0 }, 0x24E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_r, 0, 0 }, 0x00AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_r, SCIM_KEY_parenright, 0 }, 0x24E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_s, SCIM_KEY_parenright, 0 }, 0x24E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_t, SCIM_KEY_parenright, 0 }, 0x24E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_u, SCIM_KEY_parenright, 0 }, 0x24E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_v, SCIM_KEY_parenright, 0 }, 0x24E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_w, SCIM_KEY_parenright, 0 }, 0x24E6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_x, SCIM_KEY_parenright, 0 }, 0x24E7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_y, SCIM_KEY_parenright, 0 }, 0x24E8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_z, SCIM_KEY_parenright, 0 }, 0x24E9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_WO, SCIM_KEY_parenright, 0 }, 0x32FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_A, SCIM_KEY_parenright, 0 }, 0x32D0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_I, SCIM_KEY_parenright, 0 }, 0x32D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_U, SCIM_KEY_parenright, 0 }, 0x32D2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_E, SCIM_KEY_parenright, 0 }, 0x32D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_O, SCIM_KEY_parenright, 0 }, 0x32D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_KA, SCIM_KEY_parenright, 0 }, 0x32D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_KI, SCIM_KEY_parenright, 0 }, 0x32D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_KU, SCIM_KEY_parenright, 0 }, 0x32D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_KE, SCIM_KEY_parenright, 0 }, 0x32D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_KO, SCIM_KEY_parenright, 0 }, 0x32D9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_SA, SCIM_KEY_parenright, 0 }, 0x32DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_SHI, SCIM_KEY_parenright, 0 }, 0x32DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_SU, SCIM_KEY_parenright, 0 }, 0x32DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_SE, SCIM_KEY_parenright, 0 }, 0x32DD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_SO, SCIM_KEY_parenright, 0 }, 0x32DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_TA, SCIM_KEY_parenright, 0 }, 0x32DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_CHI, SCIM_KEY_parenright, 0 }, 0x32E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_TSU, SCIM_KEY_parenright, 0 }, 0x32E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_TE, SCIM_KEY_parenright, 0 }, 0x32E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_TO, SCIM_KEY_parenright, 0 }, 0x32E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_NA, SCIM_KEY_parenright, 0 }, 0x32E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_NI, SCIM_KEY_parenright, 0 }, 0x32E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_NU, SCIM_KEY_parenright, 0 }, 0x32E6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_NE, SCIM_KEY_parenright, 0 }, 0x32E7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_NO, SCIM_KEY_parenright, 0 }, 0x32E8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_HA, SCIM_KEY_parenright, 0 }, 0x32E9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_HI, SCIM_KEY_parenright, 0 }, 0x32EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_FU, SCIM_KEY_parenright, 0 }, 0x32EB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_HE, SCIM_KEY_parenright, 0 }, 0x32EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_HO, SCIM_KEY_parenright, 0 }, 0x32ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_MA, SCIM_KEY_parenright, 0 }, 0x32EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_MI, SCIM_KEY_parenright, 0 }, 0x32EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_MU, SCIM_KEY_parenright, 0 }, 0x32F0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_ME, SCIM_KEY_parenright, 0 }, 0x32F1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_MO, SCIM_KEY_parenright, 0 }, 0x32F2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_YA, SCIM_KEY_parenright, 0 }, 0x32F3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_YU, SCIM_KEY_parenright, 0 }, 0x32F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_YO, SCIM_KEY_parenright, 0 }, 0x32F5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_RA, SCIM_KEY_parenright, 0 }, 0x32F6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_RI, SCIM_KEY_parenright, 0 }, 0x32F7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_RU, SCIM_KEY_parenright, 0 }, 0x32F8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_RE, SCIM_KEY_parenright, 0 }, 0x32F9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_RO, SCIM_KEY_parenright, 0 }, 0x32FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_kana_WA, SCIM_KEY_parenright, 0 }, 0x32FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F09}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F19}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F29}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F49}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_RHO, 0, 0 }, 0x1FEC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1F59}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F69}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F01}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F11}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F21}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F31}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F41}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_rho, 0, 0 }, 0x1FE5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F51}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F61}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_parenright, 0 }, 0x2461}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_0, SCIM_KEY_parenright }, 0x2473}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_1, SCIM_KEY_parenright }, 0x3251}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_2, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_3, SCIM_KEY_parenright }, 0x3253}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_4, SCIM_KEY_parenright }, 0x3254}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_5, SCIM_KEY_parenright }, 0x3255}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_6, SCIM_KEY_parenright }, 0x3256}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_7, SCIM_KEY_parenright }, 0x3257}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_8, SCIM_KEY_parenright }, 0x3258}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_9, SCIM_KEY_parenright }, 0x3259}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x2473}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x3251}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x3253}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x3254}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x3255}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x3256}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x3257}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x3258}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_Space, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x3259}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_0, SCIM_KEY_parenright, 0 }, 0x24EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_parenright, 0 }, 0x2460}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_0, SCIM_KEY_parenright }, 0x2469}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_1, SCIM_KEY_parenright }, 0x246A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_2, SCIM_KEY_parenright }, 0x246B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_3, SCIM_KEY_parenright }, 0x246C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_4, SCIM_KEY_parenright }, 0x246D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_5, SCIM_KEY_parenright }, 0x246E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_6, SCIM_KEY_parenright }, 0x246F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_7, SCIM_KEY_parenright }, 0x2470}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_8, SCIM_KEY_parenright }, 0x2471}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_9, SCIM_KEY_parenright }, 0x2472}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x246B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x2469}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x246A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x246B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x246C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x246D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x246E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x246F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x2470}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x2471}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_1, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x2472}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_parenright, 0 }, 0x2461}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_0, SCIM_KEY_parenright }, 0x2473}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_1, SCIM_KEY_parenright }, 0x3251}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_2, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_3, SCIM_KEY_parenright }, 0x3253}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_4, SCIM_KEY_parenright }, 0x3254}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_5, SCIM_KEY_parenright }, 0x3255}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_6, SCIM_KEY_parenright }, 0x3256}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_7, SCIM_KEY_parenright }, 0x3257}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_8, SCIM_KEY_parenright }, 0x3258}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_9, SCIM_KEY_parenright }, 0x3259}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x2473}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x3251}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x3252}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x3253}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x3254}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x3255}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x3256}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x3257}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x3258}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_2, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x3259}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_parenright, 0 }, 0x2462}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_0, SCIM_KEY_parenright }, 0x325A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_1, SCIM_KEY_parenright }, 0x325B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_2, SCIM_KEY_parenright }, 0x325C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_3, SCIM_KEY_parenright }, 0x325D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_4, SCIM_KEY_parenright }, 0x325E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_5, SCIM_KEY_parenright }, 0x325F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_6, SCIM_KEY_parenright }, 0x32B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_7, SCIM_KEY_parenright }, 0x32B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_8, SCIM_KEY_parenright }, 0x32B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_9, SCIM_KEY_parenright }, 0x32B4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x325C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x325A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x325B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x325C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x325D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x325E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x325F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x32B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x32B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x32B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_3, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x32B4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_parenright, 0 }, 0x2463}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_0, SCIM_KEY_parenright }, 0x32B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_1, SCIM_KEY_parenright }, 0x32B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_2, SCIM_KEY_parenright }, 0x32B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_3, SCIM_KEY_parenright }, 0x32B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_4, SCIM_KEY_parenright }, 0x32B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_5, SCIM_KEY_parenright }, 0x32BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_6, SCIM_KEY_parenright }, 0x32BB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_7, SCIM_KEY_parenright }, 0x32BC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_8, SCIM_KEY_parenright }, 0x32BD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_9, SCIM_KEY_parenright }, 0x32BE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_Space, SCIM_KEY_parenright }, 0x32B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x32B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_1, SCIM_KEY_parenright }, 0x32B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_2, SCIM_KEY_parenright }, 0x32B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_3, SCIM_KEY_parenright }, 0x32B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_4, SCIM_KEY_parenright }, 0x32B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_5, SCIM_KEY_parenright }, 0x32BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_6, SCIM_KEY_parenright }, 0x32BB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_7, SCIM_KEY_parenright }, 0x32BC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_8, SCIM_KEY_parenright }, 0x32BD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_4, SCIM_KEY_KP_9, SCIM_KEY_parenright }, 0x32BE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_5, SCIM_KEY_parenright, 0 }, 0x2464}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_5, SCIM_KEY_0, SCIM_KEY_parenright }, 0x32BF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_5, SCIM_KEY_KP_0, SCIM_KEY_parenright }, 0x32BF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_6, SCIM_KEY_parenright, 0 }, 0x2465}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_7, SCIM_KEY_parenright, 0 }, 0x2466}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_8, SCIM_KEY_parenright, 0 }, 0x2467}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_KP_9, SCIM_KEY_parenright, 0 }, 0x2468}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001100, SCIM_KEY_parenright, 0 }, 0x3260}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001100, 0x1001161, SCIM_KEY_parenright }, 0x326E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001102, SCIM_KEY_parenright, 0 }, 0x3261}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001102, 0x1001161, SCIM_KEY_parenright }, 0x326F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001103, SCIM_KEY_parenright, 0 }, 0x3262}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001103, 0x1001161, SCIM_KEY_parenright }, 0x3270}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001105, SCIM_KEY_parenright, 0 }, 0x3263}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001105, 0x1001161, SCIM_KEY_parenright }, 0x3271}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001106, SCIM_KEY_parenright, 0 }, 0x3264}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001106, 0x1001161, SCIM_KEY_parenright }, 0x3272}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001107, SCIM_KEY_parenright, 0 }, 0x3265}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001107, 0x1001161, SCIM_KEY_parenright }, 0x3273}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001109, SCIM_KEY_parenright, 0 }, 0x3266}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001109, 0x1001161, SCIM_KEY_parenright }, 0x3274}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110b, SCIM_KEY_parenright, 0 }, 0x3267}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110b, 0x1001161, SCIM_KEY_parenright }, 0x3275}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110c, SCIM_KEY_parenright, 0 }, 0x3268}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110c, 0x1001161, SCIM_KEY_parenright }, 0x3276}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110e, SCIM_KEY_parenright, 0 }, 0x3269}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110e, 0x1001161, SCIM_KEY_parenright }, 0x3277}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110f, SCIM_KEY_parenright, 0 }, 0x326A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100110f, 0x1001161, SCIM_KEY_parenright }, 0x3278}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001110, SCIM_KEY_parenright, 0 }, 0x326B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001110, 0x1001161, SCIM_KEY_parenright }, 0x3279}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001111, SCIM_KEY_parenright, 0 }, 0x326C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001111, 0x1001161, SCIM_KEY_parenright }, 0x327A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001112, SCIM_KEY_parenright, 0 }, 0x326D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1001112, 0x1001161, SCIM_KEY_parenright }, 0x327B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10030f0, SCIM_KEY_parenright, 0 }, 0x32FC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10030f1, SCIM_KEY_parenright, 0 }, 0x32FD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e00, SCIM_KEY_parenright, 0 }, 0x3280}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e03, SCIM_KEY_parenright, 0 }, 0x3286}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e09, SCIM_KEY_parenright, 0 }, 0x3282}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e0a, SCIM_KEY_parenright, 0 }, 0x32A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e0b, SCIM_KEY_parenright, 0 }, 0x32A6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e2d, SCIM_KEY_parenright, 0 }, 0x32A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e5d, SCIM_KEY_parenright, 0 }, 0x3288}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e8c, SCIM_KEY_parenright, 0 }, 0x3281}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004e94, SCIM_KEY_parenright, 0 }, 0x3284}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004f01, SCIM_KEY_parenright, 0 }, 0x32AD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1004f11, SCIM_KEY_parenright, 0 }, 0x32A1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100512a, SCIM_KEY_parenright, 0 }, 0x329D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100516b, SCIM_KEY_parenright, 0 }, 0x3287}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100516d, SCIM_KEY_parenright, 0 }, 0x3285}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005199, SCIM_KEY_parenright, 0 }, 0x32A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10052b4, SCIM_KEY_parenright, 0 }, 0x3298}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100533b, SCIM_KEY_parenright, 0 }, 0x32A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005341, SCIM_KEY_parenright, 0 }, 0x3289}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005354, SCIM_KEY_parenright, 0 }, 0x32AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005370, SCIM_KEY_parenright, 0 }, 0x329E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10053f3, SCIM_KEY_parenright, 0 }, 0x32A8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100540d, SCIM_KEY_parenright, 0 }, 0x3294}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10056db, SCIM_KEY_parenright, 0 }, 0x3283}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100571f, SCIM_KEY_parenright, 0 }, 0x328F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100591c, SCIM_KEY_parenright, 0 }, 0x32B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005973, SCIM_KEY_parenright, 0 }, 0x329B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005b66, SCIM_KEY_parenright, 0 }, 0x32AB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005b97, SCIM_KEY_parenright, 0 }, 0x32AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1005de6, SCIM_KEY_parenright, 0 }, 0x32A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10065e5, SCIM_KEY_parenright, 0 }, 0x3290}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1006708, SCIM_KEY_parenright, 0 }, 0x328A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1006709, SCIM_KEY_parenright, 0 }, 0x3292}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1006728, SCIM_KEY_parenright, 0 }, 0x328D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100682a, SCIM_KEY_parenright, 0 }, 0x3291}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1006b63, SCIM_KEY_parenright, 0 }, 0x32A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1006c34, SCIM_KEY_parenright, 0 }, 0x328C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1006ce8, SCIM_KEY_parenright, 0 }, 0x329F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100706b, SCIM_KEY_parenright, 0 }, 0x328B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1007279, SCIM_KEY_parenright, 0 }, 0x3295}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1007537, SCIM_KEY_parenright, 0 }, 0x329A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10076e3, SCIM_KEY_parenright, 0 }, 0x32AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100793e, SCIM_KEY_parenright, 0 }, 0x3293}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x100795d, SCIM_KEY_parenright, 0 }, 0x3297}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10079d8, SCIM_KEY_parenright, 0 }, 0x3299}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1008ca1, SCIM_KEY_parenright, 0 }, 0x3296}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1008cc7, SCIM_KEY_parenright, 0 }, 0x32AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1009069, SCIM_KEY_parenright, 0 }, 0x329C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x10091d1, SCIM_KEY_parenright, 0 }, 0x328E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenleft, 0x1009805, SCIM_KEY_parenright, 0 }, 0x32A0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_parenright, 0, 0 }, 0x005D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_minus, 0, 0 }, 0x007D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F08}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1F18}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F28}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1F48}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F68}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F00}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F10}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F20}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F30}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F40}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_rho, 0, 0 }, 0x1FE4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F50}, + {{SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F60}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asterisk, SCIM_KEY_0, 0, 0 }, 0x00B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asterisk, SCIM_KEY_A, 0, 0 }, 0x00C5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asterisk, SCIM_KEY_U, 0, 0 }, 0x016E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asterisk, SCIM_KEY_a, 0, 0 }, 0x00E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asterisk, SCIM_KEY_u, 0, 0 }, 0x016F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_plus, 0, 0 }, 0x0023}, + {{SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_minus, 0, 0 }, 0x00B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_O, 0, 0 }, 0x01A0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_U, 0, 0 }, 0x01AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_o, 0, 0 }, 0x01A1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_plus, SCIM_KEY_u, 0, 0 }, 0x01B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_space, 0, 0 }, 0x00B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_quotedbl, 0, 0 }, 0x201E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_apostrophe, 0, 0 }, 0x201A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_comma, 0, 0 }, 0x00B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_minus, 0, 0 }, 0x00AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_A, 0, 0 }, 0x0104}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_C, 0, 0 }, 0x00C7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_D, 0, 0 }, 0x1E10}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_E, 0, 0 }, 0x0228}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_G, 0, 0 }, 0x0122}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_H, 0, 0 }, 0x1E28}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_I, 0, 0 }, 0x012E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_K, 0, 0 }, 0x0136}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_L, 0, 0 }, 0x013B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_N, 0, 0 }, 0x0145}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_R, 0, 0 }, 0x0156}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_S, 0, 0 }, 0x015E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_T, 0, 0 }, 0x0162}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_U, 0, 0 }, 0x0172}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_a, 0, 0 }, 0x0105}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_c, 0, 0 }, 0x00E7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_d, 0, 0 }, 0x1E11}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_e, 0, 0 }, 0x0229}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_g, 0, 0 }, 0x0123}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_h, 0, 0 }, 0x1E29}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_i, 0, 0 }, 0x012F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_k, 0, 0 }, 0x0137}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_l, 0, 0 }, 0x013C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_n, 0, 0 }, 0x0146}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_r, 0, 0 }, 0x0157}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_s, 0, 0 }, 0x015F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_t, 0, 0 }, 0x0163}, + {{SCIM_KEY_Multi_key, SCIM_KEY_comma, SCIM_KEY_u, 0, 0 }, 0x0173}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_space, 0, 0 }, 0x007E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_parenleft, 0, 0 }, 0x007B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_parenright, 0, 0 }, 0x007D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_plus, 0, 0 }, 0x00B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_comma, 0, 0 }, 0x00AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_minus, SCIM_KEY_space, 0 }, 0x00AD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_minus, SCIM_KEY_minus, 0 }, 0x2014}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_minus, SCIM_KEY_period, 0 }, 0x2013}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_colon, 0, 0 }, 0x00F7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_A, 0, 0 }, 0x0100}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_D, 0, 0 }, 0x0110}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_E, 0, 0 }, 0x0112}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_I, 0, 0 }, 0x012A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_L, 0, 0 }, 0x00A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_N, 0, 0 }, 0x00D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_O, 0, 0 }, 0x014C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_U, 0, 0 }, 0x016A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_Y, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_asciicircum, 0, 0 }, 0x00AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_a, 0, 0 }, 0x0101}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_d, 0, 0 }, 0x0111}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_e, 0, 0 }, 0x0113}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_i, 0, 0 }, 0x012B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_l, 0, 0 }, 0x00A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_n, 0, 0 }, 0x00F1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_o, 0, 0 }, 0x014D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_u, 0, 0 }, 0x016B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_minus, SCIM_KEY_y, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_exclam, SCIM_KEY_S, 0 }, 0x1E68}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_exclam, SCIM_KEY_s, 0 }, 0x1E69}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_apostrophe, SCIM_KEY_S, 0 }, 0x1E64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_apostrophe, SCIM_KEY_s, 0 }, 0x1E65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_period, 0, 0 }, 0x00B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_less, 0, 0 }, 0x2039}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_greater, 0, 0 }, 0x203A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_A, 0, 0 }, 0x0226}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_B, 0, 0 }, 0x1E02}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_C, 0, 0 }, 0x010A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_D, 0, 0 }, 0x1E0A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_E, 0, 0 }, 0x0116}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_F, 0, 0 }, 0x1E1E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_G, 0, 0 }, 0x0120}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_H, 0, 0 }, 0x1E22}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_I, 0, 0 }, 0x0130}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_M, 0, 0 }, 0x1E40}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_N, 0, 0 }, 0x1E44}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_O, 0, 0 }, 0x022E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_P, 0, 0 }, 0x1E56}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_R, 0, 0 }, 0x1E58}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_S, 0, 0 }, 0x1E60}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_T, 0, 0 }, 0x1E6A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_W, 0, 0 }, 0x1E86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_X, 0, 0 }, 0x1E8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_Y, 0, 0 }, 0x1E8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_Z, 0, 0 }, 0x017B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_asciicircum, 0, 0 }, 0x00B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_a, 0, 0 }, 0x0227}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_b, 0, 0 }, 0x1E03}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_c, 0, 0 }, 0x010B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_c, SCIM_KEY_S, 0 }, 0x1E66}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_c, SCIM_KEY_s, 0 }, 0x1E67}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_d, 0, 0 }, 0x1E0B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_e, 0, 0 }, 0x0117}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_f, 0, 0 }, 0x1E1F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_g, 0, 0 }, 0x0121}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_h, 0, 0 }, 0x1E23}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_i, 0, 0 }, 0x0131}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_m, 0, 0 }, 0x1E41}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_n, 0, 0 }, 0x1E45}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_o, 0, 0 }, 0x022F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_p, 0, 0 }, 0x1E57}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_r, 0, 0 }, 0x1E59}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_s, 0, 0 }, 0x1E61}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_t, 0, 0 }, 0x1E6B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_w, 0, 0 }, 0x1E87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_x, 0, 0 }, 0x1E8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_y, 0, 0 }, 0x1E8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_z, 0, 0 }, 0x017C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_acute, SCIM_KEY_S, 0 }, 0x1E64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_acute, SCIM_KEY_s, 0 }, 0x1E65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_Sacute, 0, 0 }, 0x1E64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_Scaron, 0, 0 }, 0x1E66}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_sacute, 0, 0 }, 0x1E65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_scaron, 0, 0 }, 0x1E67}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_combining_acute, SCIM_KEY_S, 0 }, 0x1E64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_combining_acute, SCIM_KEY_s, 0 }, 0x1E65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_combining_belowdot, SCIM_KEY_S, 0 }, 0x1E68}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_combining_belowdot, SCIM_KEY_s, 0 }, 0x1E69}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_dead_acute, SCIM_KEY_S, 0 }, 0x1E64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_dead_acute, SCIM_KEY_s, 0 }, 0x1E65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_dead_caron, SCIM_KEY_S, 0 }, 0x1E66}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_dead_caron, SCIM_KEY_s, 0 }, 0x1E67}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_dead_belowdot, SCIM_KEY_S, 0 }, 0x1E68}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, SCIM_KEY_dead_belowdot, SCIM_KEY_s, 0 }, 0x1E69}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, 0x100017f, 0, 0 }, 0x1E9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, 0x1001e62, 0, 0 }, 0x1E68}, + {{SCIM_KEY_Multi_key, SCIM_KEY_period, 0x1001e63, 0, 0 }, 0x1E69}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_slash, 0, 0 }, 0x005C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_less, 0, 0 }, 0x005C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_C, 0, 0 }, 0x20A1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_D, 0, 0 }, 0x0110}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_G, 0, 0 }, 0x01E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_H, 0, 0 }, 0x0126}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_I, 0, 0 }, 0x0197}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_L, 0, 0 }, 0x0141}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_O, 0, 0 }, 0x00D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_T, 0, 0 }, 0x0166}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_U, 0, 0 }, 0x00B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_Z, 0, 0 }, 0x01B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_asciicircum, 0, 0 }, 0x007C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_b, 0, 0 }, 0x0180}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_c, 0, 0 }, 0x00A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_d, 0, 0 }, 0x0111}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_g, 0, 0 }, 0x01E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_h, 0, 0 }, 0x0127}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_i, 0, 0 }, 0x0268}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_l, 0, 0 }, 0x0142}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_m, 0, 0 }, 0x20A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_o, 0, 0 }, 0x00F8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_t, 0, 0 }, 0x0167}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_u, 0, 0 }, 0x00B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_z, 0, 0 }, 0x01B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_Cyrillic_ghe, 0, 0 }, 0x0493}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_Cyrillic_ka, 0, 0 }, 0x049F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_Cyrillic_GHE, 0, 0 }, 0x0492}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_Cyrillic_KA, 0, 0 }, 0x049E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_leftarrow, 0, 0 }, 0x219A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, SCIM_KEY_rightarrow, 0, 0 }, 0x219B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, 0x1000294, 0, 0 }, 0x02A1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, 0x10004ae, 0, 0 }, 0x04B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, 0x10004af, 0, 0 }, 0x04B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_slash, 0x1002194, 0, 0 }, 0x21AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_asterisk, 0, 0 }, 0x00B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_C, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_S, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_X, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_asciicircum, 0, 0 }, 0x00B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_c, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_s, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_0, SCIM_KEY_x, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_1, SCIM_KEY_2, 0, 0 }, 0x00BD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_1, SCIM_KEY_4, 0, 0 }, 0x00BC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_1, SCIM_KEY_S, 0, 0 }, 0x00B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_1, SCIM_KEY_asciicircum, 0, 0 }, 0x00B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_1, SCIM_KEY_s, 0, 0 }, 0x00B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_2, SCIM_KEY_S, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_2, SCIM_KEY_asciicircum, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_2, SCIM_KEY_s, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_3, SCIM_KEY_4, 0, 0 }, 0x00BE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_3, SCIM_KEY_S, 0, 0 }, 0x00B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_3, SCIM_KEY_asciicircum, 0, 0 }, 0x00B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_3, SCIM_KEY_s, 0, 0 }, 0x00B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_colon, SCIM_KEY_minus, 0, 0 }, 0x00F7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_A, 0, 0 }, 0x0104}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_E, 0, 0 }, 0x0118}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_I, 0, 0 }, 0x012E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_O, 0, 0 }, 0x01EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_U, 0, 0 }, 0x0172}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_a, 0, 0 }, 0x0105}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_e, 0, 0 }, 0x0119}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_i, 0, 0 }, 0x012F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_o, 0, 0 }, 0x01EB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_semicolon, SCIM_KEY_u, 0, 0 }, 0x0173}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_space, 0, 0 }, 0x02C7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_quotedbl, 0, 0 }, 0x201C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_apostrophe, 0, 0 }, 0x2018}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_slash, 0, 0 }, 0x005C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_less, 0, 0 }, 0x00AB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_C, 0, 0 }, 0x010C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_D, 0, 0 }, 0x010E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_E, 0, 0 }, 0x011A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_L, 0, 0 }, 0x013D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_N, 0, 0 }, 0x0147}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_R, 0, 0 }, 0x0158}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_S, 0, 0 }, 0x0160}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_T, 0, 0 }, 0x0164}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_Z, 0, 0 }, 0x017D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_c, 0, 0 }, 0x010D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_d, 0, 0 }, 0x010F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_e, 0, 0 }, 0x011B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_l, 0, 0 }, 0x013E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_n, 0, 0 }, 0x0148}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_r, 0, 0 }, 0x0159}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_s, 0, 0 }, 0x0161}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_t, 0, 0 }, 0x0165}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, SCIM_KEY_z, 0, 0 }, 0x017E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_less, 0x1000338, 0, 0 }, 0x226E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_C, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_E, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_L, 0, 0 }, 0x20A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_N, 0, 0 }, 0x20A6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_O, 0, 0 }, 0x0150}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_U, 0, 0 }, 0x0170}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_W, 0, 0 }, 0x20A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_Y, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_c, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_e, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_l, 0, 0 }, 0x00A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_o, 0, 0 }, 0x0151}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_u, 0, 0 }, 0x0171}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_y, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_Cyrillic_u, 0, 0 }, 0x04F3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, SCIM_KEY_Cyrillic_U, 0, 0 }, 0x04F2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_equal, 0x1000338, 0, 0 }, 0x2260}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_space, 0, 0 }, 0x005E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_quotedbl, 0, 0 }, 0x201D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_apostrophe, 0, 0 }, 0x2019}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_greater, 0, 0 }, 0x00BB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_A, 0, 0 }, 0x00C2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_E, 0, 0 }, 0x00CA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_I, 0, 0 }, 0x00CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_O, 0, 0 }, 0x00D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_U, 0, 0 }, 0x00DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_a, 0, 0 }, 0x00E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_e, 0, 0 }, 0x00EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_i, 0, 0 }, 0x00EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_o, 0, 0 }, 0x00F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, SCIM_KEY_u, 0, 0 }, 0x00FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greater, 0x1000338, 0, 0 }, 0x226F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_question, 0, 0 }, 0x00BF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_A, 0, 0 }, 0x1EA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_E, 0, 0 }, 0x1EBA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_I, 0, 0 }, 0x1EC8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_O, 0, 0 }, 0x1ECE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_U, 0, 0 }, 0x1EE6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_Y, 0, 0 }, 0x1EF6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_a, 0, 0 }, 0x1EA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_e, 0, 0 }, 0x1EBB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_i, 0, 0 }, 0x1EC9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_o, 0, 0 }, 0x1ECF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_u, 0, 0 }, 0x1EE7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_y, 0, 0 }, 0x1EF7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_Acircumflex, 0, 0 }, 0x1EA8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_Ecircumflex, 0, 0 }, 0x1EC2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_Ocircumflex, 0, 0 }, 0x1ED4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_acircumflex, 0, 0 }, 0x1EA9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_ecircumflex, 0, 0 }, 0x1EC3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_ocircumflex, 0, 0 }, 0x1ED5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_Abreve, 0, 0 }, 0x1EB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_abreve, 0, 0 }, 0x1EB3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_Ohorn, 0, 0 }, 0x1EDE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_ohorn, 0, 0 }, 0x1EDF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_Uhorn, 0, 0 }, 0x1EEC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_uhorn, 0, 0 }, 0x1EED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0 }, 0x1EA8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0 }, 0x1EC2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0 }, 0x1ED4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0 }, 0x1EA9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0 }, 0x1EC3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0 }, 0x1ED5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_breve, SCIM_KEY_A, 0 }, 0x1EB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_breve, SCIM_KEY_a, 0 }, 0x1EB3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_horn, SCIM_KEY_O, 0 }, 0x1EDE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_horn, SCIM_KEY_U, 0 }, 0x1EEC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_horn, SCIM_KEY_o, 0 }, 0x1EDF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_question, SCIM_KEY_dead_horn, SCIM_KEY_u, 0 }, 0x1EED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_quotedbl, 0, 0 }, 0x00C4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_apostrophe, 0, 0 }, 0x00C1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_parenleft, 0, 0 }, 0x0102}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_asterisk, 0, 0 }, 0x00C5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_comma, 0, 0 }, 0x0104}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_minus, 0, 0 }, 0x0100}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_greater, 0, 0 }, 0x00C2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_A, 0, 0 }, 0x00C5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_E, 0, 0 }, 0x00C6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_T, 0, 0 }, 0x0040}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_asciicircum, 0, 0 }, 0x00C2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_underscore, 0, 0 }, 0x00AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_grave, 0, 0 }, 0x00C0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_asciitilde, 0, 0 }, 0x00C3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_diaeresis, 0, 0 }, 0x00C4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_A, SCIM_KEY_acute, 0, 0 }, 0x00C1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_B, SCIM_KEY_period, 0, 0 }, 0x1E02}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_apostrophe, 0, 0 }, 0x0106}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_comma, 0, 0 }, 0x00C7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_period, 0, 0 }, 0x010A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_slash, 0, 0 }, 0x00A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_0, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_less, 0, 0 }, 0x010C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_equal, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_E, 0, 0 }, 0x20A0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_O, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_o, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_r, 0, 0 }, 0x20A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_C, SCIM_KEY_bar, 0, 0 }, 0x00A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_D, SCIM_KEY_minus, 0, 0 }, 0x0110}, + {{SCIM_KEY_Multi_key, SCIM_KEY_D, SCIM_KEY_period, 0, 0 }, 0x1E0A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_D, SCIM_KEY_less, 0, 0 }, 0x010E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_D, SCIM_KEY_H, 0, 0 }, 0x00D0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_quotedbl, 0, 0 }, 0x00CB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_apostrophe, 0, 0 }, 0x00C9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_comma, 0, 0 }, 0x0118}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_minus, 0, 0 }, 0x0112}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_period, 0, 0 }, 0x0116}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_less, 0, 0 }, 0x011A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_equal, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_greater, 0, 0 }, 0x00CA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_asciicircum, 0, 0 }, 0x00CA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_underscore, 0, 0 }, 0x0112}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_grave, 0, 0 }, 0x00C8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_diaeresis, 0, 0 }, 0x00CB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_E, SCIM_KEY_acute, 0, 0 }, 0x00C9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_F, SCIM_KEY_period, 0, 0 }, 0x1E1E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_F, SCIM_KEY_r, 0, 0 }, 0x20A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_G, SCIM_KEY_parenleft, 0, 0 }, 0x011E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_G, SCIM_KEY_comma, 0, 0 }, 0x0122}, + {{SCIM_KEY_Multi_key, SCIM_KEY_G, SCIM_KEY_period, 0, 0 }, 0x0120}, + {{SCIM_KEY_Multi_key, SCIM_KEY_G, SCIM_KEY_U, 0, 0 }, 0x011E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_G, SCIM_KEY_breve, 0, 0 }, 0x011E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_quotedbl, 0, 0 }, 0x00CF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_apostrophe, 0, 0 }, 0x00CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_comma, 0, 0 }, 0x012E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_minus, 0, 0 }, 0x012A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_period, 0, 0 }, 0x0130}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_greater, 0, 0 }, 0x00CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_asciicircum, 0, 0 }, 0x00CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_underscore, 0, 0 }, 0x012A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_grave, 0, 0 }, 0x00CC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_asciitilde, 0, 0 }, 0x0128}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_diaeresis, 0, 0 }, 0x00CF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_I, SCIM_KEY_acute, 0, 0 }, 0x00CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_K, SCIM_KEY_comma, 0, 0 }, 0x0136}, + {{SCIM_KEY_Multi_key, SCIM_KEY_L, SCIM_KEY_apostrophe, 0, 0 }, 0x0139}, + {{SCIM_KEY_Multi_key, SCIM_KEY_L, SCIM_KEY_comma, 0, 0 }, 0x013B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_L, SCIM_KEY_minus, 0, 0 }, 0x00A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_L, SCIM_KEY_less, 0, 0 }, 0x013D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_L, SCIM_KEY_equal, 0, 0 }, 0x20A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_L, SCIM_KEY_V, 0, 0 }, 0x007C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_M, SCIM_KEY_period, 0, 0 }, 0x1E40}, + {{SCIM_KEY_Multi_key, SCIM_KEY_N, SCIM_KEY_apostrophe, 0, 0 }, 0x0143}, + {{SCIM_KEY_Multi_key, SCIM_KEY_N, SCIM_KEY_comma, 0, 0 }, 0x0145}, + {{SCIM_KEY_Multi_key, SCIM_KEY_N, SCIM_KEY_minus, 0, 0 }, 0x00D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_N, SCIM_KEY_less, 0, 0 }, 0x0147}, + {{SCIM_KEY_Multi_key, SCIM_KEY_N, SCIM_KEY_equal, 0, 0 }, 0x20A6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_N, SCIM_KEY_G, 0, 0 }, 0x014A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_N, SCIM_KEY_asciitilde, 0, 0 }, 0x00D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_quotedbl, 0, 0 }, 0x00D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_apostrophe, 0, 0 }, 0x00D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_minus, 0, 0 }, 0x014C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_slash, 0, 0 }, 0x00D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_greater, 0, 0 }, 0x00D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_C, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_E, 0, 0 }, 0x0152}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_R, 0, 0 }, 0x00AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_S, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_X, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_asciicircum, 0, 0 }, 0x00D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_underscore, 0, 0 }, 0x00BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_grave, 0, 0 }, 0x00D2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_c, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_r, 0, 0 }, 0x00AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_x, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_asciitilde, 0, 0 }, 0x00D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_diaeresis, 0, 0 }, 0x00D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_O, SCIM_KEY_acute, 0, 0 }, 0x00D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_P, SCIM_KEY_exclam, 0, 0 }, 0x00B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_P, SCIM_KEY_period, 0, 0 }, 0x1E56}, + {{SCIM_KEY_Multi_key, SCIM_KEY_P, SCIM_KEY_P, 0, 0 }, 0x00B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_P, SCIM_KEY_t, 0, 0 }, 0x20A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_R, SCIM_KEY_apostrophe, 0, 0 }, 0x0154}, + {{SCIM_KEY_Multi_key, SCIM_KEY_R, SCIM_KEY_comma, 0, 0 }, 0x0156}, + {{SCIM_KEY_Multi_key, SCIM_KEY_R, SCIM_KEY_less, 0, 0 }, 0x0158}, + {{SCIM_KEY_Multi_key, SCIM_KEY_R, SCIM_KEY_O, 0, 0 }, 0x00AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_R, SCIM_KEY_s, 0, 0 }, 0x20A8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_exclam, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_apostrophe, 0, 0 }, 0x015A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_comma, 0, 0 }, 0x015E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_period, 0, 0 }, 0x1E60}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_0, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_1, 0, 0 }, 0x00B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_2, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_3, 0, 0 }, 0x00B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_less, 0, 0 }, 0x0160}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_O, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_S, SCIM_KEY_cedilla, 0, 0 }, 0x015E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_T, SCIM_KEY_minus, 0, 0 }, 0x0166}, + {{SCIM_KEY_Multi_key, SCIM_KEY_T, SCIM_KEY_period, 0, 0 }, 0x1E6A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_T, SCIM_KEY_slash, 0, 0 }, 0x0166}, + {{SCIM_KEY_Multi_key, SCIM_KEY_T, SCIM_KEY_less, 0, 0 }, 0x0164}, + {{SCIM_KEY_Multi_key, SCIM_KEY_T, SCIM_KEY_H, 0, 0 }, 0x00DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_exclam, SCIM_KEY_A, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_exclam, SCIM_KEY_a, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_quotedbl, 0, 0 }, 0x00DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_apostrophe, 0, 0 }, 0x00DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_asterisk, 0, 0 }, 0x016E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_comma, 0, 0 }, 0x0172}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_comma, SCIM_KEY_E, 0 }, 0x1E1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_comma, SCIM_KEY_e, 0 }, 0x1E1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_minus, 0, 0 }, 0x016B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_slash, 0, 0 }, 0x00B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_greater, 0, 0 }, 0x00DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_A, 0, 0 }, 0x0102}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_E, 0, 0 }, 0x0114}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_G, 0, 0 }, 0x011E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_I, 0, 0 }, 0x012C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_O, 0, 0 }, 0x014E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_U, 0, 0 }, 0x016C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_asciicircum, 0, 0 }, 0x00DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_underscore, 0, 0 }, 0x016B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_grave, 0, 0 }, 0x00D9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_a, 0, 0 }, 0x0103}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_e, 0, 0 }, 0x0115}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_g, 0, 0 }, 0x011F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_i, 0, 0 }, 0x012D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_o, 0, 0 }, 0x014F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_u, 0, 0 }, 0x016D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_asciitilde, 0, 0 }, 0x0168}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_diaeresis, 0, 0 }, 0x00DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_acute, 0, 0 }, 0x00DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_a, 0, 0 }, 0x04D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_ie, 0, 0 }, 0x04D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_i, 0, 0 }, 0x0439}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_u, 0, 0 }, 0x045E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_zhe, 0, 0 }, 0x04C2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_A, 0, 0 }, 0x04D0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_IE, 0, 0 }, 0x04D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_I, 0, 0 }, 0x0419}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_U, 0, 0 }, 0x040E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Cyrillic_ZHE, 0, 0 }, 0x04C1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1FB8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1FD8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1FE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_combining_belowdot, SCIM_KEY_A, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_combining_belowdot, SCIM_KEY_a, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_dead_cedilla, SCIM_KEY_E, 0 }, 0x1E1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_dead_cedilla, SCIM_KEY_e, 0 }, 0x1E1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_dead_belowdot, SCIM_KEY_A, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, SCIM_KEY_dead_belowdot, SCIM_KEY_a, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, 0x1000228, 0, 0 }, 0x1E1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, 0x1000229, 0, 0 }, 0x1E1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, 0x1001ea0, 0, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_U, 0x1001ea1, 0, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_V, SCIM_KEY_L, 0, 0 }, 0x007C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_W, SCIM_KEY_equal, 0, 0 }, 0x20A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_W, SCIM_KEY_asciicircum, 0, 0 }, 0x0174}, + {{SCIM_KEY_Multi_key, SCIM_KEY_X, SCIM_KEY_0, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_X, SCIM_KEY_O, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_X, SCIM_KEY_o, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Y, SCIM_KEY_quotedbl, 0, 0 }, 0x0178}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Y, SCIM_KEY_apostrophe, 0, 0 }, 0x00DD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Y, SCIM_KEY_minus, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Y, SCIM_KEY_equal, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Y, SCIM_KEY_asciicircum, 0, 0 }, 0x0176}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Y, SCIM_KEY_diaeresis, 0, 0 }, 0x0178}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Y, SCIM_KEY_acute, 0, 0 }, 0x00DD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Z, SCIM_KEY_apostrophe, 0, 0 }, 0x0179}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Z, SCIM_KEY_period, 0, 0 }, 0x017B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Z, SCIM_KEY_less, 0, 0 }, 0x017D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_space, 0, 0 }, 0x005E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_exclam, SCIM_KEY_A, 0 }, 0x1EAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_exclam, SCIM_KEY_E, 0 }, 0x1EC6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_exclam, SCIM_KEY_O, 0 }, 0x1ED8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_exclam, SCIM_KEY_a, 0 }, 0x1EAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_exclam, SCIM_KEY_e, 0 }, 0x1EC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_exclam, SCIM_KEY_o, 0 }, 0x1ED9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_parenleft, 0, 0 }, 0x207D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_parenright, 0, 0 }, 0x207E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_plus, 0, 0 }, 0x207A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_minus, 0, 0 }, 0x00AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_period, 0, 0 }, 0x00B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_slash, 0, 0 }, 0x007C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_0, 0, 0 }, 0x2070}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_1, 0, 0 }, 0x00B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_2, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_3, 0, 0 }, 0x00B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_4, 0, 0 }, 0x2074}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_5, 0, 0 }, 0x2075}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_6, 0, 0 }, 0x2076}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_7, 0, 0 }, 0x2077}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_8, 0, 0 }, 0x2078}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_9, 0, 0 }, 0x2079}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_equal, 0, 0 }, 0x207C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_A, 0, 0 }, 0x00C2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_C, 0, 0 }, 0x0108}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_E, 0, 0 }, 0x00CA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_G, 0, 0 }, 0x011C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_H, 0, 0 }, 0x0124}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_I, 0, 0 }, 0x00CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_J, 0, 0 }, 0x0134}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_O, 0, 0 }, 0x00D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_S, 0, 0 }, 0x015C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_S, SCIM_KEY_M, 0 }, 0x2120}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_T, SCIM_KEY_M, 0 }, 0x2122}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_U, 0, 0 }, 0x00DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_W, 0, 0 }, 0x0174}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_Y, 0, 0 }, 0x0176}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_Z, 0, 0 }, 0x1E90}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, 0, 0 }, 0x00AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_a, 0 }, 0x00AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_h, 0 }, 0x02B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_i, 0 }, 0x2071}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_j, 0 }, 0x02B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_l, 0 }, 0x02E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_n, 0 }, 0x207F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x00BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_r, 0 }, 0x02B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_s, 0 }, 0x02E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_w, 0 }, 0x02B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_x, 0 }, 0x02E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, SCIM_KEY_y, 0 }, 0x02B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, 0x1000263, 0 }, 0x02E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, 0x1000266, 0 }, 0x02B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, 0x1000279, 0 }, 0x02B4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, 0x100027b, 0 }, 0x02B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, 0x1000281, 0 }, 0x02B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underscore, 0x1000295, 0 }, 0x02E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_a, 0, 0 }, 0x00E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_c, 0, 0 }, 0x0109}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_e, 0, 0 }, 0x00EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_g, 0, 0 }, 0x011D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_h, 0, 0 }, 0x0125}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_i, 0, 0 }, 0x00EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_j, 0, 0 }, 0x0135}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_o, 0, 0 }, 0x00F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_s, 0, 0 }, 0x015D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_u, 0, 0 }, 0x00FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_w, 0, 0 }, 0x0175}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_y, 0, 0 }, 0x0177}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_z, 0, 0 }, 0x1E91}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_a, 0 }, 0x00AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_h, 0 }, 0x02B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_i, 0 }, 0x2071}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_j, 0 }, 0x02B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_l, 0 }, 0x02E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_n, 0 }, 0x207F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_o, 0 }, 0x00BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_r, 0 }, 0x02B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_s, 0 }, 0x02E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_w, 0 }, 0x02B7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_x, 0 }, 0x02E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, SCIM_KEY_y, 0 }, 0x02B8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, 0x1000263, 0 }, 0x02E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, 0x1000266, 0 }, 0x02B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, 0x1000279, 0 }, 0x02B4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, 0x100027b, 0 }, 0x02B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, 0x1000281, 0 }, 0x02B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_underbar, 0x1000295, 0 }, 0x02E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_combining_belowdot, SCIM_KEY_A, 0 }, 0x1EAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_combining_belowdot, SCIM_KEY_E, 0 }, 0x1EC6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_combining_belowdot, SCIM_KEY_O, 0 }, 0x1ED8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_combining_belowdot, SCIM_KEY_a, 0 }, 0x1EAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_combining_belowdot, SCIM_KEY_e, 0 }, 0x1EC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_combining_belowdot, SCIM_KEY_o, 0 }, 0x1ED9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_dead_belowdot, SCIM_KEY_A, 0 }, 0x1EAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_dead_belowdot, SCIM_KEY_E, 0 }, 0x1EC6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_dead_belowdot, SCIM_KEY_O, 0 }, 0x1ED8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_dead_belowdot, SCIM_KEY_a, 0 }, 0x1EAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_dead_belowdot, SCIM_KEY_e, 0 }, 0x1EC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_dead_belowdot, SCIM_KEY_o, 0 }, 0x1ED9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_Space, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_Add, 0, 0 }, 0x207A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_0, 0, 0 }, 0x2070}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_1, 0, 0 }, 0x00B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_2, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_3, 0, 0 }, 0x00B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_4, 0, 0 }, 0x2074}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_5, 0, 0 }, 0x2075}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_6, 0, 0 }, 0x2076}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_7, 0, 0 }, 0x2077}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_8, 0, 0 }, 0x2078}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_9, 0, 0 }, 0x2079}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, SCIM_KEY_KP_Equal, 0, 0 }, 0x207C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1001ea0, 0, 0 }, 0x1EAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1001ea1, 0, 0 }, 0x1EAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1001eb8, 0, 0 }, 0x1EC6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1001eb9, 0, 0 }, 0x1EC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1001ecc, 0, 0 }, 0x1ED8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1001ecd, 0, 0 }, 0x1ED9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1002212, 0, 0 }, 0x207B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e00, 0, 0 }, 0x3192}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e01, 0, 0 }, 0x319C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e09, 0, 0 }, 0x3194}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e0a, 0, 0 }, 0x3196}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e0b, 0, 0 }, 0x3198}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e19, 0, 0 }, 0x319B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e2d, 0, 0 }, 0x3197}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e59, 0, 0 }, 0x319A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004e8c, 0, 0 }, 0x3193}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1004eba, 0, 0 }, 0x319F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x10056db, 0, 0 }, 0x3195}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1005730, 0, 0 }, 0x319E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1005929, 0, 0 }, 0x319D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciicircum, 0x1007532, 0, 0 }, 0x3199}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_exclam, SCIM_KEY_L, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_exclam, SCIM_KEY_R, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_exclam, SCIM_KEY_l, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_exclam, SCIM_KEY_r, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_quotedbl, SCIM_KEY_A, 0 }, 0x01DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_quotedbl, SCIM_KEY_O, 0 }, 0x022A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_quotedbl, SCIM_KEY_a, 0 }, 0x01DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_quotedbl, SCIM_KEY_o, 0 }, 0x022B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_parenleft, 0, 0 }, 0x208D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_parenright, 0, 0 }, 0x208E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_plus, 0, 0 }, 0x208A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_period, SCIM_KEY_A, 0 }, 0x01E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_period, SCIM_KEY_O, 0 }, 0x0230}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_period, SCIM_KEY_a, 0 }, 0x01E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_period, SCIM_KEY_o, 0 }, 0x0231}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_0, 0, 0 }, 0x2080}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_1, 0, 0 }, 0x2081}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_2, 0, 0 }, 0x2082}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_3, 0, 0 }, 0x2083}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_4, 0, 0 }, 0x2084}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_5, 0, 0 }, 0x2085}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_6, 0, 0 }, 0x2086}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_7, 0, 0 }, 0x2087}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_8, 0, 0 }, 0x2088}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_9, 0, 0 }, 0x2089}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_semicolon, SCIM_KEY_O, 0 }, 0x01EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_semicolon, SCIM_KEY_o, 0 }, 0x01ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_equal, 0, 0 }, 0x208C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_A, 0, 0 }, 0x00AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_E, 0, 0 }, 0x0112}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_G, 0, 0 }, 0x1E20}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_I, 0, 0 }, 0x012A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_O, 0, 0 }, 0x00BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_U, 0, 0 }, 0x016A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Y, 0, 0 }, 0x0232}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_asciicircum, 0, 0 }, 0x00AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_underscore, 0, 0 }, 0x00AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_a, 0, 0 }, 0x0101}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_e, 0, 0 }, 0x0113}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_g, 0, 0 }, 0x1E21}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_i, 0, 0 }, 0x012B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_o, 0, 0 }, 0x014D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_u, 0, 0 }, 0x016B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_y, 0, 0 }, 0x0233}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Adiaeresis, 0, 0 }, 0x01DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_AE, 0, 0 }, 0x01E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Otilde, 0, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Odiaeresis, 0, 0 }, 0x022A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Udiaeresis, 0, 0 }, 0x01D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_adiaeresis, 0, 0 }, 0x01DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_ae, 0, 0 }, 0x01E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_otilde, 0, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_odiaeresis, 0, 0 }, 0x022B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_udiaeresis, 0, 0 }, 0x01D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Cyrillic_i, 0, 0 }, 0x04E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Cyrillic_u, 0, 0 }, 0x04EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Cyrillic_I, 0, 0 }, 0x04E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Cyrillic_U, 0, 0 }, 0x04EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1FB9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1FD9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1FE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_combining_belowdot, SCIM_KEY_L, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_combining_belowdot, SCIM_KEY_R, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_combining_belowdot, SCIM_KEY_l, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_combining_belowdot, SCIM_KEY_r, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_abovedot, SCIM_KEY_A, 0 }, 0x01E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_abovedot, SCIM_KEY_O, 0 }, 0x0230}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_abovedot, SCIM_KEY_a, 0 }, 0x01E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_abovedot, SCIM_KEY_o, 0 }, 0x0231}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_diaeresis, SCIM_KEY_A, 0 }, 0x01DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_diaeresis, SCIM_KEY_O, 0 }, 0x022A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0 }, 0x01D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_diaeresis, SCIM_KEY_a, 0 }, 0x01DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_diaeresis, SCIM_KEY_o, 0 }, 0x022B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0 }, 0x01D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_ogonek, SCIM_KEY_O, 0 }, 0x01EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_ogonek, SCIM_KEY_o, 0 }, 0x01ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_belowdot, SCIM_KEY_L, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_belowdot, SCIM_KEY_R, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_belowdot, SCIM_KEY_l, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_dead_belowdot, SCIM_KEY_r, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_Space, 0, 0 }, 0x2082}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_Add, 0, 0 }, 0x208A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_0, 0, 0 }, 0x2080}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_1, 0, 0 }, 0x2081}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_2, 0, 0 }, 0x2082}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_3, 0, 0 }, 0x2083}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_4, 0, 0 }, 0x2084}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_5, 0, 0 }, 0x2085}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_6, 0, 0 }, 0x2086}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_7, 0, 0 }, 0x2087}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_8, 0, 0 }, 0x2088}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_9, 0, 0 }, 0x2089}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, SCIM_KEY_KP_Equal, 0, 0 }, 0x208C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x10001ea, 0, 0 }, 0x01EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x10001eb, 0, 0 }, 0x01ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1000226, 0, 0 }, 0x01E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1000227, 0, 0 }, 0x01E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x100022e, 0, 0 }, 0x0230}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x100022f, 0, 0 }, 0x0231}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1001e36, 0, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1001e37, 0, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1001e5a, 0, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1001e5b, 0, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underscore, 0x1002212, 0, 0 }, 0x208B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_space, 0, 0 }, 0x0060}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x1FD2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F03}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0 }, 0x1F13}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F23}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F33}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0 }, 0x1F43}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F63}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F02}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0 }, 0x1F12}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F22}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F32}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0 }, 0x1F42}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F62}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EEB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_A, 0, 0 }, 0x00C0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_E, 0, 0 }, 0x00C8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_I, 0, 0 }, 0x00CC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_N, 0, 0 }, 0x01F8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_O, 0, 0 }, 0x00D2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_U, 0, 0 }, 0x00D9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_W, 0, 0 }, 0x1E80}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Y, 0, 0 }, 0x1EF2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_underscore, SCIM_KEY_E, 0 }, 0x1E14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_underscore, SCIM_KEY_O, 0 }, 0x1E50}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_underscore, SCIM_KEY_e, 0 }, 0x1E15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x1E51}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_a, 0, 0 }, 0x00E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_e, 0, 0 }, 0x00E8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_i, 0, 0 }, 0x00EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_n, 0, 0 }, 0x01F9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_o, 0, 0 }, 0x00F2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_u, 0, 0 }, 0x00F9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_w, 0, 0 }, 0x1E81}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_y, 0, 0 }, 0x1EF3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_macron, SCIM_KEY_E, 0 }, 0x1E14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_macron, SCIM_KEY_O, 0 }, 0x1E50}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_macron, SCIM_KEY_e, 0 }, 0x1E15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_macron, SCIM_KEY_o, 0 }, 0x1E51}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Acircumflex, 0, 0 }, 0x1EA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Ecircumflex, 0, 0 }, 0x1EC0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Ocircumflex, 0, 0 }, 0x1ED2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Udiaeresis, 0, 0 }, 0x01DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_acircumflex, 0, 0 }, 0x1EA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_ecircumflex, 0, 0 }, 0x1EC1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_ocircumflex, 0, 0 }, 0x1ED3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_udiaeresis, 0, 0 }, 0x01DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Abreve, 0, 0 }, 0x1EB0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_abreve, 0, 0 }, 0x1EB1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Emacron, 0, 0 }, 0x1E14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_emacron, 0, 0 }, 0x1E15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Omacron, 0, 0 }, 0x1E50}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_omacron, 0, 0 }, 0x1E51}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Cyrillic_ie, 0, 0 }, 0x0450}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Cyrillic_i, 0, 0 }, 0x045D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Cyrillic_IE, 0, 0 }, 0x0400}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Cyrillic_I, 0, 0 }, 0x040D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_iotadieresis, 0, 0 }, 0x1FD2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_upsilondieresis, 0, 0 }, 0x1FE2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1FBA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x1FC8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1FCA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1FDA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x1FF8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1FEA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1FFA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F70}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x1F72}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F74}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F76}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_omicron, 0, 0 }, 0x1F78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F7A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F7C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Ohorn, 0, 0 }, 0x1EDC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_ohorn, 0, 0 }, 0x1EDD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_Uhorn, 0, 0 }, 0x1EEA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_uhorn, 0, 0 }, 0x1EEB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0 }, 0x1EA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0 }, 0x1EC0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0 }, 0x1ED2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0 }, 0x1EA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0 }, 0x1EC1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0 }, 0x1ED3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_macron, SCIM_KEY_E, 0 }, 0x1E14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_macron, SCIM_KEY_O, 0 }, 0x1E50}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_macron, SCIM_KEY_e, 0 }, 0x1E15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_macron, SCIM_KEY_o, 0 }, 0x1E51}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_breve, SCIM_KEY_A, 0 }, 0x1EB0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_breve, SCIM_KEY_a, 0 }, 0x1EB1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0 }, 0x01DB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0 }, 0x01DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0 }, 0x1FD2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_horn, SCIM_KEY_O, 0 }, 0x1EDC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_horn, SCIM_KEY_U, 0 }, 0x1EEA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_horn, SCIM_KEY_o, 0 }, 0x1EDD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, SCIM_KEY_dead_horn, SCIM_KEY_u, 0 }, 0x1EEB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F2A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F02}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_epsilon, 0 }, 0x1F12}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F22}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_iota, 0 }, 0x1F32}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_omicron, 0 }, 0x1F42}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_upsilon, 0 }, 0x1F52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1F62}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F2B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F03}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_epsilon, 0 }, 0x1F13}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F23}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_iota, 0 }, 0x1F33}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_omicron, 0 }, 0x1F43}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_upsilon, 0 }, 0x1F53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1F63}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f00, 0, 0 }, 0x1F02}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f01, 0, 0 }, 0x1F03}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f08, 0, 0 }, 0x1F0A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f09, 0, 0 }, 0x1F0B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f10, 0, 0 }, 0x1F12}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f11, 0, 0 }, 0x1F13}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f18, 0, 0 }, 0x1F1A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f19, 0, 0 }, 0x1F1B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f20, 0, 0 }, 0x1F22}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f21, 0, 0 }, 0x1F23}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f28, 0, 0 }, 0x1F2A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f29, 0, 0 }, 0x1F2B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f30, 0, 0 }, 0x1F32}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f31, 0, 0 }, 0x1F33}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f38, 0, 0 }, 0x1F3A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f39, 0, 0 }, 0x1F3B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f40, 0, 0 }, 0x1F42}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f41, 0, 0 }, 0x1F43}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f48, 0, 0 }, 0x1F4A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f49, 0, 0 }, 0x1F4B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f50, 0, 0 }, 0x1F52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f51, 0, 0 }, 0x1F53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f59, 0, 0 }, 0x1F5B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f60, 0, 0 }, 0x1F62}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f61, 0, 0 }, 0x1F63}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f68, 0, 0 }, 0x1F6A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_grave, 0x1001f69, 0, 0 }, 0x1F6B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_quotedbl, 0, 0 }, 0x00E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_apostrophe, 0, 0 }, 0x00E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_parenleft, 0, 0 }, 0x0103}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_asterisk, 0, 0 }, 0x00E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_comma, 0, 0 }, 0x0105}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_minus, 0, 0 }, 0x0101}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_greater, 0, 0 }, 0x00E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_asciicircum, 0, 0 }, 0x00E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_underscore, 0, 0 }, 0x00AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_grave, 0, 0 }, 0x00E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_a, 0, 0 }, 0x00E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_e, 0, 0 }, 0x00E6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_asciitilde, 0, 0 }, 0x00E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_diaeresis, 0, 0 }, 0x00E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_a, SCIM_KEY_acute, 0, 0 }, 0x00E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_exclam, SCIM_KEY_A, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_exclam, SCIM_KEY_a, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_comma, SCIM_KEY_E, 0 }, 0x1E1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_comma, SCIM_KEY_e, 0 }, 0x1E1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_period, 0, 0 }, 0x1E03}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_A, 0, 0 }, 0x0102}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_E, 0, 0 }, 0x0114}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_G, 0, 0 }, 0x011E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_I, 0, 0 }, 0x012C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_O, 0, 0 }, 0x014E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_U, 0, 0 }, 0x016C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_a, 0, 0 }, 0x0103}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_e, 0, 0 }, 0x0115}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_g, 0, 0 }, 0x011F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_i, 0, 0 }, 0x012D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_o, 0, 0 }, 0x014F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_u, 0, 0 }, 0x016D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_a, 0, 0 }, 0x04D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_ie, 0, 0 }, 0x04D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_i, 0, 0 }, 0x0439}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_u, 0, 0 }, 0x045E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_zhe, 0, 0 }, 0x04C2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_A, 0, 0 }, 0x04D0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_IE, 0, 0 }, 0x04D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_I, 0, 0 }, 0x0419}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_U, 0, 0 }, 0x040E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Cyrillic_ZHE, 0, 0 }, 0x04C1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1FB8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1FD8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1FE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_combining_belowdot, SCIM_KEY_A, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_combining_belowdot, SCIM_KEY_a, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_dead_cedilla, SCIM_KEY_E, 0 }, 0x1E1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_dead_cedilla, SCIM_KEY_e, 0 }, 0x1E1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_dead_belowdot, SCIM_KEY_A, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, SCIM_KEY_dead_belowdot, SCIM_KEY_a, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, 0x1000228, 0, 0 }, 0x1E1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, 0x1000229, 0, 0 }, 0x1E1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, 0x1001ea0, 0, 0 }, 0x1EB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_b, 0x1001ea1, 0, 0 }, 0x1EB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_apostrophe, 0, 0 }, 0x0107}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_comma, 0, 0 }, 0x00E7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_period, 0, 0 }, 0x010B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_slash, 0, 0 }, 0x00A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_0, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_less, 0, 0 }, 0x010D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_equal, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_A, 0, 0 }, 0x01CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_C, 0, 0 }, 0x010C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_D, 0, 0 }, 0x010E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_E, 0, 0 }, 0x011A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_G, 0, 0 }, 0x01E6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_H, 0, 0 }, 0x021E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_I, 0, 0 }, 0x01CF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_K, 0, 0 }, 0x01E8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_L, 0, 0 }, 0x013D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_N, 0, 0 }, 0x0147}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_O, 0, 0 }, 0x01D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_R, 0, 0 }, 0x0158}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_S, 0, 0 }, 0x0160}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_T, 0, 0 }, 0x0164}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_U, 0, 0 }, 0x01D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_Z, 0, 0 }, 0x017D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_a, 0, 0 }, 0x01CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_c, 0, 0 }, 0x010D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_d, 0, 0 }, 0x010F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_e, 0, 0 }, 0x011B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_g, 0, 0 }, 0x01E7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_h, 0, 0 }, 0x021F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_i, 0, 0 }, 0x01D0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_j, 0, 0 }, 0x01F0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_k, 0, 0 }, 0x01E9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_l, 0, 0 }, 0x013E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_n, 0, 0 }, 0x0148}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_o, 0, 0 }, 0x01D2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_r, 0, 0 }, 0x0159}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_s, 0, 0 }, 0x0161}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_t, 0, 0 }, 0x0165}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_u, 0, 0 }, 0x01D4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_z, 0, 0 }, 0x017E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_bar, 0, 0 }, 0x00A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_Udiaeresis, 0, 0 }, 0x01D9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_udiaeresis, 0, 0 }, 0x01DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0 }, 0x01D9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0 }, 0x01DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, 0x10001b7, 0, 0 }, 0x01EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_c, 0x1000292, 0, 0 }, 0x01EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_d, SCIM_KEY_minus, 0, 0 }, 0x20AB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_d, SCIM_KEY_period, 0, 0 }, 0x1E0B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_d, SCIM_KEY_less, 0, 0 }, 0x010F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_d, SCIM_KEY_h, 0, 0 }, 0x00F0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_quotedbl, 0, 0 }, 0x00EB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_apostrophe, 0, 0 }, 0x00E9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_comma, 0, 0 }, 0x0119}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_minus, 0, 0 }, 0x0113}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_period, 0, 0 }, 0x0117}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_less, 0, 0 }, 0x011B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_equal, 0, 0 }, 0x20AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_greater, 0, 0 }, 0x00EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_asciicircum, 0, 0 }, 0x00EA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_underscore, 0, 0 }, 0x0113}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_grave, 0, 0 }, 0x00E8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_e, 0, 0 }, 0x0259}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_diaeresis, 0, 0 }, 0x00EB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_e, SCIM_KEY_acute, 0, 0 }, 0x00E9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_f, SCIM_KEY_period, 0, 0 }, 0x1E1F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_f, SCIM_KEY_S, 0, 0 }, 0x017F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_f, SCIM_KEY_s, 0, 0 }, 0x017F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_g, SCIM_KEY_parenleft, 0, 0 }, 0x011F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_g, SCIM_KEY_comma, 0, 0 }, 0x0123}, + {{SCIM_KEY_Multi_key, SCIM_KEY_g, SCIM_KEY_period, 0, 0 }, 0x0121}, + {{SCIM_KEY_Multi_key, SCIM_KEY_g, SCIM_KEY_U, 0, 0 }, 0x011F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_g, SCIM_KEY_breve, 0, 0 }, 0x011F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_quotedbl, 0, 0 }, 0x00EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_apostrophe, 0, 0 }, 0x00ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_comma, 0, 0 }, 0x012F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_minus, 0, 0 }, 0x012B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_period, 0, 0 }, 0x0131}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_greater, 0, 0 }, 0x00EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_asciicircum, 0, 0 }, 0x00EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_underscore, 0, 0 }, 0x012B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_grave, 0, 0 }, 0x00EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_asciitilde, 0, 0 }, 0x0129}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_diaeresis, 0, 0 }, 0x00EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_i, SCIM_KEY_acute, 0, 0 }, 0x00ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_k, SCIM_KEY_comma, 0, 0 }, 0x0137}, + {{SCIM_KEY_Multi_key, SCIM_KEY_k, SCIM_KEY_k, 0, 0 }, 0x0138}, + {{SCIM_KEY_Multi_key, SCIM_KEY_l, SCIM_KEY_apostrophe, 0, 0 }, 0x013A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_l, SCIM_KEY_comma, 0, 0 }, 0x013C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_l, SCIM_KEY_minus, 0, 0 }, 0x00A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_l, SCIM_KEY_less, 0, 0 }, 0x013E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_l, SCIM_KEY_equal, 0, 0 }, 0x00A3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_l, SCIM_KEY_v, 0, 0 }, 0x007C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_m, SCIM_KEY_period, 0, 0 }, 0x1E41}, + {{SCIM_KEY_Multi_key, SCIM_KEY_m, SCIM_KEY_slash, 0, 0 }, 0x20A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_m, SCIM_KEY_u, 0, 0 }, 0x00B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_n, SCIM_KEY_apostrophe, 0, 0 }, 0x0144}, + {{SCIM_KEY_Multi_key, SCIM_KEY_n, SCIM_KEY_comma, 0, 0 }, 0x0146}, + {{SCIM_KEY_Multi_key, SCIM_KEY_n, SCIM_KEY_minus, 0, 0 }, 0x00F1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_n, SCIM_KEY_less, 0, 0 }, 0x0148}, + {{SCIM_KEY_Multi_key, SCIM_KEY_n, SCIM_KEY_g, 0, 0 }, 0x014B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_n, SCIM_KEY_asciitilde, 0, 0 }, 0x00F1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_quotedbl, 0, 0 }, 0x00F6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_apostrophe, 0, 0 }, 0x00F3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_apostrophe, SCIM_KEY_A, 0 }, 0x01FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_apostrophe, SCIM_KEY_a, 0 }, 0x01FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_minus, 0, 0 }, 0x014D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_slash, 0, 0 }, 0x00F8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_greater, 0, 0 }, 0x00F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_A, 0, 0 }, 0x00C5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_C, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_R, 0, 0 }, 0x00AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_U, 0, 0 }, 0x016E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_X, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_asciicircum, 0, 0 }, 0x00F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_underscore, 0, 0 }, 0x00BA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_grave, 0, 0 }, 0x00F2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_a, 0, 0 }, 0x00E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_c, 0, 0 }, 0x00A9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_e, 0, 0 }, 0x0153}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_o, 0, 0 }, 0x00B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_r, 0, 0 }, 0x00AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_s, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_u, 0, 0 }, 0x016F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_w, 0, 0 }, 0x1E98}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_x, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_y, 0, 0 }, 0x1E99}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_asciitilde, 0, 0 }, 0x00F5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_diaeresis, 0, 0 }, 0x00F6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_o, SCIM_KEY_acute, 0, 0 }, 0x00F3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_p, SCIM_KEY_exclam, 0, 0 }, 0x00B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_p, SCIM_KEY_period, 0, 0 }, 0x1E57}, + {{SCIM_KEY_Multi_key, SCIM_KEY_r, SCIM_KEY_apostrophe, 0, 0 }, 0x0155}, + {{SCIM_KEY_Multi_key, SCIM_KEY_r, SCIM_KEY_comma, 0, 0 }, 0x0157}, + {{SCIM_KEY_Multi_key, SCIM_KEY_r, SCIM_KEY_less, 0, 0 }, 0x0159}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_exclam, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_apostrophe, 0, 0 }, 0x015B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_comma, 0, 0 }, 0x015F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_period, 0, 0 }, 0x1E61}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_0, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_1, 0, 0 }, 0x00B9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_2, 0, 0 }, 0x00B2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_3, 0, 0 }, 0x00B3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_less, 0, 0 }, 0x0161}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_o, 0, 0 }, 0x00A7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_s, 0, 0 }, 0x00DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_s, SCIM_KEY_cedilla, 0, 0 }, 0x015F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_t, SCIM_KEY_minus, 0, 0 }, 0x0167}, + {{SCIM_KEY_Multi_key, SCIM_KEY_t, SCIM_KEY_period, 0, 0 }, 0x1E6B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_t, SCIM_KEY_slash, 0, 0 }, 0x0167}, + {{SCIM_KEY_Multi_key, SCIM_KEY_t, SCIM_KEY_less, 0, 0 }, 0x0165}, + {{SCIM_KEY_Multi_key, SCIM_KEY_t, SCIM_KEY_h, 0, 0 }, 0x00FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_quotedbl, 0, 0 }, 0x00FC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_apostrophe, 0, 0 }, 0x00FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_asterisk, 0, 0 }, 0x016F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_comma, 0, 0 }, 0x0173}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_minus, 0, 0 }, 0x016B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_slash, 0, 0 }, 0x00B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_greater, 0, 0 }, 0x00FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_asciicircum, 0, 0 }, 0x00FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_underscore, 0, 0 }, 0x016B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_grave, 0, 0 }, 0x00F9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_asciitilde, 0, 0 }, 0x0169}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_diaeresis, 0, 0 }, 0x00FC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_u, SCIM_KEY_acute, 0, 0 }, 0x00FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_v, SCIM_KEY_Z, 0, 0 }, 0x017D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_v, SCIM_KEY_l, 0, 0 }, 0x007C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_v, SCIM_KEY_z, 0, 0 }, 0x017E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_w, SCIM_KEY_asciicircum, 0, 0 }, 0x0175}, + {{SCIM_KEY_Multi_key, SCIM_KEY_x, SCIM_KEY_0, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_x, SCIM_KEY_O, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_x, SCIM_KEY_o, 0, 0 }, 0x00A4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_x, SCIM_KEY_x, 0, 0 }, 0x00D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_y, SCIM_KEY_quotedbl, 0, 0 }, 0x00FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_y, SCIM_KEY_apostrophe, 0, 0 }, 0x00FD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_y, SCIM_KEY_minus, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_y, SCIM_KEY_equal, 0, 0 }, 0x00A5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_y, SCIM_KEY_asciicircum, 0, 0 }, 0x0177}, + {{SCIM_KEY_Multi_key, SCIM_KEY_y, SCIM_KEY_diaeresis, 0, 0 }, 0x00FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_y, SCIM_KEY_acute, 0, 0 }, 0x00FD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_z, SCIM_KEY_apostrophe, 0, 0 }, 0x017A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_z, SCIM_KEY_period, 0, 0 }, 0x017C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_z, SCIM_KEY_less, 0, 0 }, 0x017E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_bar, SCIM_KEY_C, 0, 0 }, 0x00A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_bar, SCIM_KEY_c, 0, 0 }, 0x00A2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_space, 0, 0 }, 0x007E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x1FD7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F07}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F27}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F37}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F57}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F67}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F06}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F26}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F36}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F56}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F66}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EE0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EEE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EE1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EEF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_A, 0, 0 }, 0x00C3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_E, 0, 0 }, 0x1EBC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_I, 0, 0 }, 0x0128}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_N, 0, 0 }, 0x00D1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_O, 0, 0 }, 0x00D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_U, 0, 0 }, 0x0168}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EB5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_V, 0, 0 }, 0x1E7C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Y, 0, 0 }, 0x1EF8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EC5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_a, 0, 0 }, 0x00E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EB5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_e, 0, 0 }, 0x1EBD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_i, 0, 0 }, 0x0129}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_n, 0, 0 }, 0x00F1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_o, 0, 0 }, 0x00F5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_u, 0, 0 }, 0x0169}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_v, 0, 0 }, 0x1E7D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_y, 0, 0 }, 0x1EF9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Acircumflex, 0, 0 }, 0x1EAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Ecircumflex, 0, 0 }, 0x1EC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Ocircumflex, 0, 0 }, 0x1ED6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_acircumflex, 0, 0 }, 0x1EAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_ecircumflex, 0, 0 }, 0x1EC5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_ocircumflex, 0, 0 }, 0x1ED7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Abreve, 0, 0 }, 0x1EB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_abreve, 0, 0 }, 0x1EB5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_iotadieresis, 0, 0 }, 0x1FD7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_upsilondieresis, 0, 0 }, 0x1FE7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Ohorn, 0, 0 }, 0x1EE0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_ohorn, 0, 0 }, 0x1EE1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_Uhorn, 0, 0 }, 0x1EEE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_uhorn, 0, 0 }, 0x1EEF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0 }, 0x1EAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0 }, 0x1EC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0 }, 0x1ED6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0 }, 0x1EAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0 }, 0x1EC5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0 }, 0x1ED7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_breve, SCIM_KEY_A, 0 }, 0x1EB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_breve, SCIM_KEY_a, 0 }, 0x1EB5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0 }, 0x1FD7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_horn, SCIM_KEY_O, 0 }, 0x1EE0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_horn, SCIM_KEY_U, 0 }, 0x1EEE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_horn, SCIM_KEY_o, 0 }, 0x1EE1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, SCIM_KEY_dead_horn, SCIM_KEY_u, 0 }, 0x1EEF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F06}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F26}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_iota, 0 }, 0x1F36}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_upsilon, 0 }, 0x1F56}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1F66}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F07}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F27}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_iota, 0 }, 0x1F37}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_upsilon, 0 }, 0x1F57}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1F67}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f00, 0, 0 }, 0x1F06}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f01, 0, 0 }, 0x1F07}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f08, 0, 0 }, 0x1F0E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f09, 0, 0 }, 0x1F0F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f20, 0, 0 }, 0x1F26}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f21, 0, 0 }, 0x1F27}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f28, 0, 0 }, 0x1F2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f29, 0, 0 }, 0x1F2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f30, 0, 0 }, 0x1F36}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f31, 0, 0 }, 0x1F37}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f38, 0, 0 }, 0x1F3E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f39, 0, 0 }, 0x1F3F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f50, 0, 0 }, 0x1F56}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f51, 0, 0 }, 0x1F57}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f59, 0, 0 }, 0x1F5F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f60, 0, 0 }, 0x1F66}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f61, 0, 0 }, 0x1F67}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f68, 0, 0 }, 0x1F6E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_asciitilde, 0x1001f69, 0, 0 }, 0x1F6F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_apostrophe, 0, 0 }, 0x0385}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_A, 0, 0 }, 0x00C4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_E, 0, 0 }, 0x00CB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_I, 0, 0 }, 0x00CF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_O, 0, 0 }, 0x00D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_U, 0, 0 }, 0x00DC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_Y, 0, 0 }, 0x0178}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_grave, 0, 0 }, 0x1FED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_a, 0, 0 }, 0x00E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_e, 0, 0 }, 0x00EB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_i, 0, 0 }, 0x00EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_o, 0, 0 }, 0x00F6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_u, 0, 0 }, 0x00FC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_y, 0, 0 }, 0x00FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_asciitilde, 0, 0 }, 0x1FC1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_acute, 0, 0 }, 0x0385}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_combining_grave, 0, 0 }, 0x1FED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_combining_acute, 0, 0 }, 0x0385}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_dead_grave, 0, 0 }, 0x1FED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_dead_acute, 0, 0 }, 0x0385}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, SCIM_KEY_dead_tilde, 0, 0 }, 0x1FC1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_diaeresis, 0x1000342, 0, 0 }, 0x1FC1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_exclam, SCIM_KEY_L, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_exclam, SCIM_KEY_R, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_exclam, SCIM_KEY_l, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_exclam, SCIM_KEY_r, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_quotedbl, SCIM_KEY_A, 0 }, 0x01DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_quotedbl, SCIM_KEY_O, 0 }, 0x022A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_quotedbl, SCIM_KEY_a, 0 }, 0x01DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_quotedbl, SCIM_KEY_o, 0 }, 0x022B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_period, SCIM_KEY_A, 0 }, 0x01E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_period, SCIM_KEY_O, 0 }, 0x0230}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_period, SCIM_KEY_a, 0 }, 0x01E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_period, SCIM_KEY_o, 0 }, 0x0231}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_semicolon, SCIM_KEY_O, 0 }, 0x01EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_semicolon, SCIM_KEY_o, 0 }, 0x01ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_A, 0, 0 }, 0x0100}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_E, 0, 0 }, 0x0112}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_G, 0, 0 }, 0x1E20}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_I, 0, 0 }, 0x012A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_O, 0, 0 }, 0x014C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_U, 0, 0 }, 0x016A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Y, 0, 0 }, 0x0232}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_a, 0, 0 }, 0x0101}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_e, 0, 0 }, 0x0113}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_g, 0, 0 }, 0x1E21}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_i, 0, 0 }, 0x012B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_o, 0, 0 }, 0x014D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_u, 0, 0 }, 0x016B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_y, 0, 0 }, 0x0233}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Adiaeresis, 0, 0 }, 0x01DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_AE, 0, 0 }, 0x01E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Otilde, 0, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Odiaeresis, 0, 0 }, 0x022A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Udiaeresis, 0, 0 }, 0x01D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_adiaeresis, 0, 0 }, 0x01DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_ae, 0, 0 }, 0x01E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_otilde, 0, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_odiaeresis, 0, 0 }, 0x022B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_udiaeresis, 0, 0 }, 0x01D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Cyrillic_i, 0, 0 }, 0x04E3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Cyrillic_u, 0, 0 }, 0x04EF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Cyrillic_I, 0, 0 }, 0x04E2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Cyrillic_U, 0, 0 }, 0x04EE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1FB9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1FD9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1FE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_L, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_R, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_l, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_combining_belowdot, SCIM_KEY_r, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0 }, 0x022C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0 }, 0x022D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_A, 0 }, 0x01E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_O, 0 }, 0x0230}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_a, 0 }, 0x01E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_abovedot, SCIM_KEY_o, 0 }, 0x0231}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_A, 0 }, 0x01DE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_O, 0 }, 0x022A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0 }, 0x01D5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_a, 0 }, 0x01DF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_o, 0 }, 0x022B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0 }, 0x01D6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_ogonek, SCIM_KEY_O, 0 }, 0x01EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_ogonek, SCIM_KEY_o, 0 }, 0x01ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_L, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_R, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_l, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, SCIM_KEY_dead_belowdot, SCIM_KEY_r, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x10001ea, 0, 0 }, 0x01EC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x10001eb, 0, 0 }, 0x01ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x1000226, 0, 0 }, 0x01E0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x1000227, 0, 0 }, 0x01E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x100022e, 0, 0 }, 0x0230}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x100022f, 0, 0 }, 0x0231}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x1001e36, 0, 0 }, 0x1E38}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x1001e37, 0, 0 }, 0x1E39}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x1001e5a, 0, 0 }, 0x1E5C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_macron, 0x1001e5b, 0, 0 }, 0x1E5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_quotedbl, SCIM_KEY_I, 0 }, 0x1E2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_quotedbl, SCIM_KEY_U, 0 }, 0x01D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_quotedbl, SCIM_KEY_i, 0 }, 0x1E2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_quotedbl, SCIM_KEY_u, 0 }, 0x01D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x0390}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x03B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F05}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_epsilon, 0 }, 0x1F15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F25}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F35}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_omicron, 0 }, 0x1F45}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F04}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_epsilon, 0 }, 0x1F14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F24}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F34}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_omicron, 0 }, 0x1F44}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_plus, SCIM_KEY_O, 0 }, 0x1EDA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_plus, SCIM_KEY_U, 0 }, 0x1EE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_plus, SCIM_KEY_o, 0 }, 0x1EDB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_plus, SCIM_KEY_u, 0 }, 0x1EE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_comma, SCIM_KEY_C, 0 }, 0x1E08}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_comma, SCIM_KEY_c, 0 }, 0x1E09}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_slash, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_slash, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_A, 0, 0 }, 0x00C1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_C, 0, 0 }, 0x0106}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_E, 0, 0 }, 0x00C9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_G, 0, 0 }, 0x01F4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_I, 0, 0 }, 0x00CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_K, 0, 0 }, 0x1E30}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_L, 0, 0 }, 0x0139}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_M, 0, 0 }, 0x1E3E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_N, 0, 0 }, 0x0143}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_O, 0, 0 }, 0x00D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_P, 0, 0 }, 0x1E54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_R, 0, 0 }, 0x0154}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_S, 0, 0 }, 0x015A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_U, 0, 0 }, 0x00DA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_U, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_U, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_W, 0, 0 }, 0x1E82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Y, 0, 0 }, 0x00DD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Z, 0, 0 }, 0x0179}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciicircum, SCIM_KEY_A, 0 }, 0x1EA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciicircum, SCIM_KEY_E, 0 }, 0x1EBE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciicircum, SCIM_KEY_O, 0 }, 0x1ED0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciicircum, SCIM_KEY_a, 0 }, 0x1EA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciicircum, SCIM_KEY_e, 0 }, 0x1EBF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciicircum, SCIM_KEY_o, 0 }, 0x1ED1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_underscore, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_underscore, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_underscore, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_underscore, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_a, 0, 0 }, 0x00E1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_b, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_b, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_c, 0, 0 }, 0x0107}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_e, 0, 0 }, 0x00E9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_g, 0, 0 }, 0x01F5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_i, 0, 0 }, 0x00ED}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_k, 0, 0 }, 0x1E31}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_l, 0, 0 }, 0x013A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_m, 0, 0 }, 0x1E3F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_n, 0, 0 }, 0x0144}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_o, 0, 0 }, 0x00F3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_o, SCIM_KEY_A, 0 }, 0x01FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_o, SCIM_KEY_a, 0 }, 0x01FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_p, 0, 0 }, 0x1E55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_r, 0, 0 }, 0x0155}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_s, 0, 0 }, 0x015B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_u, 0, 0 }, 0x00FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_w, 0, 0 }, 0x1E83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_y, 0, 0 }, 0x00FD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_z, 0, 0 }, 0x017A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciitilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciitilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciitilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_asciitilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_macron, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_macron, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_macron, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_macron, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Acircumflex, 0, 0 }, 0x1EA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Aring, 0, 0 }, 0x01FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_AE, 0, 0 }, 0x01FC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Ccedilla, 0, 0 }, 0x1E08}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Ecircumflex, 0, 0 }, 0x1EBE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Idiaeresis, 0, 0 }, 0x1E2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Ocircumflex, 0, 0 }, 0x1ED0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Otilde, 0, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Ooblique, 0, 0 }, 0x01FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Udiaeresis, 0, 0 }, 0x01D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_acircumflex, 0, 0 }, 0x1EA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_aring, 0, 0 }, 0x01FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_ae, 0, 0 }, 0x01FD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_ccedilla, 0, 0 }, 0x1E09}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_ecircumflex, 0, 0 }, 0x1EBF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_idiaeresis, 0, 0 }, 0x1E2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_ocircumflex, 0, 0 }, 0x1ED1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_otilde, 0, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_oslash, 0, 0 }, 0x01FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_udiaeresis, 0, 0 }, 0x01D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Abreve, 0, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_abreve, 0, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Emacron, 0, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_emacron, 0, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Omacron, 0, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Utilde, 0, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_omacron, 0, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_utilde, 0, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Cyrillic_ghe, 0, 0 }, 0x0453}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Cyrillic_ka, 0, 0 }, 0x045C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Cyrillic_GHE, 0, 0 }, 0x0403}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Cyrillic_KA, 0, 0 }, 0x040C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_iotadieresis, 0, 0 }, 0x0390}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_upsilondieresis, 0, 0 }, 0x03B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x0386}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_EPSILON, 0, 0 }, 0x0388}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_ETA, 0, 0 }, 0x0389}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x038A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_OMICRON, 0, 0 }, 0x038C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x038E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x038F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_alpha, 0, 0 }, 0x03AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_epsilon, 0, 0 }, 0x03AD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_eta, 0, 0 }, 0x03AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_iota, 0, 0 }, 0x03AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_omicron, 0, 0 }, 0x03CC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x03CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Greek_omega, 0, 0 }, 0x03CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_combining_tilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_combining_tilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_combining_tilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_combining_tilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Ohorn, 0, 0 }, 0x1EDA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_ohorn, 0, 0 }, 0x1EDB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_Uhorn, 0, 0 }, 0x1EE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_uhorn, 0, 0 }, 0x1EE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_A, 0 }, 0x1EA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_E, 0 }, 0x1EBE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_O, 0 }, 0x1ED0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_a, 0 }, 0x1EA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_e, 0 }, 0x1EBF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_circumflex, SCIM_KEY_o, 0 }, 0x1ED1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_tilde, SCIM_KEY_O, 0 }, 0x1E4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_tilde, SCIM_KEY_U, 0 }, 0x1E78}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_tilde, SCIM_KEY_o, 0 }, 0x1E4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_tilde, SCIM_KEY_u, 0 }, 0x1E79}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_macron, SCIM_KEY_E, 0 }, 0x1E16}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_macron, SCIM_KEY_O, 0 }, 0x1E52}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_macron, SCIM_KEY_e, 0 }, 0x1E17}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_macron, SCIM_KEY_o, 0 }, 0x1E53}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_breve, SCIM_KEY_A, 0 }, 0x1EAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_breve, SCIM_KEY_a, 0 }, 0x1EAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_I, 0 }, 0x1E2E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_U, 0 }, 0x01D7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_i, 0 }, 0x1E2F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_u, 0 }, 0x01D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0 }, 0x0390}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0 }, 0x03B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_abovering, SCIM_KEY_A, 0 }, 0x01FA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_abovering, SCIM_KEY_a, 0 }, 0x01FB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_cedilla, SCIM_KEY_C, 0 }, 0x1E08}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_cedilla, SCIM_KEY_c, 0 }, 0x1E09}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_horn, SCIM_KEY_O, 0 }, 0x1EDA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_horn, SCIM_KEY_U, 0 }, 0x1EE8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_horn, SCIM_KEY_o, 0 }, 0x1EDB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_dead_horn, SCIM_KEY_u, 0 }, 0x1EE9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_KP_Divide, SCIM_KEY_O, 0 }, 0x01FE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, SCIM_KEY_KP_Divide, SCIM_KEY_o, 0 }, 0x01FF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F2C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F04}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_epsilon, 0 }, 0x1F14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F24}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_iota, 0 }, 0x1F34}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_omicron, 0 }, 0x1F44}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_upsilon, 0 }, 0x1F54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1F64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_EPSILON, 0 }, 0x1F1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F2D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_OMICRON, 0 }, 0x1F4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F05}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_epsilon, 0 }, 0x1F15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F25}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_iota, 0 }, 0x1F35}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_omicron, 0 }, 0x1F45}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_upsilon, 0 }, 0x1F55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1F65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x10003d2, 0, 0 }, 0x03D3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f00, 0, 0 }, 0x1F04}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f01, 0, 0 }, 0x1F05}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f08, 0, 0 }, 0x1F0C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f09, 0, 0 }, 0x1F0D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f10, 0, 0 }, 0x1F14}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f11, 0, 0 }, 0x1F15}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f18, 0, 0 }, 0x1F1C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f19, 0, 0 }, 0x1F1D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f20, 0, 0 }, 0x1F24}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f21, 0, 0 }, 0x1F25}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f28, 0, 0 }, 0x1F2C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f29, 0, 0 }, 0x1F2D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f30, 0, 0 }, 0x1F34}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f31, 0, 0 }, 0x1F35}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f38, 0, 0 }, 0x1F3C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f39, 0, 0 }, 0x1F3D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f40, 0, 0 }, 0x1F44}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f41, 0, 0 }, 0x1F45}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f48, 0, 0 }, 0x1F4C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f49, 0, 0 }, 0x1F4D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f50, 0, 0 }, 0x1F54}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f51, 0, 0 }, 0x1F55}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f59, 0, 0 }, 0x1F5D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f60, 0, 0 }, 0x1F64}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f61, 0, 0 }, 0x1F65}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f68, 0, 0 }, 0x1F6C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_acute, 0x1001f69, 0, 0 }, 0x1F6D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_cedilla, SCIM_KEY_S, 0, 0 }, 0x015E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_cedilla, SCIM_KEY_s, 0, 0 }, 0x015F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_breve, SCIM_KEY_G, 0, 0 }, 0x011E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_breve, SCIM_KEY_g, 0, 0 }, 0x011F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_ALPHA, SCIM_KEY_apostrophe, 0, 0 }, 0x0386}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_EPSILON, SCIM_KEY_apostrophe, 0, 0 }, 0x0388}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_ETA, SCIM_KEY_apostrophe, 0, 0 }, 0x0389}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_IOTA, SCIM_KEY_quotedbl, 0, 0 }, 0x03AA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_IOTA, SCIM_KEY_apostrophe, 0, 0 }, 0x038A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_OMICRON, SCIM_KEY_apostrophe, 0, 0 }, 0x038C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_UPSILON, SCIM_KEY_quotedbl, 0, 0 }, 0x03AB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_UPSILON, SCIM_KEY_apostrophe, 0, 0 }, 0x038E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_OMEGA, SCIM_KEY_apostrophe, 0, 0 }, 0x038F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_alpha, SCIM_KEY_apostrophe, 0, 0 }, 0x03AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_epsilon, SCIM_KEY_apostrophe, 0, 0 }, 0x03AD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_eta, SCIM_KEY_apostrophe, 0, 0 }, 0x03AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_quotedbl, 0, 0 }, 0x03CA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0, 0 }, 0x03AF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_Greek_alpha, 0 }, 0x1FB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_Greek_eta, 0 }, 0x1FC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, SCIM_KEY_Greek_omega, 0 }, 0x1FF4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f00, 0 }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f01, 0 }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f08, 0 }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f09, 0 }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f20, 0 }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f21, 0 }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f28, 0 }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f29, 0 }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f60, 0 }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f61, 0 }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f68, 0 }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_apostrophe, 0x1001f69, 0 }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F89}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F99}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FA9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F81}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F91}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1FA1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F88}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F98}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FA8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F80}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F90}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1FA0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_Greek_alpha, 0 }, 0x1FB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_Greek_eta, 0 }, 0x1FC2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, SCIM_KEY_Greek_omega, 0 }, 0x1FF2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f00, 0 }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f01, 0 }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f08, 0 }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f09, 0 }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f20, 0 }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f21, 0 }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f28, 0 }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f29, 0 }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f60, 0 }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f61, 0 }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f68, 0 }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_grave, 0x1001f69, 0 }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_Greek_alpha, 0 }, 0x1FB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_Greek_eta, 0 }, 0x1FC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, SCIM_KEY_Greek_omega, 0 }, 0x1FF7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f00, 0 }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f01, 0 }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f08, 0 }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f09, 0 }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f20, 0 }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f21, 0 }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f28, 0 }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f29, 0 }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f60, 0 }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f61, 0 }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f68, 0 }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_asciitilde, 0x1001f69, 0 }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_Greek_alpha, 0 }, 0x1FB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_Greek_eta, 0 }, 0x1FC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, SCIM_KEY_Greek_omega, 0 }, 0x1FF4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f00, 0 }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f01, 0 }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f08, 0 }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f09, 0 }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f20, 0 }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f21, 0 }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f28, 0 }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f29, 0 }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f60, 0 }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f61, 0 }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f68, 0 }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_acute, 0x1001f69, 0 }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_alphaaccent, 0, 0 }, 0x1FB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_etaaccent, 0, 0 }, 0x1FC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_omegaaccent, 0, 0 }, 0x1FF4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1FBC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1FCC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1FFC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1FB3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_eta, 0, 0 }, 0x1FC3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_Greek_omega, 0, 0 }, 0x1FF3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_Greek_alpha, 0 }, 0x1FB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_Greek_eta, 0 }, 0x1FC2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, SCIM_KEY_Greek_omega, 0 }, 0x1FF2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f00, 0 }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f01, 0 }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f08, 0 }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f09, 0 }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f20, 0 }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f21, 0 }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f28, 0 }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f29, 0 }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f60, 0 }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f61, 0 }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f68, 0 }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_grave, 0x1001f69, 0 }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_Greek_alpha, 0 }, 0x1FB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_Greek_eta, 0 }, 0x1FC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, SCIM_KEY_Greek_omega, 0 }, 0x1FF4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f00, 0 }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f01, 0 }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f08, 0 }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f09, 0 }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f20, 0 }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f21, 0 }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f28, 0 }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f29, 0 }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f60, 0 }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f61, 0 }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f68, 0 }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_combining_acute, 0x1001f69, 0 }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_Greek_alpha, 0 }, 0x1FB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_Greek_eta, 0 }, 0x1FC2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, SCIM_KEY_Greek_omega, 0 }, 0x1FF2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f00, 0 }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f01, 0 }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f08, 0 }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f09, 0 }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f20, 0 }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f21, 0 }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f28, 0 }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f29, 0 }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f60, 0 }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f61, 0 }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f68, 0 }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_grave, 0x1001f69, 0 }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_Greek_alpha, 0 }, 0x1FB4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_Greek_eta, 0 }, 0x1FC4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, SCIM_KEY_Greek_omega, 0 }, 0x1FF4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f00, 0 }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f01, 0 }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f08, 0 }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f09, 0 }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f20, 0 }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f21, 0 }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f28, 0 }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f29, 0 }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f60, 0 }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f61, 0 }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f68, 0 }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_acute, 0x1001f69, 0 }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Greek_alpha, 0 }, 0x1FB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Greek_eta, 0 }, 0x1FC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, SCIM_KEY_Greek_omega, 0 }, 0x1FF7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f00, 0 }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f01, 0 }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f08, 0 }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f09, 0 }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f20, 0 }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f21, 0 }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f28, 0 }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f29, 0 }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f60, 0 }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f61, 0 }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f68, 0 }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, SCIM_KEY_dead_tilde, 0x1001f69, 0 }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000313, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F88}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000313, SCIM_KEY_Greek_ETA, 0 }, 0x1F98}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000313, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FA8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000313, SCIM_KEY_Greek_alpha, 0 }, 0x1F80}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000313, SCIM_KEY_Greek_eta, 0 }, 0x1F90}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000313, SCIM_KEY_Greek_omega, 0 }, 0x1FA0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000314, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F89}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000314, SCIM_KEY_Greek_ETA, 0 }, 0x1F99}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000314, SCIM_KEY_Greek_OMEGA, 0 }, 0x1FA9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000314, SCIM_KEY_Greek_alpha, 0 }, 0x1F81}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000314, SCIM_KEY_Greek_eta, 0 }, 0x1F91}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000314, SCIM_KEY_Greek_omega, 0 }, 0x1FA1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenright, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_parenright, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_Greek_alpha, 0 }, 0x1FB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_Greek_eta, 0 }, 0x1FC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, SCIM_KEY_Greek_omega, 0 }, 0x1FF7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_ALPHA }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_ETA }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_OMEGA }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_alpha }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_eta }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000313, SCIM_KEY_Greek_omega }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_ALPHA }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_ETA }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_OMEGA }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_alpha }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_eta }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1000314, SCIM_KEY_Greek_omega }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f00, 0 }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f01, 0 }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f08, 0 }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f09, 0 }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f20, 0 }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f21, 0 }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f28, 0 }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f29, 0 }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f60, 0 }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f61, 0 }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f68, 0 }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1000342, 0x1001f69, 0 }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f00, 0, 0 }, 0x1F80}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f01, 0, 0 }, 0x1F81}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f02, 0, 0 }, 0x1F82}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f03, 0, 0 }, 0x1F83}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f04, 0, 0 }, 0x1F84}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f05, 0, 0 }, 0x1F85}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f06, 0, 0 }, 0x1F86}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f07, 0, 0 }, 0x1F87}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f08, 0, 0 }, 0x1F88}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f09, 0, 0 }, 0x1F89}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f0a, 0, 0 }, 0x1F8A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f0b, 0, 0 }, 0x1F8B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f0c, 0, 0 }, 0x1F8C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f0d, 0, 0 }, 0x1F8D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f0e, 0, 0 }, 0x1F8E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f0f, 0, 0 }, 0x1F8F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f20, 0, 0 }, 0x1F90}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f21, 0, 0 }, 0x1F91}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f22, 0, 0 }, 0x1F92}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f23, 0, 0 }, 0x1F93}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f24, 0, 0 }, 0x1F94}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f25, 0, 0 }, 0x1F95}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f26, 0, 0 }, 0x1F96}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f27, 0, 0 }, 0x1F97}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f28, 0, 0 }, 0x1F98}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f29, 0, 0 }, 0x1F99}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f2a, 0, 0 }, 0x1F9A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f2b, 0, 0 }, 0x1F9B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f2c, 0, 0 }, 0x1F9C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f2d, 0, 0 }, 0x1F9D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f2e, 0, 0 }, 0x1F9E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f2f, 0, 0 }, 0x1F9F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f60, 0, 0 }, 0x1FA0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f61, 0, 0 }, 0x1FA1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f62, 0, 0 }, 0x1FA2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f63, 0, 0 }, 0x1FA3}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f64, 0, 0 }, 0x1FA4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f65, 0, 0 }, 0x1FA5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f66, 0, 0 }, 0x1FA6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f67, 0, 0 }, 0x1FA7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f68, 0, 0 }, 0x1FA8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f69, 0, 0 }, 0x1FA9}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f6a, 0, 0 }, 0x1FAA}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f6b, 0, 0 }, 0x1FAB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f6c, 0, 0 }, 0x1FAC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f6d, 0, 0 }, 0x1FAD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f6e, 0, 0 }, 0x1FAE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f6f, 0, 0 }, 0x1FAF}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f70, 0, 0 }, 0x1FB2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f74, 0, 0 }, 0x1FC2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001f7c, 0, 0 }, 0x1FF2}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001fb6, 0, 0 }, 0x1FB7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001fc6, 0, 0 }, 0x1FC7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_iota, 0x1001ff6, 0, 0 }, 0x1FF7}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_omicron, SCIM_KEY_apostrophe, 0, 0 }, 0x03CC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_upsilon, SCIM_KEY_quotedbl, 0, 0 }, 0x03CB}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_upsilon, SCIM_KEY_apostrophe, 0, 0 }, 0x03CD}, + {{SCIM_KEY_Multi_key, SCIM_KEY_Greek_omega, SCIM_KEY_apostrophe, 0, 0 }, 0x03CE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_lessthanequal, 0x1000338, 0, 0 }, 0x2270}, + {{SCIM_KEY_Multi_key, SCIM_KEY_greaterthanequal, 0x1000338, 0, 0 }, 0x2271}, + {{SCIM_KEY_Multi_key, SCIM_KEY_approximate, 0x1000338, 0, 0 }, 0x2247}, + {{SCIM_KEY_Multi_key, SCIM_KEY_identical, 0x1000338, 0, 0 }, 0x2262}, + {{SCIM_KEY_Multi_key, SCIM_KEY_includedin, 0x1000338, 0, 0 }, 0x2284}, + {{SCIM_KEY_Multi_key, SCIM_KEY_includes, 0x1000338, 0, 0 }, 0x2285}, + {{SCIM_KEY_Multi_key, SCIM_KEY_leftcaret, 0x1000338, 0, 0 }, 0x226E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_rightcaret, 0x1000338, 0, 0 }, 0x226F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_parenleft, 0, 0 }, 0x208D}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_parenright, 0, 0 }, 0x208E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_plus, 0, 0 }, 0x208A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_0, 0, 0 }, 0x2080}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_1, 0, 0 }, 0x2081}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_2, 0, 0 }, 0x2082}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_3, 0, 0 }, 0x2083}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_4, 0, 0 }, 0x2084}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_5, 0, 0 }, 0x2085}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_6, 0, 0 }, 0x2086}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_7, 0, 0 }, 0x2087}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_8, 0, 0 }, 0x2088}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_9, 0, 0 }, 0x2089}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_equal, 0, 0 }, 0x208C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_Space, 0, 0 }, 0x2082}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_Add, 0, 0 }, 0x208A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_0, 0, 0 }, 0x2080}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_1, 0, 0 }, 0x2081}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_2, 0, 0 }, 0x2082}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_3, 0, 0 }, 0x2083}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_4, 0, 0 }, 0x2084}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_5, 0, 0 }, 0x2085}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_6, 0, 0 }, 0x2086}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_7, 0, 0 }, 0x2087}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_8, 0, 0 }, 0x2088}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_9, 0, 0 }, 0x2089}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, SCIM_KEY_KP_Equal, 0, 0 }, 0x208C}, + {{SCIM_KEY_Multi_key, SCIM_KEY_underbar, 0x1002212, 0, 0 }, 0x208B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_rightshoe, 0x1000338, 0, 0 }, 0x2285}, + {{SCIM_KEY_Multi_key, SCIM_KEY_leftshoe, 0x1000338, 0, 0 }, 0x2284}, + {{SCIM_KEY_Multi_key, SCIM_KEY_righttack, 0x1000338, 0, 0 }, 0x22AC}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_D, 0, 0 }, 0x0110}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_G, 0, 0 }, 0x01E4}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_H, 0, 0 }, 0x0126}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_I, 0, 0 }, 0x0197}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_L, 0, 0 }, 0x0141}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_O, 0, 0 }, 0x00D8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_T, 0, 0 }, 0x0166}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_Z, 0, 0 }, 0x01B5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_b, 0, 0 }, 0x0180}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_d, 0, 0 }, 0x0111}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_g, 0, 0 }, 0x01E5}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_h, 0, 0 }, 0x0127}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_i, 0, 0 }, 0x0268}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_l, 0, 0 }, 0x0142}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_o, 0, 0 }, 0x00F8}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_t, 0, 0 }, 0x0167}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_z, 0, 0 }, 0x01B6}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_Cyrillic_ghe, 0, 0 }, 0x0493}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_Cyrillic_ka, 0, 0 }, 0x049F}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_Cyrillic_GHE, 0, 0 }, 0x0492}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_Cyrillic_KA, 0, 0 }, 0x049E}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_leftarrow, 0, 0 }, 0x219A}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, SCIM_KEY_rightarrow, 0, 0 }, 0x219B}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, 0x1000294, 0, 0 }, 0x02A1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, 0x10004ae, 0, 0 }, 0x04B0}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, 0x10004af, 0, 0 }, 0x04B1}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Divide, 0x1002194, 0, 0 }, 0x21AE}, + {{SCIM_KEY_Multi_key, SCIM_KEY_KP_Equal, 0x1000338, 0, 0 }, 0x2260}, + {{SCIM_KEY_Multi_key, 0x10005b4, SCIM_KEY_hebrew_yod, 0, 0 }, 0xFB1D}, + {{SCIM_KEY_Multi_key, 0x10005b7, SCIM_KEY_hebrew_aleph, 0, 0 }, 0xFB2E}, + {{SCIM_KEY_Multi_key, 0x10005b7, 0x10005f2, 0, 0 }, 0xFB1F}, + {{SCIM_KEY_Multi_key, 0x10005b8, SCIM_KEY_hebrew_aleph, 0, 0 }, 0xFB2F}, + {{SCIM_KEY_Multi_key, 0x10005b9, SCIM_KEY_hebrew_waw, 0, 0 }, 0xFB4B}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_aleph, 0, 0 }, 0xFB30}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_bet, 0, 0 }, 0xFB31}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_gimel, 0, 0 }, 0xFB32}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_dalet, 0, 0 }, 0xFB33}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_he, 0, 0 }, 0xFB34}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_waw, 0, 0 }, 0xFB35}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_zain, 0, 0 }, 0xFB36}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_tet, 0, 0 }, 0xFB38}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_yod, 0, 0 }, 0xFB39}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_finalkaph, 0, 0 }, 0xFB3A}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_kaph, 0, 0 }, 0xFB3B}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_lamed, 0, 0 }, 0xFB3C}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_mem, 0, 0 }, 0xFB3E}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_nun, 0, 0 }, 0xFB40}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_samech, 0, 0 }, 0xFB41}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_finalpe, 0, 0 }, 0xFB43}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_pe, 0, 0 }, 0xFB44}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_zade, 0, 0 }, 0xFB46}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_kuf, 0, 0 }, 0xFB47}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_resh, 0, 0 }, 0xFB48}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_shin, 0, 0 }, 0xFB49}, + {{SCIM_KEY_Multi_key, 0x10005bc, SCIM_KEY_hebrew_taf, 0, 0 }, 0xFB4A}, + {{SCIM_KEY_Multi_key, 0x10005bf, SCIM_KEY_hebrew_bet, 0, 0 }, 0xFB4C}, + {{SCIM_KEY_Multi_key, 0x10005bf, SCIM_KEY_hebrew_kaph, 0, 0 }, 0xFB4D}, + {{SCIM_KEY_Multi_key, 0x10005bf, SCIM_KEY_hebrew_pe, 0, 0 }, 0xFB4E}, + {{SCIM_KEY_Multi_key, 0x10005c1, SCIM_KEY_hebrew_shin, 0, 0 }, 0xFB2A}, + {{SCIM_KEY_Multi_key, 0x10005c1, 0x10005bc, SCIM_KEY_hebrew_shin, 0 }, 0xFB2C}, + {{SCIM_KEY_Multi_key, 0x10005c1, 0x100fb49, 0, 0 }, 0xFB2C}, + {{SCIM_KEY_Multi_key, 0x10005c2, SCIM_KEY_hebrew_shin, 0, 0 }, 0xFB2B}, + {{SCIM_KEY_Multi_key, 0x10005c2, 0x10005bc, SCIM_KEY_hebrew_shin, 0 }, 0xFB2D}, + {{SCIM_KEY_Multi_key, 0x10005c2, 0x100fb49, 0, 0 }, 0xFB2D}, + {{SCIM_KEY_Multi_key, 0x1000653, SCIM_KEY_Arabic_alef, 0, 0 }, 0x0622}, + {{SCIM_KEY_Multi_key, 0x1000654, SCIM_KEY_Arabic_alef, 0, 0 }, 0x0623}, + {{SCIM_KEY_Multi_key, 0x1000654, SCIM_KEY_Arabic_waw, 0, 0 }, 0x0624}, + {{SCIM_KEY_Multi_key, 0x1000654, SCIM_KEY_Arabic_yeh, 0, 0 }, 0x0626}, + {{SCIM_KEY_Multi_key, 0x1000654, 0x10006c1, 0, 0 }, 0x06C2}, + {{SCIM_KEY_Multi_key, 0x1000654, 0x10006d2, 0, 0 }, 0x06D3}, + {{SCIM_KEY_Multi_key, 0x1000654, 0x10006d5, 0, 0 }, 0x06C0}, + {{SCIM_KEY_Multi_key, 0x1000655, SCIM_KEY_Arabic_alef, 0, 0 }, 0x0625}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000915, 0, 0 }, 0x0958}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000916, 0, 0 }, 0x0959}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000917, 0, 0 }, 0x095A}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x100091c, 0, 0 }, 0x095B}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000921, 0, 0 }, 0x095C}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000922, 0, 0 }, 0x095D}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000928, 0, 0 }, 0x0929}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x100092b, 0, 0 }, 0x095E}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x100092f, 0, 0 }, 0x095F}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000930, 0, 0 }, 0x0931}, + {{SCIM_KEY_Multi_key, 0x100093c, 0x1000933, 0, 0 }, 0x0934}, + {{SCIM_KEY_Multi_key, 0x10009bc, 0x10009a1, 0, 0 }, 0x09DC}, + {{SCIM_KEY_Multi_key, 0x10009bc, 0x10009a2, 0, 0 }, 0x09DD}, + {{SCIM_KEY_Multi_key, 0x10009bc, 0x10009af, 0, 0 }, 0x09DF}, + {{SCIM_KEY_Multi_key, 0x10009c7, 0x10009be, 0, 0 }, 0x09CB}, + {{SCIM_KEY_Multi_key, 0x10009c7, 0x10009d7, 0, 0 }, 0x09CC}, + {{SCIM_KEY_Multi_key, 0x1000a3c, 0x1000a16, 0, 0 }, 0x0A59}, + {{SCIM_KEY_Multi_key, 0x1000a3c, 0x1000a17, 0, 0 }, 0x0A5A}, + {{SCIM_KEY_Multi_key, 0x1000a3c, 0x1000a1c, 0, 0 }, 0x0A5B}, + {{SCIM_KEY_Multi_key, 0x1000a3c, 0x1000a2b, 0, 0 }, 0x0A5E}, + {{SCIM_KEY_Multi_key, 0x1000a3c, 0x1000a32, 0, 0 }, 0x0A33}, + {{SCIM_KEY_Multi_key, 0x1000a3c, 0x1000a38, 0, 0 }, 0x0A36}, + {{SCIM_KEY_Multi_key, 0x1000b3c, 0x1000b21, 0, 0 }, 0x0B5C}, + {{SCIM_KEY_Multi_key, 0x1000b3c, 0x1000b22, 0, 0 }, 0x0B5D}, + {{SCIM_KEY_Multi_key, 0x1000b47, 0x1000b3e, 0, 0 }, 0x0B4B}, + {{SCIM_KEY_Multi_key, 0x1000b47, 0x1000b56, 0, 0 }, 0x0B48}, + {{SCIM_KEY_Multi_key, 0x1000b47, 0x1000b57, 0, 0 }, 0x0B4C}, + {{SCIM_KEY_Multi_key, 0x1000bc6, 0x1000bbe, 0, 0 }, 0x0BCA}, + {{SCIM_KEY_Multi_key, 0x1000bc6, 0x1000bd7, 0, 0 }, 0x0BCC}, + {{SCIM_KEY_Multi_key, 0x1000bc7, 0x1000bbe, 0, 0 }, 0x0BCB}, + {{SCIM_KEY_Multi_key, 0x1000bd7, 0x1000b92, 0, 0 }, 0x0B94}, + {{SCIM_KEY_Multi_key, 0x1000c46, 0x1000c56, 0, 0 }, 0x0C48}, + {{SCIM_KEY_Multi_key, 0x1000cbf, 0x1000cd5, 0, 0 }, 0x0CC0}, + {{SCIM_KEY_Multi_key, 0x1000cc6, 0x1000cc2, 0, 0 }, 0x0CCA}, + {{SCIM_KEY_Multi_key, 0x1000cc6, 0x1000cc2, 0x1000cd5, 0 }, 0x0CCB}, + {{SCIM_KEY_Multi_key, 0x1000cc6, 0x1000cd5, 0, 0 }, 0x0CC7}, + {{SCIM_KEY_Multi_key, 0x1000cc6, 0x1000cd6, 0, 0 }, 0x0CC8}, + {{SCIM_KEY_Multi_key, 0x1000cca, 0x1000cd5, 0, 0 }, 0x0CCB}, + {{SCIM_KEY_Multi_key, 0x1000d46, 0x1000d3e, 0, 0 }, 0x0D4A}, + {{SCIM_KEY_Multi_key, 0x1000d46, 0x1000d57, 0, 0 }, 0x0D4C}, + {{SCIM_KEY_Multi_key, 0x1000d47, 0x1000d3e, 0, 0 }, 0x0D4B}, + {{SCIM_KEY_Multi_key, 0x1000dd9, 0x1000dca, 0, 0 }, 0x0DDA}, + {{SCIM_KEY_Multi_key, 0x1000dd9, 0x1000dcf, 0, 0 }, 0x0DDC}, + {{SCIM_KEY_Multi_key, 0x1000dd9, 0x1000dcf, 0x1000dca, 0 }, 0x0DDD}, + {{SCIM_KEY_Multi_key, 0x1000dd9, 0x1000ddf, 0, 0 }, 0x0DDE}, + {{SCIM_KEY_Multi_key, 0x1000ddc, 0x1000dca, 0, 0 }, 0x0DDD}, + {{SCIM_KEY_Multi_key, 0x1000f71, 0x1000f72, 0, 0 }, 0x0F73}, + {{SCIM_KEY_Multi_key, 0x1000f71, 0x1000f74, 0, 0 }, 0x0F75}, + {{SCIM_KEY_Multi_key, 0x1000f71, 0x1000f80, 0, 0 }, 0x0F81}, + {{SCIM_KEY_Multi_key, 0x1000f90, 0x1000fb5, 0, 0 }, 0x0FB9}, + {{SCIM_KEY_Multi_key, 0x1000f92, 0x1000fb7, 0, 0 }, 0x0F93}, + {{SCIM_KEY_Multi_key, 0x1000f9c, 0x1000fb7, 0, 0 }, 0x0F9D}, + {{SCIM_KEY_Multi_key, 0x1000fa1, 0x1000fb7, 0, 0 }, 0x0FA2}, + {{SCIM_KEY_Multi_key, 0x1000fa6, 0x1000fb7, 0, 0 }, 0x0FA7}, + {{SCIM_KEY_Multi_key, 0x1000fab, 0x1000fb7, 0, 0 }, 0x0FAC}, + {{SCIM_KEY_Multi_key, 0x1000fb2, 0x1000f80, 0, 0 }, 0x0F76}, + {{SCIM_KEY_Multi_key, 0x1000fb3, 0x1000f80, 0, 0 }, 0x0F78}, + {{SCIM_KEY_Multi_key, 0x1000fb5, 0x1000f40, 0, 0 }, 0x0F69}, + {{SCIM_KEY_Multi_key, 0x1000fb7, 0x1000f42, 0, 0 }, 0x0F43}, + {{SCIM_KEY_Multi_key, 0x1000fb7, 0x1000f4c, 0, 0 }, 0x0F4D}, + {{SCIM_KEY_Multi_key, 0x1000fb7, 0x1000f51, 0, 0 }, 0x0F52}, + {{SCIM_KEY_Multi_key, 0x1000fb7, 0x1000f56, 0, 0 }, 0x0F57}, + {{SCIM_KEY_Multi_key, 0x1000fb7, 0x1000f5b, 0, 0 }, 0x0F5C}, + {{SCIM_KEY_Multi_key, 0x100102e, 0x1001025, 0, 0 }, 0x1026}, + {{SCIM_KEY_Multi_key, 0x1001100, 0x1001100, 0, 0 }, 0x1101}, + {{SCIM_KEY_Multi_key, 0x1001102, 0x1001100, 0, 0 }, 0x1113}, + {{SCIM_KEY_Multi_key, 0x1001102, 0x1001102, 0, 0 }, 0x1114}, + {{SCIM_KEY_Multi_key, 0x1001102, 0x1001103, 0, 0 }, 0x1115}, + {{SCIM_KEY_Multi_key, 0x1001102, 0x1001107, 0, 0 }, 0x1116}, + {{SCIM_KEY_Multi_key, 0x1001103, 0x1001100, 0, 0 }, 0x1117}, + {{SCIM_KEY_Multi_key, 0x1001103, 0x1001103, 0, 0 }, 0x1104}, + {{SCIM_KEY_Multi_key, 0x1001105, 0x1001102, 0, 0 }, 0x1118}, + {{SCIM_KEY_Multi_key, 0x1001105, 0x1001105, 0, 0 }, 0x1119}, + {{SCIM_KEY_Multi_key, 0x1001105, 0x100110b, 0, 0 }, 0x111B}, + {{SCIM_KEY_Multi_key, 0x1001105, 0x1001112, 0, 0 }, 0x111A}, + {{SCIM_KEY_Multi_key, 0x1001106, 0x1001107, 0, 0 }, 0x111C}, + {{SCIM_KEY_Multi_key, 0x1001106, 0x100110b, 0, 0 }, 0x111D}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001100, 0, 0 }, 0x111E}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001102, 0, 0 }, 0x111F}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001103, 0, 0 }, 0x1120}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001107, 0, 0 }, 0x1108}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001107, 0x100110b, 0 }, 0x112C}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001109, 0, 0 }, 0x1121}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001109, 0x1001100, 0 }, 0x1122}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001109, 0x1001103, 0 }, 0x1123}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001109, 0x1001107, 0 }, 0x1124}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001109, 0x1001109, 0 }, 0x1125}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001109, 0x100110c, 0 }, 0x1126}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x100110a, 0, 0 }, 0x1125}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x100110b, 0, 0 }, 0x112B}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x100110c, 0, 0 }, 0x1127}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x100110e, 0, 0 }, 0x1128}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001110, 0, 0 }, 0x1129}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001111, 0, 0 }, 0x112A}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x100112b, 0, 0 }, 0x112C}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x100112d, 0, 0 }, 0x1122}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x100112f, 0, 0 }, 0x1123}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001132, 0, 0 }, 0x1124}, + {{SCIM_KEY_Multi_key, 0x1001107, 0x1001136, 0, 0 }, 0x1126}, + {{SCIM_KEY_Multi_key, 0x1001108, 0x100110b, 0, 0 }, 0x112C}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001100, 0, 0 }, 0x112D}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001102, 0, 0 }, 0x112E}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001103, 0, 0 }, 0x112F}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001105, 0, 0 }, 0x1130}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001106, 0, 0 }, 0x1131}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001107, 0, 0 }, 0x1132}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001107, 0x1001100, 0 }, 0x1133}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001109, 0, 0 }, 0x110A}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001109, 0x1001109, 0 }, 0x1134}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x100110a, 0, 0 }, 0x1134}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x100110b, 0, 0 }, 0x1135}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x100110c, 0, 0 }, 0x1136}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x100110e, 0, 0 }, 0x1137}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x100110f, 0, 0 }, 0x1138}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001110, 0, 0 }, 0x1139}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001111, 0, 0 }, 0x113A}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x1001112, 0, 0 }, 0x113B}, + {{SCIM_KEY_Multi_key, 0x1001109, 0x100111e, 0, 0 }, 0x1133}, + {{SCIM_KEY_Multi_key, 0x100110a, 0x1001109, 0, 0 }, 0x1134}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001100, 0, 0 }, 0x1141}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001103, 0, 0 }, 0x1142}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001106, 0, 0 }, 0x1143}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001107, 0, 0 }, 0x1144}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001109, 0, 0 }, 0x1145}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x100110b, 0, 0 }, 0x1147}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x100110c, 0, 0 }, 0x1148}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x100110e, 0, 0 }, 0x1149}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001110, 0, 0 }, 0x114A}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001111, 0, 0 }, 0x114B}, + {{SCIM_KEY_Multi_key, 0x100110b, 0x1001140, 0, 0 }, 0x1146}, + {{SCIM_KEY_Multi_key, 0x100110c, 0x100110b, 0, 0 }, 0x114D}, + {{SCIM_KEY_Multi_key, 0x100110c, 0x100110c, 0, 0 }, 0x110D}, + {{SCIM_KEY_Multi_key, 0x100110e, 0x100110f, 0, 0 }, 0x1152}, + {{SCIM_KEY_Multi_key, 0x100110e, 0x1001112, 0, 0 }, 0x1153}, + {{SCIM_KEY_Multi_key, 0x1001111, 0x1001107, 0, 0 }, 0x1156}, + {{SCIM_KEY_Multi_key, 0x1001111, 0x100110b, 0, 0 }, 0x1157}, + {{SCIM_KEY_Multi_key, 0x1001112, 0x1001112, 0, 0 }, 0x1158}, + {{SCIM_KEY_Multi_key, 0x1001121, 0x1001100, 0, 0 }, 0x1122}, + {{SCIM_KEY_Multi_key, 0x1001121, 0x1001103, 0, 0 }, 0x1123}, + {{SCIM_KEY_Multi_key, 0x1001121, 0x1001107, 0, 0 }, 0x1124}, + {{SCIM_KEY_Multi_key, 0x1001121, 0x1001109, 0, 0 }, 0x1125}, + {{SCIM_KEY_Multi_key, 0x1001121, 0x100110c, 0, 0 }, 0x1126}, + {{SCIM_KEY_Multi_key, 0x1001132, 0x1001100, 0, 0 }, 0x1133}, + {{SCIM_KEY_Multi_key, 0x100113c, 0x100113c, 0, 0 }, 0x113D}, + {{SCIM_KEY_Multi_key, 0x100113e, 0x100113e, 0, 0 }, 0x113F}, + {{SCIM_KEY_Multi_key, 0x100114e, 0x100114e, 0, 0 }, 0x114F}, + {{SCIM_KEY_Multi_key, 0x1001150, 0x1001150, 0, 0 }, 0x1151}, + {{SCIM_KEY_Multi_key, 0x1001161, 0x1001169, 0, 0 }, 0x1176}, + {{SCIM_KEY_Multi_key, 0x1001161, 0x100116e, 0, 0 }, 0x1177}, + {{SCIM_KEY_Multi_key, 0x1001161, 0x1001175, 0, 0 }, 0x1162}, + {{SCIM_KEY_Multi_key, 0x1001163, 0x1001169, 0, 0 }, 0x1178}, + {{SCIM_KEY_Multi_key, 0x1001163, 0x100116d, 0, 0 }, 0x1179}, + {{SCIM_KEY_Multi_key, 0x1001163, 0x1001175, 0, 0 }, 0x1164}, + {{SCIM_KEY_Multi_key, 0x1001165, 0x1001169, 0, 0 }, 0x117A}, + {{SCIM_KEY_Multi_key, 0x1001165, 0x100116e, 0, 0 }, 0x117B}, + {{SCIM_KEY_Multi_key, 0x1001165, 0x1001173, 0, 0 }, 0x117C}, + {{SCIM_KEY_Multi_key, 0x1001165, 0x1001175, 0, 0 }, 0x1166}, + {{SCIM_KEY_Multi_key, 0x1001167, 0x1001169, 0, 0 }, 0x117D}, + {{SCIM_KEY_Multi_key, 0x1001167, 0x100116e, 0, 0 }, 0x117E}, + {{SCIM_KEY_Multi_key, 0x1001167, 0x1001175, 0, 0 }, 0x1168}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001161, 0, 0 }, 0x116A}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001161, 0x1001175, 0 }, 0x116B}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001162, 0, 0 }, 0x116B}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001165, 0, 0 }, 0x117F}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001166, 0, 0 }, 0x1180}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001168, 0, 0 }, 0x1181}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001169, 0, 0 }, 0x1182}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x100116e, 0, 0 }, 0x1183}, + {{SCIM_KEY_Multi_key, 0x1001169, 0x1001175, 0, 0 }, 0x116C}, + {{SCIM_KEY_Multi_key, 0x100116a, 0x1001175, 0, 0 }, 0x116B}, + {{SCIM_KEY_Multi_key, 0x100116d, 0x1001163, 0, 0 }, 0x1184}, + {{SCIM_KEY_Multi_key, 0x100116d, 0x1001164, 0, 0 }, 0x1185}, + {{SCIM_KEY_Multi_key, 0x100116d, 0x1001167, 0, 0 }, 0x1186}, + {{SCIM_KEY_Multi_key, 0x100116d, 0x1001169, 0, 0 }, 0x1187}, + {{SCIM_KEY_Multi_key, 0x100116d, 0x1001175, 0, 0 }, 0x1188}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001161, 0, 0 }, 0x1189}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001162, 0, 0 }, 0x118A}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001165, 0, 0 }, 0x116F}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001165, 0x1001173, 0 }, 0x118B}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001165, 0x1001175, 0 }, 0x1170}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001166, 0, 0 }, 0x1170}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001168, 0, 0 }, 0x118C}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x100116e, 0, 0 }, 0x118D}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x1001175, 0, 0 }, 0x1171}, + {{SCIM_KEY_Multi_key, 0x100116e, 0x100117c, 0, 0 }, 0x118B}, + {{SCIM_KEY_Multi_key, 0x100116f, 0x1001173, 0, 0 }, 0x118B}, + {{SCIM_KEY_Multi_key, 0x100116f, 0x1001175, 0, 0 }, 0x1170}, + {{SCIM_KEY_Multi_key, 0x1001172, 0x1001161, 0, 0 }, 0x118E}, + {{SCIM_KEY_Multi_key, 0x1001172, 0x1001165, 0, 0 }, 0x118F}, + {{SCIM_KEY_Multi_key, 0x1001172, 0x1001166, 0, 0 }, 0x1190}, + {{SCIM_KEY_Multi_key, 0x1001172, 0x1001167, 0, 0 }, 0x1191}, + {{SCIM_KEY_Multi_key, 0x1001172, 0x1001168, 0, 0 }, 0x1192}, + {{SCIM_KEY_Multi_key, 0x1001172, 0x100116e, 0, 0 }, 0x1193}, + {{SCIM_KEY_Multi_key, 0x1001172, 0x1001175, 0, 0 }, 0x1194}, + {{SCIM_KEY_Multi_key, 0x1001173, 0x100116e, 0, 0 }, 0x1195}, + {{SCIM_KEY_Multi_key, 0x1001173, 0x1001173, 0, 0 }, 0x1196}, + {{SCIM_KEY_Multi_key, 0x1001173, 0x1001175, 0, 0 }, 0x1174}, + {{SCIM_KEY_Multi_key, 0x1001174, 0x100116e, 0, 0 }, 0x1197}, + {{SCIM_KEY_Multi_key, 0x1001175, 0x1001161, 0, 0 }, 0x1198}, + {{SCIM_KEY_Multi_key, 0x1001175, 0x1001163, 0, 0 }, 0x1199}, + {{SCIM_KEY_Multi_key, 0x1001175, 0x1001169, 0, 0 }, 0x119A}, + {{SCIM_KEY_Multi_key, 0x1001175, 0x100116e, 0, 0 }, 0x119B}, + {{SCIM_KEY_Multi_key, 0x1001175, 0x1001173, 0, 0 }, 0x119C}, + {{SCIM_KEY_Multi_key, 0x1001175, 0x100119e, 0, 0 }, 0x119D}, + {{SCIM_KEY_Multi_key, 0x100119e, 0x1001165, 0, 0 }, 0x119F}, + {{SCIM_KEY_Multi_key, 0x100119e, 0x100116e, 0, 0 }, 0x11A0}, + {{SCIM_KEY_Multi_key, 0x100119e, 0x1001175, 0, 0 }, 0x11A1}, + {{SCIM_KEY_Multi_key, 0x100119e, 0x100119e, 0, 0 }, 0x11A2}, + {{SCIM_KEY_Multi_key, 0x10011a8, 0x10011a8, 0, 0 }, 0x11A9}, + {{SCIM_KEY_Multi_key, 0x10011a8, 0x10011af, 0, 0 }, 0x11C3}, + {{SCIM_KEY_Multi_key, 0x10011a8, 0x10011ba, 0, 0 }, 0x11AA}, + {{SCIM_KEY_Multi_key, 0x10011a8, 0x10011ba, 0x10011a8, 0 }, 0x11C4}, + {{SCIM_KEY_Multi_key, 0x10011a8, 0x10011e7, 0, 0 }, 0x11C4}, + {{SCIM_KEY_Multi_key, 0x10011aa, 0x10011a8, 0, 0 }, 0x11C4}, + {{SCIM_KEY_Multi_key, 0x10011ab, 0x10011a8, 0, 0 }, 0x11C5}, + {{SCIM_KEY_Multi_key, 0x10011ab, 0x10011ae, 0, 0 }, 0x11C6}, + {{SCIM_KEY_Multi_key, 0x10011ab, 0x10011ba, 0, 0 }, 0x11C7}, + {{SCIM_KEY_Multi_key, 0x10011ab, 0x10011bd, 0, 0 }, 0x11AC}, + {{SCIM_KEY_Multi_key, 0x10011ab, 0x10011c0, 0, 0 }, 0x11C9}, + {{SCIM_KEY_Multi_key, 0x10011ab, 0x10011c2, 0, 0 }, 0x11AD}, + {{SCIM_KEY_Multi_key, 0x10011ab, 0x10011eb, 0, 0 }, 0x11C8}, + {{SCIM_KEY_Multi_key, 0x10011ae, 0x10011a8, 0, 0 }, 0x11CA}, + {{SCIM_KEY_Multi_key, 0x10011ae, 0x10011af, 0, 0 }, 0x11CB}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011a8, 0, 0 }, 0x11B0}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011a8, 0x10011ba, 0 }, 0x11CC}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011aa, 0, 0 }, 0x11CC}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011ab, 0, 0 }, 0x11CD}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011ae, 0, 0 }, 0x11CE}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011ae, 0x10011c2, 0 }, 0x11CF}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011af, 0, 0 }, 0x11D0}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b7, 0, 0 }, 0x11B1}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b7, 0x10011a8, 0 }, 0x11D1}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b7, 0x10011ba, 0 }, 0x11D2}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b8, 0, 0 }, 0x11B2}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b8, 0x10011ba, 0 }, 0x11D3}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b8, 0x10011bc, 0 }, 0x11D5}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b8, 0x10011c2, 0 }, 0x11D4}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011b9, 0, 0 }, 0x11D3}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011ba, 0, 0 }, 0x11B3}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011ba, 0x10011ba, 0 }, 0x11D6}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011bb, 0, 0 }, 0x11D6}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011bf, 0, 0 }, 0x11D8}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011c0, 0, 0 }, 0x11B4}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011c1, 0, 0 }, 0x11B5}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011c2, 0, 0 }, 0x11B6}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011da, 0, 0 }, 0x11D1}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011dd, 0, 0 }, 0x11D2}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011e5, 0, 0 }, 0x11D4}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011e6, 0, 0 }, 0x11D5}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011eb, 0, 0 }, 0x11D7}, + {{SCIM_KEY_Multi_key, 0x10011af, 0x10011f9, 0, 0 }, 0x11D9}, + {{SCIM_KEY_Multi_key, 0x10011b0, 0x10011ba, 0, 0 }, 0x11CC}, + {{SCIM_KEY_Multi_key, 0x10011b1, 0x10011a8, 0, 0 }, 0x11D1}, + {{SCIM_KEY_Multi_key, 0x10011b1, 0x10011ba, 0, 0 }, 0x11D2}, + {{SCIM_KEY_Multi_key, 0x10011b2, 0x10011ba, 0, 0 }, 0x11D3}, + {{SCIM_KEY_Multi_key, 0x10011b2, 0x10011bc, 0, 0 }, 0x11D5}, + {{SCIM_KEY_Multi_key, 0x10011b2, 0x10011c2, 0, 0 }, 0x11D4}, + {{SCIM_KEY_Multi_key, 0x10011b3, 0x10011ba, 0, 0 }, 0x11D6}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011a8, 0, 0 }, 0x11DA}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011af, 0, 0 }, 0x11DB}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011b8, 0, 0 }, 0x11DC}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011ba, 0, 0 }, 0x11DD}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011ba, 0x10011ba, 0 }, 0x11DE}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011bb, 0, 0 }, 0x11DE}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011bc, 0, 0 }, 0x11E2}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011be, 0, 0 }, 0x11E0}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011c2, 0, 0 }, 0x11E1}, + {{SCIM_KEY_Multi_key, 0x10011b7, 0x10011eb, 0, 0 }, 0x11DF}, + {{SCIM_KEY_Multi_key, 0x10011b8, 0x10011af, 0, 0 }, 0x11E3}, + {{SCIM_KEY_Multi_key, 0x10011b8, 0x10011ba, 0, 0 }, 0x11B9}, + {{SCIM_KEY_Multi_key, 0x10011b8, 0x10011bc, 0, 0 }, 0x11E6}, + {{SCIM_KEY_Multi_key, 0x10011b8, 0x10011c1, 0, 0 }, 0x11E4}, + {{SCIM_KEY_Multi_key, 0x10011b8, 0x10011c2, 0, 0 }, 0x11E5}, + {{SCIM_KEY_Multi_key, 0x10011ba, 0x10011a8, 0, 0 }, 0x11E7}, + {{SCIM_KEY_Multi_key, 0x10011ba, 0x10011ae, 0, 0 }, 0x11E8}, + {{SCIM_KEY_Multi_key, 0x10011ba, 0x10011af, 0, 0 }, 0x11E9}, + {{SCIM_KEY_Multi_key, 0x10011ba, 0x10011b8, 0, 0 }, 0x11EA}, + {{SCIM_KEY_Multi_key, 0x10011ba, 0x10011ba, 0, 0 }, 0x11BB}, + {{SCIM_KEY_Multi_key, 0x10011bc, 0x10011a8, 0, 0 }, 0x11EC}, + {{SCIM_KEY_Multi_key, 0x10011bc, 0x10011a8, 0x10011a8, 0 }, 0x11ED}, + {{SCIM_KEY_Multi_key, 0x10011bc, 0x10011a9, 0, 0 }, 0x11ED}, + {{SCIM_KEY_Multi_key, 0x10011bc, 0x10011bc, 0, 0 }, 0x11EE}, + {{SCIM_KEY_Multi_key, 0x10011bc, 0x10011bf, 0, 0 }, 0x11EF}, + {{SCIM_KEY_Multi_key, 0x10011c1, 0x10011b8, 0, 0 }, 0x11F3}, + {{SCIM_KEY_Multi_key, 0x10011c1, 0x10011bc, 0, 0 }, 0x11F4}, + {{SCIM_KEY_Multi_key, 0x10011c2, 0x10011ab, 0, 0 }, 0x11F5}, + {{SCIM_KEY_Multi_key, 0x10011c2, 0x10011af, 0, 0 }, 0x11F6}, + {{SCIM_KEY_Multi_key, 0x10011c2, 0x10011b7, 0, 0 }, 0x11F7}, + {{SCIM_KEY_Multi_key, 0x10011c2, 0x10011b8, 0, 0 }, 0x11F8}, + {{SCIM_KEY_Multi_key, 0x10011ce, 0x10011c2, 0, 0 }, 0x11CF}, + {{SCIM_KEY_Multi_key, 0x10011dd, 0x10011ba, 0, 0 }, 0x11DE}, + {{SCIM_KEY_Multi_key, 0x10011ec, 0x10011a8, 0, 0 }, 0x11ED}, + {{SCIM_KEY_Multi_key, 0x10011f0, 0x10011ba, 0, 0 }, 0x11F1}, + {{SCIM_KEY_Multi_key, 0x10011f0, 0x10011eb, 0, 0 }, 0x11F2}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_apostrophe, 0, 0 }, 0x1FCE}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_grave, 0, 0 }, 0x1FCD}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_asciitilde, 0, 0 }, 0x1FCF}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_acute, 0, 0 }, 0x1FCE}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_combining_grave, 0, 0 }, 0x1FCD}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_combining_acute, 0, 0 }, 0x1FCE}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_dead_grave, 0, 0 }, 0x1FCD}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_dead_acute, 0, 0 }, 0x1FCE}, + {{SCIM_KEY_Multi_key, 0x1001fbf, SCIM_KEY_dead_tilde, 0, 0 }, 0x1FCF}, + {{SCIM_KEY_Multi_key, 0x1001fbf, 0x1000342, 0, 0 }, 0x1FCF}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_apostrophe, 0, 0 }, 0x1FDE}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_grave, 0, 0 }, 0x1FDD}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_asciitilde, 0, 0 }, 0x1FDF}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_acute, 0, 0 }, 0x1FDE}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_combining_grave, 0, 0 }, 0x1FDD}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_combining_acute, 0, 0 }, 0x1FDE}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_dead_grave, 0, 0 }, 0x1FDD}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_dead_acute, 0, 0 }, 0x1FDE}, + {{SCIM_KEY_Multi_key, 0x1001ffe, SCIM_KEY_dead_tilde, 0, 0 }, 0x1FDF}, + {{SCIM_KEY_Multi_key, 0x1001ffe, 0x1000342, 0, 0 }, 0x1FDF}, + {{SCIM_KEY_Multi_key, 0x1002203, 0x1000338, 0, 0 }, 0x2204}, + {{SCIM_KEY_Multi_key, 0x1002208, 0x1000338, 0, 0 }, 0x2209}, + {{SCIM_KEY_Multi_key, 0x100220b, 0x1000338, 0, 0 }, 0x220C}, + {{SCIM_KEY_Multi_key, 0x1002223, 0x1000338, 0, 0 }, 0x2224}, + {{SCIM_KEY_Multi_key, 0x1002225, 0x1000338, 0, 0 }, 0x2226}, + {{SCIM_KEY_Multi_key, 0x100223c, 0x1000338, 0, 0 }, 0x2241}, + {{SCIM_KEY_Multi_key, 0x1002243, 0x1000338, 0, 0 }, 0x2244}, + {{SCIM_KEY_Multi_key, 0x1002248, 0x1000338, 0, 0 }, 0x2249}, + {{SCIM_KEY_Multi_key, 0x100224d, 0x1000338, 0, 0 }, 0x226D}, + {{SCIM_KEY_Multi_key, 0x1002272, 0x1000338, 0, 0 }, 0x2274}, + {{SCIM_KEY_Multi_key, 0x1002273, 0x1000338, 0, 0 }, 0x2275}, + {{SCIM_KEY_Multi_key, 0x1002276, 0x1000338, 0, 0 }, 0x2278}, + {{SCIM_KEY_Multi_key, 0x1002277, 0x1000338, 0, 0 }, 0x2279}, + {{SCIM_KEY_Multi_key, 0x100227a, 0x1000338, 0, 0 }, 0x2280}, + {{SCIM_KEY_Multi_key, 0x100227b, 0x1000338, 0, 0 }, 0x2281}, + {{SCIM_KEY_Multi_key, 0x100227c, 0x1000338, 0, 0 }, 0x22E0}, + {{SCIM_KEY_Multi_key, 0x100227d, 0x1000338, 0, 0 }, 0x22E1}, + {{SCIM_KEY_Multi_key, 0x1002286, 0x1000338, 0, 0 }, 0x2288}, + {{SCIM_KEY_Multi_key, 0x1002287, 0x1000338, 0, 0 }, 0x2289}, + {{SCIM_KEY_Multi_key, 0x1002291, 0x1000338, 0, 0 }, 0x22E2}, + {{SCIM_KEY_Multi_key, 0x1002292, 0x1000338, 0, 0 }, 0x22E3}, + {{SCIM_KEY_Multi_key, 0x10022a8, 0x1000338, 0, 0 }, 0x22AD}, + {{SCIM_KEY_Multi_key, 0x10022a9, 0x1000338, 0, 0 }, 0x22AE}, + {{SCIM_KEY_Multi_key, 0x10022ab, 0x1000338, 0, 0 }, 0x22AF}, + {{SCIM_KEY_Multi_key, 0x10022b2, 0x1000338, 0, 0 }, 0x22EA}, + {{SCIM_KEY_Multi_key, 0x10022b3, 0x1000338, 0, 0 }, 0x22EB}, + {{SCIM_KEY_Multi_key, 0x10022b4, 0x1000338, 0, 0 }, 0x22EC}, + {{SCIM_KEY_Multi_key, 0x10022b5, 0x1000338, 0, 0 }, 0x22ED}, + {{SCIM_KEY_Multi_key, 0x1002add, 0x1000338, 0, 0 }, 0x2ADC}, + {{0x100030f, SCIM_KEY_A, 0, 0, 0 }, 0x0200}, + {{0x100030f, SCIM_KEY_E, 0, 0, 0 }, 0x0204}, + {{0x100030f, SCIM_KEY_I, 0, 0, 0 }, 0x0208}, + {{0x100030f, SCIM_KEY_O, 0, 0, 0 }, 0x020C}, + {{0x100030f, SCIM_KEY_R, 0, 0, 0 }, 0x0210}, + {{0x100030f, SCIM_KEY_U, 0, 0, 0 }, 0x0214}, + {{0x100030f, SCIM_KEY_a, 0, 0, 0 }, 0x0201}, + {{0x100030f, SCIM_KEY_e, 0, 0, 0 }, 0x0205}, + {{0x100030f, SCIM_KEY_i, 0, 0, 0 }, 0x0209}, + {{0x100030f, SCIM_KEY_o, 0, 0, 0 }, 0x020D}, + {{0x100030f, SCIM_KEY_r, 0, 0, 0 }, 0x0211}, + {{0x100030f, SCIM_KEY_u, 0, 0, 0 }, 0x0215}, + {{0x100030f, 0x1000474, 0, 0, 0 }, 0x0476}, + {{0x100030f, 0x1000475, 0, 0, 0 }, 0x0477}, + {{0x1000311, SCIM_KEY_A, 0, 0, 0 }, 0x0202}, + {{0x1000311, SCIM_KEY_E, 0, 0, 0 }, 0x0206}, + {{0x1000311, SCIM_KEY_I, 0, 0, 0 }, 0x020A}, + {{0x1000311, SCIM_KEY_O, 0, 0, 0 }, 0x020E}, + {{0x1000311, SCIM_KEY_R, 0, 0, 0 }, 0x0212}, + {{0x1000311, SCIM_KEY_U, 0, 0, 0 }, 0x0216}, + {{0x1000311, SCIM_KEY_a, 0, 0, 0 }, 0x0203}, + {{0x1000311, SCIM_KEY_e, 0, 0, 0 }, 0x0207}, + {{0x1000311, SCIM_KEY_i, 0, 0, 0 }, 0x020B}, + {{0x1000311, SCIM_KEY_o, 0, 0, 0 }, 0x020F}, + {{0x1000311, SCIM_KEY_r, 0, 0, 0 }, 0x0213}, + {{0x1000311, SCIM_KEY_u, 0, 0, 0 }, 0x0217}, + {{0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x1F08}, + {{0x1000313, SCIM_KEY_Greek_EPSILON, 0, 0, 0 }, 0x1F18}, + {{0x1000313, SCIM_KEY_Greek_ETA, 0, 0, 0 }, 0x1F28}, + {{0x1000313, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x1F38}, + {{0x1000313, SCIM_KEY_Greek_OMICRON, 0, 0, 0 }, 0x1F48}, + {{0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0, 0 }, 0x1F68}, + {{0x1000313, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1F00}, + {{0x1000313, SCIM_KEY_Greek_epsilon, 0, 0, 0 }, 0x1F10}, + {{0x1000313, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x1F20}, + {{0x1000313, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1F30}, + {{0x1000313, SCIM_KEY_Greek_omicron, 0, 0, 0 }, 0x1F40}, + {{0x1000313, SCIM_KEY_Greek_rho, 0, 0, 0 }, 0x1FE4}, + {{0x1000313, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1F50}, + {{0x1000313, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x1F60}, + {{0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0, 0 }, 0x1F09}, + {{0x1000314, SCIM_KEY_Greek_EPSILON, 0, 0, 0 }, 0x1F19}, + {{0x1000314, SCIM_KEY_Greek_ETA, 0, 0, 0 }, 0x1F29}, + {{0x1000314, SCIM_KEY_Greek_IOTA, 0, 0, 0 }, 0x1F39}, + {{0x1000314, SCIM_KEY_Greek_OMICRON, 0, 0, 0 }, 0x1F49}, + {{0x1000314, SCIM_KEY_Greek_RHO, 0, 0, 0 }, 0x1FEC}, + {{0x1000314, SCIM_KEY_Greek_UPSILON, 0, 0, 0 }, 0x1F59}, + {{0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0, 0 }, 0x1F69}, + {{0x1000314, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1F01}, + {{0x1000314, SCIM_KEY_Greek_epsilon, 0, 0, 0 }, 0x1F11}, + {{0x1000314, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x1F21}, + {{0x1000314, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1F31}, + {{0x1000314, SCIM_KEY_Greek_omicron, 0, 0, 0 }, 0x1F41}, + {{0x1000314, SCIM_KEY_Greek_rho, 0, 0, 0 }, 0x1FE5}, + {{0x1000314, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1F51}, + {{0x1000314, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x1F61}, + {{0x1000324, SCIM_KEY_U, 0, 0, 0 }, 0x1E72}, + {{0x1000324, SCIM_KEY_u, 0, 0, 0 }, 0x1E73}, + {{0x1000325, SCIM_KEY_A, 0, 0, 0 }, 0x1E00}, + {{0x1000325, SCIM_KEY_a, 0, 0, 0 }, 0x1E01}, + {{0x1000326, SCIM_KEY_S, 0, 0, 0 }, 0x0218}, + {{0x1000326, SCIM_KEY_T, 0, 0, 0 }, 0x021A}, + {{0x1000326, SCIM_KEY_s, 0, 0, 0 }, 0x0219}, + {{0x1000326, SCIM_KEY_t, 0, 0, 0 }, 0x021B}, + {{0x100032d, SCIM_KEY_D, 0, 0, 0 }, 0x1E12}, + {{0x100032d, SCIM_KEY_E, 0, 0, 0 }, 0x1E18}, + {{0x100032d, SCIM_KEY_L, 0, 0, 0 }, 0x1E3C}, + {{0x100032d, SCIM_KEY_N, 0, 0, 0 }, 0x1E4A}, + {{0x100032d, SCIM_KEY_T, 0, 0, 0 }, 0x1E70}, + {{0x100032d, SCIM_KEY_U, 0, 0, 0 }, 0x1E76}, + {{0x100032d, SCIM_KEY_d, 0, 0, 0 }, 0x1E13}, + {{0x100032d, SCIM_KEY_e, 0, 0, 0 }, 0x1E19}, + {{0x100032d, SCIM_KEY_l, 0, 0, 0 }, 0x1E3D}, + {{0x100032d, SCIM_KEY_n, 0, 0, 0 }, 0x1E4B}, + {{0x100032d, SCIM_KEY_t, 0, 0, 0 }, 0x1E71}, + {{0x100032d, SCIM_KEY_u, 0, 0, 0 }, 0x1E77}, + {{0x100032e, SCIM_KEY_H, 0, 0, 0 }, 0x1E2A}, + {{0x100032e, SCIM_KEY_h, 0, 0, 0 }, 0x1E2B}, + {{0x1000330, SCIM_KEY_E, 0, 0, 0 }, 0x1E1A}, + {{0x1000330, SCIM_KEY_I, 0, 0, 0 }, 0x1E2C}, + {{0x1000330, SCIM_KEY_U, 0, 0, 0 }, 0x1E74}, + {{0x1000330, SCIM_KEY_e, 0, 0, 0 }, 0x1E1B}, + {{0x1000330, SCIM_KEY_i, 0, 0, 0 }, 0x1E2D}, + {{0x1000330, SCIM_KEY_u, 0, 0, 0 }, 0x1E75}, + {{0x1000331, SCIM_KEY_B, 0, 0, 0 }, 0x1E06}, + {{0x1000331, SCIM_KEY_D, 0, 0, 0 }, 0x1E0E}, + {{0x1000331, SCIM_KEY_K, 0, 0, 0 }, 0x1E34}, + {{0x1000331, SCIM_KEY_L, 0, 0, 0 }, 0x1E3A}, + {{0x1000331, SCIM_KEY_N, 0, 0, 0 }, 0x1E48}, + {{0x1000331, SCIM_KEY_R, 0, 0, 0 }, 0x1E5E}, + {{0x1000331, SCIM_KEY_T, 0, 0, 0 }, 0x1E6E}, + {{0x1000331, SCIM_KEY_Z, 0, 0, 0 }, 0x1E94}, + {{0x1000331, SCIM_KEY_b, 0, 0, 0 }, 0x1E07}, + {{0x1000331, SCIM_KEY_d, 0, 0, 0 }, 0x1E0F}, + {{0x1000331, SCIM_KEY_h, 0, 0, 0 }, 0x1E96}, + {{0x1000331, SCIM_KEY_k, 0, 0, 0 }, 0x1E35}, + {{0x1000331, SCIM_KEY_l, 0, 0, 0 }, 0x1E3B}, + {{0x1000331, SCIM_KEY_n, 0, 0, 0 }, 0x1E49}, + {{0x1000331, SCIM_KEY_r, 0, 0, 0 }, 0x1E5F}, + {{0x1000331, SCIM_KEY_t, 0, 0, 0 }, 0x1E6F}, + {{0x1000331, SCIM_KEY_z, 0, 0, 0 }, 0x1E95}, + {{0x1000342, SCIM_KEY_Greek_iotadieresis, 0, 0, 0 }, 0x1FD7}, + {{0x1000342, SCIM_KEY_Greek_upsilondieresis, 0, 0, 0 }, 0x1FE7}, + {{0x1000342, SCIM_KEY_Greek_alpha, 0, 0, 0 }, 0x1FB6}, + {{0x1000342, SCIM_KEY_Greek_eta, 0, 0, 0 }, 0x1FC6}, + {{0x1000342, SCIM_KEY_Greek_iota, 0, 0, 0 }, 0x1FD6}, + {{0x1000342, SCIM_KEY_Greek_upsilon, 0, 0, 0 }, 0x1FE6}, + {{0x1000342, SCIM_KEY_Greek_omega, 0, 0, 0 }, 0x1FF6}, + {{0x1000342, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_iota, 0, 0 }, 0x1FD7}, + {{0x1000342, SCIM_KEY_dead_diaeresis, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1FE7}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_iota, 0 }, 0x1FD7}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_quotedbl, SCIM_KEY_Greek_upsilon, 0 }, 0x1FE7}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0F}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_ETA, 0 }, 0x1F2F}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3F}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_UPSILON, 0 }, 0x1F5F}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6F}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_alpha, 0 }, 0x1F07}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_eta, 0 }, 0x1F27}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_iota, 0 }, 0x1F37}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_upsilon, 0 }, 0x1F57}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenleft, SCIM_KEY_Greek_omega, 0 }, 0x1F67}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ALPHA, 0 }, 0x1F0E}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_ETA, 0 }, 0x1F2E}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_IOTA, 0 }, 0x1F3E}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_OMEGA, 0 }, 0x1F6E}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_alpha, 0 }, 0x1F06}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_eta, 0 }, 0x1F26}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_iota, 0 }, 0x1F36}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_upsilon, 0 }, 0x1F56}, + {{0x1000342, SCIM_KEY_Multi_key, SCIM_KEY_parenright, SCIM_KEY_Greek_omega, 0 }, 0x1F66}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0E}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2E}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3E}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6E}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F06}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F26}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F36}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F56}, + {{0x1000342, 0x1000313, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F66}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_ALPHA, 0, 0 }, 0x1F0F}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_ETA, 0, 0 }, 0x1F2F}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_IOTA, 0, 0 }, 0x1F3F}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_UPSILON, 0, 0 }, 0x1F5F}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_OMEGA, 0, 0 }, 0x1F6F}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_alpha, 0, 0 }, 0x1F07}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_eta, 0, 0 }, 0x1F27}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_iota, 0, 0 }, 0x1F37}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_upsilon, 0, 0 }, 0x1F57}, + {{0x1000342, 0x1000314, SCIM_KEY_Greek_omega, 0, 0 }, 0x1F67}, + {{0x1000342, 0x1001f00, 0, 0, 0 }, 0x1F06}, + {{0x1000342, 0x1001f01, 0, 0, 0 }, 0x1F07}, + {{0x1000342, 0x1001f08, 0, 0, 0 }, 0x1F0E}, + {{0x1000342, 0x1001f09, 0, 0, 0 }, 0x1F0F}, + {{0x1000342, 0x1001f20, 0, 0, 0 }, 0x1F26}, + {{0x1000342, 0x1001f21, 0, 0, 0 }, 0x1F27}, + {{0x1000342, 0x1001f28, 0, 0, 0 }, 0x1F2E}, + {{0x1000342, 0x1001f29, 0, 0, 0 }, 0x1F2F}, + {{0x1000342, 0x1001f30, 0, 0, 0 }, 0x1F36}, + {{0x1000342, 0x1001f31, 0, 0, 0 }, 0x1F37}, + {{0x1000342, 0x1001f38, 0, 0, 0 }, 0x1F3E}, + {{0x1000342, 0x1001f39, 0, 0, 0 }, 0x1F3F}, + {{0x1000342, 0x1001f50, 0, 0, 0 }, 0x1F56}, + {{0x1000342, 0x1001f51, 0, 0, 0 }, 0x1F57}, + {{0x1000342, 0x1001f59, 0, 0, 0 }, 0x1F5F}, + {{0x1000342, 0x1001f60, 0, 0, 0 }, 0x1F66}, + {{0x1000342, 0x1001f61, 0, 0, 0 }, 0x1F67}, + {{0x1000342, 0x1001f68, 0, 0, 0 }, 0x1F6E}, + {{0x1000342, 0x1001f69, 0, 0, 0 }, 0x1F6F}, diff --git a/ism/src/scim_config_agent.cpp b/ism/src/scim_config_agent.cpp new file mode 100644 index 0000000..7ea312b --- /dev/null +++ b/ism/src/scim_config_agent.cpp @@ -0,0 +1,475 @@ +/* + * Smart Common Input Method + * + * Copyright (c) 2002-2005 James Su + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * $Id: scim_config_agent.cpp,v 1.10 2005/07/03 08:36:42 suzhe Exp $ + * + */ + +#define Uses_STL_IOSTREAM +#define Uses_C_LOCALE +#define Uses_SCIM_CONFIG_MODULE +#define Uses_SCIM_HELPER +#define Uses_SCIM_CONFIG_PATH + +#include "scim_private.h" +#include +#include + +using namespace scim; +using std::cout; +using std::cerr; +using std::endl; + +enum DataType +{ + DATA_TYPE_STRING, + DATA_TYPE_INT, + DATA_TYPE_DOUBLE, + DATA_TYPE_BOOL, + DATA_TYPE_STRING_LIST, + DATA_TYPE_INT_LIST +}; + +enum Command +{ + DO_NOTHING, + GET_DATA, + SET_DATA, + DEL_KEY +}; + +static String trim_blank (const String &str) +{ + String::size_type begin, len; + + begin = str.find_first_not_of (" \t\n\v"); + + if (begin == String::npos) + return String (); + + len = str.find_last_not_of (" \t\n\v") - begin + 1; + + return str.substr (begin, len); +} + +static String get_param_portion (const String &str) +{ + String::size_type begin = str.find_first_of (" \t\n\v="); + + if (begin == String::npos) return str; + + return str.substr (0, begin); +} + +static String get_value_portion (const String &str) +{ + String::size_type begin = str.find_first_of ("="); + + if (begin == String::npos || (begin + 1) == str.length ()) return String (""); + + return trim_blank (str.substr (begin + 1, String::npos)); +} + +int main (int argc, char *argv []) +{ + static ConfigModule config_module; + + ConfigPointer config; + std::vector config_list; + String def_config; + String key; + String value; + String display; + + DataType type = DATA_TYPE_STRING; + Command cmd = DO_NOTHING; + bool reload = false; + bool global = false; + + int i; + + char *p = getenv ("DISPLAY"); + if (p) display = String (p); + + //get modules list + scim_get_config_module_list (config_list); + + //Use simple Config module as default if available. + if (config_list.size ()) { + def_config = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE, String ("simple")); + if (std::find (config_list.begin (), + config_list.end (), + def_config) == config_list.end ()) + def_config = config_list [0]; + } else { + cerr << "No config module found.\n"; + return -1; + } + + // parse command options + i = 0; + while (i= argc) break; + + if (String ("-h") == argv [i] || + String ("--help") == argv [i]) { + cout << "Usage: " << argv [0] << "