commit 9b452c0ffa2e70a3c4f624069a6b0f61147c42fb Author: Daiki Ueno Date: Fri Jun 4 12:09:08 2010 +0900 Initial commit. diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 00000000..dd71db9d --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,2 @@ +((c-mode . ((c-basic-offset . 4) + (indent-tabs-mode . nil)))) \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..4a9b5868 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +*.la +*.lo +*.loT +*.o +*.so +*~ +Makefile +Makefile.in +.deps +.libs +INSTALL +aclocal.m4 +autom4te.cache +compile +config.guess +config.h +config.h.in +config.log +config.rpath +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +missing +stamp-h1 +libkeyactor*.tar.* +mkinstalldirs +docs/reference/eek/eek-overrides.txt +docs/reference/eek/eek-sections.txt +docs/reference/eek/eek.types +m4/*.m4 +gtk-doc.make +eek/eek-special-keysym-labels.h +eek/eek-unicode-keysym-labels.h +eek/eek-keyname-keysym-labels.h \ No newline at end of file diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..e69de29b diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state 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 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..85f73808 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,20 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = eek examples tests docs diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/README b/README new file mode 100644 index 00000000..571a745c --- /dev/null +++ b/README @@ -0,0 +1,39 @@ +eek - easy embedded keyboard + +*NOTE* This is not usable by now. It has still a lot of bugs and lacks +many essentital features. + +* How to test + + $ git clone git://github.com/ueno/eek.git + $ cd eek + $ ./autogen.sh --prefix=/usr --enable-gtk-doc + $ make + $ ./examples/eek-clutter-xkb-test --geometry=winbook --symbols=in + +* API + +There are two kinds of objects in eek. One is "keyboard element" and +another is "keyboard layout engine". A keyboard element represents +either a keyboard, a section, or a key. Each element implements the +Builder pattern so that it can be converted into a UI widget +(ClutterActor, GTK+ button, ...). A keyboard layout engine arranges +keyboard elements using layout rules from external configuration +mechanisms (XKB, matchbox-keyboard layouts in XML, ...) + +Here is a sample code which utilizes Clutter-based keyboard elements +and an XKB-based layout engine: + + EekKeyboard *keyboard; + EekLayout *layout; + + /* Create a keyboard layout from XKB configuration. */ + layout = eek_xkb_layout_new (NULL, "winbook", "in"); + + /* Create a keyboard that is implemented as ClutterActor. */ + keyboard = eek_clutter_keyboard_new (); + + /* Apply the layout to the keyboard. */ + eek_keyboard_set_layout (keyboard, layout); + + clutter_group_add (CLUTTER_GROUP(stage), CLUTTER_ACTOR(keyboard)); diff --git a/TODO b/TODO new file mode 100644 index 00000000..4acf1d3f --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +- modifier handling +- step-by-step scaling of key labels +- GTK+ keyboard elements +- matchbox-keyboard layout engine +- emit key events using libfakekey or xtest +- .spec +- .pc diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..c7b05b9b --- /dev/null +++ b/autogen.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +PKG_NAME="eek" + +(test -f $srcdir/configure.ac \ + && test -f $srcdir/README ) || { + echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" + echo " top-level $PKG_NAME directory" + exit 1 +} + +which gnome-autogen.sh || { + echo "You need to install gnome-common from the GNOME CVS" + exit 1 +} + +ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4" +REQUIRED_AUTOMAKE_VERSION=1.8 + +. gnome-autogen.sh diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..344d9472 --- /dev/null +++ b/configure.ac @@ -0,0 +1,53 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +AC_INIT([eek], [0.0.0], [ueno@unixuser.org]) +AC_CONFIG_SRCDIR([configure.ac]) +AC_PREREQ(2.63) +AM_INIT_AUTOMAKE +AM_PROG_CC_C_O +AC_CONFIG_MACRO_DIR([m4]) +LT_INIT + +PKG_CHECK_MODULES([GLIB2], [glib-2.0], , + [AC_MSG_ERROR([GLib2 not found])]) +PKG_CHECK_MODULES([GOBJECT2], [gobject-2.0], , + [AC_MSG_ERROR([GObject2 not found])]) +PKG_CHECK_MODULES([CAIRO], [cairo], , + [AC_MSG_ERROR([Cairo not found])]) +PKG_CHECK_MODULES([PANGO], [pango], , + [AC_MSG_ERROR([Pango not found])]) +PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], , + [AC_MSG_ERROR([Clutter not found])]) +PKG_CHECK_MODULES([XKB], [gtk+-2.0 gdk-2.0 x11], , + [AC_MSG_ERROR([XKB support not found])]) + +GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) + +EEK_API_VERSION=0.1 +AC_SUBST(EEK_API_VERSION) + +AC_CONFIG_HEADERS([eek/config.h]) +AC_CONFIG_FILES([Makefile +eek/Makefile +examples/Makefile +tests/Makefile +docs/Makefile +docs/reference/Makefile +docs/reference/eek/Makefile]) +AC_OUTPUT diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 00000000..173a4e6e --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,19 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +SUBDIRS = reference \ No newline at end of file diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am new file mode 100644 index 00000000..123b1f1b --- /dev/null +++ b/docs/reference/Makefile.am @@ -0,0 +1,19 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +SUBDIRS = eek diff --git a/docs/reference/eek/Makefile.am b/docs/reference/eek/Makefile.am new file mode 100644 index 00000000..9233497b --- /dev/null +++ b/docs/reference/eek/Makefile.am @@ -0,0 +1,129 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +## Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=eek + +# Uncomment for versioned docs and specify the version of the module, e.g. '2'. +#DOC_MODULE_VERSION=2 + + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR=../../../eek + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS= + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS=--sgml-mode --output-format=xml + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-mkhtml +MKHTML_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS= + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/eek/*.h +CFILE_GLOB=$(top_srcdir)/eek/*.c + +# Extra header to include when scanning, which are not under DOC_SOURCE_DIR +# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h +EXTRA_HFILES= + +# Header files to ignore when scanning. Use base file name, no paths +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES= eek-private.h \ + eek-clutter-private.h \ + eek-keysyms.h \ + $(NULL) + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files= + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS = $(GOBJECT2_CFLAGS) +GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \ + $(top_srcdir)/eek/libeek-clutter.la \ + $(top_srcdir)/eek/libeek-xkb.la \ + $(GOBJECT2_LIBS) \ + $(CLUTTER_LIBS) \ + $(XKB_LIBS) \ + $(NULL) + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += + +# Files not to distribute +# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types +# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt +#DISTCLEANFILES += + +# Comment this out if you want your docs-status tested during 'make check' +if ENABLE_GTK_DOC +#TESTS_ENVIRONMENT = cd $(srcsrc) && +#TESTS = $(GTKDOC_CHECK) +endif + +-include $(top_srcdir)/gtk-doc.mk diff --git a/docs/reference/eek/eek-docs.sgml b/docs/reference/eek/eek-docs.sgml new file mode 100644 index 00000000..7c75aa0f --- /dev/null +++ b/docs/reference/eek/eek-docs.sgml @@ -0,0 +1,42 @@ + + +]> + + + eek Reference Manual + + for eek 0.0.0. + + + + + Base classes and interfaces + + + + + + + Clutter keyboard elements + + + + + + XKB layout engine + + + + Object Hierarchy + + + + API Index + + + + + diff --git a/eek/Makefile.am b/eek/Makefile.am new file mode 100644 index 00000000..de048710 --- /dev/null +++ b/eek/Makefile.am @@ -0,0 +1,107 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +lib_LTLIBRARIES = libeek.la libeek-clutter.la libeek-xkb.la + +libeek_la_SOURCES = \ + eek-layout.c \ + eek-layout.h \ + eek-keyboard.c \ + eek-keyboard.h \ + eek-section.c \ + eek-section.h \ + eek-key.c \ + eek-key.h \ + eek-simple-keyboard.c \ + eek-simple-keyboard.h \ + eek-simple-section.c \ + eek-simple-section.h \ + eek-simple-key.c \ + eek-simple-key.h \ + eek-private.c \ + eek-private.h \ + eek-types.h \ + eek-types.c \ + eek-keysym.h \ + eek-keysym.c \ + eek-special-keysym-labels.h \ + eek-unicode-keysym-labels.h \ + eek-keyname-keysym-labels.h \ + $(NULL) + +libeek_la_CFLAGS = $(GOBJECT2_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) +libeek_la_LIBADD = $(GOBJECT2_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS) + +libeek_clutter_la_SOURCES = \ + eek-clutter-keyboard.c \ + eek-clutter-keyboard.h \ + eek-clutter-section.c \ + eek-clutter-section.h \ + eek-clutter-key.c \ + eek-clutter-key.h \ + eek-clutter-private.c \ + eek-clutter-private.h \ + eek-clutter.h \ + $(NULL) + +libeek_clutter_la_CFLAGS = $(CLUTTER_CFLAGS) +libeek_clutter_la_LIBADD = libeek.la $(CLUTTER_LIBS) + +libeek_xkb_la_SOURCES = \ + eek-xkb-layout.h \ + eek-xkb-layout.c \ + $(NULL) + +libeek_xkb_la_CFLAGS = $(XKB_CFLAGS) +libeek_xkb_la_LIBADD = libeek.la $(XKB_LIBS) + +eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek +eek_HEADERS = \ + $(top_srcdir)/eek/eek-keyboard.h \ + $(top_srcdir)/eek/eek-section.h \ + $(top_srcdir)/eek/eek-key.h \ + $(top_srcdir)/eek/eek-layout.h \ + $(top_srcdir)/eek/eek-keysym.h \ + $(top_srcdir)/eek/eek-types.h \ + $(top_srcdir)/eek/eek-clutter-keyboard.h \ + $(top_srcdir)/eek/eek-clutter-section.h \ + $(top_srcdir)/eek/eek-clutter-key.h \ + $(top_srcdir)/eek/eek-xkb-layout.h \ + $(top_srcdir)/eek/eek.h \ + $(top_srcdir)/eek/eek-clutter.h \ + $(top_srcdir)/eek/eek-xkb.h + +eek-keysym.c: eek-special-keysym-labels.h eek-unicode-keysym-labels.h eek-keyname-keysym-labels.h + +eek-special-keysym-labels.h: special-keysym-labels.txt + ./gen-keysym-labels.py $< special_keysym_labels > $@ +eek-unicode-keysym-labels.h: unicode-keysym-labels.txt + ./gen-keysym-labels.py $< unicode_keysym_labels > $@ +eek-keyname-keysym-labels.h: keyname-keysym-labels.txt + ./gen-keysym-labels.py $< keyname_keysym_labels > $@ + +DISTCLEANFILES = \ + eek-special-keysym-labels.h \ + eek-unicode-keysym-labels.h \ + eek-keyname-keysym-labels.h + +EXTRA_DIST = \ + gen-keysym-labels.py \ + special-keysym-labels.txt \ + unicode-keysym-labels.txt \ + keyname-keysym-labels.txt diff --git a/eek/eek-clutter-key.c b/eek/eek-clutter-key.c new file mode 100644 index 00000000..ac82736a --- /dev/null +++ b/eek/eek-clutter-key.c @@ -0,0 +1,558 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-clutter-key + * @short_description: #EekKey implemented as a #ClutterActor + * + * The #EekClutterKey class implements the #EekKeyIface interface as a + * #ClutterActor. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include "eek-clutter-key.h" +#include "eek-simple-key.h" +#include "eek-keysym.h" + +enum { + PROP_0, + PROP_KEYSYMS, + PROP_COLUMN, + PROP_ROW, + PROP_OUTLINE, + PROP_BOUNDS, + PROP_GROUP, + PROP_LEVEL, + PROP_LAST +}; + +static void eek_key_iface_init (EekKeyIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekClutterKey, eek_clutter_key, + CLUTTER_TYPE_GROUP, + G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY, + eek_key_iface_init)); + +#define EEK_CLUTTER_KEY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyPrivate)) + +struct _EekClutterKeyPrivate +{ + EekSimpleKey *simple; +}; + +static void +eek_clutter_key_real_set_keysyms (EekKey *self, + guint *keysyms, + gint groups, + gint levels) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_key_set_keysyms (EEK_KEY(priv->simple), keysyms, groups, levels); +} + +static gint +eek_clutter_key_real_get_groups (EekKey *self) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_val_if_fail (priv, -1); + return eek_key_get_groups (EEK_KEY(priv->simple)); +} + +static guint +eek_clutter_key_real_get_keysym (EekKey *self) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_val_if_fail (priv, EEK_INVALID_KEYSYM); + return eek_key_get_keysym (EEK_KEY(priv->simple)); +} + +static void +eek_clutter_key_real_set_index (EekKey *self, + gint column, + gint row) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_key_set_index (EEK_KEY(priv->simple), column, row); +} + +static void +eek_clutter_key_real_get_index (EekKey *self, + gint *column, + gint *row) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_key_get_index (EEK_KEY(priv->simple), column, row); +} + +static void +eek_clutter_key_real_set_outline (EekKey *self, EekOutline *outline) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_key_set_outline (EEK_KEY(priv->simple), outline); +} + +static EekOutline * +eek_clutter_key_real_get_outline (EekKey *self) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_val_if_fail (priv, NULL); + return eek_key_get_outline (EEK_KEY(priv->simple)); +} + +static void +eek_clutter_key_real_set_bounds (EekKey *self, EekBounds *bounds) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_key_set_bounds (EEK_KEY(priv->simple), bounds); + + clutter_actor_set_anchor_point_from_gravity (CLUTTER_ACTOR(self), + CLUTTER_GRAVITY_CENTER); + clutter_actor_set_position (CLUTTER_ACTOR(self), + bounds->x + bounds->w / 2, + bounds->y + bounds->h / 2); +} + +static void +eek_clutter_key_real_get_bounds (EekKey *self, + EekBounds *bounds) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + return eek_key_get_bounds (EEK_KEY(priv->simple), bounds); +} + +static void +eek_clutter_key_real_set_keysym_index (EekKey *self, + gint group, + gint level) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_key_set_index (EEK_KEY(priv->simple), group, level); +} + +static void +eek_clutter_key_real_get_keysym_index (EekKey *self, gint *group, gint *level) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + return eek_key_get_keysym_index (EEK_KEY(priv->simple), group, level); +} + +static void +eek_key_iface_init (EekKeyIface *iface) +{ + iface->set_keysyms = eek_clutter_key_real_set_keysyms; + iface->get_groups = eek_clutter_key_real_get_groups; + iface->get_keysym = eek_clutter_key_real_get_keysym; + iface->set_index = eek_clutter_key_real_set_index; + iface->get_index = eek_clutter_key_real_get_index; + iface->set_outline = eek_clutter_key_real_set_outline; + iface->get_outline = eek_clutter_key_real_get_outline; + iface->set_bounds = eek_clutter_key_real_set_bounds; + iface->get_bounds = eek_clutter_key_real_get_bounds; + iface->set_keysym_index = eek_clutter_key_real_set_keysym_index; + iface->get_keysym_index = eek_clutter_key_real_get_keysym_index; +} + +static void +eek_clutter_key_dispose (GObject *object) +{ + clutter_group_remove_all (CLUTTER_GROUP(object)); + G_OBJECT_CLASS (eek_clutter_key_parent_class)->dispose (object); +} + +static void +eek_clutter_key_finalize (GObject *object) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); + + g_object_unref (priv->simple); + G_OBJECT_CLASS (eek_clutter_key_parent_class)->finalize (object); +} + +static void +draw_text_on_layout (PangoLayout *layout, + const gchar *text, + gdouble scale) +{ + PangoFontDescription *font_desc; + +#define FONT_SIZE (720 * 50) + /* FIXME: Font should be configurable through a property. */ + font_desc = pango_font_description_from_string ("Sans"); + pango_font_description_set_size (font_desc, FONT_SIZE * scale); + pango_layout_set_font_description (layout, font_desc); + pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); + pango_layout_set_text (layout, text, -1); + pango_font_description_free (font_desc); +} + +static void +draw_key_on_layout (EekKey *key, + PangoLayout *layout) +{ + PangoLayout *buffer; + PangoRectangle logical_rect = { 0, }; + EekBounds bounds; + guint keysym; + const gchar *label; + gdouble scale_x, scale_y; + + eek_key_get_bounds (key, &bounds); + keysym = eek_key_get_keysym (key); + if (keysym == EEK_INVALID_KEYSYM) + return; + label = eek_keysym_to_string (keysym); + if (!label) + label = ""; + + /* Compute the layout extents. */ + buffer = pango_layout_copy (layout); + draw_text_on_layout (buffer, label, 1.0); + pango_layout_get_extents (buffer, NULL, &logical_rect); + scale_x = scale_y = 1.0; + if (PANGO_PIXELS(logical_rect.width) > bounds.w) + scale_x = bounds.w / PANGO_PIXELS(logical_rect.width); + if (PANGO_PIXELS(logical_rect.height) > bounds.h) + scale_y = bounds.h / PANGO_PIXELS(logical_rect.height); + g_object_unref (buffer); + + /* Actually draw on the layout */ + draw_text_on_layout (layout, label, scale_x < scale_y ? scale_x : scale_y); +} + +static void +eek_clutter_key_paint (ClutterActor *self) +{ + PangoLayout *layout; + PangoRectangle logical_rect = { 0, }; + CoglColor color; + ClutterGeometry geom; + EekBounds bounds; + gfloat width, height; + gfloat x, y; + + g_return_if_fail (CLUTTER_IS_ACTOR(self)); + g_return_if_fail (EEK_IS_KEY(self)); + + /* Draw the background texture first. */ + CLUTTER_ACTOR_CLASS (eek_clutter_key_parent_class)->paint (self); + + /* Draw the label on the key. */ + layout = clutter_actor_create_pango_layout (self, NULL); + draw_key_on_layout (EEK_KEY(self), layout); + pango_layout_get_extents (layout, NULL, &logical_rect); + + /* FIXME: Color should be configurable through a property. */ + cogl_color_set_from_4ub (&color, 0x80, 0x00, 0x00, 0xff); + clutter_actor_get_allocation_geometry (self, &geom); + cogl_pango_render_layout (layout, + (geom.width - logical_rect.width / PANGO_SCALE) / 2, + (geom.height - logical_rect.height / PANGO_SCALE) / 2, + &color, + 0); + g_object_unref (layout); +} + +/* FIXME: This is a workaround for the bug + * http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer + * says this is not a right way to solve the original problem. + */ +static void +eek_clutter_key_get_preferred_width (ClutterActor *self, + gfloat for_height, + gfloat *min_width_p, + gfloat *natural_width_p) +{ + PangoLayout *layout; + PangoFontDescription *font_desc; + PangoRectangle logical_rect = { 0, }; + EekBounds bounds; + guint keysym; + const gchar *label; + gdouble scale = 1.0; + + eek_key_get_bounds (EEK_KEY(self), &bounds); + keysym = eek_key_get_keysym (EEK_KEY(self)); + g_return_if_fail (keysym != EEK_INVALID_KEYSYM); + label = eek_keysym_to_string (keysym); + if (!label) + label = ""; + + /* Draw the label on the key. */ + layout = clutter_actor_create_pango_layout (self, NULL); + draw_key_on_layout (EEK_KEY(self), layout); + pango_layout_get_extents (layout, NULL, &logical_rect); + + cogl_pango_ensure_glyph_cache_for_layout (layout); + g_object_unref (layout); + + CLUTTER_ACTOR_CLASS (eek_clutter_key_parent_class)->get_preferred_width + (self, for_height, min_width_p, natural_width_p); +} + +static void +eek_clutter_key_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); + + g_return_if_fail (priv); + switch (prop_id) { + /* Properties which affect the appearance of the key as a + ClutterActor. */ + case PROP_BOUNDS: + eek_key_set_bounds (EEK_KEY(object), + g_value_get_boxed (value)); + break; + case PROP_OUTLINE: + eek_key_set_outline (EEK_KEY(object), + g_value_get_pointer (value)); + break; + /* Otherwise delegate to priv->simple or the parent. */ + case PROP_KEYSYMS: + case PROP_COLUMN: + case PROP_GROUP: + case PROP_ROW: + case PROP_LEVEL: + g_object_set_property (G_OBJECT(priv->simple), + g_param_spec_get_name (pspec), + value); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_clutter_key_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekClutterKeyPrivate *priv = EEK_CLUTTER_KEY_GET_PRIVATE(object); + EekBounds bounds; + + g_return_if_fail (priv); + switch (prop_id) { + case PROP_BOUNDS: + eek_key_get_bounds (EEK_KEY(object), &bounds); + g_value_set_boxed (value, &bounds); + break; + case PROP_KEYSYMS: + case PROP_COLUMN: + case PROP_ROW: + case PROP_OUTLINE: + case PROP_GROUP: + case PROP_LEVEL: + g_object_get_property (G_OBJECT(priv->simple), + g_param_spec_get_name (pspec), + value); + break; + default: + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_clutter_key_class_init (EekClutterKeyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, + sizeof (EekClutterKeyPrivate)); + + actor_class->paint = eek_clutter_key_paint; + /* FIXME: This is a workaround for the bug + * http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer + * says this is not a right way to solve the original problem. + */ + actor_class->get_preferred_width = eek_clutter_key_get_preferred_width; + + gobject_class->set_property = eek_clutter_key_set_property; + gobject_class->get_property = eek_clutter_key_get_property; + gobject_class->finalize = eek_clutter_key_finalize; + gobject_class->dispose = eek_clutter_key_dispose; + + g_object_class_override_property (gobject_class, + PROP_KEYSYMS, + "keysyms"); + g_object_class_override_property (gobject_class, + PROP_COLUMN, + "column"); + g_object_class_override_property (gobject_class, + PROP_ROW, + "row"); + g_object_class_override_property (gobject_class, + PROP_OUTLINE, + "outline"); + g_object_class_override_property (gobject_class, + PROP_BOUNDS, + "bounds"); + g_object_class_override_property (gobject_class, + PROP_GROUP, + "group"); + g_object_class_override_property (gobject_class, + PROP_LEVEL, + "level"); +} + +static void +on_key_animate_complete (ClutterAnimation *animation, + gpointer user_data) +{ + ClutterActor *actor = (ClutterActor*)user_data; + + /* reset after effect */ + clutter_actor_set_opacity (actor, 0xff); + clutter_actor_set_scale (actor, 1.0, 1.0); +} + +static void +key_enlarge (ClutterActor *actor) +{ + clutter_actor_set_scale (actor, 1.0, 1.0); + clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 150, + "scale-x", 1.5, + "scale-y", 1.5, + NULL); +} + +static void +key_shrink (ClutterActor *actor) +{ + clutter_actor_set_scale (actor, 1.5, 1.5); + clutter_actor_animate (actor, CLUTTER_EASE_OUT_SINE, 150, + "scale-x", 1.0, + "scale-y", 1.0, + NULL); +} + +static gboolean +on_event (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data) +{ + g_return_val_if_fail (EEK_IS_KEY(actor), FALSE); + if (clutter_event_get_source (event) == actor) { + ClutterActor *section; + + /* Make sure the enlarged key show up on the keys which belong + to other sections. */ + section = clutter_actor_get_parent (actor); + clutter_actor_raise_top (section); + clutter_actor_raise_top (actor); + if (event->type == CLUTTER_BUTTON_PRESS) + key_enlarge (actor); + else if (event->type == CLUTTER_BUTTON_RELEASE) + key_shrink (actor); + } + return FALSE; +} + +static void +eek_clutter_key_init (EekClutterKey *self) +{ + EekClutterKeyPrivate *priv; + + priv = self->priv = EEK_CLUTTER_KEY_GET_PRIVATE(self); + priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEY, NULL); + + clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE); + g_signal_connect (self, "event", G_CALLBACK (on_event), NULL); +} + +ClutterActor * +eek_clutter_key_create_texture (EekClutterKey *key) +{ + EekOutline *outline; + EekBounds bounds; + ClutterActor *texture; + cairo_t *cr; + cairo_pattern_t *pat; + + outline = eek_key_get_outline (EEK_KEY(key)); + eek_key_get_bounds (EEK_KEY(key), &bounds); + + texture = clutter_cairo_texture_new (bounds.w, bounds.h); + cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE(texture)); + cairo_set_line_width (cr, 1); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0); + cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1); + cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1); + + cairo_set_source (cr, pat); + + eek_cairo_draw_rounded_polygon (cr, + TRUE, + outline->corner_radius, + outline->points, + outline->num_points); + + cairo_pattern_destroy (pat); + + cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5); + eek_cairo_draw_rounded_polygon (cr, + FALSE, + outline->corner_radius, + outline->points, + outline->num_points); + cairo_destroy (cr); + return texture; +} + +void +eek_clutter_key_set_texture (EekClutterKey *key, + ClutterActor *texture) +{ + clutter_actor_set_position (texture, 0, 0); + clutter_container_add_actor (CLUTTER_CONTAINER(key), texture); +} diff --git a/eek/eek-clutter-key.h b/eek/eek-clutter-key.h new file mode 100644 index 00000000..28fb33ac --- /dev/null +++ b/eek/eek-clutter-key.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_CLUTTER_KEY_H +#define EEK_CLUTTER_KEY_H 1 + +#include +#include "eek-key.h" + +G_BEGIN_DECLS +#define EEK_TYPE_CLUTTER_KEY (eek_clutter_key_get_type()) +#define EEK_CLUTTER_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKey)) +#define EEK_CLUTTER_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEY, EekClutterKeyClass)) +#define EEK_IS_CLUTTER_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEY)) +#define EEK_IS_CLUTTER_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEY)) +#define EEK_CLUTTER_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEY, EekClutterKeyClass)) + +typedef struct _EekClutterKey EekClutterKey; +typedef struct _EekClutterKeyClass EekClutterKeyClass; +typedef struct _EekClutterKeyPrivate EekClutterKeyPrivate; + +struct _EekClutterKey +{ + /*< private >*/ + ClutterGroup parent; + + /*< private >*/ + EekClutterKeyPrivate *priv; +}; + +struct _EekClutterKeyClass +{ + /*< private >*/ + ClutterGroupClass parent_class; +}; + +GType eek_clutter_key_get_type (void) G_GNUC_CONST; + +ClutterActor *eek_clutter_key_create_texture (EekClutterKey *key); +void eek_clutter_key_set_texture (EekClutterKey *key, + ClutterActor *texture); + +G_END_DECLS +#endif /* EEK_CLUTTER_KEY_H */ diff --git a/eek/eek-clutter-keyboard.c b/eek/eek-clutter-keyboard.c new file mode 100644 index 00000000..72d10df7 --- /dev/null +++ b/eek/eek-clutter-keyboard.c @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-clutter-keyboard + * @short_description: #EekKeyboard implemented as a #ClutterActor + * + * The #EekClutterKeyboard class implements the #EekKeyboardIface + * interface as a #ClutterActor. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-clutter-keyboard.h" +#include "eek-clutter-private.h" +#include "eek-simple-keyboard.h" + +enum { + PROP_0, + PROP_BOUNDS, + PROP_LAST +}; + +static void eek_keyboard_iface_init (EekKeyboardIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekClutterKeyboard, eek_clutter_keyboard, + CLUTTER_TYPE_GROUP, + G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD, + eek_keyboard_iface_init)); + +#define EEK_CLUTTER_KEYBOARD_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardPrivate)) + + +struct _EekClutterKeyboardPrivate +{ + EekSimpleKeyboard *simple; +}; + +static void +eek_clutter_keyboard_real_set_bounds (EekKeyboard *self, + EekBounds *bounds) +{ + EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); + + fflush (stdout); + g_return_if_fail (priv); + eek_keyboard_set_bounds (EEK_KEYBOARD(priv->simple), bounds); + clutter_actor_set_position (CLUTTER_ACTOR(self), bounds->x, bounds->y); + clutter_actor_set_size (CLUTTER_ACTOR(self), bounds->w, bounds->h); +} + +static void +eek_clutter_keyboard_real_get_bounds (EekKeyboard *self, + EekBounds *bounds) +{ + EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); + + g_return_if_fail (priv); + return eek_keyboard_get_bounds (EEK_KEYBOARD(priv->simple), bounds); +} + +static EekSection * +eek_clutter_keyboard_real_create_section (EekKeyboard *self, + const gchar *name, + gint angle, + EekBounds *bounds) +{ + EekSection *section; + + g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(self)); + + section = g_object_new (EEK_TYPE_CLUTTER_SECTION, + "name", name, + "angle", angle, + "bounds", bounds, + NULL); + + clutter_container_add_actor (CLUTTER_CONTAINER(self), + CLUTTER_ACTOR(section)); + + return section; +} + +static void +eek_clutter_keyboard_real_foreach_section (EekKeyboard *self, + GFunc func, + gpointer user_data) +{ + EekClutterCallbackData data; + + g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(self)); + + data.func = func; + data.user_data = user_data; + + clutter_container_foreach (CLUTTER_CONTAINER(self), + eek_clutter_callback, + &data); +} + +static void +eek_clutter_keyboard_real_set_layout (EekKeyboard *self, + EekLayout *layout) +{ + g_return_if_fail (EEK_IS_KEYBOARD(self)); + g_return_if_fail (EEK_IS_LAYOUT(layout)); + + EEK_LAYOUT_GET_CLASS(layout)->apply_to_keyboard (layout, self); + if (g_object_is_floating (layout)) + g_object_unref (layout); +} + +static void +eek_keyboard_iface_init (EekKeyboardIface *iface) +{ + iface->set_bounds = eek_clutter_keyboard_real_set_bounds; + iface->get_bounds = eek_clutter_keyboard_real_get_bounds; + iface->create_section = eek_clutter_keyboard_real_create_section; + iface->foreach_section = eek_clutter_keyboard_real_foreach_section; + iface->set_layout = eek_clutter_keyboard_real_set_layout; +} + +static void +eek_clutter_keyboard_dispose (GObject *object) +{ + clutter_group_remove_all (CLUTTER_GROUP(object)); + G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->dispose (object); +} + +static void +eek_clutter_keyboard_finalize (GObject *object) +{ + EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); + + g_object_unref (priv->simple); + G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->finalize (object); +} + +static void +eek_clutter_keyboard_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); + + g_return_if_fail (priv); + switch (prop_id) { + case PROP_BOUNDS: + eek_keyboard_set_bounds (EEK_KEYBOARD(object), + g_value_get_boxed (value)); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_clutter_keyboard_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(object); + + g_return_if_fail (priv); + switch (prop_id) { + case PROP_BOUNDS: + eek_keyboard_set_bounds (EEK_KEYBOARD(object), + g_value_get_boxed (value)); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_clutter_keyboard_paint (ClutterActor *self) +{ + CLUTTER_ACTOR_CLASS (eek_clutter_keyboard_parent_class)->paint (self); +} + +static void +eek_clutter_keyboard_class_init (EekClutterKeyboardClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, + sizeof (EekClutterKeyboardPrivate)); + + gobject_class->set_property = eek_clutter_keyboard_set_property; + gobject_class->get_property = eek_clutter_keyboard_get_property; + gobject_class->finalize = eek_clutter_keyboard_finalize; + gobject_class->dispose = eek_clutter_keyboard_dispose; + + actor_class->paint = eek_clutter_keyboard_paint; + + g_object_class_override_property (gobject_class, + PROP_BOUNDS, + "bounds"); +} + +static void +eek_clutter_keyboard_init (EekClutterKeyboard *self) +{ + EekClutterKeyboardPrivate *priv; + + priv = self->priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self); + priv->simple = g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL); +} + +/** + * eek_clutter_keyboard_new: + * @width: max width of the area where the keyboard to be drawn + * @height: max height of the area where the keyboard to be drawn + * + * Create a new #EekClutterKeyboard. + */ +EekKeyboard* +eek_clutter_keyboard_new (gfloat width, + gfloat height) +{ + EekBounds bounds; + + bounds.x = bounds.y = 0; + bounds.w = width; + bounds.h = height; + return g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, "bounds", &bounds, NULL); +} diff --git a/eek/eek-clutter-keyboard.h b/eek/eek-clutter-keyboard.h new file mode 100644 index 00000000..534c00b3 --- /dev/null +++ b/eek/eek-clutter-keyboard.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_CLUTTER_KEYBOARD_H +#define EEK_CLUTTER_KEYBOARD_H 1 + +#include "eek-clutter-section.h" +#include "eek-keyboard.h" + +G_BEGIN_DECLS +#define EEK_TYPE_CLUTTER_KEYBOARD (eek_clutter_keyboard_get_type()) +#define EEK_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekKeyboard)) +#define EEK_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass)) +#define EEK_IS_CLUTTER_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_KEYBOARD)) +#define EEK_IS_CLUTTER_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_KEYBOARD)) +#define EEK_CLUTTER_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_KEYBOARD, EekClutterKeyboardClass)) + +typedef struct _EekClutterKeyboard EekClutterKeyboard; +typedef struct _EekClutterKeyboardClass EekClutterKeyboardClass; +typedef struct _EekClutterKeyboardPrivate EekClutterKeyboardPrivate; + +struct _EekClutterKeyboard +{ + /*< private >*/ + ClutterGroup parent; + + EekClutterKeyboardPrivate *priv; +}; + +struct _EekClutterKeyboardClass +{ + /*< private >*/ + ClutterGroupClass parent_class; +}; + +GType eek_clutter_keyboard_get_type (void) G_GNUC_CONST; + +EekKeyboard *eek_clutter_keyboard_new (gfloat width, + gfloat height); + +G_END_DECLS +#endif /* EEK_CLUTTER_KEYBOARD_H */ diff --git a/eek/eek-clutter-private.c b/eek/eek-clutter-private.c new file mode 100644 index 00000000..44cc262d --- /dev/null +++ b/eek/eek-clutter-private.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-clutter-private.h" + +void +eek_clutter_callback (ClutterActor *actor, gpointer user_data) +{ + EekClutterCallbackData *data = user_data; + data->func (actor, data->user_data); +} diff --git a/eek/eek-clutter-private.h b/eek/eek-clutter-private.h new file mode 100644 index 00000000..89ab30d9 --- /dev/null +++ b/eek/eek-clutter-private.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_CLUTTER_PRIVATE_H +#define EEK_CLUTTER_PRIVATE_H 1 + +#include +#include + +struct _EekClutterCallbackData { + GFunc func; + gpointer user_data; +}; +typedef struct _EekClutterCallbackData EekClutterCallbackData; + +void eek_clutter_callback (ClutterActor *actor, gpointer user_data); + +#endif /* EEK_CLUTTER_PRIVATE_H */ diff --git a/eek/eek-clutter-section.c b/eek/eek-clutter-section.c new file mode 100644 index 00000000..b0fe670d --- /dev/null +++ b/eek/eek-clutter-section.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-clutter-section + * @short_description: #EekSection implemented as a #ClutterActor + * + * The #EekClutterSection class implements the #EekSectionIface + * interface as a #ClutterActor. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include "eek-clutter-section.h" +#include "eek-clutter-private.h" +#include "eek-simple-section.h" +#include + +enum { + PROP_0, + PROP_COLUMNS, + PROP_ROWS, + PROP_ANGLE, + PROP_BOUNDS, + PROP_LAST +}; + +static void eek_section_iface_init (EekSectionIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekClutterSection, eek_clutter_section, + CLUTTER_TYPE_GROUP, + G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION, + eek_section_iface_init)); + +#define EEK_CLUTTER_SECTION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionPrivate)) + +struct _EekClutterSectionPrivate +{ + EekSimpleSection *simple; + GHashTable *key_outline_texture_hash; /* outline pointer -> texture */ +}; + +static void +eek_clutter_section_real_set_dimensions (EekSection *self, + gint columns, + gint rows) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_section_set_dimensions (EEK_SECTION(priv->simple), columns, rows); +} + +static void +eek_clutter_section_real_get_dimensions (EekSection *self, + gint *columns, + gint *rows) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_section_get_dimensions (EEK_SECTION(priv->simple), columns, rows); +} + +static void +eek_clutter_section_real_set_angle (EekSection *self, + gint angle) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_section_set_angle (EEK_SECTION(priv->simple), angle); + clutter_actor_set_rotation (CLUTTER_ACTOR(self), + CLUTTER_Z_AXIS, + angle, + 0, + 0, + 0); +} + +static gint +eek_clutter_section_real_get_angle (EekSection *self) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + + g_return_val_if_fail (priv, 0); + eek_section_get_angle (EEK_SECTION(priv->simple)); +} + +static void +eek_clutter_section_real_set_bounds (EekSection *self, + EekBounds *bounds) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + eek_section_set_bounds (EEK_SECTION(priv->simple), bounds); + clutter_actor_set_position (CLUTTER_ACTOR(self), bounds->x, bounds->y); + clutter_actor_set_size (CLUTTER_ACTOR(self), bounds->w, bounds->h); +} + +static void +eek_clutter_section_real_get_bounds (EekSection *self, + EekBounds *bounds) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + return eek_section_get_bounds (EEK_SECTION(priv->simple), bounds); +} + +static EekKey * +eek_clutter_section_real_create_key (EekSection *self, + const gchar *name, + guint *keysyms, + gint num_groups, + gint num_levels, + gint column, + gint row, + EekOutline *outline, + EekBounds *bounds) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(self); + EekKey *key; + EekKeysymMatrix matrix; + gint columns, rows; + ClutterActor *texture; + + g_return_val_if_fail (priv, NULL); + + eek_section_get_dimensions (self, &columns, &rows); + g_return_val_if_fail (column < columns, NULL); + g_return_val_if_fail (row < rows, NULL); + + matrix.data = keysyms; + matrix.num_groups = num_groups; + matrix.num_levels = num_levels; + key = g_object_new (EEK_TYPE_CLUTTER_KEY, + "name", name, + "keysyms", &matrix, + "column", column, + "row", row, + "outline", outline, + "bounds", bounds, + NULL); + g_return_val_if_fail (key, NULL); + + texture = g_hash_table_lookup (priv->key_outline_texture_hash, outline); + if (texture == NULL) { + texture = eek_clutter_key_create_texture (EEK_CLUTTER_KEY(key)); + g_hash_table_insert (priv->key_outline_texture_hash, outline, texture); + } else + texture = clutter_clone_new (texture); + + eek_clutter_key_set_texture (EEK_CLUTTER_KEY(key), texture); + clutter_container_add_actor (CLUTTER_CONTAINER(self), + CLUTTER_ACTOR(key)); + return key; +} + +static void +eek_clutter_section_real_foreach_key (EekSection *self, + GFunc func, + gpointer user_data) +{ + EekClutterCallbackData data; + + g_return_if_fail (EEK_IS_CLUTTER_SECTION(self)); + + data.func = func; + data.user_data = user_data; + + clutter_container_foreach (CLUTTER_CONTAINER(self), + eek_clutter_callback, + &data); +} + +static void +eek_section_iface_init (EekSectionIface *iface) +{ + iface->set_dimensions = eek_clutter_section_real_set_dimensions; + iface->get_dimensions = eek_clutter_section_real_get_dimensions; + iface->set_angle = eek_clutter_section_real_set_angle; + iface->get_angle = eek_clutter_section_real_get_angle; + iface->set_bounds = eek_clutter_section_real_set_bounds; + iface->get_bounds = eek_clutter_section_real_get_bounds; + iface->create_key = eek_clutter_section_real_create_key; + iface->foreach_key = eek_clutter_section_real_foreach_key; +} + +static void +eek_clutter_section_dispose (GObject *object) +{ + clutter_group_remove_all (CLUTTER_GROUP(object)); + G_OBJECT_CLASS (eek_clutter_section_parent_class)->dispose (object); +} + +static void +eek_clutter_section_finalize (GObject *object) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); + + g_object_unref (priv->simple); + G_OBJECT_CLASS (eek_clutter_section_parent_class)->finalize (object); +} + +static void +eek_clutter_section_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_ANGLE: + eek_section_set_angle (EEK_SECTION(object), + g_value_get_int (value)); + break; + case PROP_BOUNDS: + eek_section_set_bounds (EEK_SECTION(object), + g_value_get_boxed (value)); + break; + default: + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_clutter_section_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekClutterSectionPrivate *priv = EEK_CLUTTER_SECTION_GET_PRIVATE(object); + EekBounds bounds; + + switch (prop_id) { + case PROP_ANGLE: + g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object))); + break; + case PROP_BOUNDS: + eek_section_get_bounds (EEK_SECTION(object), &bounds); + g_value_set_boxed (value, &bounds); + break; + default: + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_clutter_section_paint (ClutterActor *self) +{ + ClutterGeometry geom; + + CLUTTER_ACTOR_CLASS (eek_clutter_section_parent_class)->paint (self); + + //clutter_actor_get_allocation_geometry (self, &geom); + //cogl_set_source_color4ub (0x80, 0x00, 0x00, 0xff); + //cogl_rectangle (0, 0, geom.width, geom.height); +} + +static void +eek_clutter_section_class_init (EekClutterSectionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, sizeof (EekClutterSectionPrivate)); + + gobject_class->set_property = eek_clutter_section_set_property; + gobject_class->get_property = eek_clutter_section_get_property; + gobject_class->finalize = eek_clutter_section_finalize; + gobject_class->dispose = eek_clutter_section_dispose; + + actor_class->paint = eek_clutter_section_paint; + + g_object_class_override_property (gobject_class, + PROP_ANGLE, + "angle"); + g_object_class_override_property (gobject_class, + PROP_BOUNDS, + "bounds"); +} + +static void +eek_clutter_section_init (EekClutterSection *self) +{ + EekClutterSectionPrivate *priv; + + priv = self->priv = EEK_CLUTTER_SECTION_GET_PRIVATE (self); + priv->simple = g_object_new (EEK_TYPE_SIMPLE_SECTION, NULL); + priv->key_outline_texture_hash = + g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + g_free); +} diff --git a/eek/eek-clutter-section.h b/eek/eek-clutter-section.h new file mode 100644 index 00000000..09baabbb --- /dev/null +++ b/eek/eek-clutter-section.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_CLUTTER_SECTION_H +#define EEK_CLUTTER_SECTION_H 1 + +#include "eek-clutter-key.h" +#include "eek-section.h" + +G_BEGIN_DECLS +#define EEK_TYPE_CLUTTER_SECTION (eek_clutter_section_get_type()) +#define EEK_CLUTTER_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSection)) +#define EEK_CLUTTER_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionClass)) +#define EEK_IS_CLUTTER_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CLUTTER_SECTION)) +#define EEK_IS_CLUTTER_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CLUTTER_SECTION)) +#define EEK_CLUTTER_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CLUTTER_SECTION, EekClutterSectionClass)) + +typedef struct _EekClutterSection EekClutterSection; +typedef struct _EekClutterSectionClass EekClutterSectionClass; +typedef struct _EekClutterSectionPrivate EekClutterSectionPrivate; + +struct _EekClutterSection +{ + /*< private >*/ + ClutterGroup parent; + + /*< private >*/ + EekClutterSectionPrivate *priv; +}; + +struct _EekClutterSectionClass +{ + /*< private >*/ + ClutterGroupClass parent_class; +}; + +GType eek_clutter_section_get_type (void) G_GNUC_CONST; + +G_END_DECLS +#endif /* EEK_CLUTTER_SECTION_H */ diff --git a/eek/eek-clutter.h b/eek/eek-clutter.h new file mode 100644 index 00000000..835b3b8f --- /dev/null +++ b/eek/eek-clutter.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_CLUTTER_H +#define EEK_CLUTTER_H 1 + +#include "eek.h" +#include "eek-clutter-keyboard.h" + +#endif /* EEK_CLUTTER_H */ diff --git a/eek/eek-key.c b/eek/eek-key.c new file mode 100644 index 00000000..e1d5d9fd --- /dev/null +++ b/eek/eek-key.c @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-key + * @short_description: Base interface of a key + * @see_also: #EekSection + * + * The #EekKeyIface interface represents a key, which is parented to + * #EekSectionIface. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-key.h" +#include "eek-keysym.h" + +static void +eek_key_base_init (gpointer g_iface) +{ + static gboolean is_initialized = FALSE; + + if (!is_initialized) { + GParamSpec *pspec; + + /** + * EekKey:name: + * + * The name of #EekKey. + */ + pspec = g_param_spec_string ("name", + "Name", + "Name", + NULL, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekKey:keysyms: + * + * The symbol matrix of #EekKey. + */ + pspec = g_param_spec_boxed ("keysyms", + "Keysyms", + "Symbol matrix of the key", + EEK_TYPE_KEYSYM_MATRIX, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekKey:column: + * + * The column index of #EekKey in the parent #EekSection. + */ + pspec = g_param_spec_int ("column", + "Column", + "Column index of the key in section", + -1, G_MAXINT, -1, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekKey:row: + * + * The row index of #EekKey in the parent #EekSection. + */ + pspec = g_param_spec_int ("row", + "Row", + "Row index of the key in section", + -1, G_MAXINT, -1, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekKey:outline: + * + * The pointer to the outline shape of #EekKey. + */ + /* Use pointer instead of boxed to avoid copy, since we can + assume that only a few outline shapes are used in a whole + keyboard (unlike labels and bounds). */ + pspec = g_param_spec_pointer ("outline", + "Outline", + "Pointer to outline shape of the key", + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekKey:bounds: + * + * The bounding box of #EekKey. + */ + pspec = g_param_spec_boxed ("bounds", + "Bounds", + "Bounding box of the key", + EEK_TYPE_BOUNDS, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekKey:group: + * + * The column index of #EekKey in the label matrix #EekKey:labels. + */ + pspec = g_param_spec_int ("group", + "Group", + "Current group of the key", + 0, 64, 0, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekKey:level: + * + * The row index of #EekKey in the label matrix #EekKey:labels. + */ + pspec = g_param_spec_int ("level", + "Level", + "Current level of the key", + 0, 3, 0, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + is_initialized = TRUE; + } +} + +GType +eek_key_get_type (void) +{ + static GType iface_type = 0; + + if (iface_type == 0) { + static const GTypeInfo info = { + sizeof (EekKeyIface), + eek_key_base_init, /* iface_base_init */ + NULL /* iface_base_finalize */ + }; + + iface_type = g_type_register_static (G_TYPE_INTERFACE, + "EekKey", + &info, + 0); + } + return iface_type; +} + +/** + * eek_key_set_keysyms: + * @key: an #EekKey + * @keysyms: symbol matrix of @key + * @num_groups: the number of groups (rows) of @keysyms + * @num_levels: the number of levels (columns) of @keysyms + * + * Set the symbol matrix of @key to @keysyms. @keysyms is an array of + * symbols (unsigned int) and the length must match with @num_groups * + * @num_levels. + */ +void +eek_key_set_keysyms (EekKey *key, + guint *keysyms, + gint num_groups, + gint num_levels) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->set_keysyms); + (*iface->set_keysyms) (key, keysyms, num_groups, num_levels); +} + +/** + * eek_key_get_groups: + * @key: an #EekKey + * + * Get the number of groups (rows) of the symbol matrix of @key. + */ +gint +eek_key_get_groups (EekKey *key) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_val_if_fail (iface, -1); + g_return_val_if_fail (iface->get_groups, -1); + return (*iface->get_groups) (key); +} + +/** + * eek_key_get_keysym: + * @key: an #EekKey + * + * Get the current symbol of @key. It is depend on the current group, + * level, and the symbol matrix of @key. They are set with + * eek_key_set_group(), eek_key_set_level(), and eek_key_set_labels(), + * respectively. + */ +guint +eek_key_get_keysym (EekKey *key) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_val_if_fail (iface, EEK_INVALID_KEYSYM); + g_return_val_if_fail (iface->get_keysym, EEK_INVALID_KEYSYM); + return (*iface->get_keysym) (key); +} + +/** + * eek_key_set_index: + * @key: an #EekKey + * @column: column index in the section + * @row: row index in the section + * + * Set column and row index of @key in the parent section. + */ +void +eek_key_set_index (EekKey *key, + gint column, + gint row) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->set_index); + (*iface->set_index) (key, column, row); +} + +/** + * eek_key_get_index: + * @key: an #EekKey + * @column: a pointer to where column index in the section is stored + * @row: a pointer to where row index in the section is stored + * + * Get column and row index of @key in the parent section. + */ +void +eek_key_get_index (EekKey *key, + gint *column, + gint *row) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->get_index); + return (*iface->get_index) (key, column, row); +} + +/** + * eek_key_set_outline: + * @key: an #EekKey + * @outline: a pointer to the outline shape of @key + * + * Set outline shape of @key. + */ +void +eek_key_set_outline (EekKey *key, + EekOutline *outline) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->set_outline); + (*iface->set_outline) (key, outline); +} + +/** + * eek_key_get_outline: + * @key: an #EekKey + * + * Get outline shape of @key as a pointer. + */ +EekOutline * +eek_key_get_outline (EekKey *key) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_val_if_fail (iface, NULL); + g_return_val_if_fail (iface->get_outline, NULL); + return (*iface->get_outline) (key); +} + +/** + * eek_key_set_bounds: + * @key: a #EekKey + * @bounds: bounding box of @key + * + * Set the bounding box of @key to @bounds. + */ +void +eek_key_set_bounds (EekKey *key, + EekBounds *bounds) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->set_bounds); + (*iface->set_bounds) (key, bounds); +} + +/** + * eek_key_get_bounds: + * @key: a #EekKey + * @bounds: the bounding box of @key + * + * Get the bounding box of @key. + */ +void +eek_key_get_bounds (EekKey *key, + EekBounds *bounds) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->get_bounds); + return (*iface->get_bounds) (key, bounds); +} + +/** + * eek_key_set_keysym_index: + * @key: a #EekKey + * @group: row index of the symbol matrix #EekKey:keysyms + * @level: column index of the symbol matrix #EekKey:keysyms + * + * Select a cell of the symbol matrix of @key. + */ +void +eek_key_set_keysym_index (EekKey *key, + gint group, + gint level) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->set_keysym_index); + (*iface->set_keysym_index) (key, group, level); +} + +/** + * eek_key_get_keysym_index: + * @key: a #EekKey + * @group: a pointer to row index of the symbol matrix #EekKey:keysyms + * to be stored + * @level: a pointer to column index of the symbol matrix + * #EekKey:keysyms to be stored + * + * Get the current cell position of the symbol matrix of @key. + */ +void +eek_key_get_keysym_index (EekKey *key, gint *column, gint *row) +{ + EekKeyIface *iface = EEK_KEY_GET_IFACE(key); + + g_return_if_fail (iface); + g_return_if_fail (iface->get_keysym_index); + return (*iface->get_keysym_index) (key, column, row); +} diff --git a/eek/eek-key.h b/eek/eek-key.h new file mode 100644 index 00000000..29c83d2a --- /dev/null +++ b/eek/eek-key.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_KEY_H +#define EEK_KEY_H 1 + +#include +#include "eek-types.h" + +G_BEGIN_DECLS + +#define EEK_TYPE_KEY (eek_key_get_type()) +#define EEK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEY, EekKey)) +#define EEK_IS_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEY)) +#define EEK_KEY_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_KEY, EekKeyIface)) + +typedef struct _EekKeyIface EekKeyIface; + +struct _EekKeyIface +{ + /*< private >*/ + GTypeInterface g_iface; + + /*< public >*/ + void (* set_keysyms) (EekKey *self, + guint *keysyms, + gint groups, + gint levels); + gint (* get_groups) (EekKey *self); + guint (* get_keysym) (EekKey *self); + + void (* set_index) (EekKey *self, + gint column, + gint row); + void (* get_index) (EekKey *self, + gint *column, + gint *row); + + void (* set_outline) (EekKey *self, + EekOutline *outline); + EekOutline *(* get_outline) (EekKey *self); + void (* set_bounds) (EekKey *self, + EekBounds *bounds); + void (* get_bounds) (EekKey *self, + EekBounds *bounds); + + void (* set_keysym_index) (EekKey *self, + gint group, + gint level); + void (* get_keysym_index) (EekKey *self, + gint *group, + gint *level); +}; + +GType eek_key_get_type (void) G_GNUC_CONST; + +void eek_key_set_keysyms (EekKey *key, + guint *keysyms, + gint groups, + gint levels); +gint eek_key_get_groups (EekKey *key); +guint eek_key_get_keysym (EekKey *key); + +void eek_key_set_index (EekKey *key, + gint column, + gint row); +void eek_key_get_index (EekKey *key, + gint *column, + gint *row); + +void eek_key_set_outline (EekKey *key, + EekOutline *outline); +EekOutline *eek_key_get_outline (EekKey *key); +void eek_key_set_bounds (EekKey *key, + EekBounds *bounds); +void eek_key_get_bounds (EekKey *key, + EekBounds *bounds); + +void eek_key_set_keysym_index (EekKey *key, + gint group, + gint level); +void eek_key_get_keysym_index (EekKey *key, + gint *group, + gint *level); + +G_END_DECLS +#endif /* EEK_KEY_H */ diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c new file mode 100644 index 00000000..26140fc6 --- /dev/null +++ b/eek/eek-keyboard.c @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-keyboard + * @short_description: Base interface of a keyboard + * @see_also: #EekSection + * + * The #EekKeyboardIface interface represents a keyboard, which + * consists of one or more sections of the #EekSectionIface interface. + * + * #EekKeyboardIface follows the Builder pattern and is responsible + * for creation of sections. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-keyboard.h" + +static void +eek_keyboard_base_init (gpointer g_iface) +{ + static gboolean is_initialized = FALSE; + + if (!is_initialized) { + GParamSpec *pspec; + + /** + * EekKeyboard:bounds: + * + * The bounding box of #EekKeyboard. + */ + pspec = g_param_spec_boxed ("bounds", + "Bounds", + "Bounding box of the keyboard", + EEK_TYPE_BOUNDS, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + is_initialized = TRUE; + } +} + +GType +eek_keyboard_get_type (void) +{ + static GType iface_type = 0; + + if (iface_type == 0) { + static const GTypeInfo info = { + sizeof (EekKeyboardIface), + eek_keyboard_base_init, + NULL + }; + + iface_type = g_type_register_static (G_TYPE_INTERFACE, + "EekKeyboard", + &info, + 0); + } + return iface_type; +} + +/** + * eek_keyboard_set_bounds: + * @keyboard: a #EekKeyboard + * @bounds: bounding box of the keyboard + * + * Set the bounding box of @keyboard to @bounds. + */ +void +eek_keyboard_set_bounds (EekKeyboard *keyboard, + EekBounds *bounds) +{ + EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); + + g_return_if_fail (iface); + g_return_if_fail (iface->set_bounds); + (*iface->set_bounds) (keyboard, bounds); +} + +/** + * eek_keyboard_get_bounds: + * @keyboard: a #EekKeyboard + * @bounds: the bounding box of @keyboard + * + * Get the bounding box of @keyboard. + */ +void +eek_keyboard_get_bounds (EekKeyboard *keyboard, + EekBounds *bounds) +{ + EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); + + g_return_if_fail (iface); + g_return_if_fail (iface->get_bounds); + return (*iface->get_bounds) (keyboard, bounds); +} + +/** + * eek_keyboard_create_section: + * @keyboard: a #EekKeyboard + * @name: name of the section + * @angle: rotation angle of the section + * @bounds: bounding box of the section + * + * Create an #EekSection instance and attach it to @keyboard. + */ +EekSection * +eek_keyboard_create_section (EekKeyboard *keyboard, + const gchar *name, + gint angle, + EekBounds *bounds) +{ + EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); + + g_return_val_if_fail (iface, NULL); + g_return_val_if_fail (iface->create_section, NULL); + return (*iface->create_section) (keyboard, name, angle, bounds); +} + +/** + * eek_keyboard_foreach_section: + * @keyboard: a #EekKeyboard + * @func: a callback of #GFunc + * @user_data: a pointer to an object passed to @func + * + * Iterate over @keyboard's children list. + */ +void +eek_keyboard_foreach_section (EekKeyboard *keyboard, + GFunc func, + gpointer user_data) +{ + EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); + + g_return_if_fail (iface); + g_return_if_fail (iface->foreach_section); + (*iface->foreach_section) (keyboard, func, user_data); +} + +/** + * eek_keyboard_set_layout: + * @keyboard: a #EekKeyboard + * @layout: a #EekLayout + * + * Set the layout of @keyboard to @layout. For the user of EEK, it is + * preferable to call this function rather than + * eek_layout_apply_to_keyboard(), while the implementation calls it + * internally. + */ +void +eek_keyboard_set_layout (EekKeyboard *keyboard, + EekLayout *layout) +{ + EekKeyboardIface *iface = EEK_KEYBOARD_GET_IFACE(keyboard); + + g_return_if_fail (iface); + g_return_if_fail (iface->set_layout); + g_return_if_fail (EEK_IS_LAYOUT(layout)); + (*iface->set_layout) (keyboard, layout); +} diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h new file mode 100644 index 00000000..e36b795b --- /dev/null +++ b/eek/eek-keyboard.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_KEYBOARD_H +#define EEK_KEYBOARD_H 1 + +#include "eek-section.h" +#include "eek-layout.h" + +G_BEGIN_DECLS + +#define EEK_TYPE_KEYBOARD (eek_keyboard_get_type()) +#define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard)) +#define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD)) +#define EEK_KEYBOARD_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardIface)) + +typedef struct _EekKeyboardIface EekKeyboardIface; + +struct _EekKeyboardIface +{ + /*< private >*/ + GTypeInterface g_iface; + + /*< public >*/ + void (* set_bounds) (EekKeyboard *self, + EekBounds *bounds); + void (* get_bounds) (EekKeyboard *self, + EekBounds *bounds); + EekSection *(* create_section) (EekKeyboard *self, + const gchar *name, + gint angle, + EekBounds *bounds); + + void (* foreach_section) (EekKeyboard *self, + GFunc func, + gpointer user_data); + + void (* set_layout) (EekKeyboard *self, + EekLayout *layout); +}; + +GType eek_keyboard_get_type (void) G_GNUC_CONST; + +void eek_keyboard_set_bounds (EekKeyboard *keyboard, + EekBounds *bounds); +void eek_keyboard_get_bounds (EekKeyboard *keyboard, + EekBounds *bounds); + +EekSection *eek_keyboard_create_section (EekKeyboard *keyboard, + const gchar *name, + gint angle, + EekBounds *bounds); + +void eek_keyboard_foreach_section (EekKeyboard *keyboard, + GFunc func, + gpointer user_data); + +void eek_keyboard_set_layout (EekKeyboard *keyboard, + EekLayout *layout); + +G_END_DECLS +#endif /* EEK_KEYBOARD_H */ diff --git a/eek/eek-keysym.c b/eek/eek-keysym.c new file mode 100644 index 00000000..e4bcdfa0 --- /dev/null +++ b/eek/eek-keysym.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include +#include + +#include "eek-keysym.h" + +struct eek_keysym_label { + guint keysym; + const gchar *label; +}; + +#include "eek-special-keysym-labels.h" +#include "eek-unicode-keysym-labels.h" +#include "eek-keyname-keysym-labels.h" + +static G_CONST_RETURN gchar * +unichar_to_utf8 (gunichar uc) +{ + if (g_unichar_isgraph (uc)) { + gchar *buf; + gint len; + + len = g_unichar_to_utf8 (uc, NULL); + buf = g_malloc0 (len + 1); + g_unichar_to_utf8 (uc, buf); + return buf; + } + return g_strdup (""); +} + +static int +keysym_label_compare (const void *key0, const void *key1) +{ + const struct eek_keysym_label *entry0 = key0, *entry1 = key1; + return (gint)entry0->keysym - (gint)entry1->keysym; +} + +G_CONST_RETURN gchar * +eek_keysym_to_string (guint keysym) +{ + struct eek_keysym_label bsearch_key, *bsearch_val; + + /* First, search special keysyms. */ + bsearch_key.keysym = keysym; + bsearch_val = bsearch (&bsearch_key, + special_keysym_labels, + G_N_ELEMENTS(special_keysym_labels), + sizeof (struct eek_keysym_label), + keysym_label_compare); + if (bsearch_val) + return g_strdup (bsearch_val->label); + + /* Check for Latin-1 characters (1:1 mapping) */ + if ((keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff)) + return unichar_to_utf8 (keysym); + + /* Also check for directly encoded 24-bit UCS characters: + */ + if ((keysym & 0xff000000) == 0x01000000) + return unichar_to_utf8 (keysym & 0x00ffffff); + + /* Search known unicode keysyms. */ + bsearch_key.keysym = keysym; + bsearch_val = bsearch (&bsearch_key, + unicode_keysym_labels, + G_N_ELEMENTS(unicode_keysym_labels), + sizeof (struct eek_keysym_label), + keysym_label_compare); + if (bsearch_val) + return g_strdup (bsearch_val->label); + + /* Finally, search keynames. */ + bsearch_key.keysym = keysym; + bsearch_val = bsearch (&bsearch_key, + keyname_keysym_labels, + G_N_ELEMENTS(keyname_keysym_labels), + sizeof (struct eek_keysym_label), + keysym_label_compare); + if (bsearch_val) + return g_strdup (bsearch_val->label); + + return g_strdup (""); +} diff --git a/eek/eek-keysym.h b/eek/eek-keysym.h new file mode 100644 index 00000000..1f642e79 --- /dev/null +++ b/eek/eek-keysym.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_KEYSYMS_H +#define EEK_KEYSYMS_H 1 + +#define EEK_INVALID_KEYSYM ((guint)(-1)) +G_CONST_RETURN gchar *eek_keysym_to_string (guint keysym); + +#endif /* EEK_KEYSYMS_H */ diff --git a/eek/eek-layout.c b/eek/eek-layout.c new file mode 100644 index 00000000..b480ab8c --- /dev/null +++ b/eek/eek-layout.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-layout + * @short_description: Base class of a layout engine + * + * The #EekLayout class is a base abstract class of layout engine + * which arranges keyboard elements. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-layout.h" +#include "eek-keyboard.h" + +G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_INITIALLY_UNOWNED); + +static void +eek_layout_finalize (GObject *object) +{ + G_OBJECT_CLASS (eek_layout_parent_class)->finalize (object); +} + +static void +eek_layout_dispose (GObject *object) +{ + G_OBJECT_CLASS (eek_layout_parent_class)->dispose (object); +} + +static void +eek_layout_class_init (EekLayoutClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + gobject_class->finalize = eek_layout_finalize; + gobject_class->dispose = eek_layout_dispose; +} + +static void +eek_layout_init (EekLayout *self) +{ +} diff --git a/eek/eek-layout.h b/eek/eek-layout.h new file mode 100644 index 00000000..08333d68 --- /dev/null +++ b/eek/eek-layout.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef EEK_LAYOUT_H +#define EEK_LAYOUT_H 1 + +#include +#include "eek-types.h" + +G_BEGIN_DECLS + +#define EEK_TYPE_LAYOUT (eek_layout_get_type()) +#define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout)) +#define EEK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_LAYOUT, EekLayoutClass)) +#define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT)) +#define EEK_IS_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_LAYOUT)) +#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass)) + +typedef struct _EekLayoutClass EekLayoutClass; +typedef struct _EekLayout EekLayout; + +struct _EekLayout +{ + /*< private >*/ + GInitiallyUnowned parent; +}; + +struct _EekLayoutClass +{ + /*< private >*/ + GInitiallyUnownedClass parent_class; + + /*< public >*/ + void (*apply_to_keyboard) (EekLayout *self, + EekKeyboard *keyboard); +}; + +GType eek_layout_get_type (void) G_GNUC_CONST; + +G_END_DECLS +#endif /* EEK_LAYOUT_H */ diff --git a/eek/eek-private.c b/eek/eek-private.c new file mode 100644 index 00000000..5191628a --- /dev/null +++ b/eek/eek-private.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2006 Sergey V. Udaltsov + * + * 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. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-private.h" +#include + +#define noKBDRAW_DEBUG + +static gdouble +length (gdouble x, gdouble y) +{ + return sqrt (x * x + y * y); +} + +static gdouble +point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny) +{ + return ax * nx + ay * ny; +} + +static void +normal_form (gdouble ax, gdouble ay, + gdouble bx, gdouble by, + gdouble * nx, gdouble * ny, gdouble * d) +{ + gdouble l; + + *nx = by - ay; + *ny = ax - bx; + + l = length (*nx, *ny); + + *nx /= l; + *ny /= l; + + *d = point_line_distance (ax, ay, *nx, *ny); +} + +static void +inverse (gdouble a, gdouble b, gdouble c, gdouble d, + gdouble * e, gdouble * f, gdouble * g, gdouble * h) +{ + gdouble det; + + det = a * d - b * c; + + *e = d / det; + *f = -b / det; + *g = -c / det; + *h = a / det; +} + +static void +multiply (gdouble a, gdouble b, gdouble c, gdouble d, + gdouble e, gdouble f, gdouble * x, gdouble * y) +{ + *x = a * e + b * f; + *y = c * e + d * f; +} + +static void +intersect (gdouble n1x, gdouble n1y, gdouble d1, + gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y) +{ + gdouble e, f, g, h; + + inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h); + multiply (e, f, g, h, d1, d2, x, y); +} + + +/* draw an angle from the current point to b and then to c, + * with a rounded corner of the given radius. + */ +static void +rounded_corner (cairo_t * cr, + gdouble bx, gdouble by, + gdouble cx, gdouble cy, gdouble radius) +{ + gdouble ax, ay; + gdouble n1x, n1y, d1; + gdouble n2x, n2y, d2; + gdouble pd1, pd2; + gdouble ix, iy; + gdouble dist1, dist2; + gdouble nx, ny, d; + gdouble a1x, a1y, c1x, c1y; + gdouble phi1, phi2; + + cairo_get_current_point (cr, &ax, &ay); +#ifdef KBDRAW_DEBUG + printf (" current point: (%f, %f), radius %f:\n", ax, ay, + radius); +#endif + + /* make sure radius is not too large */ + dist1 = length (bx - ax, by - ay); + dist2 = length (cx - bx, cy - by); + + radius = MIN (radius, MIN (dist1, dist2)); + + /* construct normal forms of the lines */ + normal_form (ax, ay, bx, by, &n1x, &n1y, &d1); + normal_form (bx, by, cx, cy, &n2x, &n2y, &d2); + + /* find which side of the line a,b the point c is on */ + if (point_line_distance (cx, cy, n1x, n1y) < d1) + pd1 = d1 - radius; + else + pd1 = d1 + radius; + + /* find which side of the line b,c the point a is on */ + if (point_line_distance (ax, ay, n2x, n2y) < d2) + pd2 = d2 - radius; + else + pd2 = d2 + radius; + + /* intersect the parallels to find the center of the arc */ + intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy); + + nx = (bx - ax) / dist1; + ny = (by - ay) / dist1; + d = point_line_distance (ix, iy, nx, ny); + + /* a1 is the point on the line a-b where the arc starts */ + intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y); + + nx = (cx - bx) / dist2; + ny = (cy - by) / dist2; + d = point_line_distance (ix, iy, nx, ny); + + /* c1 is the point on the line b-c where the arc ends */ + intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y); + + /* determine the first angle */ + if (a1x - ix == 0) + phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2; + else if (a1x - ix > 0) + phi1 = atan ((a1y - iy) / (a1x - ix)); + else + phi1 = M_PI + atan ((a1y - iy) / (a1x - ix)); + + /* determine the second angle */ + if (c1x - ix == 0) + phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2; + else if (c1x - ix > 0) + phi2 = atan ((c1y - iy) / (c1x - ix)); + else + phi2 = M_PI + atan ((c1y - iy) / (c1x - ix)); + + /* compute the difference between phi2 and phi1 mod 2pi */ + d = phi2 - phi1; + while (d < 0) + d += 2 * M_PI; + while (d > 2 * M_PI) + d -= 2 * M_PI; + +#ifdef KBDRAW_DEBUG + printf (" line 1 to: (%f, %f):\n", a1x, a1y); +#endif + if (!(isnan (a1x) || isnan (a1y))) + cairo_line_to (cr, a1x, a1y); + + /* pick the short arc from phi1 to phi2 */ + if (d < M_PI) + cairo_arc (cr, ix, iy, radius, phi1, phi2); + else + cairo_arc_negative (cr, ix, iy, radius, phi1, phi2); + +#ifdef KBDRAW_DEBUG + printf (" line 2 to: (%f, %f):\n", cx, cy); +#endif + cairo_line_to (cr, cx, cy); +} + +void +eek_cairo_draw_rounded_polygon (cairo_t * cr, + gboolean filled, + gdouble radius, + EekPoint * points, + gint num_points) +{ + gint i, j; + + cairo_move_to (cr, + (gdouble) (points[num_points - 1].x + + points[0].x) / 2, + (gdouble) (points[num_points - 1].y + + points[0].y) / 2); + + +#ifdef KBDRAW_DEBUG + printf (" rounded polygon of radius %f:\n", radius); +#endif + for (i = 0; i < num_points; i++) { + j = (i + 1) % num_points; + rounded_corner (cr, (gdouble) points[i].x, + (gdouble) points[i].y, + (gdouble) (points[i].x + points[j].x) / 2, + (gdouble) (points[i].y + points[j].y) / 2, + radius); +#ifdef KBDRAW_DEBUG + printf (" corner (%d, %d) -> (%d, %d):\n", + points[i].x, points[i].y, points[j].x, + points[j].y); +#endif + }; + cairo_close_path (cr); + + if (filled) + cairo_fill (cr); + else + cairo_stroke (cr); +} + diff --git a/eek/eek-private.h b/eek/eek-private.h new file mode 100644 index 00000000..61fcdddc --- /dev/null +++ b/eek/eek-private.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_PRIVATE_H +#define EEK_PRIVATE_H 1 + +#include +#include +#include "eek-types.h" + +G_BEGIN_DECLS + +void eek_cairo_draw_rounded_polygon (cairo_t * cr, + gboolean filled, + gdouble radius, + EekPoint * points, + gint num_points); + +G_END_DECLS +#endif /* EEK_PRIVATE_H */ diff --git a/eek/eek-section.c b/eek/eek-section.c new file mode 100644 index 00000000..628540f2 --- /dev/null +++ b/eek/eek-section.c @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-section + * @short_description: Base interface of a keyboard section + * @see_also: #EekKeyboard, #EekKey + * + * The #EekSectionIface interface represents a keyboard section, which + * is parented to #EekKeyboardIface and can have one or more keys of + * the #EekKeyIface interface. + * + * #EekSectionIface follows the Builder pattern and is responsible for + * creation of keys. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-section.h" + +static void +eek_section_base_init (gpointer g_iface) +{ + static gboolean is_initialized = FALSE; + + if (!is_initialized) { + GParamSpec *pspec; + + /** + * EekSection:name: + * + * The name of #EekSection. + */ + pspec = g_param_spec_string ("name", + "Name", + "Name", + NULL, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekSection:columns: + * + * The number of columns in #EekSection. + */ + pspec = g_param_spec_int ("columns", + "Columns", + "The number of columns in the section", + 0, G_MAXINT, 0, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekSection:rows: + * + * The number of rows in #EekSection. + */ + pspec = g_param_spec_int ("rows", + "Rows", + "The number of rows of the section", + 0, G_MAXINT, 0, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekSection:angle: + * + * The rotation angle of #EekSection. + */ + pspec = g_param_spec_int ("angle", + "Angle", + "Rotation angle of the section", + -360, 360, 0, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + /** + * EekSection:bounds: + * + * The bounding box of #EekSection. + */ + pspec = g_param_spec_boxed ("bounds", + "Bounds", + "Bounding box of the section", + EEK_TYPE_BOUNDS, + G_PARAM_READWRITE); + g_object_interface_install_property (g_iface, pspec); + + is_initialized = TRUE; + } +} + +GType +eek_section_get_type (void) +{ + static GType iface_type = 0; + + if (iface_type == 0) { + static const GTypeInfo info = { + sizeof (EekSectionIface), + eek_section_base_init, + NULL + }; + + iface_type = g_type_register_static (G_TYPE_INTERFACE, + "EekSection", + &info, + 0); + } + return iface_type; +} + +/** + * eek_section_set_dimensions: + * @section: a #EekSection + * @columns: the number of columns in @section + * @rows: the number of rows in @section + * + * Set dimensions of @section from @columns and @rows. + */ +void +eek_section_set_dimensions (EekSection *section, + gint columns, + gint rows) +{ + EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); + + g_return_if_fail (iface->set_dimensions); + (*iface->set_dimensions) (section, columns, rows); +} + +/** + * eek_section_get_dimensions: + * @section: a #EekSection + * @columns: a pointer where the number of columns in @section is stored + * @rows: a pointer where the number of rows in @section is stored + * + * Get the rotation angle of @section. + */ +void +eek_section_get_dimensions (EekSection *section, + gint *columns, + gint *rows) +{ + EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); + + g_return_if_fail (iface->get_dimensions); + return (*iface->get_dimensions) (section, columns, rows); +} + +/** + * eek_section_set_angle: + * @section: a #EekSection + * @angle: rotation angle of @section + * + * Set the rotation angle of @section to @angle. + */ +void +eek_section_set_angle (EekSection *section, + gint angle) +{ + EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); + + g_return_if_fail (iface->set_angle); + (*iface->set_angle) (section, angle); +} + +/** + * eek_section_get_angle: + * @section: a #EekSection + * + * Get the rotation angle of @section. + */ +gint +eek_section_get_angle (EekSection *section) +{ + EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); + + g_return_val_if_fail (iface->get_angle, 0); + return (*iface->get_angle) (section); +} + +/** + * eek_section_set_bounds: + * @section: a #EekSection + * @bounds: bounding box of @section + * + * Set the bounding box of @section to @bounds. + */ +void +eek_section_set_bounds (EekSection *section, + EekBounds *bounds) +{ + EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); + + g_return_if_fail (iface->set_bounds); + (*iface->set_bounds) (section, bounds); +} + +/** + * eek_section_get_bounds: + * @section: a #EekSection + * @bounds: the bounding box of @section + * + * Get the bounding box of @section. + */ +void +eek_section_get_bounds (EekSection *section, + EekBounds *bounds) +{ + EekSectionIface *iface = EEK_SECTION_GET_IFACE(section); + + g_return_if_fail (iface->get_bounds); + return (*iface->get_bounds) (section, bounds); +} + +/** + * eek_section_create_key: + * @section: a #EekSection + * @name: name of the key + * @keysyms: symbol matrix of the key + * @num_groups: number of rows in the @keysyms + * @num_levels: number of columns in the @keysyms + * @column: column index in the @section + * @row: row index in the section + * @outline: outline shape of the key + * @bounds: bounding box of the key + * + * Create an #EekKey instance and attach it to @section. + */ +EekKey * +eek_section_create_key (EekSection *section, + const gchar *name, + guint *keysyms, + gint num_groups, + gint num_levels, + gint column, + gint row, + EekOutline *outline, + EekBounds *bounds) +{ + EekSectionIface *iface; + + g_return_if_fail (EEK_IS_SECTION(section)); + + iface = EEK_SECTION_GET_IFACE(section); + g_return_if_fail (iface->create_key); + + return (*iface->create_key) (section, + name, + keysyms, + num_groups, + num_levels, + column, + row, + outline, + bounds); +} + +/** + * eek_section_foreach_key: + * @section: a #EekSection + * @func: a callback of #GFunc + * @user_data: a pointer to an object passed to @func + * + * Iterate over @section's children list. + */ +void +eek_section_foreach_key (EekSection *section, + GFunc func, + gpointer user_data) +{ + EekSectionIface *iface; + + g_return_if_fail (EEK_IS_SECTION(section)); + + iface = EEK_SECTION_GET_IFACE(section); + g_return_if_fail (iface->foreach_key); + + return (*iface->foreach_key) (section, func, user_data); +} diff --git a/eek/eek-section.h b/eek/eek-section.h new file mode 100644 index 00000000..85d46956 --- /dev/null +++ b/eek/eek-section.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_SECTION_H +#define EEK_SECTION_H 1 + +#include "eek-key.h" + +G_BEGIN_DECLS + +#define EEK_TYPE_SECTION (eek_section_get_type()) +#define EEK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SECTION, EekSection)) +#define EEK_IS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SECTION)) +#define EEK_SECTION_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_SECTION, EekSectionIface)) + +typedef struct _EekSectionIface EekSectionIface; + +struct _EekSectionIface +{ + /*< private >*/ + GTypeInterface g_iface; + + /*< public >*/ + void (* set_dimensions) (EekSection *self, + gint columns, + gint rows); + void (* get_dimensions) (EekSection *self, + gint *columns, + gint *rows); + void (* set_angle) (EekSection *self, + gint angle); + gint (* get_angle) (EekSection *self); + + void (* set_bounds) (EekSection *self, + EekBounds *bounds); + void (* get_bounds) (EekSection *self, + EekBounds *bounds); + + EekKey *(* create_key) (EekSection *self, + const gchar *name, + guint *keysyms, + gint num_groups, + gint num_levels, + gint column, + gint row, + EekOutline *outline, + EekBounds *bounds); + + void (* foreach_key) (EekSection *self, + GFunc func, + gpointer user_data); +}; + +GType eek_section_get_type (void) G_GNUC_CONST; + +void eek_section_set_dimensions (EekSection *section, + gint columns, + gint rows); +void eek_section_get_dimensions (EekSection *section, + gint *columns, + gint *rows); +void eek_section_set_angle (EekSection *section, + gint angle); +gint eek_section_get_angle (EekSection *section); + +void eek_section_set_bounds (EekSection *section, + EekBounds *bounds); +void eek_section_get_bounds (EekSection *section, + EekBounds *bounds); + +EekKey *eek_section_create_key (EekSection *section, + const gchar *name, + guint *labels, + gint num_groups, + gint num_levels, + gint column, + gint row, + EekOutline *outline, + EekBounds *bounds); + +void eek_section_foreach_key (EekSection *section, + GFunc func, + gpointer user_data); + +G_END_DECLS +#endif /* EEK_SECTION_H */ diff --git a/eek/eek-simple-key.c b/eek/eek-simple-key.c new file mode 100644 index 00000000..36828f8a --- /dev/null +++ b/eek/eek-simple-key.c @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include "eek-simple-key.h" +#include "eek-keysym.h" +#include + +enum { + PROP_0, + PROP_NAME, + PROP_KEYSYMS, + PROP_COLUMN, + PROP_ROW, + PROP_OUTLINE, + PROP_BOUNDS, + PROP_GROUP, + PROP_LEVEL, + PROP_LAST +}; + +static void eek_key_iface_init (EekKeyIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekSimpleKey, eek_simple_key, + G_TYPE_INITIALLY_UNOWNED, + G_IMPLEMENT_INTERFACE (EEK_TYPE_KEY, + eek_key_iface_init)); + +#define EEK_SIMPLE_KEY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyPrivate)) + +struct _EekSimpleKeyPrivate +{ + gchar *name; + guint *keysyms; + gint num_levels; + gint num_groups; + gint column; + gint row; + EekOutline *outline; + EekBounds bounds; + gint group; + gint level; +}; + +static void +eek_simple_key_real_set_keysyms (EekKey *self, + guint *keysyms, + gint groups, + gint levels) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + if (priv->keysyms) + g_slice_free (guint, priv->keysyms); + priv->keysyms = g_slice_alloc (groups * levels * sizeof(guint)); + memcpy (priv->keysyms, keysyms, groups * levels * sizeof(guint)); + priv->num_groups = groups; + priv->num_levels = levels; +} + +static gint +eek_simple_key_real_get_groups (EekKey *self) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_val_if_fail (priv, -1); + return priv->num_groups; +} + +static guint +eek_simple_key_real_get_keysym (EekKey *self) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_val_if_fail (priv, EEK_INVALID_KEYSYM); + if (priv->num_groups * priv->num_levels == 0) + return EEK_INVALID_KEYSYM; + return priv->keysyms[priv->group * priv->num_levels + priv->level]; +} + +static void +eek_simple_key_real_set_index (EekKey *self, + gint column, + gint row) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (column < 0); + g_return_if_fail (row < 0); + priv->column = column; + priv->row = row; +} + +static void +eek_simple_key_real_get_index (EekKey *self, + gint *column, + gint *row) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (column); + g_return_if_fail (row); + *column = priv->column; + *row = priv->row; +} + +static void +eek_simple_key_real_set_outline (EekKey *self, EekOutline *outline) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + priv->outline = outline; +} + +static EekOutline * +eek_simple_key_real_get_outline (EekKey *self) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_val_if_fail (priv, NULL); + return priv->outline; +} + +static void +eek_simple_key_real_set_bounds (EekKey *self, + EekBounds *bounds) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + priv->bounds = *bounds; +} + +static void +eek_simple_key_real_get_bounds (EekKey *self, + EekBounds *bounds) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (bounds); + *bounds = priv->bounds; +} + +static void +eek_simple_key_real_set_keysym_index (EekKey *self, + gint group, + gint level) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (group < priv->num_groups); + g_return_if_fail (level < priv->num_levels); + priv->group = group; + priv->level = level; +} + +static void +eek_simple_key_real_get_keysym_index (EekKey *self, + gint *group, + gint *level) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (group); + g_return_if_fail (level); + *group = priv->group; + *level = priv->level; +} + +static void +eek_key_iface_init (EekKeyIface *iface) +{ + iface->set_keysyms = eek_simple_key_real_set_keysyms; + iface->get_groups = eek_simple_key_real_get_groups; + iface->get_keysym = eek_simple_key_real_get_keysym; + iface->set_index = eek_simple_key_real_set_index; + iface->get_index = eek_simple_key_real_get_index; + iface->set_outline = eek_simple_key_real_set_outline; + iface->get_outline = eek_simple_key_real_get_outline; + iface->set_bounds = eek_simple_key_real_set_bounds; + iface->get_bounds = eek_simple_key_real_get_bounds; + iface->set_keysym_index = eek_simple_key_real_set_keysym_index; + iface->get_keysym_index = eek_simple_key_real_get_keysym_index; +} + +static void +eek_simple_key_dispose (GObject *object) +{ + G_OBJECT_CLASS (eek_simple_key_parent_class)->dispose (object); +} + +static void +eek_simple_key_finalize (GObject *object) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); + + g_free (priv->name); + g_slice_free (guint, priv->keysyms); + G_OBJECT_CLASS (eek_simple_key_parent_class)->finalize (object); +} + +static void +eek_simple_key_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); + EekKeysymMatrix *matrix; + + g_return_if_fail (priv); + switch (prop_id) { + case PROP_NAME: + g_free (priv->name); + priv->name = g_strdup (g_value_get_string (value)); + break; + case PROP_KEYSYMS: + matrix = g_value_get_boxed (value); + eek_key_set_keysyms (EEK_KEY(object), + matrix->data, + matrix->num_groups, + matrix->num_levels); + break; + case PROP_COLUMN: + priv->column = g_value_get_int (value); + break; + case PROP_ROW: + priv->row = g_value_get_int (value); + break; + case PROP_OUTLINE: + priv->outline = g_value_get_pointer (value); + break; + case PROP_BOUNDS: + priv->bounds = *(EekBounds *)g_value_get_boxed (value); + break; + case PROP_GROUP: + priv->group = g_value_get_int (value); + break; + case PROP_LEVEL: + priv->level = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_simple_key_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekSimpleKeyPrivate *priv = EEK_SIMPLE_KEY_GET_PRIVATE(object); + EekKeysymMatrix matrix; + + g_return_if_fail (priv); + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + case PROP_KEYSYMS: + matrix.data = priv->keysyms; + matrix.num_groups = priv->num_groups; + matrix.num_levels = priv->num_levels; + g_value_set_boxed (value, &matrix); + break; + case PROP_COLUMN: + g_value_set_int (value, priv->column); + break; + case PROP_ROW: + g_value_set_int (value, priv->row); + break; + case PROP_OUTLINE: + g_value_set_pointer (value, priv->outline); + break; + case PROP_BOUNDS: + g_value_set_boxed (value, &priv->bounds); + break; + case PROP_GROUP: + g_value_set_int (value, priv->group); + break; + case PROP_LEVEL: + g_value_set_int (value, priv->level); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_simple_key_class_init (EekSimpleKeyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, + sizeof (EekSimpleKeyPrivate)); + + gobject_class->set_property = eek_simple_key_set_property; + gobject_class->get_property = eek_simple_key_get_property; + gobject_class->finalize = eek_simple_key_finalize; + gobject_class->dispose = eek_simple_key_dispose; + + g_object_class_override_property (gobject_class, + PROP_NAME, + "name"); + g_object_class_override_property (gobject_class, + PROP_KEYSYMS, + "keysyms"); + g_object_class_override_property (gobject_class, + PROP_COLUMN, + "column"); + g_object_class_override_property (gobject_class, + PROP_ROW, + "row"); + g_object_class_override_property (gobject_class, + PROP_OUTLINE, + "outline"); + g_object_class_override_property (gobject_class, + PROP_BOUNDS, + "bounds"); + g_object_class_override_property (gobject_class, + PROP_GROUP, + "group"); + g_object_class_override_property (gobject_class, + PROP_LEVEL, + "level"); +} + +static void +eek_simple_key_init (EekSimpleKey *self) +{ + EekSimpleKeyPrivate *priv; + + priv = self->priv = EEK_SIMPLE_KEY_GET_PRIVATE(self); + priv->keysyms = NULL; + priv->num_groups = 0; + priv->num_levels = 0; + priv->column = 0; + priv->row = 0; + priv->outline = NULL; + memset (&priv->bounds, 0, sizeof priv->bounds); +} diff --git a/eek/eek-simple-key.h b/eek/eek-simple-key.h new file mode 100644 index 00000000..3beb1866 --- /dev/null +++ b/eek/eek-simple-key.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_SIMPLE_KEY_H +#define EEK_SIMPLE_KEY_H 1 + +#include "eek-key.h" + +G_BEGIN_DECLS +#define EEK_TYPE_SIMPLE_KEY (eek_simple_key_get_type()) +#define EEK_SIMPLE_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKey)) +#define EEK_SIMPLE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyClass)) +#define EEK_IS_SIMPLE_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_KEY)) +#define EEK_IS_SIMPLE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_KEY)) +#define EEK_SIMPLE_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_KEY, EekSimpleKeyClass)) + +typedef struct _EekSimpleKey EekSimpleKey; +typedef struct _EekSimpleKeyClass EekSimpleKeyClass; +typedef struct _EekSimpleKeyPrivate EekSimpleKeyPrivate; + +struct _EekSimpleKey +{ + /*< private >*/ + GInitiallyUnowned parent; + + /*< private >*/ + EekSimpleKeyPrivate *priv; +}; + +struct _EekSimpleKeyClass +{ + /*< private >*/ + GInitiallyUnownedClass parent_class; +}; + +GType eek_simple_key_get_type (void) G_GNUC_CONST; + +G_END_DECLS +#endif /* EEK_SIMPLE_KEY_H */ diff --git a/eek/eek-simple-keyboard.c b/eek/eek-simple-keyboard.c new file mode 100644 index 00000000..bf42467c --- /dev/null +++ b/eek/eek-simple-keyboard.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-simple-keyboard.h" + +enum { + PROP_0, + PROP_BOUNDS, + PROP_LAST +}; + +static void eek_keyboard_iface_init (EekKeyboardIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekSimpleKeyboard, eek_simple_keyboard, + G_TYPE_INITIALLY_UNOWNED, + G_IMPLEMENT_INTERFACE (EEK_TYPE_KEYBOARD, + eek_keyboard_iface_init)); + +#define EEK_SIMPLE_KEYBOARD_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardPrivate)) + + +struct _EekSimpleKeyboardPrivate +{ + EekBounds bounds; + GSList *sections; +}; + +static void +eek_simple_keyboard_real_set_bounds (EekKeyboard *self, + EekBounds *bounds) +{ + EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); + + g_return_if_fail (priv); + priv->bounds = *bounds; +} + +static void +eek_simple_keyboard_real_get_bounds (EekKeyboard *self, + EekBounds *bounds) +{ + EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (bounds); + *bounds = priv->bounds; +} + +static EekSection * +eek_simple_keyboard_real_create_section (EekKeyboard *self, + const gchar *name, + gint angle, + EekBounds *bounds) +{ + EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); + EekSection *section; + + g_return_val_if_fail (priv, NULL); + section = g_object_new (EEK_TYPE_SIMPLE_SECTION, + "name", name, + "angle", angle, + "bounds", bounds, + NULL); + g_return_val_if_fail (section, NULL); + priv->sections = g_slist_prepend (priv->sections, section); + return section; +} + +static void +eek_simple_keyboard_real_foreach_section (EekKeyboard *self, + GFunc func, + gpointer user_data) +{ + EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_slist_foreach (priv->sections, func, user_data); +} + +static void +eek_simple_keyboard_real_set_layout (EekKeyboard *self, + EekLayout *layout) +{ + g_return_if_fail (EEK_IS_KEYBOARD(self)); + g_return_if_fail (EEK_IS_LAYOUT(layout)); + + EEK_LAYOUT_GET_CLASS(layout)->apply_to_keyboard (layout, self); + if (g_object_is_floating (layout)) + g_object_unref (layout); +} + +static void +eek_keyboard_iface_init (EekKeyboardIface *iface) +{ + iface->set_bounds = eek_simple_keyboard_real_set_bounds; + iface->get_bounds = eek_simple_keyboard_real_get_bounds; + iface->create_section = eek_simple_keyboard_real_create_section; + iface->foreach_section = eek_simple_keyboard_real_foreach_section; + iface->set_layout = eek_simple_keyboard_real_set_layout; +} + +static void +eek_simple_keyboard_dispose (GObject *object) +{ + EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object); + GSList *head; + + for (head = priv->sections; head; head = g_slist_next (head)) + g_object_unref (head->data); + G_OBJECT_CLASS (eek_simple_keyboard_parent_class)->dispose (object); +} + +static void +eek_simple_keyboard_finalize (GObject *object) +{ + EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object); + + g_slist_free (priv->sections); + G_OBJECT_CLASS (eek_simple_keyboard_parent_class)->finalize (object); +} + +static void +eek_simple_keyboard_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_BOUNDS: + eek_keyboard_set_bounds (EEK_KEYBOARD(object), + g_value_get_boxed (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_simple_keyboard_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekSimpleKeyboardPrivate *priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(object); + + g_return_if_fail (priv); + switch (prop_id) { + case PROP_BOUNDS: + g_value_set_boxed (value, &priv->bounds); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_simple_keyboard_class_init (EekSimpleKeyboardClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, + sizeof (EekSimpleKeyboardPrivate)); + + gobject_class->set_property = eek_simple_keyboard_set_property; + gobject_class->get_property = eek_simple_keyboard_get_property; + gobject_class->finalize = eek_simple_keyboard_finalize; + gobject_class->dispose = eek_simple_keyboard_dispose; + + g_object_class_override_property (gobject_class, + PROP_BOUNDS, + "bounds"); +} + +static void +eek_simple_keyboard_init (EekSimpleKeyboard *self) +{ + EekSimpleKeyboardPrivate *priv; + + priv = self->priv = EEK_SIMPLE_KEYBOARD_GET_PRIVATE(self); + priv->sections = NULL; +} + +EekKeyboard* +eek_simple_keyboard_new (void) +{ + return g_object_new (EEK_TYPE_SIMPLE_KEYBOARD, NULL); +} diff --git a/eek/eek-simple-keyboard.h b/eek/eek-simple-keyboard.h new file mode 100644 index 00000000..658dbc72 --- /dev/null +++ b/eek/eek-simple-keyboard.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_SIMPLE_KEYBOARD_H +#define EEK_SIMPLE_KEYBOARD_H 1 + +#include "eek-simple-section.h" +#include "eek-keyboard.h" + +G_BEGIN_DECLS +#define EEK_TYPE_SIMPLE_KEYBOARD (eek_simple_keyboard_get_type()) +#define EEK_SIMPLE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekKeyboard)) +#define EEK_SIMPLE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardClass)) +#define EEK_IS_SIMPLE_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_KEYBOARD)) +#define EEK_IS_SIMPLE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_KEYBOARD)) +#define EEK_SIMPLE_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_KEYBOARD, EekSimpleKeyboardClass)) + +typedef struct _EekSimpleKeyboard EekSimpleKeyboard; +typedef struct _EekSimpleKeyboardClass EekSimpleKeyboardClass; +typedef struct _EekSimpleKeyboardPrivate EekSimpleKeyboardPrivate; + +struct _EekSimpleKeyboard +{ + /*< private >*/ + GInitiallyUnowned parent; + + EekSimpleKeyboardPrivate *priv; +}; + +struct _EekSimpleKeyboardClass +{ + /*< private >*/ + GInitiallyUnownedClass parent_class; +}; + +GType eek_simple_keyboard_get_type (void) G_GNUC_CONST; + +EekKeyboard *eek_simple_keyboard_new (void); + +G_END_DECLS +#endif /* EEK_SIMPLE_KEYBOARD_H */ diff --git a/eek/eek-simple-section.c b/eek/eek-simple-section.c new file mode 100644 index 00000000..6a33e082 --- /dev/null +++ b/eek/eek-simple-section.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include "eek-simple-section.h" +#include + +enum { + PROP_0, + PROP_NAME, + PROP_COLUMNS, + PROP_ROWS, + PROP_ANGLE, + PROP_BOUNDS, + PROP_LAST +}; + +static void eek_section_iface_init (EekSectionIface *iface); + +G_DEFINE_TYPE_WITH_CODE (EekSimpleSection, eek_simple_section, + G_TYPE_INITIALLY_UNOWNED, + G_IMPLEMENT_INTERFACE (EEK_TYPE_SECTION, + eek_section_iface_init)); + +#define EEK_SIMPLE_SECTION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionPrivate)) + +struct _EekSimpleSectionPrivate +{ + gchar *name; + gint num_columns; + gint num_rows; + gint angle; + EekBounds bounds; + GSList *keys; +}; + +static void +eek_simple_section_real_set_dimensions (EekSection *self, + gint columns, + gint rows) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + priv->num_columns = columns; + priv->num_rows = rows; +} + +static void +eek_simple_section_real_get_dimensions (EekSection *self, + gint *columns, + gint *rows) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + *columns = priv->num_columns; + *rows = priv->num_rows; +} + +static void +eek_simple_section_real_set_angle (EekSection *self, + gint angle) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + priv->angle = angle; +} + +static gint +eek_simple_section_real_get_angle (EekSection *self) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + + g_return_val_if_fail (priv, 0); + return priv->angle; +} + +static void +eek_simple_section_real_set_bounds (EekSection *self, + EekBounds *bounds) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (bounds); + priv->bounds = *bounds; +} + +static void +eek_simple_section_real_get_bounds (EekSection *self, EekBounds *bounds) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_return_if_fail (bounds); + priv->bounds = *bounds; +} + +static EekKey * +eek_simple_section_real_create_key (EekSection *self, + const gchar *name, + guint *keysyms, + gint num_groups, + gint num_levels, + gint column, + gint row, + EekOutline *outline, + EekBounds *bounds) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + EekKey *key; + EekKeysymMatrix matrix; + + g_return_val_if_fail (priv, NULL); + g_return_val_if_fail (column < priv->num_columns, NULL); + g_return_val_if_fail (row < priv->num_rows, NULL); + + matrix.data = keysyms; + matrix.num_groups = num_groups; + matrix.num_levels = num_levels; + key = g_object_new (EEK_TYPE_SIMPLE_KEY, + "name", name, + "keysyms", &matrix, + "column", column, + "row", row, + "outline", outline, + "bounds", bounds, + NULL); + g_return_val_if_fail (key, NULL); + priv->keys = g_slist_prepend (priv->keys, key); + return key; +} + +static void +eek_simple_section_real_foreach_key (EekSection *self, + GFunc func, + gpointer user_data) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(self); + + g_return_if_fail (priv); + g_slist_foreach (priv->keys, func, user_data); +} + +static void +eek_section_iface_init (EekSectionIface *iface) +{ + iface->set_dimensions = eek_simple_section_real_set_dimensions; + iface->get_dimensions = eek_simple_section_real_get_dimensions; + iface->set_angle = eek_simple_section_real_set_angle; + iface->get_angle = eek_simple_section_real_get_angle; + iface->set_bounds = eek_simple_section_real_set_bounds; + iface->get_bounds = eek_simple_section_real_get_bounds; + iface->create_key = eek_simple_section_real_create_key; + iface->foreach_key = eek_simple_section_real_foreach_key; +} + +static void +eek_simple_section_dispose (GObject *object) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); + GSList *head; + + for (head = priv->keys; head; head = g_slist_next (head)) + g_object_unref (head->data); + + G_OBJECT_CLASS (eek_simple_section_parent_class)->dispose (object); +} + +static void +eek_simple_section_finalize (GObject *object) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); + + g_free (priv->name); + g_slist_free (priv->keys); + G_OBJECT_CLASS (eek_simple_section_parent_class)->finalize (object); +} + +static void +eek_simple_section_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NAME: + g_free (priv->name); + priv->name = g_strdup (g_value_get_string (value)); + break; + case PROP_ANGLE: + eek_section_set_angle (EEK_SECTION(object), + g_value_get_int (value)); + break; + case PROP_BOUNDS: + eek_section_set_bounds (EEK_SECTION(object), + g_value_get_boxed (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_set_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_simple_section_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EekSimpleSectionPrivate *priv = EEK_SIMPLE_SECTION_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + case PROP_ANGLE: + g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object))); + break; + case PROP_BOUNDS: + g_value_set_boxed (value, &priv->bounds); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + g_object_get_property (object, + g_param_spec_get_name (pspec), + value); + break; + } +} + +static void +eek_simple_section_class_init (EekSimpleSectionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (gobject_class, sizeof (EekSimpleSectionPrivate)); + + gobject_class->set_property = eek_simple_section_set_property; + gobject_class->get_property = eek_simple_section_get_property; + gobject_class->finalize = eek_simple_section_finalize; + gobject_class->dispose = eek_simple_section_dispose; + + g_object_class_override_property (gobject_class, + PROP_NAME, + "name"); + g_object_class_override_property (gobject_class, + PROP_ANGLE, + "angle"); + g_object_class_override_property (gobject_class, + PROP_BOUNDS, + "bounds"); +} + +static void +eek_simple_section_init (EekSimpleSection *self) +{ + EekSimpleSectionPrivate *priv; + + priv = self->priv = EEK_SIMPLE_SECTION_GET_PRIVATE (self); + priv->angle = 0; + memset (&priv->bounds, 0, sizeof priv->bounds); + priv->keys = NULL; +} diff --git a/eek/eek-simple-section.h b/eek/eek-simple-section.h new file mode 100644 index 00000000..c6f7eb72 --- /dev/null +++ b/eek/eek-simple-section.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_SIMPLE_SECTION_H +#define EEK_SIMPLE_SECTION_H 1 + +#include "eek-simple-key.h" +#include "eek-section.h" + +G_BEGIN_DECLS +#define EEK_TYPE_SIMPLE_SECTION (eek_simple_section_get_type()) +#define EEK_SIMPLE_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSection)) +#define EEK_SIMPLE_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionClass)) +#define EEK_IS_SIMPLE_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SIMPLE_SECTION)) +#define EEK_IS_SIMPLE_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SIMPLE_SECTION)) +#define EEK_SIMPLE_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SIMPLE_SECTION, EekSimpleSectionClass)) + +typedef struct _EekSimpleSection EekSimpleSection; +typedef struct _EekSimpleSectionClass EekSimpleSectionClass; +typedef struct _EekSimpleSectionPrivate EekSimpleSectionPrivate; + +struct _EekSimpleSection +{ + /*< private >*/ + GInitiallyUnowned parent; + + /*< private >*/ + EekSimpleSectionPrivate *priv; +}; + +struct _EekSimpleSectionClass +{ + /*< private >*/ + GInitiallyUnownedClass parent_class; +}; + +GType eek_simple_section_get_type (void) G_GNUC_CONST; + +G_END_DECLS +#endif /* EEK_SIMPLE_SECTION_H */ diff --git a/eek/eek-types.c b/eek/eek-types.c new file mode 100644 index 00000000..b313bd35 --- /dev/null +++ b/eek/eek-types.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "eek-types.h" + +/* EekKeysymMatrix */ +static EekKeysymMatrix * +eek_keysym_matrix_copy (const EekKeysymMatrix *matrix) +{ + return g_slice_dup (EekKeysymMatrix, matrix); +} + +static void +eek_keysym_matrix_free (EekKeysymMatrix *matrix) +{ + g_slice_free (EekKeysymMatrix, matrix); +} + +GType +eek_keysym_matrix_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = + g_boxed_type_register_static ("EekKeysymMatrix", + (GBoxedCopyFunc)eek_keysym_matrix_copy, + (GBoxedFreeFunc)eek_keysym_matrix_free); + return our_type; +} + +/* EekPoint */ +static EekPoint * +eek_point_copy (const EekPoint *point) +{ + return g_slice_dup (EekPoint, point); +} + +static void +eek_point_free (EekPoint *point) +{ + g_slice_free (EekPoint, point); +} + +GType +eek_point_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = + g_boxed_type_register_static ("EekPoint", + (GBoxedCopyFunc)eek_point_copy, + (GBoxedFreeFunc)eek_point_free); + return our_type; +} + +/* EekBounds */ +static EekBounds * +eek_bounds_copy (const EekBounds *bounds) +{ + return g_slice_dup (EekBounds, bounds); +} + +static void +eek_bounds_free (EekBounds *bounds) +{ + g_slice_free (EekBounds, bounds); +} + +GType +eek_bounds_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = + g_boxed_type_register_static ("EekBounds", + (GBoxedCopyFunc)eek_bounds_copy, + (GBoxedFreeFunc)eek_bounds_free); + return our_type; +} + +/* EekOutline */ +static EekOutline * +eek_outline_copy (const EekOutline *outline) +{ + return g_slice_dup (EekOutline, outline); +} + +static void +eek_outline_free (EekOutline *outline) +{ + g_slice_free (EekOutline, outline); +} + +GType +eek_outline_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = + g_boxed_type_register_static ("EekOutline", + (GBoxedCopyFunc)eek_outline_copy, + (GBoxedFreeFunc)eek_outline_free); + return our_type; +} diff --git a/eek/eek-types.h b/eek/eek-types.h new file mode 100644 index 00000000..2205184a --- /dev/null +++ b/eek/eek-types.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_TYPES_H +#define EEK_TYPES_H 1 + +#include + +G_BEGIN_DECLS + +/** + * EekKeysymMatrix: + * @data: array of keysyms + * @num_groups: the number of groups (rows) + * @num_levels: the number of levels (columns) + * + * Symbol matrix of a key. + */ +struct _EekKeysymMatrix +{ + guint *data; + gint num_groups; + gint num_levels; +}; +typedef struct _EekKeysymMatrix EekKeysymMatrix; + +#define EEK_TYPE_KEYSYM_MATRIX (eek_keysym_matrix_get_type ()) +GType eek_keysym_matrix_get_type (void) G_GNUC_CONST; + +/** + * EekPoint: + * @x: X coordinate of the point + * @y: Y coordinate of the point + * + * 2D vertex + */ +struct _EekPoint +{ + gdouble x; + gdouble y; +}; +typedef struct _EekPoint EekPoint; + +#define EEK_TYPE_POINT (eek_point_get_type ()) +GType eek_point_get_type (void) G_GNUC_CONST; + +/** + * EekBounds: + * @x: X coordinate of the top left point + * @y: Y coordinate of the top left point + * @width: width of the box + * @height: height of the box + * + * 2D bounding box + */ +struct _EekBounds +{ + gdouble x; + gdouble y; + gdouble w; + gdouble h; +}; +typedef struct _EekBounds EekBounds; + +#define EEK_TYPE_BOUNDS (eek_bounds_get_type ()) +GType eek_bounds_get_type (void) G_GNUC_CONST; + +/** + * EekOutline: + * @corner_radius: radius of corners of rounded polygon + * @points: an array of points represents a polygon + * @num_points: the length of @points + * + * 2D rounded polygon used to draw key shape + */ +struct _EekOutline +{ + gdouble corner_radius; + EekPoint *points; + gint num_points; +}; +typedef struct _EekOutline EekOutline; + +#define EEK_TYPE_OUTLINE (eek_outline_get_type ()) +GType eek_outline_get_type (void) G_GNUC_CONST; + +/* dummy */ +typedef struct _EekKeyboard EekKeyboard; +typedef struct _EekSection EekSection; +typedef struct _EekKey EekKey; + +G_END_DECLS +#endif /* EEK_TYPES_H */ diff --git a/eek/eek-xkb-layout.c b/eek/eek-xkb-layout.c new file mode 100644 index 00000000..147c02a2 --- /dev/null +++ b/eek/eek-xkb-layout.c @@ -0,0 +1,759 @@ +/* + * Copyright (C) 2006 Sergey V. Udaltsov + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/** + * SECTION:eek-xkb-layout + * @short_description: Layout engine using XKB configuration + * + * The #EekXkbLayout inherits #EekLayout class and arranges keyboard + * elements using XKB. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include +#include "eek-xkb-layout.h" +#include "eek-keyboard.h" + +#define noKBDRAW_DEBUG + +G_DEFINE_TYPE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT); + +#define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate)) + +enum { + PROP_0, + PROP_KEYCODES, + PROP_GEOMETRY, + PROP_SYMBOLS, + PROP_LAST +}; + +struct _EekXkbLayoutPrivate +{ + /* Configuration names that should synch'ed to the symbolic names + in priv->xkb->names. Since we use GLib's memory allocator, + don't store any address returned from the X server here. */ + XkbComponentNamesRec names; + + Display *display; + + /* Actual XKB configuration of DISPLAY. */ + XkbDescRec *xkb; + + /* Hash table to cache outlines by shape address. */ + GHashTable *outline_hash; + + gint scale_numerator; + gint scale_denominator; +}; + +#define INVALID_KEYCODE ((guint)(-1)) + +static guint +find_keycode (EekXkbLayout *layout, gchar *key_name); + +static void +get_keyboard (EekXkbLayout *layout); + +static void +get_names (EekXkbLayout *layout); + +static void +setup_scaling (EekXkbLayout *layout, + gdouble width, + gdouble height); + +G_INLINE_FUNC gint +xkb_to_pixmap_coord (EekXkbLayout *layout, + gint n) +{ + EekXkbLayoutPrivate *priv = layout->priv; + return n * priv->scale_numerator / priv->scale_denominator; +} + +G_INLINE_FUNC gdouble +xkb_to_pixmap_double (EekXkbLayout *layout, + gdouble d) +{ + EekXkbLayoutPrivate *priv = layout->priv; + return d * priv->scale_numerator / priv->scale_denominator; +} + +static EekKey * +create_key (EekXkbLayout *layout, + EekSection *section, + gint column, + gint row, + gdouble x, + gdouble y, + XkbKeyRec *xkbkey) +{ + XkbGeometryRec *xkbgeometry; + XkbBoundsRec *xkbbounds; + XkbShapeRec *xkbshape; + XkbOutlineRec *xkboutline; + EekXkbLayoutPrivate *priv = layout->priv; + EekKey *key; + EekBounds bounds; + guint *keysyms; + gchar name[XkbKeyNameLength + 1]; + EekOutline *outline; + KeyCode keycode; + gint num_groups, num_levels; + + xkbgeometry = priv->xkb->geom; + xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx]; + outline = g_hash_table_lookup (priv->outline_hash, xkbshape); + if (outline == NULL) { + xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] : + xkbshape->primary; + + outline = g_new0 (EekOutline, 1); + outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius); + + if (xkboutline->num_points <= 2) { /* rectangular */ + gdouble x1, y1, x2, y2; + + outline->num_points = 4; + outline->points = g_new0 (EekPoint, outline->num_points); + if (xkboutline->num_points == 1) { + x1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.x1); + y1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.y1); + x2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x); + y2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y); + } else { + x1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x); + y1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y); + x2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].x); + y2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].y); + } + outline->points[0].x = outline->points[3].x = x1; + outline->points[0].y = outline->points[1].y = y1; + outline->points[1].x = outline->points[2].x = x2; + outline->points[2].y = outline->points[3].y = y2; + } else { /* polygon */ + gint i; + + outline->num_points = xkboutline->num_points; + outline->points = g_new0 (EekPoint, outline->num_points); + for (i = 0; i < xkboutline->num_points; i++) { + outline->points[i].x = xkb_to_pixmap_coord(layout, xkboutline->points[i].x); + outline->points[i].y = xkb_to_pixmap_coord(layout, xkboutline->points[i].y); + } + } + g_hash_table_insert (priv->outline_hash, xkbshape, outline); + } + + memset (name, 0, sizeof name); + memcpy (name, xkbkey->name.name, sizeof name - 1); + + xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds; + bounds.x = xkb_to_pixmap_coord(layout, xkbbounds->x1 + x); + bounds.y = xkb_to_pixmap_coord(layout, xkbbounds->y1 + y); + bounds.w = xkb_to_pixmap_coord(layout, xkbbounds->x2 - xkbbounds->x1); + bounds.h = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1); + + keycode = find_keycode (layout, name); + if (keycode == INVALID_KEYCODE) + num_groups = num_levels = 0; + else { + KeySym keysym; + gint num_keysyms, i, j; + + num_groups = XkbKeyNumGroups (priv->xkb, keycode); + num_levels = XkbKeyGroupsWidth (priv->xkb, keycode); + num_keysyms = num_groups * num_levels; + keysyms = g_malloc0 ((num_keysyms) * sizeof(guint)); + for (i = 0; i < num_groups; i++) + for (j = 0; j < num_levels; j++) { + keysym = XkbKeySymEntry (priv->xkb, keycode, i, j); + keysyms[i * num_levels + j] = keysym; + } + } + + eek_section_create_key (section, + name, + keysyms, + num_groups, + num_levels, + column, + row, + outline, + &bounds); +} + +static void +create_section (EekXkbLayout *layout, + EekKeyboard *keyboard, + XkbSectionRec *xkbsection) +{ + XkbGeometryRec *xkbgeometry; + EekXkbLayoutPrivate *priv; + EekSection *section; + EekBounds bounds; + const gchar *name; + gfloat left, top; + gint i, j, columns; + + bounds.x = xkb_to_pixmap_coord(layout, xkbsection->left); + bounds.y = xkb_to_pixmap_coord(layout, xkbsection->top); + bounds.w = xkb_to_pixmap_coord(layout, xkbsection->width); + bounds.h = xkb_to_pixmap_coord(layout, xkbsection->height); + + priv = layout->priv; + xkbgeometry = priv->xkb->geom; + name = XGetAtomName (priv->display, xkbsection->name); + section = eek_keyboard_create_section (keyboard, + name, + /* angle is in tenth of degree */ + xkbsection->angle / 10, + &bounds); + + for (columns = 0, i = 0; i < xkbsection->num_rows; i++) { + XkbRowRec *xkbrow; + + xkbrow = &xkbsection->rows[i]; + if (xkbrow->num_keys > columns) + columns = xkbrow->num_keys; + } + eek_section_set_dimensions (section, columns, xkbsection->num_rows); + + for (i = 0; i < xkbsection->num_rows; i++) { + XkbRowRec *xkbrow; + + xkbrow = &xkbsection->rows[i]; + left = xkbrow->left; + top = xkbrow->top; + for (j = 0; j < xkbrow->num_keys; j++) { + XkbKeyRec *xkbkey; + XkbBoundsRec *xkbbounds; + + xkbkey = &xkbrow->keys[j]; + if (xkbrow->vertical) + top += xkbkey->gap; + else + left += xkbkey->gap; + create_key (layout, section, j, i, left, top, xkbkey); + xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds; + if (xkbrow->vertical) + top += xkbbounds->y2 - xkbbounds->y1; + else + left += xkbbounds->x2 - xkbbounds->x1; + } + } +} + +static void +create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard) +{ + EekXkbLayoutPrivate *priv = layout->priv; + XkbGeometryRec *xkbgeometry; + EekBounds bounds; + gint i; + + g_return_if_fail (priv->xkb); + g_return_if_fail (priv->xkb->geom); + + xkbgeometry = priv->xkb->geom; + + eek_keyboard_get_bounds (keyboard, &bounds); + setup_scaling (EEK_XKB_LAYOUT(layout), bounds.w, bounds.h); + + bounds.x = bounds.y = 0; + bounds.w = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm); + bounds.h = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm); + eek_keyboard_set_bounds (keyboard, &bounds); + + for (i = 0; i < xkbgeometry->num_sections; i++) { + XkbSectionRec *xkbsection; + EekSection *section; + + xkbsection = &xkbgeometry->sections[i]; + create_section (layout, keyboard, xkbsection); + } +} + +static void +eek_xkb_layout_apply_to_keyboard (EekLayout *layout, EekKeyboard *keyboard) +{ + g_return_if_fail (EEK_IS_XKB_LAYOUT(layout)); + g_return_if_fail (EEK_IS_KEYBOARD(keyboard)); + create_keyboard (EEK_XKB_LAYOUT(layout), keyboard); + if (g_object_is_floating (keyboard)) + g_object_unref (keyboard); +} + +static void +eek_xkb_layout_dispose (GObject *object) +{ + G_OBJECT_CLASS (eek_xkb_layout_parent_class)->dispose (object); +} + +static void +eek_xkb_layout_finalize (GObject *object) +{ + EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (object); + + g_free (priv->names.keycodes); + g_free (priv->names.geometry); + g_free (priv->names.symbols); + g_hash_table_unref (priv->outline_hash); + XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */ + G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object); +} + +static void +eek_xkb_layout_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + const gchar *name; + + switch (prop_id) + { + case PROP_KEYCODES: + name = g_value_get_string (value); + eek_xkb_layout_set_keycodes (EEK_XKB_LAYOUT(object), name); + break; + case PROP_GEOMETRY: + name = g_value_get_string (value); + eek_xkb_layout_set_geometry (EEK_XKB_LAYOUT(object), name); + break; + case PROP_SYMBOLS: + name = g_value_get_string (value); + eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eek_xkb_layout_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + const gchar *name; + + switch (prop_id) + { + case PROP_KEYCODES: + name = eek_xkb_layout_get_keycodes (EEK_XKB_LAYOUT(object)); + g_value_set_string (value, name); + break; + case PROP_GEOMETRY: + name = eek_xkb_layout_get_geometry (EEK_XKB_LAYOUT(object)); + g_value_set_string (value, name); + break; + case PROP_SYMBOLS: + name = eek_xkb_layout_get_symbols (EEK_XKB_LAYOUT(object)); + g_value_set_string (value, name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eek_xkb_layout_class_init (EekXkbLayoutClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass); + + g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate)); + + gobject_class->finalize = eek_xkb_layout_finalize; + gobject_class->dispose = eek_xkb_layout_dispose; + gobject_class->set_property = eek_xkb_layout_set_property; + gobject_class->get_property = eek_xkb_layout_get_property; + + layout_class->apply_to_keyboard = eek_xkb_layout_apply_to_keyboard; + + pspec = g_param_spec_string ("keycodes", + "Keycodes", + "XKB keycodes component name", + NULL, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_KEYCODES, pspec); + + pspec = g_param_spec_string ("geometry", + "Geometry", + "XKB geometry component name", + NULL, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_GEOMETRY, pspec); + + pspec = g_param_spec_string ("symbols", + "Symbols", + "XKB symbols component name", + NULL, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, PROP_SYMBOLS, pspec); +} + +static void +eek_xkb_layout_init (EekXkbLayout *self) +{ + EekXkbLayoutPrivate *priv; + + priv = self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self); + + memset (&priv->names, 0, sizeof priv->names); + priv->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + + /* XXX: XkbClientMapMask | XkbIndicatorMapMask | XkbNamesMask | + XkbGeometryMask */ + priv->xkb = XkbGetKeyboard (priv->display, + XkbGBN_GeometryMask | + XkbGBN_KeyNamesMask | + XkbGBN_OtherNamesMask | + XkbGBN_SymbolsMask | + XkbGBN_IndicatorMapMask, + XkbUseCoreKbd); + + priv->outline_hash = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + g_free); + if (priv->xkb == NULL) { + g_critical ("XkbGetKeyboard failed to get keyboard from the server!"); + return; + } + get_names (self); +} + +static void +get_names (EekXkbLayout *layout) +{ + EekXkbLayoutPrivate *priv = layout->priv; + gchar *name; + + XkbGetNames (priv->display, XkbAllNamesMask, priv->xkb); + + if (priv->xkb->names->keycodes <= 0) + g_warning ("XKB keycodes setting is not loaded properly"); + else { + name = XGetAtomName (priv->display, priv->xkb->names->keycodes); + if (!name) + g_warning ("Can't get the name of keycodes"); + else if (!priv->names.keycodes || + g_strcmp0 (name, priv->names.keycodes)) { + g_free (priv->names.keycodes); + priv->names.keycodes = g_strdup (name); + XFree (name); + } + } + + if (priv->xkb->names->geometry <= 0) + g_warning ("XKB geometry setting is not loaded"); + else { + name = XGetAtomName (priv->display, priv->xkb->names->geometry); + if (!name) + g_warning ("Can't get the name of geometry"); + else if (!priv->names.geometry || + g_strcmp0 (name, priv->names.geometry)) { + g_free (priv->names.geometry); + priv->names.geometry = g_strdup (name); + XFree (name); + } + } + + if (priv->xkb->names->symbols <= 0) + g_warning ("XKB symbols setting is not loaded"); + else { + name = XGetAtomName (priv->display, priv->xkb->names->symbols); + if (!name) + g_warning ("Can't get the name of symbols"); + else if (!priv->names.symbols || + g_strcmp0 (name, priv->names.symbols)) { + g_free (priv->names.symbols); + priv->names.symbols = g_strdup (name); + XFree (name); + } + } +} + +/** + * eek_xkb_layout_new: + * @keycodes: component name for keycodes + * @geometry: component name for geometry + * @symbols: component name for symbols + * + * Create a new #EekXkbLayout. + */ +EekLayout * +eek_xkb_layout_new (const gchar *keycodes, + const gchar *geometry, + const gchar *symbols) +{ + EekXkbLayout *layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL); + EekXkbLayoutPrivate *priv = layout->priv; + + g_return_val_if_fail (layout, NULL); + if (keycodes) + priv->names.keycodes = g_strdup (keycodes); + if (geometry) + priv->names.geometry = g_strdup (geometry); + if (symbols) + priv->names.symbols = g_strdup (symbols); + + get_keyboard (layout); + return EEK_LAYOUT(layout); +} + +/** + * eek_xkb_layout_set_keycodes: + * @layout: an #EekXkbLayout + * @keycodes: component name for keycodes + * + * Set the keycodes component (in the XKB terminology). + */ +void +eek_xkb_layout_set_keycodes (EekXkbLayout *layout, const gchar *keycodes) +{ + EekXkbLayoutPrivate *priv = layout->priv; + + g_free (priv->names.keycodes); + priv->names.keycodes = g_strdup (keycodes); + get_keyboard (layout); +} + +/** + * eek_xkb_layout_set_geometry: + * @layout: an #EekXkbLayout + * @geometry: component name for geometry + * + * Set the keycodes component (in the XKB terminology). + */ +void +eek_xkb_layout_set_geometry (EekXkbLayout *layout, const gchar *geometry) +{ + EekXkbLayoutPrivate *priv = layout->priv; + + g_free (priv->names.geometry); + priv->names.geometry = g_strdup (geometry); + get_keyboard (layout); +} + +/** + * eek_xkb_layout_set_symbols: + * @layout: an #EekXkbLayout + * @symbols: component name for symbols + * + * Set the symbols component (in the XKB terminology). + */ +void +eek_xkb_layout_set_symbols (EekXkbLayout *layout, const gchar *symbols) +{ + EekXkbLayoutPrivate *priv = layout->priv; + + g_free (priv->names.symbols); + priv->names.symbols = g_strdup (symbols); + get_keyboard (layout); +} + +/** + * eek_xkb_layout_get_keycodes: + * @layout: an #EekXkbLayout + * + * Get the keycodes component name (in the XKB terminology). + */ +G_CONST_RETURN gchar * +eek_xkb_layout_get_keycodes (EekXkbLayout *layout) +{ + EekXkbLayoutPrivate *priv = layout->priv; + + return priv->names.keycodes; +} + +/** + * eek_xkb_layout_get_geometry: + * @layout: an #EekXkbLayout + * + * Get the geometry component name (in the XKB terminology). + */ +G_CONST_RETURN gchar * +eek_xkb_layout_get_geometry (EekXkbLayout *layout) +{ + EekXkbLayoutPrivate *priv = layout->priv; + char *name; + + return priv->names.geometry; +} + +/** + * eek_xkb_layout_get_symbols: + * @layout: an #EekXkbLayout + * + * Get the symbols component name (in the XKB terminology). + */ +G_CONST_RETURN gchar * +eek_xkb_layout_get_symbols (EekXkbLayout *layout) +{ + EekXkbLayoutPrivate *priv = layout->priv; + + return priv->names.symbols; +} + +static void +get_keyboard (EekXkbLayout *layout) +{ + EekXkbLayoutPrivate *priv = layout->priv; + + if (priv->xkb) + XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */ + priv->xkb = NULL; + + if (priv->names.keycodes && + priv->names.geometry && + priv->names.symbols) { + priv->xkb = XkbGetKeyboardByName (priv->display, XkbUseCoreKbd, + &priv->names, 0, + XkbGBN_GeometryMask | + XkbGBN_KeyNamesMask | + XkbGBN_OtherNamesMask | + XkbGBN_ClientSymbolsMask | + XkbGBN_IndicatorMapMask, FALSE); + } else { + priv->xkb = XkbGetKeyboard (priv->display, + XkbGBN_GeometryMask | + XkbGBN_KeyNamesMask | + XkbGBN_OtherNamesMask | + XkbGBN_SymbolsMask | + XkbGBN_IndicatorMapMask, + XkbUseCoreKbd); + get_names (layout); + } + + if (priv->xkb == NULL) { + g_free (priv->names.keycodes); + priv->names.keycodes = NULL; + g_free (priv->names.geometry); + priv->names.geometry = NULL; + g_free (priv->names.symbols); + priv->names.symbols = NULL; + } +} + + +static guint +find_keycode (EekXkbLayout *layout, gchar *key_name) +{ +#define KEYSYM_NAME_MAX_LENGTH 4 + guint keycode; + gint i, j; + XkbKeyNamePtr pkey; + XkbKeyAliasPtr palias; + guint is_name_matched; + gchar *src, *dst; + EekXkbLayoutPrivate *priv = layout->priv; + + if (!priv->xkb) + return INVALID_KEYCODE; + +#ifdef KBDRAW_DEBUG + printf (" looking for keycode for (%c%c%c%c)\n", + key_name[0], key_name[1], key_name[2], key_name[3]); +#endif + + pkey = priv->xkb->names->keys + priv->xkb->min_key_code; + for (keycode = priv->xkb->min_key_code; + keycode <= priv->xkb->max_key_code; keycode++) { + is_name_matched = 1; + src = key_name; + dst = pkey->name; + for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) { + if ('\0' == *src) + break; + if (*src++ != *dst++) { + is_name_matched = 0; + break; + } + } + if (is_name_matched) { +#ifdef KBDRAW_DEBUG + printf (" found keycode %u\n", keycode); +#endif + return keycode; + } + pkey++; + } + + palias = priv->xkb->names->key_aliases; + for (j = priv->xkb->names->num_key_aliases; --j >= 0;) { + is_name_matched = 1; + src = key_name; + dst = palias->alias; + for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) { + if ('\0' == *src) + break; + if (*src++ != *dst++) { + is_name_matched = 0; + break; + } + } + + if (is_name_matched) { + keycode = find_keycode (layout, palias->real); +#ifdef KBDRAW_DEBUG + printf ("found alias keycode %u\n", keycode); +#endif + return keycode; + } + palias++; + } + + return INVALID_KEYCODE; +} + +static void +setup_scaling (EekXkbLayout *layout, + gdouble width, + gdouble height) +{ + EekXkbLayoutPrivate *priv = layout->priv; + + g_return_if_fail (priv->xkb); + + g_return_if_fail (priv->xkb->geom->width_mm > 0); + g_return_if_fail (priv->xkb->geom->height_mm > 0); + + if (width * priv->xkb->geom->height_mm < + height * priv->xkb->geom->width_mm) { + priv->scale_numerator = width; + priv->scale_denominator = priv->xkb->geom->width_mm; + } else { + priv->scale_numerator = height; + priv->scale_denominator = priv->xkb->geom->height_mm; + } +} diff --git a/eek/eek-xkb-layout.h b/eek/eek-xkb-layout.h new file mode 100644 index 00000000..9c1662c5 --- /dev/null +++ b/eek/eek-xkb-layout.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_XKB_LAYOUT_H +#define EEK_XKB_LAYOUT_H 1 + +#include +#include +#include "eek-layout.h" + +G_BEGIN_DECLS + +#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type()) +#define EEK_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayout)) +#define EEK_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass)) +#define EEK_IS_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKB_LAYOUT)) +#define EEK_IS_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKB_LAYOUT)) +#define EEK_XKB_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass)) + +typedef struct _EekXkbLayout EekXkbLayout; +typedef struct _EekXkbLayoutClass EekXkbLayoutClass; +typedef struct _EekXkbLayoutPrivate EekXkbLayoutPrivate; + +struct _EekXkbLayout +{ + /*< private >*/ + EekLayout parent; + + EekXkbLayoutPrivate *priv; +}; + +struct _EekXkbLayoutClass +{ + /*< private >*/ + EekLayoutClass parent_class; + + void (* set_keycodes) (EekXkbLayout *self, + const gchar *keycodes); + void (* set_geometry) (EekXkbLayout *self, + const gchar *geometry); + void (* set_symbols) (EekXkbLayout *self, + const gchar *symbols); + + G_CONST_RETURN gchar *(* get_keycodes) (EekXkbLayout *self); + G_CONST_RETURN gchar *(* get_geometry) (EekXkbLayout *self); + G_CONST_RETURN gchar *(* get_symbols) (EekXkbLayout *self); +}; + +GType eek_xkb_layout_get_type (void) G_GNUC_CONST; + +EekLayout *eek_xkb_layout_new (const gchar *keycodes, + const gchar *geometry, + const gchar *symbols); + +void eek_xkb_layout_set_keycodes (EekXkbLayout *layout, + const gchar *keycodes); +void eek_xkb_layout_set_geometry (EekXkbLayout *layout, + const gchar *geometry); +void eek_xkb_layout_set_symbols (EekXkbLayout *layout, + const gchar *symbols); + +G_CONST_RETURN gchar *eek_xkb_layout_get_keycodes (EekXkbLayout * layout); +G_CONST_RETURN gchar *eek_xkb_layout_get_geometry (EekXkbLayout * layout); +G_CONST_RETURN gchar *eek_xkb_layout_get_symbols (EekXkbLayout * layout); + +G_END_DECLS +#endif /* #ifndef EEK_XKB_LAYOUT_H */ diff --git a/eek/eek-xkb.h b/eek/eek-xkb.h new file mode 100644 index 00000000..42036ea3 --- /dev/null +++ b/eek/eek-xkb.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_XKB_H +#define EEK_XKB_H 1 + +#include "eek.h" +#include "eek-xkb-layout.h" + +#endif /* EEK_XKB_H */ diff --git a/eek/eek.h b/eek/eek.h new file mode 100644 index 00000000..deda670a --- /dev/null +++ b/eek/eek.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef EEK_H +#define EEK_H 1 + +#include "eek-keyboard.h" +#include "eek-layout.h" +#include "eek-keysym.c" + +#endif /* EEK_H */ diff --git a/eek/gen-keysym-labels.py b/eek/gen-keysym-labels.py new file mode 100755 index 00000000..be3531b3 --- /dev/null +++ b/eek/gen-keysym-labels.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +from __future__ import with_statement +import sys +import re + +if len(sys.argv) != 3: + print >> sys.stderr, "Usage: %s table.txt table-name" % sys.argv[0] + sys.exit(-1) + +table = dict() +with open(sys.argv[1], 'r') as fp: + for line in fp: + line = line.decode('UTF-8') + match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)', line, re.I) + if match: + table[int(match.group(1), 16)] = match.group(2) + +sys.stdout.write("static const struct eek_keysym_label %s[] = {\n" % + sys.argv[2]) + +for index, (keysym, label) in enumerate([(keysym, table[keysym]) + for keysym in sorted(table.keys())]): + sys.stdout.write(" { 0x%X, %s }" % (keysym, label.encode('UTF-8'))) + if index < len(table) - 1: + sys.stdout.write(",") + sys.stdout.write("\n") +sys.stdout.write("};\n") diff --git a/eek/keyname-keysym-labels.txt b/eek/keyname-keysym-labels.txt new file mode 100644 index 00000000..38869af1 --- /dev/null +++ b/eek/keyname-keysym-labels.txt @@ -0,0 +1,1306 @@ +0x000020 "space" +0x000021 "exclam" +0x000022 "quotedbl" +0x000023 "numbersign" +0x000024 "dollar" +0x000025 "percent" +0x000026 "ampersand" +0x000027 "apostrophe" +0x000027 "quoteright" +0x000028 "parenleft" +0x000029 "parenright" +0x00002a "asterisk" +0x00002b "plus" +0x00002c "comma" +0x00002d "minus" +0x00002e "period" +0x00002f "slash" +0x000030 "0" +0x000031 "1" +0x000032 "2" +0x000033 "3" +0x000034 "4" +0x000035 "5" +0x000036 "6" +0x000037 "7" +0x000038 "8" +0x000039 "9" +0x00003a "colon" +0x00003b "semicolon" +0x00003c "less" +0x00003d "equal" +0x00003e "greater" +0x00003f "question" +0x000040 "at" +0x000041 "A" +0x000042 "B" +0x000043 "C" +0x000044 "D" +0x000045 "E" +0x000046 "F" +0x000047 "G" +0x000048 "H" +0x000049 "I" +0x00004a "J" +0x00004b "K" +0x00004c "L" +0x00004d "M" +0x00004e "N" +0x00004f "O" +0x000050 "P" +0x000051 "Q" +0x000052 "R" +0x000053 "S" +0x000054 "T" +0x000055 "U" +0x000056 "V" +0x000057 "W" +0x000058 "X" +0x000059 "Y" +0x00005a "Z" +0x00005b "bracketleft" +0x00005c "backslash" +0x00005d "bracketright" +0x00005e "asciicircum" +0x00005f "underscore" +0x000060 "grave" +0x000060 "quoteleft" +0x000061 "a" +0x000062 "b" +0x000063 "c" +0x000064 "d" +0x000065 "e" +0x000066 "f" +0x000067 "g" +0x000068 "h" +0x000069 "i" +0x00006a "j" +0x00006b "k" +0x00006c "l" +0x00006d "m" +0x00006e "n" +0x00006f "o" +0x000070 "p" +0x000071 "q" +0x000072 "r" +0x000073 "s" +0x000074 "t" +0x000075 "u" +0x000076 "v" +0x000077 "w" +0x000078 "x" +0x000079 "y" +0x00007a "z" +0x00007b "braceleft" +0x00007c "bar" +0x00007d "braceright" +0x00007e "asciitilde" +0x0000a0 "nobreakspace" +0x0000a1 "exclamdown" +0x0000a2 "cent" +0x0000a3 "sterling" +0x0000a4 "currency" +0x0000a5 "yen" +0x0000a6 "brokenbar" +0x0000a7 "section" +0x0000a8 "diaeresis" +0x0000a9 "copyright" +0x0000aa "ordfeminine" +0x0000ab "guillemotleft" +0x0000ac "notsign" +0x0000ad "hyphen" +0x0000ae "registered" +0x0000af "macron" +0x0000b0 "degree" +0x0000b1 "plusminus" +0x0000b2 "twosuperior" +0x0000b3 "threesuperior" +0x0000b4 "acute" +0x0000b5 "mu" +0x0000b6 "paragraph" +0x0000b7 "periodcentered" +0x0000b8 "cedilla" +0x0000b9 "onesuperior" +0x0000ba "masculine" +0x0000bb "guillemotright" +0x0000bc "onequarter" +0x0000bd "onehalf" +0x0000be "threequarters" +0x0000bf "questiondown" +0x0000c0 "Agrave" +0x0000c1 "Aacute" +0x0000c2 "Acircumflex" +0x0000c3 "Atilde" +0x0000c4 "Adiaeresis" +0x0000c5 "Aring" +0x0000c6 "AE" +0x0000c7 "Ccedilla" +0x0000c8 "Egrave" +0x0000c9 "Eacute" +0x0000ca "Ecircumflex" +0x0000cb "Ediaeresis" +0x0000cc "Igrave" +0x0000cd "Iacute" +0x0000ce "Icircumflex" +0x0000cf "Idiaeresis" +0x0000d0 "ETH" +0x0000d0 "Eth" +0x0000d1 "Ntilde" +0x0000d2 "Ograve" +0x0000d3 "Oacute" +0x0000d4 "Ocircumflex" +0x0000d5 "Otilde" +0x0000d6 "Odiaeresis" +0x0000d7 "multiply" +0x0000d8 "Ooblique" +0x0000d9 "Ugrave" +0x0000da "Uacute" +0x0000db "Ucircumflex" +0x0000dc "Udiaeresis" +0x0000dd "Yacute" +0x0000de "THORN" +0x0000de "Thorn" +0x0000df "ssharp" +0x0000e0 "agrave" +0x0000e1 "aacute" +0x0000e2 "acircumflex" +0x0000e3 "atilde" +0x0000e4 "adiaeresis" +0x0000e5 "aring" +0x0000e6 "ae" +0x0000e7 "ccedilla" +0x0000e8 "egrave" +0x0000e9 "eacute" +0x0000ea "ecircumflex" +0x0000eb "ediaeresis" +0x0000ec "igrave" +0x0000ed "iacute" +0x0000ee "icircumflex" +0x0000ef "idiaeresis" +0x0000f0 "eth" +0x0000f1 "ntilde" +0x0000f2 "ograve" +0x0000f3 "oacute" +0x0000f4 "ocircumflex" +0x0000f5 "otilde" +0x0000f6 "odiaeresis" +0x0000f7 "division" +0x0000f8 "oslash" +0x0000f9 "ugrave" +0x0000fa "uacute" +0x0000fb "ucircumflex" +0x0000fc "udiaeresis" +0x0000fd "yacute" +0x0000fe "thorn" +0x0000ff "ydiaeresis" +0x0001a1 "Aogonek" +0x0001a2 "breve" +0x0001a3 "Lstroke" +0x0001a5 "Lcaron" +0x0001a6 "Sacute" +0x0001a9 "Scaron" +0x0001aa "Scedilla" +0x0001ab "Tcaron" +0x0001ac "Zacute" +0x0001ae "Zcaron" +0x0001af "Zabovedot" +0x0001b1 "aogonek" +0x0001b2 "ogonek" +0x0001b3 "lstroke" +0x0001b5 "lcaron" +0x0001b6 "sacute" +0x0001b7 "caron" +0x0001b9 "scaron" +0x0001ba "scedilla" +0x0001bb "tcaron" +0x0001bc "zacute" +0x0001bd "doubleacute" +0x0001be "zcaron" +0x0001bf "zabovedot" +0x0001c0 "Racute" +0x0001c3 "Abreve" +0x0001c5 "Lacute" +0x0001c6 "Cacute" +0x0001c8 "Ccaron" +0x0001ca "Eogonek" +0x0001cc "Ecaron" +0x0001cf "Dcaron" +0x0001d0 "Dstroke" +0x0001d1 "Nacute" +0x0001d2 "Ncaron" +0x0001d5 "Odoubleacute" +0x0001d8 "Rcaron" +0x0001d9 "Uring" +0x0001db "Udoubleacute" +0x0001de "Tcedilla" +0x0001e0 "racute" +0x0001e3 "abreve" +0x0001e5 "lacute" +0x0001e6 "cacute" +0x0001e8 "ccaron" +0x0001ea "eogonek" +0x0001ec "ecaron" +0x0001ef "dcaron" +0x0001f0 "dstroke" +0x0001f1 "nacute" +0x0001f2 "ncaron" +0x0001f5 "odoubleacute" +0x0001f8 "rcaron" +0x0001f9 "uring" +0x0001fb "udoubleacute" +0x0001fe "tcedilla" +0x0001ff "abovedot" +0x0002a1 "Hstroke" +0x0002a6 "Hcircumflex" +0x0002a9 "Iabovedot" +0x0002ab "Gbreve" +0x0002ac "Jcircumflex" +0x0002b1 "hstroke" +0x0002b6 "hcircumflex" +0x0002b9 "idotless" +0x0002bb "gbreve" +0x0002bc "jcircumflex" +0x0002c5 "Cabovedot" +0x0002c6 "Ccircumflex" +0x0002d5 "Gabovedot" +0x0002d8 "Gcircumflex" +0x0002dd "Ubreve" +0x0002de "Scircumflex" +0x0002e5 "cabovedot" +0x0002e6 "ccircumflex" +0x0002f5 "gabovedot" +0x0002f8 "gcircumflex" +0x0002fd "ubreve" +0x0002fe "scircumflex" +0x0003a2 "kappa" +0x0003a2 "kra" +0x0003a3 "Rcedilla" +0x0003a5 "Itilde" +0x0003a6 "Lcedilla" +0x0003aa "Emacron" +0x0003ab "Gcedilla" +0x0003ac "Tslash" +0x0003b3 "rcedilla" +0x0003b5 "itilde" +0x0003b6 "lcedilla" +0x0003ba "emacron" +0x0003bb "gcedilla" +0x0003bc "tslash" +0x0003bd "ENG" +0x0003bf "eng" +0x0003c0 "Amacron" +0x0003c7 "Iogonek" +0x0003cc "Eabovedot" +0x0003cf "Imacron" +0x0003d1 "Ncedilla" +0x0003d2 "Omacron" +0x0003d3 "Kcedilla" +0x0003d9 "Uogonek" +0x0003dd "Utilde" +0x0003de "Umacron" +0x0003e0 "amacron" +0x0003e7 "iogonek" +0x0003ec "eabovedot" +0x0003ef "imacron" +0x0003f1 "ncedilla" +0x0003f2 "omacron" +0x0003f3 "kcedilla" +0x0003f9 "uogonek" +0x0003fd "utilde" +0x0003fe "umacron" +0x00047e "overline" +0x0004a1 "kana_fullstop" +0x0004a2 "kana_openingbracket" +0x0004a3 "kana_closingbracket" +0x0004a4 "kana_comma" +0x0004a5 "kana_conjunctive" +0x0004a5 "kana_middledot" +0x0004a6 "kana_WO" +0x0004a7 "kana_a" +0x0004a8 "kana_i" +0x0004a9 "kana_u" +0x0004aa "kana_e" +0x0004ab "kana_o" +0x0004ac "kana_ya" +0x0004ad "kana_yu" +0x0004ae "kana_yo" +0x0004af "kana_tsu" +0x0004af "kana_tu" +0x0004b0 "prolongedsound" +0x0004b1 "kana_A" +0x0004b2 "kana_I" +0x0004b3 "kana_U" +0x0004b4 "kana_E" +0x0004b5 "kana_O" +0x0004b6 "kana_KA" +0x0004b7 "kana_KI" +0x0004b8 "kana_KU" +0x0004b9 "kana_KE" +0x0004ba "kana_KO" +0x0004bb "kana_SA" +0x0004bc "kana_SHI" +0x0004bd "kana_SU" +0x0004be "kana_SE" +0x0004bf "kana_SO" +0x0004c0 "kana_TA" +0x0004c1 "kana_CHI" +0x0004c1 "kana_TI" +0x0004c2 "kana_TSU" +0x0004c2 "kana_TU" +0x0004c3 "kana_TE" +0x0004c4 "kana_TO" +0x0004c5 "kana_NA" +0x0004c6 "kana_NI" +0x0004c7 "kana_NU" +0x0004c8 "kana_NE" +0x0004c9 "kana_NO" +0x0004ca "kana_HA" +0x0004cb "kana_HI" +0x0004cc "kana_FU" +0x0004cc "kana_HU" +0x0004cd "kana_HE" +0x0004ce "kana_HO" +0x0004cf "kana_MA" +0x0004d0 "kana_MI" +0x0004d1 "kana_MU" +0x0004d2 "kana_ME" +0x0004d3 "kana_MO" +0x0004d4 "kana_YA" +0x0004d5 "kana_YU" +0x0004d6 "kana_YO" +0x0004d7 "kana_RA" +0x0004d8 "kana_RI" +0x0004d9 "kana_RU" +0x0004da "kana_RE" +0x0004db "kana_RO" +0x0004dc "kana_WA" +0x0004dd "kana_N" +0x0004de "voicedsound" +0x0004df "semivoicedsound" +0x0005ac "Arabic_comma" +0x0005bb "Arabic_semicolon" +0x0005bf "Arabic_question_mark" +0x0005c1 "Arabic_hamza" +0x0005c2 "Arabic_maddaonalef" +0x0005c3 "Arabic_hamzaonalef" +0x0005c4 "Arabic_hamzaonwaw" +0x0005c5 "Arabic_hamzaunderalef" +0x0005c6 "Arabic_hamzaonyeh" +0x0005c7 "Arabic_alef" +0x0005c8 "Arabic_beh" +0x0005c9 "Arabic_tehmarbuta" +0x0005ca "Arabic_teh" +0x0005cb "Arabic_theh" +0x0005cc "Arabic_jeem" +0x0005cd "Arabic_hah" +0x0005ce "Arabic_khah" +0x0005cf "Arabic_dal" +0x0005d0 "Arabic_thal" +0x0005d1 "Arabic_ra" +0x0005d2 "Arabic_zain" +0x0005d3 "Arabic_seen" +0x0005d4 "Arabic_sheen" +0x0005d5 "Arabic_sad" +0x0005d6 "Arabic_dad" +0x0005d7 "Arabic_tah" +0x0005d8 "Arabic_zah" +0x0005d9 "Arabic_ain" +0x0005da "Arabic_ghain" +0x0005e0 "Arabic_tatweel" +0x0005e1 "Arabic_feh" +0x0005e2 "Arabic_qaf" +0x0005e3 "Arabic_kaf" +0x0005e4 "Arabic_lam" +0x0005e5 "Arabic_meem" +0x0005e6 "Arabic_noon" +0x0005e7 "Arabic_ha" +0x0005e7 "Arabic_heh" +0x0005e8 "Arabic_waw" +0x0005e9 "Arabic_alefmaksura" +0x0005ea "Arabic_yeh" +0x0005eb "Arabic_fathatan" +0x0005ec "Arabic_dammatan" +0x0005ed "Arabic_kasratan" +0x0005ee "Arabic_fatha" +0x0005ef "Arabic_damma" +0x0005f0 "Arabic_kasra" +0x0005f1 "Arabic_shadda" +0x0005f2 "Arabic_sukun" +0x0006a1 "Serbian_dje" +0x0006a2 "Macedonia_gje" +0x0006a3 "Cyrillic_io" +0x0006a4 "Ukrainian_ie" +0x0006a4 "Ukranian_je" +0x0006a5 "Macedonia_dse" +0x0006a6 "Ukrainian_i" +0x0006a6 "Ukranian_i" +0x0006a7 "Ukrainian_yi" +0x0006a7 "Ukranian_yi" +0x0006a8 "Cyrillic_je" +0x0006a8 "Serbian_je" +0x0006a9 "Cyrillic_lje" +0x0006a9 "Serbian_lje" +0x0006aa "Cyrillic_nje" +0x0006aa "Serbian_nje" +0x0006ab "Serbian_tshe" +0x0006ac "Macedonia_kje" +0x0006ae "Byelorussian_shortu" +0x0006af "Cyrillic_dzhe" +0x0006af "Serbian_dze" +0x0006b0 "numerosign" +0x0006b1 "Serbian_DJE" +0x0006b2 "Macedonia_GJE" +0x0006b3 "Cyrillic_IO" +0x0006b4 "Ukrainian_IE" +0x0006b4 "Ukranian_JE" +0x0006b5 "Macedonia_DSE" +0x0006b6 "Ukrainian_I" +0x0006b6 "Ukranian_I" +0x0006b7 "Ukrainian_YI" +0x0006b7 "Ukranian_YI" +0x0006b8 "Cyrillic_JE" +0x0006b8 "Serbian_JE" +0x0006b9 "Cyrillic_LJE" +0x0006b9 "Serbian_LJE" +0x0006ba "Cyrillic_NJE" +0x0006ba "Serbian_NJE" +0x0006bb "Serbian_TSHE" +0x0006bc "Macedonia_KJE" +0x0006be "Byelorussian_SHORTU" +0x0006bf "Cyrillic_DZHE" +0x0006bf "Serbian_DZE" +0x0006c0 "Cyrillic_yu" +0x0006c1 "Cyrillic_a" +0x0006c2 "Cyrillic_be" +0x0006c3 "Cyrillic_tse" +0x0006c4 "Cyrillic_de" +0x0006c5 "Cyrillic_ie" +0x0006c6 "Cyrillic_ef" +0x0006c7 "Cyrillic_ghe" +0x0006c8 "Cyrillic_ha" +0x0006c9 "Cyrillic_i" +0x0006ca "Cyrillic_shorti" +0x0006cb "Cyrillic_ka" +0x0006cc "Cyrillic_el" +0x0006cd "Cyrillic_em" +0x0006ce "Cyrillic_en" +0x0006cf "Cyrillic_o" +0x0006d0 "Cyrillic_pe" +0x0006d1 "Cyrillic_ya" +0x0006d2 "Cyrillic_er" +0x0006d3 "Cyrillic_es" +0x0006d4 "Cyrillic_te" +0x0006d5 "Cyrillic_u" +0x0006d6 "Cyrillic_zhe" +0x0006d7 "Cyrillic_ve" +0x0006d8 "Cyrillic_softsign" +0x0006d9 "Cyrillic_yeru" +0x0006da "Cyrillic_ze" +0x0006db "Cyrillic_sha" +0x0006dc "Cyrillic_e" +0x0006dd "Cyrillic_shcha" +0x0006de "Cyrillic_che" +0x0006df "Cyrillic_hardsign" +0x0006e0 "Cyrillic_YU" +0x0006e1 "Cyrillic_A" +0x0006e2 "Cyrillic_BE" +0x0006e3 "Cyrillic_TSE" +0x0006e4 "Cyrillic_DE" +0x0006e5 "Cyrillic_IE" +0x0006e6 "Cyrillic_EF" +0x0006e7 "Cyrillic_GHE" +0x0006e8 "Cyrillic_HA" +0x0006e9 "Cyrillic_I" +0x0006ea "Cyrillic_SHORTI" +0x0006eb "Cyrillic_KA" +0x0006ec "Cyrillic_EL" +0x0006ed "Cyrillic_EM" +0x0006ee "Cyrillic_EN" +0x0006ef "Cyrillic_O" +0x0006f0 "Cyrillic_PE" +0x0006f1 "Cyrillic_YA" +0x0006f2 "Cyrillic_ER" +0x0006f3 "Cyrillic_ES" +0x0006f4 "Cyrillic_TE" +0x0006f5 "Cyrillic_U" +0x0006f6 "Cyrillic_ZHE" +0x0006f7 "Cyrillic_VE" +0x0006f8 "Cyrillic_SOFTSIGN" +0x0006f9 "Cyrillic_YERU" +0x0006fa "Cyrillic_ZE" +0x0006fb "Cyrillic_SHA" +0x0006fc "Cyrillic_E" +0x0006fd "Cyrillic_SHCHA" +0x0006fe "Cyrillic_CHE" +0x0006ff "Cyrillic_HARDSIGN" +0x0007a1 "Greek_ALPHAaccent" +0x0007a2 "Greek_EPSILONaccent" +0x0007a3 "Greek_ETAaccent" +0x0007a4 "Greek_IOTAaccent" +0x0007a5 "Greek_IOTAdieresis" +0x0007a5 "Greek_IOTAdiaeresis" +0x0007a7 "Greek_OMICRONaccent" +0x0007a8 "Greek_UPSILONaccent" +0x0007a9 "Greek_UPSILONdieresis" +0x0007ab "Greek_OMEGAaccent" +0x0007ae "Greek_accentdieresis" +0x0007af "Greek_horizbar" +0x0007b1 "Greek_alphaaccent" +0x0007b2 "Greek_epsilonaccent" +0x0007b3 "Greek_etaaccent" +0x0007b4 "Greek_iotaaccent" +0x0007b5 "Greek_iotadieresis" +0x0007b6 "Greek_iotaaccentdieresis" +0x0007b7 "Greek_omicronaccent" +0x0007b8 "Greek_upsilonaccent" +0x0007b9 "Greek_upsilondieresis" +0x0007ba "Greek_upsilonaccentdieresis" +0x0007bb "Greek_omegaaccent" +0x0007c1 "Greek_ALPHA" +0x0007c2 "Greek_BETA" +0x0007c3 "Greek_GAMMA" +0x0007c4 "Greek_DELTA" +0x0007c5 "Greek_EPSILON" +0x0007c6 "Greek_ZETA" +0x0007c7 "Greek_ETA" +0x0007c8 "Greek_THETA" +0x0007c9 "Greek_IOTA" +0x0007ca "Greek_KAPPA" +0x0007cb "Greek_LAMBDA" +0x0007cb "Greek_LAMDA" +0x0007cc "Greek_MU" +0x0007cd "Greek_NU" +0x0007ce "Greek_XI" +0x0007cf "Greek_OMICRON" +0x0007d0 "Greek_PI" +0x0007d1 "Greek_RHO" +0x0007d2 "Greek_SIGMA" +0x0007d4 "Greek_TAU" +0x0007d5 "Greek_UPSILON" +0x0007d6 "Greek_PHI" +0x0007d7 "Greek_CHI" +0x0007d8 "Greek_PSI" +0x0007d9 "Greek_OMEGA" +0x0007e1 "Greek_alpha" +0x0007e2 "Greek_beta" +0x0007e3 "Greek_gamma" +0x0007e4 "Greek_delta" +0x0007e5 "Greek_epsilon" +0x0007e6 "Greek_zeta" +0x0007e7 "Greek_eta" +0x0007e8 "Greek_theta" +0x0007e9 "Greek_iota" +0x0007ea "Greek_kappa" +0x0007eb "Greek_lambda" +0x0007eb "Greek_lamda" +0x0007ec "Greek_mu" +0x0007ed "Greek_nu" +0x0007ee "Greek_xi" +0x0007ef "Greek_omicron" +0x0007f0 "Greek_pi" +0x0007f1 "Greek_rho" +0x0007f2 "Greek_sigma" +0x0007f3 "Greek_finalsmallsigma" +0x0007f4 "Greek_tau" +0x0007f5 "Greek_upsilon" +0x0007f6 "Greek_phi" +0x0007f7 "Greek_chi" +0x0007f8 "Greek_psi" +0x0007f9 "Greek_omega" +0x0008a1 "leftradical" +0x0008a2 "topleftradical" +0x0008a3 "horizconnector" +0x0008a4 "topintegral" +0x0008a5 "botintegral" +0x0008a6 "vertconnector" +0x0008a7 "topleftsqbracket" +0x0008a8 "botleftsqbracket" +0x0008a9 "toprightsqbracket" +0x0008aa "botrightsqbracket" +0x0008ab "topleftparens" +0x0008ac "botleftparens" +0x0008ad "toprightparens" +0x0008ae "botrightparens" +0x0008af "leftmiddlecurlybrace" +0x0008b0 "rightmiddlecurlybrace" +0x0008b1 "topleftsummation" +0x0008b2 "botleftsummation" +0x0008b3 "topvertsummationconnector" +0x0008b4 "botvertsummationconnector" +0x0008b5 "toprightsummation" +0x0008b6 "botrightsummation" +0x0008b7 "rightmiddlesummation" +0x0008bc "lessthanequal" +0x0008bd "notequal" +0x0008be "greaterthanequal" +0x0008bf "integral" +0x0008c0 "therefore" +0x0008c1 "variation" +0x0008c2 "infinity" +0x0008c5 "nabla" +0x0008c8 "approximate" +0x0008c9 "similarequal" +0x0008cd "ifonlyif" +0x0008ce "implies" +0x0008cf "identical" +0x0008d6 "radical" +0x0008da "includedin" +0x0008db "includes" +0x0008dc "intersection" +0x0008dd "union" +0x0008de "logicaland" +0x0008df "logicalor" +0x0008ef "partialderivative" +0x0008f6 "function" +0x0008fb "leftarrow" +0x0008fc "uparrow" +0x0008fd "rightarrow" +0x0008fe "downarrow" +0x0009df "blank" +0x0009e0 "soliddiamond" +0x0009e1 "checkerboard" +0x0009e2 "ht" +0x0009e3 "ff" +0x0009e4 "cr" +0x0009e5 "lf" +0x0009e8 "nl" +0x0009e9 "vt" +0x0009ea "lowrightcorner" +0x0009eb "uprightcorner" +0x0009ec "upleftcorner" +0x0009ed "lowleftcorner" +0x0009ee "crossinglines" +0x0009ef "horizlinescan1" +0x0009f0 "horizlinescan3" +0x0009f1 "horizlinescan5" +0x0009f2 "horizlinescan7" +0x0009f3 "horizlinescan9" +0x0009f4 "leftt" +0x0009f5 "rightt" +0x0009f6 "bott" +0x0009f7 "topt" +0x0009f8 "vertbar" +0x000aa1 "emspace" +0x000aa2 "enspace" +0x000aa3 "em3space" +0x000aa4 "em4space" +0x000aa5 "digitspace" +0x000aa6 "punctspace" +0x000aa7 "thinspace" +0x000aa8 "hairspace" +0x000aa9 "emdash" +0x000aaa "endash" +0x000aac "signifblank" +0x000aae "ellipsis" +0x000aaf "doubbaselinedot" +0x000ab0 "onethird" +0x000ab1 "twothirds" +0x000ab2 "onefifth" +0x000ab3 "twofifths" +0x000ab4 "threefifths" +0x000ab5 "fourfifths" +0x000ab6 "onesixth" +0x000ab7 "fivesixths" +0x000ab8 "careof" +0x000abb "figdash" +0x000abc "leftanglebracket" +0x000abd "decimalpoint" +0x000abe "rightanglebracket" +0x000abf "marker" +0x000ac3 "oneeighth" +0x000ac4 "threeeighths" +0x000ac5 "fiveeighths" +0x000ac6 "seveneighths" +0x000ac9 "trademark" +0x000aca "signaturemark" +0x000acb "trademarkincircle" +0x000acc "leftopentriangle" +0x000acd "rightopentriangle" +0x000ace "emopencircle" +0x000acf "emopenrectangle" +0x000ad0 "leftsinglequotemark" +0x000ad1 "rightsinglequotemark" +0x000ad2 "leftdoublequotemark" +0x000ad3 "rightdoublequotemark" +0x000ad4 "prescription" +0x000ad6 "minutes" +0x000ad7 "seconds" +0x000ad9 "latincross" +0x000ada "hexagram" +0x000adb "filledrectbullet" +0x000adc "filledlefttribullet" +0x000add "filledrighttribullet" +0x000ade "emfilledcircle" +0x000adf "emfilledrect" +0x000ae0 "enopencircbullet" +0x000ae1 "enopensquarebullet" +0x000ae2 "openrectbullet" +0x000ae3 "opentribulletup" +0x000ae4 "opentribulletdown" +0x000ae5 "openstar" +0x000ae6 "enfilledcircbullet" +0x000ae7 "enfilledsqbullet" +0x000ae8 "filledtribulletup" +0x000ae9 "filledtribulletdown" +0x000aea "leftpointer" +0x000aeb "rightpointer" +0x000aec "club" +0x000aed "diamond" +0x000aee "heart" +0x000af0 "maltesecross" +0x000af1 "dagger" +0x000af2 "doubledagger" +0x000af3 "checkmark" +0x000af4 "ballotcross" +0x000af5 "musicalsharp" +0x000af6 "musicalflat" +0x000af7 "malesymbol" +0x000af8 "femalesymbol" +0x000af9 "telephone" +0x000afa "telephonerecorder" +0x000afb "phonographcopyright" +0x000afc "caret" +0x000afd "singlelowquotemark" +0x000afe "doublelowquotemark" +0x000aff "cursor" +0x000ba3 "leftcaret" +0x000ba6 "rightcaret" +0x000ba8 "downcaret" +0x000ba9 "upcaret" +0x000bc0 "overbar" +0x000bc2 "downtack" +0x000bc3 "upshoe" +0x000bc4 "downstile" +0x000bc6 "underbar" +0x000bca "jot" +0x000bcc "quad" +0x000bce "uptack" +0x000bcf "circle" +0x000bd3 "upstile" +0x000bd6 "downshoe" +0x000bd8 "rightshoe" +0x000bda "leftshoe" +0x000bdc "lefttack" +0x000bfc "righttack" +0x000cdf "hebrew_doublelowline" +0x000ce0 "hebrew_aleph" +0x000ce1 "hebrew_bet" +0x000ce1 "hebrew_beth" +0x000ce2 "hebrew_gimel" +0x000ce2 "hebrew_gimmel" +0x000ce3 "hebrew_dalet" +0x000ce3 "hebrew_daleth" +0x000ce4 "hebrew_he" +0x000ce5 "hebrew_waw" +0x000ce6 "hebrew_zain" +0x000ce6 "hebrew_zayin" +0x000ce7 "hebrew_chet" +0x000ce7 "hebrew_het" +0x000ce8 "hebrew_tet" +0x000ce8 "hebrew_teth" +0x000ce9 "hebrew_yod" +0x000cea "hebrew_finalkaph" +0x000ceb "hebrew_kaph" +0x000cec "hebrew_lamed" +0x000ced "hebrew_finalmem" +0x000cee "hebrew_mem" +0x000cef "hebrew_finalnun" +0x000cf0 "hebrew_nun" +0x000cf1 "hebrew_samech" +0x000cf1 "hebrew_samekh" +0x000cf2 "hebrew_ayin" +0x000cf3 "hebrew_finalpe" +0x000cf4 "hebrew_pe" +0x000cf5 "hebrew_finalzade" +0x000cf5 "hebrew_finalzadi" +0x000cf6 "hebrew_zade" +0x000cf6 "hebrew_zadi" +0x000cf7 "hebrew_kuf" +0x000cf7 "hebrew_qoph" +0x000cf8 "hebrew_resh" +0x000cf9 "hebrew_shin" +0x000cfa "hebrew_taf" +0x000cfa "hebrew_taw" +0x000da1 "Thai_kokai" +0x000da2 "Thai_khokhai" +0x000da3 "Thai_khokhuat" +0x000da4 "Thai_khokhwai" +0x000da5 "Thai_khokhon" +0x000da6 "Thai_khorakhang" +0x000da7 "Thai_ngongu" +0x000da8 "Thai_chochan" +0x000da9 "Thai_choching" +0x000daa "Thai_chochang" +0x000dab "Thai_soso" +0x000dac "Thai_chochoe" +0x000dad "Thai_yoying" +0x000dae "Thai_dochada" +0x000daf "Thai_topatak" +0x000db0 "Thai_thothan" +0x000db1 "Thai_thonangmontho" +0x000db2 "Thai_thophuthao" +0x000db3 "Thai_nonen" +0x000db4 "Thai_dodek" +0x000db5 "Thai_totao" +0x000db6 "Thai_thothung" +0x000db7 "Thai_thothahan" +0x000db8 "Thai_thothong" +0x000db9 "Thai_nonu" +0x000dba "Thai_bobaimai" +0x000dbb "Thai_popla" +0x000dbc "Thai_phophung" +0x000dbd "Thai_fofa" +0x000dbe "Thai_phophan" +0x000dbf "Thai_fofan" +0x000dc0 "Thai_phosamphao" +0x000dc1 "Thai_moma" +0x000dc2 "Thai_yoyak" +0x000dc3 "Thai_rorua" +0x000dc4 "Thai_ru" +0x000dc5 "Thai_loling" +0x000dc6 "Thai_lu" +0x000dc7 "Thai_wowaen" +0x000dc8 "Thai_sosala" +0x000dc9 "Thai_sorusi" +0x000dca "Thai_sosua" +0x000dcb "Thai_hohip" +0x000dcc "Thai_lochula" +0x000dcd "Thai_oang" +0x000dce "Thai_honokhuk" +0x000dcf "Thai_paiyannoi" +0x000dd0 "Thai_saraa" +0x000dd1 "Thai_maihanakat" +0x000dd2 "Thai_saraaa" +0x000dd3 "Thai_saraam" +0x000dd4 "Thai_sarai" +0x000dd5 "Thai_saraii" +0x000dd6 "Thai_saraue" +0x000dd7 "Thai_sarauee" +0x000dd8 "Thai_sarau" +0x000dd9 "Thai_sarauu" +0x000dda "Thai_phinthu" +0x000dde "Thai_maihanakat_maitho" +0x000ddf "Thai_baht" +0x000de0 "Thai_sarae" +0x000de1 "Thai_saraae" +0x000de2 "Thai_sarao" +0x000de3 "Thai_saraaimaimuan" +0x000de4 "Thai_saraaimaimalai" +0x000de5 "Thai_lakkhangyao" +0x000de6 "Thai_maiyamok" +0x000de7 "Thai_maitaikhu" +0x000de8 "Thai_maiek" +0x000de9 "Thai_maitho" +0x000dea "Thai_maitri" +0x000deb "Thai_maichattawa" +0x000dec "Thai_thanthakhat" +0x000ded "Thai_nikhahit" +0x000df0 "Thai_leksun" +0x000df1 "Thai_leknung" +0x000df2 "Thai_leksong" +0x000df3 "Thai_leksam" +0x000df4 "Thai_leksi" +0x000df5 "Thai_lekha" +0x000df6 "Thai_lekhok" +0x000df7 "Thai_lekchet" +0x000df8 "Thai_lekpaet" +0x000df9 "Thai_lekkao" +0x000ea1 "Hangul_Kiyeog" +0x000ea2 "Hangul_SsangKiyeog" +0x000ea3 "Hangul_KiyeogSios" +0x000ea4 "Hangul_Nieun" +0x000ea5 "Hangul_NieunJieuj" +0x000ea6 "Hangul_NieunHieuh" +0x000ea7 "Hangul_Dikeud" +0x000ea8 "Hangul_SsangDikeud" +0x000ea9 "Hangul_Rieul" +0x000eaa "Hangul_RieulKiyeog" +0x000eab "Hangul_RieulMieum" +0x000eac "Hangul_RieulPieub" +0x000ead "Hangul_RieulSios" +0x000eae "Hangul_RieulTieut" +0x000eaf "Hangul_RieulPhieuf" +0x000eb0 "Hangul_RieulHieuh" +0x000eb1 "Hangul_Mieum" +0x000eb2 "Hangul_Pieub" +0x000eb3 "Hangul_SsangPieub" +0x000eb4 "Hangul_PieubSios" +0x000eb5 "Hangul_Sios" +0x000eb6 "Hangul_SsangSios" +0x000eb7 "Hangul_Ieung" +0x000eb8 "Hangul_Jieuj" +0x000eb9 "Hangul_SsangJieuj" +0x000eba "Hangul_Cieuc" +0x000ebb "Hangul_Khieuq" +0x000ebc "Hangul_Tieut" +0x000ebd "Hangul_Phieuf" +0x000ebe "Hangul_Hieuh" +0x000ebf "Hangul_A" +0x000ec0 "Hangul_AE" +0x000ec1 "Hangul_YA" +0x000ec2 "Hangul_YAE" +0x000ec3 "Hangul_EO" +0x000ec4 "Hangul_E" +0x000ec5 "Hangul_YEO" +0x000ec6 "Hangul_YE" +0x000ec7 "Hangul_O" +0x000ec8 "Hangul_WA" +0x000ec9 "Hangul_WAE" +0x000eca "Hangul_OE" +0x000ecb "Hangul_YO" +0x000ecc "Hangul_U" +0x000ecd "Hangul_WEO" +0x000ece "Hangul_WE" +0x000ecf "Hangul_WI" +0x000ed0 "Hangul_YU" +0x000ed1 "Hangul_EU" +0x000ed2 "Hangul_YI" +0x000ed3 "Hangul_I" +0x000ed4 "Hangul_J_Kiyeog" +0x000ed5 "Hangul_J_SsangKiyeog" +0x000ed6 "Hangul_J_KiyeogSios" +0x000ed7 "Hangul_J_Nieun" +0x000ed8 "Hangul_J_NieunJieuj" +0x000ed9 "Hangul_J_NieunHieuh" +0x000eda "Hangul_J_Dikeud" +0x000edb "Hangul_J_Rieul" +0x000edc "Hangul_J_RieulKiyeog" +0x000edd "Hangul_J_RieulMieum" +0x000ede "Hangul_J_RieulPieub" +0x000edf "Hangul_J_RieulSios" +0x000ee0 "Hangul_J_RieulTieut" +0x000ee1 "Hangul_J_RieulPhieuf" +0x000ee2 "Hangul_J_RieulHieuh" +0x000ee3 "Hangul_J_Mieum" +0x000ee4 "Hangul_J_Pieub" +0x000ee5 "Hangul_J_PieubSios" +0x000ee6 "Hangul_J_Sios" +0x000ee7 "Hangul_J_SsangSios" +0x000ee8 "Hangul_J_Ieung" +0x000ee9 "Hangul_J_Jieuj" +0x000eea "Hangul_J_Cieuc" +0x000eeb "Hangul_J_Khieuq" +0x000eec "Hangul_J_Tieut" +0x000eed "Hangul_J_Phieuf" +0x000eee "Hangul_J_Hieuh" +0x000eef "Hangul_RieulYeorinHieuh" +0x000ef0 "Hangul_SunkyeongeumMieum" +0x000ef1 "Hangul_SunkyeongeumPieub" +0x000ef2 "Hangul_PanSios" +0x000ef3 "Hangul_KkogjiDalrinIeung" +0x000ef4 "Hangul_SunkyeongeumPhieuf" +0x000ef5 "Hangul_YeorinHieuh" +0x000ef6 "Hangul_AraeA" +0x000ef7 "Hangul_AraeAE" +0x000ef8 "Hangul_J_PanSios" +0x000ef9 "Hangul_J_KkogjiDalrinIeung" +0x000efa "Hangul_J_YeorinHieuh" +0x000eff "Korean_Won" +0x0013bc "OE" +0x0013bd "oe" +0x0013be "Ydiaeresis" +0x0020a0 "EcuSign" +0x0020a1 "ColonSign" +0x0020a2 "CruzeiroSign" +0x0020a3 "FFrancSign" +0x0020a4 "LiraSign" +0x0020a5 "MillSign" +0x0020a6 "NairaSign" +0x0020a7 "PesetaSign" +0x0020a8 "RupeeSign" +0x0020a9 "WonSign" +0x0020aa "NewSheqelSign" +0x0020ab "DongSign" +0x0020ac "EuroSign" +0x00fd01 "3270_Duplicate" +0x00fd02 "3270_FieldMark" +0x00fd03 "3270_Right2" +0x00fd04 "3270_Left2" +0x00fd05 "3270_BackTab" +0x00fd06 "3270_EraseEOF" +0x00fd07 "3270_EraseInput" +0x00fd08 "3270_Reset" +0x00fd09 "3270_Quit" +0x00fd0a "3270_PA1" +0x00fd0b "3270_PA2" +0x00fd0c "3270_PA3" +0x00fd0d "3270_Test" +0x00fd0e "3270_Attn" +0x00fd0f "3270_CursorBlink" +0x00fd10 "3270_AltCursor" +0x00fd11 "3270_KeyClick" +0x00fd12 "3270_Jump" +0x00fd13 "3270_Ident" +0x00fd14 "3270_Rule" +0x00fd15 "3270_Copy" +0x00fd16 "3270_Play" +0x00fd17 "3270_Setup" +0x00fd18 "3270_Record" +0x00fd19 "3270_ChangeScreen" +0x00fd1a "3270_DeleteWord" +0x00fd1b "3270_ExSelect" +0x00fd1c "3270_CursorSelect" +0x00fd1d "3270_PrintScreen" +0x00fd1e "3270_Enter" +0x00fe01 "ISO_Lock" +0x00fe02 "ISO_Level2_Latch" +0x00fe03 "ISO_Level3_Shift" +0x00fe04 "ISO_Level3_Latch" +0x00fe05 "ISO_Level3_Lock" +0x00fe06 "ISO_Group_Latch" +0x00fe07 "ISO_Group_Lock" +0x00fe08 "ISO_Next_Group" +0x00fe09 "ISO_Next_Group_Lock" +0x00fe0a "ISO_Prev_Group" +0x00fe0b "ISO_Prev_Group_Lock" +0x00fe0c "ISO_First_Group" +0x00fe0d "ISO_First_Group_Lock" +0x00fe0e "ISO_Last_Group" +0x00fe0f "ISO_Last_Group_Lock" +0x00fe20 "ISO_Left_Tab" +0x00fe21 "ISO_Move_Line_Up" +0x00fe22 "ISO_Move_Line_Down" +0x00fe23 "ISO_Partial_Line_Up" +0x00fe24 "ISO_Partial_Line_Down" +0x00fe25 "ISO_Partial_Space_Left" +0x00fe26 "ISO_Partial_Space_Right" +0x00fe27 "ISO_Set_Margin_Left" +0x00fe28 "ISO_Set_Margin_Right" +0x00fe29 "ISO_Release_Margin_Left" +0x00fe2a "ISO_Release_Margin_Right" +0x00fe2b "ISO_Release_Both_Margins" +0x00fe2c "ISO_Fast_Cursor_Left" +0x00fe2d "ISO_Fast_Cursor_Right" +0x00fe2e "ISO_Fast_Cursor_Up" +0x00fe2f "ISO_Fast_Cursor_Down" +0x00fe30 "ISO_Continuous_Underline" +0x00fe31 "ISO_Discontinuous_Underline" +0x00fe32 "ISO_Emphasize" +0x00fe33 "ISO_Center_Object" +0x00fe34 "ISO_Enter" +0x00fe50 "dead_grave" +0x00fe51 "dead_acute" +0x00fe52 "dead_circumflex" +0x00fe53 "dead_tilde" +0x00fe54 "dead_macron" +0x00fe55 "dead_breve" +0x00fe56 "dead_abovedot" +0x00fe57 "dead_diaeresis" +0x00fe58 "dead_abovering" +0x00fe59 "dead_doubleacute" +0x00fe5a "dead_caron" +0x00fe5b "dead_cedilla" +0x00fe5c "dead_ogonek" +0x00fe5d "dead_iota" +0x00fe5e "dead_voiced_sound" +0x00fe5f "dead_semivoiced_sound" +0x00fe60 "dead_belowdot" +0x00fe61 "dead_hook" +0x00fe62 "dead_horn" +0x00fe70 "AccessX_Enable" +0x00fe71 "AccessX_Feedback_Enable" +0x00fe72 "RepeatKeys_Enable" +0x00fe73 "SlowKeys_Enable" +0x00fe74 "BounceKeys_Enable" +0x00fe75 "StickyKeys_Enable" +0x00fe76 "MouseKeys_Enable" +0x00fe77 "MouseKeys_Accel_Enable" +0x00fe78 "Overlay1_Enable" +0x00fe79 "Overlay2_Enable" +0x00fe7a "AudibleBell_Enable" +0x00fed0 "First_Virtual_Screen" +0x00fed1 "Prev_Virtual_Screen" +0x00fed2 "Next_Virtual_Screen" +0x00fed4 "Last_Virtual_Screen" +0x00fed5 "Terminate_Server" +0x00fee0 "Pointer_Left" +0x00fee1 "Pointer_Right" +0x00fee2 "Pointer_Up" +0x00fee3 "Pointer_Down" +0x00fee4 "Pointer_UpLeft" +0x00fee5 "Pointer_UpRight" +0x00fee6 "Pointer_DownLeft" +0x00fee7 "Pointer_DownRight" +0x00fee8 "Pointer_Button_Dflt" +0x00fee9 "Pointer_Button1" +0x00feea "Pointer_Button2" +0x00feeb "Pointer_Button3" +0x00feec "Pointer_Button4" +0x00feed "Pointer_Button5" +0x00feee "Pointer_DblClick_Dflt" +0x00feef "Pointer_DblClick1" +0x00fef0 "Pointer_DblClick2" +0x00fef1 "Pointer_DblClick3" +0x00fef2 "Pointer_DblClick4" +0x00fef3 "Pointer_DblClick5" +0x00fef4 "Pointer_Drag_Dflt" +0x00fef5 "Pointer_Drag1" +0x00fef6 "Pointer_Drag2" +0x00fef7 "Pointer_Drag3" +0x00fef8 "Pointer_Drag4" +0x00fef9 "Pointer_EnableKeys" +0x00fefa "Pointer_Accelerate" +0x00fefb "Pointer_DfltBtnNext" +0x00fefc "Pointer_DfltBtnPrev" +0x00fefd "Pointer_Drag5" +0x00ff08 "BackSpace" # 1 +0x00ff09 "Tab" # 1 +0x00ff0a "Linefeed" +0x00ff0b "Clear" +0x00ff0d "Return" # 1 +0x00ff13 "Pause" # 1 +0x00ff14 "Scroll_Lock" # 1 +0x00ff15 "Sys_Req" # 1 +0x00ff1b "Escape" # 1 +0x00ff20 "Multi_key" # 1 +0x00ff21 "Kanji" +0x00ff22 "Muhenkan" +0x00ff23 "Henkan" +0x00ff23 "Henkan_Mode" +0x00ff24 "Romaji" +0x00ff25 "Hiragana" +0x00ff26 "Katakana" +0x00ff27 "Hiragana_Katakana" +0x00ff28 "Zenkaku" +0x00ff29 "Hankaku" +0x00ff2a "Zenkaku_Hankaku" +0x00ff2b "Touroku" +0x00ff2c "Massyo" +0x00ff2d "Kana_Lock" +0x00ff2e "Kana_Shift" +0x00ff2f "Eisu_Shift" +0x00ff30 "Eisu_toggle" +0x00ff31 "Hangul" +0x00ff32 "Hangul_Start" +0x00ff33 "Hangul_End" +0x00ff34 "Hangul_Hanja" +0x00ff35 "Hangul_Jamo" +0x00ff36 "Hangul_Romaja" +0x00ff37 "Codeinput" +0x00ff38 "Hangul_Jeonja" +0x00ff39 "Hangul_Banja" +0x00ff3a "Hangul_PreHanja" +0x00ff3b "Hangul_PostHanja" +0x00ff3c "SingleCandidate" +0x00ff3d "MultipleCandidate" +0x00ff3e "PreviousCandidate" +0x00ff3f "Hangul_Special" +0x00ff50 "Home" # 1 +0x00ff51 "Left" # 1 +0x00ff52 "Up" # 1 +0x00ff53 "Right" # 1 +0x00ff54 "Down" # 1 +0x00ff55 "Page_Up" # 1 +0x00ff55 "Prior" +0x00ff56 "Page_Down" # 1 +0x00ff56 "Next" +0x00ff57 "End" # 1 +0x00ff58 "Begin" # 1 +0x00ff60 "Select" +0x00ff61 "Print" # 1 +0x00ff62 "Execute" +0x00ff63 "Insert" # 1 +0x00ff65 "Undo" +0x00ff66 "Redo" +0x00ff67 "Menu" +0x00ff68 "Find" +0x00ff69 "Cancel" +0x00ff6a "Help" +0x00ff6b "Break" +0x00ff7e "Arabic_switch" +0x00ff7e "Greek_switch" +0x00ff7e "Hangul_switch" +0x00ff7e "Hebrew_switch" +0x00ff7e "ISO_Group_Shift" +0x00ff7e "Mode_switch" +0x00ff7e "kana_switch" +0x00ff7e "script_switch" +0x00ff7f "Num_Lock" # 1 +0x00ff80 "KP_Space" # 1 +0x00ff89 "KP_Tab" # 1 +0x00ff8d "KP_Enter" # 1 +0x00ff91 "KP_F1" +0x00ff92 "KP_F2" +0x00ff93 "KP_F3" +0x00ff94 "KP_F4" +0x00ff95 "KP_Home" # 1 +0x00ff96 "KP_Left" # 1 +0x00ff97 "KP_Up" # 1 +0x00ff98 "KP_Right" # 1 +0x00ff99 "KP_Down" # 1 +0x00ff9a "KP_Page_Up" # 1 +0x00ff9a "KP_Prior" # 1 +0x00ff9b "KP_Page_Down" # 1 +0x00ff9b "KP_Next" # 1 +0x00ff9c "KP_End" # 1 +0x00ff9d "KP_Begin" # 1 +0x00ff9e "KP_Insert" # 1 +0x00ff9f "KP_Delete" # 1 +0x00ffaa "KP_Multiply" +0x00ffab "KP_Add" +0x00ffac "KP_Separator" +0x00ffad "KP_Subtract" +0x00ffae "KP_Decimal" +0x00ffaf "KP_Divide" +0x00ffb0 "KP_0" +0x00ffb1 "KP_1" +0x00ffb2 "KP_2" +0x00ffb3 "KP_3" +0x00ffb4 "KP_4" +0x00ffb5 "KP_5" +0x00ffb6 "KP_6" +0x00ffb7 "KP_7" +0x00ffb8 "KP_8" +0x00ffb9 "KP_9" +0x00ffbd "KP_Equal" +0x00ffbe "F1" +0x00ffbf "F2" +0x00ffc0 "F3" +0x00ffc1 "F4" +0x00ffc2 "F5" +0x00ffc3 "F6" +0x00ffc4 "F7" +0x00ffc5 "F8" +0x00ffc6 "F9" +0x00ffc7 "F10" +0x00ffc8 "F11" +0x00ffc9 "F12" +0x00ffca "F13" +0x00ffcb "F14" +0x00ffcc "F15" +0x00ffcd "F16" +0x00ffce "F17" +0x00ffcf "F18" +0x00ffd0 "F19" +0x00ffd1 "F20" +0x00ffd2 "F21" +0x00ffd3 "F22" +0x00ffd4 "F23" +0x00ffd5 "F24" +0x00ffd6 "F25" +0x00ffd7 "F26" +0x00ffd8 "F27" +0x00ffd9 "F28" +0x00ffda "F29" +0x00ffdb "F30" +0x00ffdc "F31" +0x00ffdd "F32" +0x00ffde "F33" +0x00ffdf "F34" +0x00ffe0 "F35" +0x00ffe1 "Shift_L" +0x00ffe2 "Shift_R" +0x00ffe3 "Control_L" +0x00ffe4 "Control_R" +0x00ffe5 "Caps_Lock" +0x00ffe6 "Shift_Lock" +0x00ffe7 "Meta_L" +0x00ffe8 "Meta_R" +0x00ffe9 "Alt_L" +0x00ffea "Alt_R" +0x00ffeb "Super_L" +0x00ffec "Super_R" +0x00ffed "Hyper_L" +0x00ffee "Hyper_R" +0x00ffff "Delete" # 1 +0xffffff "VoidSymbol" diff --git a/eek/special-keysym-labels.txt b/eek/special-keysym-labels.txt new file mode 100644 index 00000000..dc219563 --- /dev/null +++ b/eek/special-keysym-labels.txt @@ -0,0 +1,31 @@ +0x20 "" +0x8A3 "horiz\nconn" +0xFE50 "ˋ" +0xFE51 "ˊ" +0xFE52 "ˆ" +0xFE53 "~" +0xFE54 "ˉ" +0xFE55 "˘" +0xFE56 "˙" +0xFE57 "¨" +0xFE58 "˚" +0xFE59 "˝" +0xFE5A "ˇ" +0xFE5B "¸" +0xFE5C "˛" +0xFF14 "Scroll\nLock" +0xFF20 "Compose" +0xFF55 "Page\nUp" +0xFF56 "Page\nDown" +0xFF7E "AltGr" +0xFF7F "Num\nLock" +0xFF8D "Enter" +0xFF95 "Home" +0xFF96 "Left" +0xFF97 "Up" +0xFF98 "Right" +0xFF99 "Down" +0xFF9C "End" +0xFF9D "Begin" +0xFF9E "Ins" +0xFF9F "Del" diff --git a/eek/unicode-keysym-labels.txt b/eek/unicode-keysym-labels.txt new file mode 100644 index 00000000..95adfeec --- /dev/null +++ b/eek/unicode-keysym-labels.txt @@ -0,0 +1,826 @@ +# This file is derived from gdkkeyuni.c in GTK+. Thanks for the +# team. The original comments are below: + +# Modified by the GTK+ Team and others 1997-2000. See the AUTHORS +# file for a list of people on the GTK+ Team. See the ChangeLog +# files for a list of changes. These files are distributed with +# GTK+ at ftp://ftp.gtk.org/pub/gtk/. + +# Thanks to Markus G. Kuhn for the ksysym<->Unicode +# mapping functions, from the xterm sources. + +# These tables could be compressed by contiguous ranges, but the +# benefit of doing so is smallish. It would save about ~1000 bytes +# total. + +0x01a1 "Ą" # Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK +0x01a2 "˘" # breve ˘ BREVE +0x01a3 "Ł" # Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE +0x01a5 "Ľ" # Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON +0x01a6 "Ś" # Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE +0x01a9 "Š" # Scaron Š LATIN CAPITAL LETTER S WITH CARON +0x01aa "Ş" # Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA +0x01ab "Ť" # Tcaron Ť LATIN CAPITAL LETTER T WITH CARON +0x01ac "Ź" # Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE +0x01ae "Ž" # Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON +0x01af "Ż" # Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE +0x01b1 "ą" # aogonek ą LATIN SMALL LETTER A WITH OGONEK +0x01b2 "˛" # ogonek ˛ OGONEK +0x01b3 "ł" # lstroke ł LATIN SMALL LETTER L WITH STROKE +0x01b5 "ľ" # lcaron ľ LATIN SMALL LETTER L WITH CARON +0x01b6 "ś" # sacute ś LATIN SMALL LETTER S WITH ACUTE +0x01b7 "ˇ" # caron ˇ CARON +0x01b9 "š" # scaron š LATIN SMALL LETTER S WITH CARON +0x01ba "ş" # scedilla ş LATIN SMALL LETTER S WITH CEDILLA +0x01bb "ť" # tcaron ť LATIN SMALL LETTER T WITH CARON +0x01bc "ź" # zacute ź LATIN SMALL LETTER Z WITH ACUTE +0x01bd "˝" # doubleacute ˝ DOUBLE ACUTE ACCENT +0x01be "ž" # zcaron ž LATIN SMALL LETTER Z WITH CARON +0x01bf "ż" # zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE +0x01c0 "Ŕ" # Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE +0x01c3 "Ă" # Abreve Ă LATIN CAPITAL LETTER A WITH BREVE +0x01c5 "Ĺ" # Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE +0x01c6 "Ć" # Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE +0x01c8 "Č" # Ccaron Č LATIN CAPITAL LETTER C WITH CARON +0x01ca "Ę" # Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK +0x01cc "Ě" # Ecaron Ě LATIN CAPITAL LETTER E WITH CARON +0x01cf "Ď" # Dcaron Ď LATIN CAPITAL LETTER D WITH CARON +0x01d0 "Đ" # Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE +0x01d1 "Ń" # Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE +0x01d2 "Ň" # Ncaron Ň LATIN CAPITAL LETTER N WITH CARON +0x01d5 "Ő" # Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0x01d8 "Ř" # Rcaron Ř LATIN CAPITAL LETTER R WITH CARON +0x01d9 "Ů" # Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE +0x01db "Ű" # Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0x01de "Ţ" # Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA +0x01e0 "ŕ" # racute ŕ LATIN SMALL LETTER R WITH ACUTE +0x01e3 "ă" # abreve ă LATIN SMALL LETTER A WITH BREVE +0x01e5 "ĺ" # lacute ĺ LATIN SMALL LETTER L WITH ACUTE +0x01e6 "ć" # cacute ć LATIN SMALL LETTER C WITH ACUTE +0x01e8 "č" # ccaron č LATIN SMALL LETTER C WITH CARON +0x01ea "ę" # eogonek ę LATIN SMALL LETTER E WITH OGONEK +0x01ec "ě" # ecaron ě LATIN SMALL LETTER E WITH CARON +0x01ef "ď" # dcaron ď LATIN SMALL LETTER D WITH CARON +0x01f0 "đ" # dstroke đ LATIN SMALL LETTER D WITH STROKE +0x01f1 "ń" # nacute ń LATIN SMALL LETTER N WITH ACUTE +0x01f2 "ň" # ncaron ň LATIN SMALL LETTER N WITH CARON +0x01f5 "ő" # odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE +0x01f8 "ř" # rcaron ř LATIN SMALL LETTER R WITH CARON +0x01f9 "ů" # uring ů LATIN SMALL LETTER U WITH RING ABOVE +0x01fb "ű" # udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE +0x01fe "ţ" # tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA +0x01ff "˙" # abovedot ˙ DOT ABOVE +0x02a1 "Ħ" # Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE +0x02a6 "Ĥ" # Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0x02a9 "İ" # Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE +0x02ab "Ğ" # Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE +0x02ac "Ĵ" # Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0x02b1 "ħ" # hstroke ħ LATIN SMALL LETTER H WITH STROKE +0x02b6 "ĥ" # hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX +0x02b9 "ı" # idotless ı LATIN SMALL LETTER DOTLESS I +0x02bb "ğ" # gbreve ğ LATIN SMALL LETTER G WITH BREVE +0x02bc "ĵ" # jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX +0x02c5 "Ċ" # Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE +0x02c6 "Ĉ" # Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX +0x02d5 "Ġ" # Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE +0x02d8 "Ĝ" # Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX +0x02dd "Ŭ" # Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE +0x02de "Ŝ" # Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX +0x02e5 "ċ" # cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE +0x02e6 "ĉ" # ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX +0x02f5 "ġ" # gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE +0x02f8 "ĝ" # gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX +0x02fd "ŭ" # ubreve ŭ LATIN SMALL LETTER U WITH BREVE +0x02fe "ŝ" # scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX +0x03a2 "ĸ" # kra ĸ LATIN SMALL LETTER KRA +0x03a3 "Ŗ" # Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA +0x03a5 "Ĩ" # Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE +0x03a6 "Ļ" # Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA +0x03aa "Ē" # Emacron Ē LATIN CAPITAL LETTER E WITH MACRON +0x03ab "Ģ" # Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA +0x03ac "Ŧ" # Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE +0x03b3 "ŗ" # rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA +0x03b5 "ĩ" # itilde ĩ LATIN SMALL LETTER I WITH TILDE +0x03b6 "ļ" # lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA +0x03ba "ē" # emacron ē LATIN SMALL LETTER E WITH MACRON +0x03bb "ģ" # gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA +0x03bc "ŧ" # tslash ŧ LATIN SMALL LETTER T WITH STROKE +0x03bd "Ŋ" # ENG Ŋ LATIN CAPITAL LETTER ENG +0x03bf "ŋ" # eng ŋ LATIN SMALL LETTER ENG +0x03c0 "Ā" # Amacron Ā LATIN CAPITAL LETTER A WITH MACRON +0x03c7 "Į" # Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK +0x03cc "Ė" # Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE +0x03cf "Ī" # Imacron Ī LATIN CAPITAL LETTER I WITH MACRON +0x03d1 "Ņ" # Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA +0x03d2 "Ō" # Omacron Ō LATIN CAPITAL LETTER O WITH MACRON +0x03d3 "Ķ" # Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA +0x03d9 "Ų" # Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK +0x03dd "Ũ" # Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE +0x03de "Ū" # Umacron Ū LATIN CAPITAL LETTER U WITH MACRON +0x03e0 "ā" # amacron ā LATIN SMALL LETTER A WITH MACRON +0x03e7 "į" # iogonek į LATIN SMALL LETTER I WITH OGONEK +0x03ec "ė" # eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE +0x03ef "ī" # imacron ī LATIN SMALL LETTER I WITH MACRON +0x03f1 "ņ" # ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA +0x03f2 "ō" # omacron ō LATIN SMALL LETTER O WITH MACRON +0x03f3 "ķ" # kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA +0x03f9 "ų" # uogonek ų LATIN SMALL LETTER U WITH OGONEK +0x03fd "ũ" # utilde ũ LATIN SMALL LETTER U WITH TILDE +0x03fe "ū" # umacron ū LATIN SMALL LETTER U WITH MACRON +0x047e "‾" # overline ‾ OVERLINE +0x04a1 "。" # kana_fullstop 。 IDEOGRAPHIC FULL STOP +0x04a2 "「" # kana_openingbracket 「 LEFT CORNER BRACKET +0x04a3 "」" # kana_closingbracket 」 RIGHT CORNER BRACKET +0x04a4 "、" # kana_comma 、 IDEOGRAPHIC COMMA +0x04a5 "・" # kana_conjunctive ・ KATAKANA MIDDLE DOT +0x04a6 "ヲ" # kana_WO ヲ KATAKANA LETTER WO +0x04a7 "ァ" # kana_a ァ KATAKANA LETTER SMALL A +0x04a8 "ィ" # kana_i ィ KATAKANA LETTER SMALL I +0x04a9 "ゥ" # kana_u ゥ KATAKANA LETTER SMALL U +0x04aa "ェ" # kana_e ェ KATAKANA LETTER SMALL E +0x04ab "ォ" # kana_o ォ KATAKANA LETTER SMALL O +0x04ac "ャ" # kana_ya ャ KATAKANA LETTER SMALL YA +0x04ad "ュ" # kana_yu ュ KATAKANA LETTER SMALL YU +0x04ae "ョ" # kana_yo ョ KATAKANA LETTER SMALL YO +0x04af "ッ" # kana_tsu ッ KATAKANA LETTER SMALL TU +0x04b0 "ー" # prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK +0x04b1 "ア" # kana_A ア KATAKANA LETTER A +0x04b2 "イ" # kana_I イ KATAKANA LETTER I +0x04b3 "ウ" # kana_U ウ KATAKANA LETTER U +0x04b4 "エ" # kana_E エ KATAKANA LETTER E +0x04b5 "オ" # kana_O オ KATAKANA LETTER O +0x04b6 "カ" # kana_KA カ KATAKANA LETTER KA +0x04b7 "キ" # kana_KI キ KATAKANA LETTER KI +0x04b8 "ク" # kana_KU ク KATAKANA LETTER KU +0x04b9 "ケ" # kana_KE ケ KATAKANA LETTER KE +0x04ba "コ" # kana_KO コ KATAKANA LETTER KO +0x04bb "サ" # kana_SA サ KATAKANA LETTER SA +0x04bc "シ" # kana_SHI シ KATAKANA LETTER SI +0x04bd "ス" # kana_SU ス KATAKANA LETTER SU +0x04be "セ" # kana_SE セ KATAKANA LETTER SE +0x04bf "ソ" # kana_SO ソ KATAKANA LETTER SO +0x04c0 "タ" # kana_TA タ KATAKANA LETTER TA +0x04c1 "チ" # kana_CHI チ KATAKANA LETTER TI +0x04c2 "ツ" # kana_TSU ツ KATAKANA LETTER TU +0x04c3 "テ" # kana_TE テ KATAKANA LETTER TE +0x04c4 "ト" # kana_TO ト KATAKANA LETTER TO +0x04c5 "ナ" # kana_NA ナ KATAKANA LETTER NA +0x04c6 "ニ" # kana_NI ニ KATAKANA LETTER NI +0x04c7 "ヌ" # kana_NU ヌ KATAKANA LETTER NU +0x04c8 "ネ" # kana_NE ネ KATAKANA LETTER NE +0x04c9 "ノ" # kana_NO ノ KATAKANA LETTER NO +0x04ca "ハ" # kana_HA ハ KATAKANA LETTER HA +0x04cb "ヒ" # kana_HI ヒ KATAKANA LETTER HI +0x04cc "フ" # kana_FU フ KATAKANA LETTER HU +0x04cd "ヘ" # kana_HE ヘ KATAKANA LETTER HE +0x04ce "ホ" # kana_HO ホ KATAKANA LETTER HO +0x04cf "マ" # kana_MA マ KATAKANA LETTER MA +0x04d0 "ミ" # kana_MI ミ KATAKANA LETTER MI +0x04d1 "ム" # kana_MU ム KATAKANA LETTER MU +0x04d2 "メ" # kana_ME メ KATAKANA LETTER ME +0x04d3 "モ" # kana_MO モ KATAKANA LETTER MO +0x04d4 "ヤ" # kana_YA ヤ KATAKANA LETTER YA +0x04d5 "ユ" # kana_YU ユ KATAKANA LETTER YU +0x04d6 "ヨ" # kana_YO ヨ KATAKANA LETTER YO +0x04d7 "ラ" # kana_RA ラ KATAKANA LETTER RA +0x04d8 "リ" # kana_RI リ KATAKANA LETTER RI +0x04d9 "ル" # kana_RU ル KATAKANA LETTER RU +0x04da "レ" # kana_RE レ KATAKANA LETTER RE +0x04db "ロ" # kana_RO ロ KATAKANA LETTER RO +0x04dc "ワ" # kana_WA ワ KATAKANA LETTER WA +0x04dd "ン" # kana_N ン KATAKANA LETTER N +0x04de "゛" # voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK +0x04df "゜" # semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +0x05ac "،" # Arabic_comma ، ARABIC COMMA +0x05bb "؛" # Arabic_semicolon ؛ ARABIC SEMICOLON +0x05bf "؟" # Arabic_question_mark ؟ ARABIC QUESTION MARK +0x05c1 "ء" # Arabic_hamza ء ARABIC LETTER HAMZA +0x05c2 "آ" # Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE +0x05c3 "أ" # Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE +0x05c4 "ؤ" # Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE +0x05c5 "إ" # Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW +0x05c6 "ئ" # Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE +0x05c7 "ا" # Arabic_alef ا ARABIC LETTER ALEF +0x05c8 "ب" # Arabic_beh ب ARABIC LETTER BEH +0x05c9 "ة" # Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA +0x05ca "ت" # Arabic_teh ت ARABIC LETTER TEH +0x05cb "ث" # Arabic_theh ث ARABIC LETTER THEH +0x05cc "ج" # Arabic_jeem ج ARABIC LETTER JEEM +0x05cd "ح" # Arabic_hah ح ARABIC LETTER HAH +0x05ce "خ" # Arabic_khah خ ARABIC LETTER KHAH +0x05cf "د" # Arabic_dal د ARABIC LETTER DAL +0x05d0 "ذ" # Arabic_thal ذ ARABIC LETTER THAL +0x05d1 "ر" # Arabic_ra ر ARABIC LETTER REH +0x05d2 "ز" # Arabic_zain ز ARABIC LETTER ZAIN +0x05d3 "س" # Arabic_seen س ARABIC LETTER SEEN +0x05d4 "ش" # Arabic_sheen ش ARABIC LETTER SHEEN +0x05d5 "ص" # Arabic_sad ص ARABIC LETTER SAD +0x05d6 "ض" # Arabic_dad ض ARABIC LETTER DAD +0x05d7 "ط" # Arabic_tah ط ARABIC LETTER TAH +0x05d8 "ظ" # Arabic_zah ظ ARABIC LETTER ZAH +0x05d9 "ع" # Arabic_ain ع ARABIC LETTER AIN +0x05da "غ" # Arabic_ghain غ ARABIC LETTER GHAIN +0x05e0 "ـ" # Arabic_tatweel ـ ARABIC TATWEEL +0x05e1 "ف" # Arabic_feh ف ARABIC LETTER FEH +0x05e2 "ق" # Arabic_qaf ق ARABIC LETTER QAF +0x05e3 "ك" # Arabic_kaf ك ARABIC LETTER KAF +0x05e4 "ل" # Arabic_lam ل ARABIC LETTER LAM +0x05e5 "م" # Arabic_meem م ARABIC LETTER MEEM +0x05e6 "ن" # Arabic_noon ن ARABIC LETTER NOON +0x05e7 "ه" # Arabic_ha ه ARABIC LETTER HEH +0x05e8 "و" # Arabic_waw و ARABIC LETTER WAW +0x05e9 "ى" # Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA +0x05ea "ي" # Arabic_yeh ي ARABIC LETTER YEH +0x05eb "ً" # Arabic_fathatan ً ARABIC FATHATAN +0x05ec "ٌ" # Arabic_dammatan ٌ ARABIC DAMMATAN +0x05ed "ٍ" # Arabic_kasratan ٍ ARABIC KASRATAN +0x05ee "َ" # Arabic_fatha َ ARABIC FATHA +0x05ef "ُ" # Arabic_damma ُ ARABIC DAMMA +0x05f0 "ِ" # Arabic_kasra ِ ARABIC KASRA +0x05f1 "ّ" # Arabic_shadda ّ ARABIC SHADDA +0x05f2 "ْ" # Arabic_sukun ْ ARABIC SUKUN +0x06a1 "ђ" # Serbian_dje ђ CYRILLIC SMALL LETTER DJE +0x06a2 "ѓ" # Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE +0x06a3 "ё" # Cyrillic_io ё CYRILLIC SMALL LETTER IO +0x06a4 "є" # Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE +0x06a5 "ѕ" # Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE +0x06a6 "і" # Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0x06a7 "ї" # Ukrainian_yi ї CYRILLIC SMALL LETTER YI +0x06a8 "ј" # Cyrillic_je ј CYRILLIC SMALL LETTER JE +0x06a9 "љ" # Cyrillic_lje љ CYRILLIC SMALL LETTER LJE +0x06aa "њ" # Cyrillic_nje њ CYRILLIC SMALL LETTER NJE +0x06ab "ћ" # Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE +0x06ac "ќ" # Macedonia_kje ќ CYRILLIC SMALL LETTER KJE +0x06ad "ґ" # Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN +0x06ae "ў" # Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U +0x06af "џ" # Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE +0x06b0 "№" # numerosign № NUMERO SIGN +0x06b1 "Ђ" # Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE +0x06b2 "Ѓ" # Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE +0x06b3 "Ё" # Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO +0x06b4 "Є" # Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE +0x06b5 "Ѕ" # Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE +0x06b6 "І" # Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0x06b7 "Ї" # Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI +0x06b8 "Ј" # Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE +0x06b9 "Љ" # Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE +0x06ba "Њ" # Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE +0x06bb "Ћ" # Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE +0x06bc "Ќ" # Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE +0x06bd "Ґ" # Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0x06be "Ў" # Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U +0x06bf "Џ" # Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE +0x06c0 "ю" # Cyrillic_yu ю CYRILLIC SMALL LETTER YU +0x06c1 "а" # Cyrillic_a а CYRILLIC SMALL LETTER A +0x06c2 "б" # Cyrillic_be б CYRILLIC SMALL LETTER BE +0x06c3 "ц" # Cyrillic_tse ц CYRILLIC SMALL LETTER TSE +0x06c4 "д" # Cyrillic_de д CYRILLIC SMALL LETTER DE +0x06c5 "е" # Cyrillic_ie е CYRILLIC SMALL LETTER IE +0x06c6 "ф" # Cyrillic_ef ф CYRILLIC SMALL LETTER EF +0x06c7 "г" # Cyrillic_ghe г CYRILLIC SMALL LETTER GHE +0x06c8 "х" # Cyrillic_ha х CYRILLIC SMALL LETTER HA +0x06c9 "и" # Cyrillic_i и CYRILLIC SMALL LETTER I +0x06ca "й" # Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I +0x06cb "к" # Cyrillic_ka к CYRILLIC SMALL LETTER KA +0x06cc "л" # Cyrillic_el л CYRILLIC SMALL LETTER EL +0x06cd "м" # Cyrillic_em м CYRILLIC SMALL LETTER EM +0x06ce "н" # Cyrillic_en н CYRILLIC SMALL LETTER EN +0x06cf "о" # Cyrillic_o о CYRILLIC SMALL LETTER O +0x06d0 "п" # Cyrillic_pe п CYRILLIC SMALL LETTER PE +0x06d1 "я" # Cyrillic_ya я CYRILLIC SMALL LETTER YA +0x06d2 "р" # Cyrillic_er р CYRILLIC SMALL LETTER ER +0x06d3 "с" # Cyrillic_es с CYRILLIC SMALL LETTER ES +0x06d4 "т" # Cyrillic_te т CYRILLIC SMALL LETTER TE +0x06d5 "у" # Cyrillic_u у CYRILLIC SMALL LETTER U +0x06d6 "ж" # Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE +0x06d7 "в" # Cyrillic_ve в CYRILLIC SMALL LETTER VE +0x06d8 "ь" # Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN +0x06d9 "ы" # Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU +0x06da "з" # Cyrillic_ze з CYRILLIC SMALL LETTER ZE +0x06db "ш" # Cyrillic_sha ш CYRILLIC SMALL LETTER SHA +0x06dc "э" # Cyrillic_e э CYRILLIC SMALL LETTER E +0x06dd "щ" # Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA +0x06de "ч" # Cyrillic_che ч CYRILLIC SMALL LETTER CHE +0x06df "ъ" # Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN +0x06e0 "Ю" # Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU +0x06e1 "А" # Cyrillic_A А CYRILLIC CAPITAL LETTER A +0x06e2 "Б" # Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE +0x06e3 "Ц" # Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE +0x06e4 "Д" # Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE +0x06e5 "Е" # Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE +0x06e6 "Ф" # Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF +0x06e7 "Г" # Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE +0x06e8 "Х" # Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA +0x06e9 "И" # Cyrillic_I И CYRILLIC CAPITAL LETTER I +0x06ea "Й" # Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I +0x06eb "К" # Cyrillic_KA К CYRILLIC CAPITAL LETTER KA +0x06ec "Л" # Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL +0x06ed "М" # Cyrillic_EM М CYRILLIC CAPITAL LETTER EM +0x06ee "Н" # Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN +0x06ef "О" # Cyrillic_O О CYRILLIC CAPITAL LETTER O +0x06f0 "П" # Cyrillic_PE П CYRILLIC CAPITAL LETTER PE +0x06f1 "Я" # Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA +0x06f2 "Р" # Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER +0x06f3 "С" # Cyrillic_ES С CYRILLIC CAPITAL LETTER ES +0x06f4 "Т" # Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE +0x06f5 "У" # Cyrillic_U У CYRILLIC CAPITAL LETTER U +0x06f6 "Ж" # Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE +0x06f7 "В" # Cyrillic_VE В CYRILLIC CAPITAL LETTER VE +0x06f8 "Ь" # Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN +0x06f9 "Ы" # Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU +0x06fa "З" # Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE +0x06fb "Ш" # Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA +0x06fc "Э" # Cyrillic_E Э CYRILLIC CAPITAL LETTER E +0x06fd "Щ" # Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA +0x06fe "Ч" # Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE +0x06ff "Ъ" # Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN +0x07a1 "Ά" # Geek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS +0x07a2 "Έ" # Geek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS +0x07a3 "Ή" # Geek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS +0x07a4 "Ί" # Geek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS +0x07a5 "Ϊ" # Geek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +0x07a7 "Ό" # Geek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS +0x07a8 "Ύ" # Geek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS +0x07a9 "Ϋ" # Geek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +0x07ab "Ώ" # Geek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS +0x07ae "΅" # Geek_accentdieresis ΅ GREEK DIALYTIKA TONOS +0x07af "―" # Geek_horizbar ― HORIZONTAL BAR +0x07b1 "ά" # Geek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS +0x07b2 "έ" # Geek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS +0x07b3 "ή" # Geek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS +0x07b4 "ί" # Geek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS +0x07b5 "ϊ" # Geek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA +0x07b6 "ΐ" # Geek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0x07b7 "ό" # Geek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS +0x07b8 "ύ" # Geek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS +0x07b9 "ϋ" # Geek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA +0x07ba "ΰ" # Geek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +0x07bb "ώ" # Geek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS +0x07c1 "Α" # Geek_ALPHA Α GREEK CAPITAL LETTER ALPHA +0x07c2 "Β" # Geek_BETA Β GREEK CAPITAL LETTER BETA +0x07c3 "Γ" # Geek_GAMMA Γ GREEK CAPITAL LETTER GAMMA +0x07c4 "Δ" # Geek_DELTA Δ GREEK CAPITAL LETTER DELTA +0x07c5 "Ε" # Geek_EPSILON Ε GREEK CAPITAL LETTER EPSILON +0x07c6 "Ζ" # Geek_ZETA Ζ GREEK CAPITAL LETTER ZETA +0x07c7 "Η" # Geek_ETA Η GREEK CAPITAL LETTER ETA +0x07c8 "Θ" # Geek_THETA Θ GREEK CAPITAL LETTER THETA +0x07c9 "Ι" # Geek_IOTA Ι GREEK CAPITAL LETTER IOTA +0x07ca "Κ" # Geek_KAPPA Κ GREEK CAPITAL LETTER KAPPA +0x07cb "Λ" # Geek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA +0x07cc "Μ" # Geek_MU Μ GREEK CAPITAL LETTER MU +0x07cd "Ν" # Geek_NU Ν GREEK CAPITAL LETTER NU +0x07ce "Ξ" # Geek_XI Ξ GREEK CAPITAL LETTER XI +0x07cf "Ο" # Geek_OMICRON Ο GREEK CAPITAL LETTER OMICRON +0x07d0 "Π" # Geek_PI Π GREEK CAPITAL LETTER PI +0x07d1 "Ρ" # Geek_RHO Ρ GREEK CAPITAL LETTER RHO +0x07d2 "Σ" # Geek_SIGMA Σ GREEK CAPITAL LETTER SIGMA +0x07d4 "Τ" # Geek_TAU Τ GREEK CAPITAL LETTER TAU +0x07d5 "Υ" # Geek_UPSILON Υ GREEK CAPITAL LETTER UPSILON +0x07d6 "Φ" # Geek_PHI Φ GREEK CAPITAL LETTER PHI +0x07d7 "Χ" # Geek_CHI Χ GREEK CAPITAL LETTER CHI +0x07d8 "Ψ" # Geek_PSI Ψ GREEK CAPITAL LETTER PSI +0x07d9 "Ω" # Geek_OMEGA Ω GREEK CAPITAL LETTER OMEGA +0x07e1 "α" # Geek_alpha α GREEK SMALL LETTER ALPHA +0x07e2 "β" # Geek_beta β GREEK SMALL LETTER BETA +0x07e3 "γ" # Geek_gamma γ GREEK SMALL LETTER GAMMA +0x07e4 "δ" # Geek_delta δ GREEK SMALL LETTER DELTA +0x07e5 "ε" # Geek_epsilon ε GREEK SMALL LETTER EPSILON +0x07e6 "ζ" # Geek_zeta ζ GREEK SMALL LETTER ZETA +0x07e7 "η" # Geek_eta η GREEK SMALL LETTER ETA +0x07e8 "θ" # Geek_theta θ GREEK SMALL LETTER THETA +0x07e9 "ι" # Geek_iota ι GREEK SMALL LETTER IOTA +0x07ea "κ" # Geek_kappa κ GREEK SMALL LETTER KAPPA +0x07eb "λ" # Geek_lambda λ GREEK SMALL LETTER LAMDA +0x07ec "μ" # Geek_mu μ GREEK SMALL LETTER MU +0x07ed "ν" # Geek_nu ν GREEK SMALL LETTER NU +0x07ee "ξ" # Geek_xi ξ GREEK SMALL LETTER XI +0x07ef "ο" # Geek_omicron ο GREEK SMALL LETTER OMICRON +0x07f0 "π" # Geek_pi π GREEK SMALL LETTER PI +0x07f1 "ρ" # Geek_rho ρ GREEK SMALL LETTER RHO +0x07f2 "σ" # Geek_sigma σ GREEK SMALL LETTER SIGMA +0x07f3 "ς" # Geek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA +0x07f4 "τ" # Geek_tau τ GREEK SMALL LETTER TAU +0x07f5 "υ" # Geek_upsilon υ GREEK SMALL LETTER UPSILON +0x07f6 "φ" # Geek_phi φ GREEK SMALL LETTER PHI +0x07f7 "χ" # Geek_chi χ GREEK SMALL LETTER CHI +0x07f8 "ψ" # Geek_psi ψ GREEK SMALL LETTER PSI +0x07f9 "ω" # Geek_omega ω GREEK SMALL LETTER OMEGA +# 0x08a1 leftradical ? ??? +# 0x08a2 topleftradical ? ??? +# 0x08a3 horizconnector ? ??? +0x08a4 "⌠" # topintegral ⌠ TOP HALF INTEGRAL +0x08a5 "⌡" # botintegral ⌡ BOTTOM HALF INTEGRAL +0x08a6 "│" # vertconnector │ BOX DRAWINGS LIGHT VERTICAL +# 0x08a7 topleftsqbracket ? ??? +# 0x08a8 botleftsqbracket ? ??? +# 0x08a9 toprightsqbracket ? ??? +# 0x08aa botrightsqbracket ? ??? +# 0x08ab topleftparens ? ??? +# 0x08ac botleftparens ? ??? +# 0x08ad toprightparens ? ??? +# 0x08ae botrightparens ? ??? +# 0x08af leftmiddlecurlybrace ? ??? +# 0x08b0 rightmiddlecurlybrace ? ??? +# 0x08b1 topleftsummation ? ??? +# 0x08b2 botleftsummation ? ??? +# 0x08b3 topvertsummationconnector ? ??? +# 0x08b4 botvertsummationconnector ? ??? +# 0x08b5 toprightsummation ? ??? +# 0x08b6 botrightsummation ? ??? +# 0x08b7 rightmiddlesummation ? ??? +0x08bc "≤" # lessthanequal ≤ LESS-THAN OR EQUAL TO +0x08bd "≠" # notequal ≠ NOT EQUAL TO +0x08be "≥" # greaterthanequal ≥ GREATER-THAN OR EQUAL TO +0x08bf "∫" # integral ∫ INTEGRAL +0x08c0 "∴" # therefore ∴ THEREFORE +0x08c1 "∝" # variation ∝ PROPORTIONAL TO +0x08c2 "∞" # infinity ∞ INFINITY +0x08c5 "∇" # nabla ∇ NABLA +0x08c8 "≅" # approximate ≅ APPROXIMATELY EQUAL TO +# 0x08c9 similarequal ? ??? +0x08cd "⇔" # ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW +0x08ce "⇒" # implies ⇒ RIGHTWARDS DOUBLE ARROW +0x08cf "≡" # identical ≡ IDENTICAL TO +0x08d6 "√" # radical √ SQUARE ROOT +0x08da "⊂" # includedin ⊂ SUBSET OF +0x08db "⊃" # includes ⊃ SUPERSET OF +0x08dc "∩" # intersection ∩ INTERSECTION +0x08dd "∪" # union ∪ UNION +0x08de "∧" # logicaland ∧ LOGICAL AND +0x08df "∨" # logicalor ∨ LOGICAL OR +0x08ef "∂" # partialderivative ∂ PARTIAL DIFFERENTIAL +0x08f6 "ƒ" # function ƒ LATIN SMALL LETTER F WITH HOOK +0x08fb "←" # leftarrow ← LEFTWARDS ARROW +0x08fc "↑" # uparrow ↑ UPWARDS ARROW +0x08fd "→" # rightarrow → RIGHTWARDS ARROW +0x08fe "↓" # downarrow ↓ DOWNWARDS ARROW +0x09df "␢" # blank ␢ BLANK SYMBOL +0x09e0 "◆" # soliddiamond ◆ BLACK DIAMOND +0x09e1 "▒" # checkerboard ▒ MEDIUM SHADE +0x09e2 "␉" # ht ␉ SYMBOL FOR HORIZONTAL TABULATION +0x09e3 "␌" # ff ␌ SYMBOL FOR FORM FEED +0x09e4 "␍" # cr ␍ SYMBOL FOR CARRIAGE RETURN +0x09e5 "␊" # lf ␊ SYMBOL FOR LINE FEED +0x09e8 "␤" # nl ␤ SYMBOL FOR NEWLINE +0x09e9 "␋" # vt ␋ SYMBOL FOR VERTICAL TABULATION +0x09ea "┘" # lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT +0x09eb "┐" # uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT +0x09ec "┌" # upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT +0x09ed "└" # lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT +0x09ee "┼" # crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +# 0x09ef horizlinescan1 ? ??? +# 0x09f0 horizlinescan3 ? ??? +0x09f1 "─" # horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL +# 0x09f2 horizlinescan7 ? ??? +# 0x09f3 horizlinescan9 ? ??? +0x09f4 "├" # leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0x09f5 "┤" # rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT +0x09f6 "┴" # bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL +0x09f7 "┬" # topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0x09f8 "│" # vertbar │ BOX DRAWINGS LIGHT VERTICAL +0x0aa1 " " # emspace   EM SPACE +0x0aa2 " " # enspace   EN SPACE +0x0aa3 " " # em3space   THREE-PER-EM SPACE +0x0aa4 " " # em4space   FOUR-PER-EM SPACE +0x0aa5 " " # digitspace   FIGURE SPACE +0x0aa6 " " # punctspace   PUNCTUATION SPACE +0x0aa7 " " # thinspace   THIN SPACE +0x0aa8 " " # hairspace   HAIR SPACE +0x0aa9 "—" # emdash — EM DASH +0x0aaa "–" # endash – EN DASH +# 0x0aac signifblank ? ??? +0x0aae "…" # ellipsis … HORIZONTAL ELLIPSIS +# 0x0aaf doubbaselinedot ? ??? +0x0ab0 "⅓" # onethird ⅓ VULGAR FRACTION ONE THIRD +0x0ab1 "⅔" # twothirds ⅔ VULGAR FRACTION TWO THIRDS +0x0ab2 "⅕" # onefifth ⅕ VULGAR FRACTION ONE FIFTH +0x0ab3 "⅖" # twofifths ⅖ VULGAR FRACTION TWO FIFTHS +0x0ab4 "⅗" # threefifths ⅗ VULGAR FRACTION THREE FIFTHS +0x0ab5 "⅘" # fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS +0x0ab6 "⅙" # onesixth ⅙ VULGAR FRACTION ONE SIXTH +0x0ab7 "⅚" # fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS +0x0ab8 "℅" # careof ℅ CARE OF +0x0abb "‒" # figdash ‒ FIGURE DASH +0x0abc "〈" # leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET +0x0abd "." # decimalpoint . FULL STOP +0x0abe "〉" # rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET +# 0x0abf marker ? ??? +0x0ac3 "⅛" # oneeighth ⅛ VULGAR FRACTION ONE EIGHTH +0x0ac4 "⅜" # threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS +0x0ac5 "⅝" # fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS +0x0ac6 "⅞" # seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS +0x0ac9 "™" # trademark ™ TRADE MARK SIGN +0x0aca "☓" # signaturemark ☓ SALTIRE +# 0x0acb trademarkincircle ? ??? +0x0acc "◁" # leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE +0x0acd "▷" # rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE +0x0ace "○" # emopencircle ○ WHITE CIRCLE +0x0acf "□" # emopenrectangle □ WHITE SQUARE +0x0ad0 "‘" # leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK +0x0ad1 "’" # rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK +0x0ad2 "“" # leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK +0x0ad3 "”" # rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK +0x0ad4 "℞" # prescription ℞ PRESCRIPTION TAKE +0x0ad6 "′" # minutes ′ PRIME +0x0ad7 "″" # seconds ″ DOUBLE PRIME +0x0ad9 "✝" # latincross ✝ LATIN CROSS +# 0x0ada hexagram ? ??? +0x0adb "▬" # filledrectbullet ▬ BLACK RECTANGLE +0x0adc "◀" # filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE +0x0add "▶" # filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE +0x0ade "●" # emfilledcircle ● BLACK CIRCLE +0x0adf "■" # emfilledrect ■ BLACK SQUARE +0x0ae0 "◦" # enopencircbullet ◦ WHITE BULLET +0x0ae1 "▫" # enopensquarebullet ▫ WHITE SMALL SQUARE +0x0ae2 "▭" # openrectbullet ▭ WHITE RECTANGLE +0x0ae3 "△" # opentribulletup △ WHITE UP-POINTING TRIANGLE +0x0ae4 "▽" # opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE +0x0ae5 "☆" # openstar ☆ WHITE STAR +0x0ae6 "•" # enfilledcircbullet • BULLET +0x0ae7 "▪" # enfilledsqbullet ▪ BLACK SMALL SQUARE +0x0ae8 "▲" # filledtribulletup ▲ BLACK UP-POINTING TRIANGLE +0x0ae9 "▼" # filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE +0x0aea "☜" # leftpointer ☜ WHITE LEFT POINTING INDEX +0x0aeb "☞" # rightpointer ☞ WHITE RIGHT POINTING INDEX +0x0aec "♣" # club ♣ BLACK CLUB SUIT +0x0aed "♦" # diamond ♦ BLACK DIAMOND SUIT +0x0aee "♥" # heart ♥ BLACK HEART SUIT +0x0af0 "✠" # maltesecross ✠ MALTESE CROSS +0x0af1 "†" # dagger † DAGGER +0x0af2 "‡" # doubledagger ‡ DOUBLE DAGGER +0x0af3 "✓" # checkmark ✓ CHECK MARK +0x0af4 "✗" # ballotcross ✗ BALLOT X +0x0af5 "♯" # musicalsharp ♯ MUSIC SHARP SIGN +0x0af6 "♭" # musicalflat ♭ MUSIC FLAT SIGN +0x0af7 "♂" # malesymbol ♂ MALE SIGN +0x0af8 "♀" # femalesymbol ♀ FEMALE SIGN +0x0af9 "☎" # telephone ☎ BLACK TELEPHONE +0x0afa "⌕" # telephonerecorder ⌕ TELEPHONE RECORDER +0x0afb "℗" # phonographcopyright ℗ SOUND RECORDING COPYRIGHT +0x0afc "‸" # caret ‸ CARET +0x0afd "‚" # singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK +0x0afe "„" # doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK +# 0x0aff cursor ? ??? +0x0ba3 "<" # leftcaret < LESS-THAN SIGN +0x0ba6 ">" # rightcaret > GREATER-THAN SIGN +0x0ba8 "∨" # downcaret ∨ LOGICAL OR +0x0ba9 "∧" # upcaret ∧ LOGICAL AND +0x0bc0 "¯" # overbar ¯ MACRON +0x0bc2 "⊤" # downtack ⊤ DOWN TACK +0x0bc3 "∩" # upshoe ∩ INTERSECTION +0x0bc4 "⌊" # downstile ⌊ LEFT FLOOR +0x0bc6 "_" # underbar _ LOW LINE +0x0bca "∘" # jot ∘ RING OPERATOR +0x0bcc "⎕" # quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) +0x0bce "⊥" # uptack ⊥ UP TACK +0x0bcf "○" # circle ○ WHITE CIRCLE +0x0bd3 "⌈" # upstile ⌈ LEFT CEILING +0x0bd6 "∪" # downshoe ∪ UNION +0x0bd8 "⊃" # rightshoe ⊃ SUPERSET OF +0x0bda "⊂" # leftshoe ⊂ SUBSET OF +0x0bdc "⊣" # lefttack ⊣ LEFT TACK +0x0bfc "⊢" # righttack ⊢ RIGHT TACK +0x0cdf "‗" # hebrew_doublelowline ‗ DOUBLE LOW LINE +0x0ce0 "א" # hebrew_aleph א HEBREW LETTER ALEF +0x0ce1 "ב" # hebrew_bet ב HEBREW LETTER BET +0x0ce2 "ג" # hebrew_gimel ג HEBREW LETTER GIMEL +0x0ce3 "ד" # hebrew_dalet ד HEBREW LETTER DALET +0x0ce4 "ה" # hebrew_he ה HEBREW LETTER HE +0x0ce5 "ו" # hebrew_waw ו HEBREW LETTER VAV +0x0ce6 "ז" # hebrew_zain ז HEBREW LETTER ZAYIN +0x0ce7 "ח" # hebrew_chet ח HEBREW LETTER HET +0x0ce8 "ט" # hebrew_tet ט HEBREW LETTER TET +0x0ce9 "י" # hebrew_yod י HEBREW LETTER YOD +0x0cea "ך" # hebrew_finalkaph ך HEBREW LETTER FINAL KAF +0x0ceb "כ" # hebrew_kaph כ HEBREW LETTER KAF +0x0cec "ל" # hebrew_lamed ל HEBREW LETTER LAMED +0x0ced "ם" # hebrew_finalmem ם HEBREW LETTER FINAL MEM +0x0cee "מ" # hebrew_mem מ HEBREW LETTER MEM +0x0cef "ן" # hebrew_finalnun ן HEBREW LETTER FINAL NUN +0x0cf0 "נ" # hebrew_nun נ HEBREW LETTER NUN +0x0cf1 "ס" # hebrew_samech ס HEBREW LETTER SAMEKH +0x0cf2 "ע" # hebrew_ayin ע HEBREW LETTER AYIN +0x0cf3 "ף" # hebrew_finalpe ף HEBREW LETTER FINAL PE +0x0cf4 "פ" # hebrew_pe פ HEBREW LETTER PE +0x0cf5 "ץ" # hebrew_finalzade ץ HEBREW LETTER FINAL TSADI +0x0cf6 "צ" # hebrew_zade צ HEBREW LETTER TSADI +0x0cf7 "ק" # hebrew_qoph ק HEBREW LETTER QOF +0x0cf8 "ר" # hebrew_resh ר HEBREW LETTER RESH +0x0cf9 "ש" # hebrew_shin ש HEBREW LETTER SHIN +0x0cfa "ת" # hebrew_taw ת HEBREW LETTER TAV +0x0da1 "ก" # Thai_kokai ก THAI CHARACTER KO KAI +0x0da2 "ข" # Thai_khokhai ข THAI CHARACTER KHO KHAI +0x0da3 "ฃ" # Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT +0x0da4 "ค" # Thai_khokhwai ค THAI CHARACTER KHO KHWAI +0x0da5 "ฅ" # Thai_khokhon ฅ THAI CHARACTER KHO KHON +0x0da6 "ฆ" # Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG +0x0da7 "ง" # Thai_ngongu ง THAI CHARACTER NGO NGU +0x0da8 "จ" # Thai_chochan จ THAI CHARACTER CHO CHAN +0x0da9 "ฉ" # Thai_choching ฉ THAI CHARACTER CHO CHING +0x0daa "ช" # Thai_chochang ช THAI CHARACTER CHO CHANG +0x0dab "ซ" # Thai_soso ซ THAI CHARACTER SO SO +0x0dac "ฌ" # Thai_chochoe ฌ THAI CHARACTER CHO CHOE +0x0dad "ญ" # Thai_yoying ญ THAI CHARACTER YO YING +0x0dae "ฎ" # Thai_dochada ฎ THAI CHARACTER DO CHADA +0x0daf "ฏ" # Thai_topatak ฏ THAI CHARACTER TO PATAK +0x0db0 "ฐ" # Thai_thothan ฐ THAI CHARACTER THO THAN +0x0db1 "ฑ" # Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO +0x0db2 "ฒ" # Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO +0x0db3 "ณ" # Thai_nonen ณ THAI CHARACTER NO NEN +0x0db4 "ด" # Thai_dodek ด THAI CHARACTER DO DEK +0x0db5 "ต" # Thai_totao ต THAI CHARACTER TO TAO +0x0db6 "ถ" # Thai_thothung ถ THAI CHARACTER THO THUNG +0x0db7 "ท" # Thai_thothahan ท THAI CHARACTER THO THAHAN +0x0db8 "ธ" # Thai_thothong ธ THAI CHARACTER THO THONG +0x0db9 "น" # Thai_nonu น THAI CHARACTER NO NU +0x0dba "บ" # Thai_bobaimai บ THAI CHARACTER BO BAIMAI +0x0dbb "ป" # Thai_popla ป THAI CHARACTER PO PLA +0x0dbc "ผ" # Thai_phophung ผ THAI CHARACTER PHO PHUNG +0x0dbd "ฝ" # Thai_fofa ฝ THAI CHARACTER FO FA +0x0dbe "พ" # Thai_phophan พ THAI CHARACTER PHO PHAN +0x0dbf "ฟ" # Thai_fofan ฟ THAI CHARACTER FO FAN +0x0dc0 "ภ" # Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO +0x0dc1 "ม" # Thai_moma ม THAI CHARACTER MO MA +0x0dc2 "ย" # Thai_yoyak ย THAI CHARACTER YO YAK +0x0dc3 "ร" # Thai_rorua ร THAI CHARACTER RO RUA +0x0dc4 "ฤ" # Thai_ru ฤ THAI CHARACTER RU +0x0dc5 "ล" # Thai_loling ล THAI CHARACTER LO LING +0x0dc6 "ฦ" # Thai_lu ฦ THAI CHARACTER LU +0x0dc7 "ว" # Thai_wowaen ว THAI CHARACTER WO WAEN +0x0dc8 "ศ" # Thai_sosala ศ THAI CHARACTER SO SALA +0x0dc9 "ษ" # Thai_sorusi ษ THAI CHARACTER SO RUSI +0x0dca "ส" # Thai_sosua ส THAI CHARACTER SO SUA +0x0dcb "ห" # Thai_hohip ห THAI CHARACTER HO HIP +0x0dcc "ฬ" # Thai_lochula ฬ THAI CHARACTER LO CHULA +0x0dcd "อ" # Thai_oang อ THAI CHARACTER O ANG +0x0dce "ฮ" # Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK +0x0dcf "ฯ" # Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI +0x0dd0 "ะ" # Thai_saraa ะ THAI CHARACTER SARA A +0x0dd1 "ั" # Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT +0x0dd2 "า" # Thai_saraaa า THAI CHARACTER SARA AA +0x0dd3 "ำ" # Thai_saraam ำ THAI CHARACTER SARA AM +0x0dd4 "ิ" # Thai_sarai ิ THAI CHARACTER SARA I +0x0dd5 "ี" # Thai_saraii ี THAI CHARACTER SARA II +0x0dd6 "ึ" # Thai_saraue ึ THAI CHARACTER SARA UE +0x0dd7 "ื" # Thai_sarauee ื THAI CHARACTER SARA UEE +0x0dd8 "ุ" # Thai_sarau ุ THAI CHARACTER SARA U +0x0dd9 "ู" # Thai_sarauu ู THAI CHARACTER SARA UU +0x0dda "ฺ" # Thai_phinthu ฺ THAI CHARACTER PHINTHU +0x0dde "฾" # Thai_maihanakat_maitho ฾ ??? +0x0ddf "฿" # Thai_baht ฿ THAI CURRENCY SYMBOL BAHT +0x0de0 "เ" # Thai_sarae เ THAI CHARACTER SARA E +0x0de1 "แ" # Thai_saraae แ THAI CHARACTER SARA AE +0x0de2 "โ" # Thai_sarao โ THAI CHARACTER SARA O +0x0de3 "ใ" # Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN +0x0de4 "ไ" # Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI +0x0de5 "ๅ" # Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO +0x0de6 "ๆ" # Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK +0x0de7 "็" # Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU +0x0de8 "่" # Thai_maiek ่ THAI CHARACTER MAI EK +0x0de9 "้" # Thai_maitho ้ THAI CHARACTER MAI THO +0x0dea "๊" # Thai_maitri ๊ THAI CHARACTER MAI TRI +0x0deb "๋" # Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA +0x0dec "์" # Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT +0x0ded "ํ" # Thai_nikhahit ํ THAI CHARACTER NIKHAHIT +0x0df0 "๐" # Thai_leksun ๐ THAI DIGIT ZERO +0x0df1 "๑" # Thai_leknung ๑ THAI DIGIT ONE +0x0df2 "๒" # Thai_leksong ๒ THAI DIGIT TWO +0x0df3 "๓" # Thai_leksam ๓ THAI DIGIT THREE +0x0df4 "๔" # Thai_leksi ๔ THAI DIGIT FOUR +0x0df5 "๕" # Thai_lekha ๕ THAI DIGIT FIVE +0x0df6 "๖" # Thai_lekhok ๖ THAI DIGIT SIX +0x0df7 "๗" # Thai_lekchet ๗ THAI DIGIT SEVEN +0x0df8 "๘" # Thai_lekpaet ๘ THAI DIGIT EIGHT +0x0df9 "๙" # Thai_lekkao ๙ THAI DIGIT NINE +0x0ea1 "ㄱ" # Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK +0x0ea2 "ㄲ" # Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK +0x0ea3 "ㄳ" # Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS +0x0ea4 "ㄴ" # Hangul_Nieun ㄴ HANGUL LETTER NIEUN +0x0ea5 "ㄵ" # Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC +0x0ea6 "ㄶ" # Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH +0x0ea7 "ㄷ" # Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT +0x0ea8 "ㄸ" # Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT +0x0ea9 "ㄹ" # Hangul_Rieul ㄹ HANGUL LETTER RIEUL +0x0eaa "ㄺ" # Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK +0x0eab "ㄻ" # Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM +0x0eac "ㄼ" # Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP +0x0ead "ㄽ" # Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS +0x0eae "ㄾ" # Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH +0x0eaf "ㄿ" # Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH +0x0eb0 "ㅀ" # Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH +0x0eb1 "ㅁ" # Hangul_Mieum ㅁ HANGUL LETTER MIEUM +0x0eb2 "ㅂ" # Hangul_Pieub ㅂ HANGUL LETTER PIEUP +0x0eb3 "ㅃ" # Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP +0x0eb4 "ㅄ" # Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS +0x0eb5 "ㅅ" # Hangul_Sios ㅅ HANGUL LETTER SIOS +0x0eb6 "ㅆ" # Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS +0x0eb7 "ㅇ" # Hangul_Ieung ㅇ HANGUL LETTER IEUNG +0x0eb8 "ㅈ" # Hangul_Jieuj ㅈ HANGUL LETTER CIEUC +0x0eb9 "ㅉ" # Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC +0x0eba "ㅊ" # Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH +0x0ebb "ㅋ" # Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH +0x0ebc "ㅌ" # Hangul_Tieut ㅌ HANGUL LETTER THIEUTH +0x0ebd "ㅍ" # Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH +0x0ebe "ㅎ" # Hangul_Hieuh ㅎ HANGUL LETTER HIEUH +0x0ebf "ㅏ" # Hangul_A ㅏ HANGUL LETTER A +0x0ec0 "ㅐ" # Hangul_AE ㅐ HANGUL LETTER AE +0x0ec1 "ㅑ" # Hangul_YA ㅑ HANGUL LETTER YA +0x0ec2 "ㅒ" # Hangul_YAE ㅒ HANGUL LETTER YAE +0x0ec3 "ㅓ" # Hangul_EO ㅓ HANGUL LETTER EO +0x0ec4 "ㅔ" # Hangul_E ㅔ HANGUL LETTER E +0x0ec5 "ㅕ" # Hangul_YEO ㅕ HANGUL LETTER YEO +0x0ec6 "ㅖ" # Hangul_YE ㅖ HANGUL LETTER YE +0x0ec7 "ㅗ" # Hangul_O ㅗ HANGUL LETTER O +0x0ec8 "ㅘ" # Hangul_WA ㅘ HANGUL LETTER WA +0x0ec9 "ㅙ" # Hangul_WAE ㅙ HANGUL LETTER WAE +0x0eca "ㅚ" # Hangul_OE ㅚ HANGUL LETTER OE +0x0ecb "ㅛ" # Hangul_YO ㅛ HANGUL LETTER YO +0x0ecc "ㅜ" # Hangul_U ㅜ HANGUL LETTER U +0x0ecd "ㅝ" # Hangul_WEO ㅝ HANGUL LETTER WEO +0x0ece "ㅞ" # Hangul_WE ㅞ HANGUL LETTER WE +0x0ecf "ㅟ" # Hangul_WI ㅟ HANGUL LETTER WI +0x0ed0 "ㅠ" # Hangul_YU ㅠ HANGUL LETTER YU +0x0ed1 "ㅡ" # Hangul_EU ㅡ HANGUL LETTER EU +0x0ed2 "ㅢ" # Hangul_YI ㅢ HANGUL LETTER YI +0x0ed3 "ㅣ" # Hangul_I ㅣ HANGUL LETTER I +0x0ed4 "ᆨ" # Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK +0x0ed5 "ᆩ" # Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK +0x0ed6 "ᆪ" # Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS +0x0ed7 "ᆫ" # Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN +0x0ed8 "ᆬ" # Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC +0x0ed9 "ᆭ" # Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH +0x0eda "ᆮ" # Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT +0x0edb "ᆯ" # Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL +0x0edc "ᆰ" # Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK +0x0edd "ᆱ" # Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM +0x0ede "ᆲ" # Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP +0x0edf "ᆳ" # Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS +0x0ee0 "ᆴ" # Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH +0x0ee1 "ᆵ" # Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH +0x0ee2 "ᆶ" # Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH +0x0ee3 "ᆷ" # Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM +0x0ee4 "ᆸ" # Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP +0x0ee5 "ᆹ" # Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS +0x0ee6 "ᆺ" # Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS +0x0ee7 "ᆻ" # Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS +0x0ee8 "ᆼ" # Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG +0x0ee9 "ᆽ" # Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC +0x0eea "ᆾ" # Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH +0x0eeb "ᆿ" # Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH +0x0eec "ᇀ" # Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH +0x0eed "ᇁ" # Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH +0x0eee "ᇂ" # Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH +0x0eef "ㅭ" # Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH +0x0ef0 "ㅱ" # Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM +0x0ef1 "ㅸ" # Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP +0x0ef2 "ㅿ" # Hangul_PanSios ㅿ HANGUL LETTER PANSIOS +# 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? +0x0ef4 "ㆄ" # Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH +0x0ef5 "ㆆ" # Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH +0x0ef6 "ㆍ" # Hangul_AraeA ㆍ HANGUL LETTER ARAEA +0x0ef7 "ㆎ" # Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE +0x0ef8 "ᇫ" # Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS +# 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? +0x0efa "ᇹ" # Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH +0x0eff "₩" # Korean_Won ₩ WON SIGN +0x13bc "Œ" # OE Œ LATIN CAPITAL LIGATURE OE +0x13bd "œ" # oe œ LATIN SMALL LIGATURE OE +0x13be "Ÿ" # Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS +0x20a0 "₠" # EcuSign ₠ EURO-CURRENCY SIGN +0x20a1 "₡" # ColonSign ₡ COLON SIGN +0x20a2 "₢" # CruzeiroSign ₢ CRUZEIRO SIGN +0x20a3 "₣" # FFrancSign ₣ FRENCH FRANC SIGN +0x20a4 "₤" # LiraSign ₤ LIRA SIGN +0x20a5 "₥" # MillSign ₥ MILL SIGN +0x20a6 "₦" # NairaSign ₦ NAIRA SIGN +0x20a7 "₧" # PesetaSign ₧ PESETA SIGN +0x20a8 "₨" # RupeeSign ₨ RUPEE SIGN +0x20a9 "₩" # WonSign ₩ WON SIGN +0x20aa "₪" # NewSheqelSign ₪ NEW SHEQEL SIGN +0x20ab "₫" # DongSign ₫ DONG SIGN +0x20ac "€" # EuroSign € EURO SIGN + +# Following items added to GTK, not in the xterm table + +# Numeric keypad + +# 0xFF80 # Space * +0xFFAA "*" # Multiply * +0xFFAB "+" # Add * +0xFFAC "," # Separator * +0xFFAD "-" # Subtract * +0xFFAE "." # Decimal * +0xFFAF "/" # Divide * +0xFFB0 "0" # 0 * +0xFFB1 "1" # 1 * +0xFFB2 "2" # 2 * +0xFFB3 "3" # 3 * +0xFFB4 "4" # 4 * +0xFFB5 "5" # 5 * +0xFFB6 "6" # 6 * +0xFFB7 "7" # 7 * +0xFFB8 "8" # 8 * +0xFFB9 "9" # 9 * +0xFFBD "=" # Equal * + +# End numeric keypad diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 00000000..48a27d09 --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,21 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_PROGRAMS = eek-clutter-xkb-test +eek_clutter_xkb_test_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(CLUTTER_CFLAGS) $(XKB_CFLAGS) +eek_clutter_xkb_test_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la $(top_builddir)/eek/libeek-clutter.la $(GOBJECT2_LIBS) $(CLUTTER_LIBS) $(XKB_LIBS) diff --git a/examples/eek-clutter-xkb-test.c b/examples/eek-clutter-xkb-test.c new file mode 100644 index 00000000..6c124ea9 --- /dev/null +++ b/examples/eek-clutter-xkb-test.c @@ -0,0 +1,149 @@ +#include "eek/eek-clutter.h" +#include "eek/eek-xkb.h" +#include +#include +#include + +#define CSW 640 +#define CSH 480 + +static gchar *symbols = NULL; +static gchar *keycodes = NULL; +static gchar *geometry = NULL; + +static const GOptionEntry options[] = { + {"symbols", '\0', 0, G_OPTION_ARG_STRING, &symbols, + "Symbols component of the keyboard. If you omit this option, it is " + "obtained from the X server; that is, the keyboard that is currently " + "configured is drawn. Examples: --symbols=us or " + "--symbols=us(pc104)+iso9995-3+group(switch)+ctrl(nocaps)", NULL}, + {"keycodes", '\0', 0, G_OPTION_ARG_STRING, &keycodes, + "Keycodes component of the keyboard. If you omit this option, it is " + "obtained from the X server; that is, the keyboard that is currently" + " configured is drawn. Examples: --keycodes=xfree86+aliases(qwerty)", + NULL}, + {"geometry", '\0', 0, G_OPTION_ARG_STRING, &geometry, + "Geometry xkb component. If you omit this option, it is obtained from the" + " X server; that is, the keyboard that is currently configured is drawn. " + "Example: --geometry=kinesis", NULL}, + {NULL}, +}; + +gfloat stage_width, stage_height; + +static gboolean +on_event (ClutterStage *stage, + ClutterEvent *event, + gpointer user_data) +{ + if (event->type == CLUTTER_BUTTON_PRESS) { + ClutterActor *actor = clutter_event_get_source (event); + + if (EEK_IS_KEY(actor)) { + guint keysym; + const gchar *label = NULL; + + keysym = eek_key_get_keysym (EEK_KEY(actor)); + if (keysym != EEK_INVALID_KEYSYM) + label = eek_keysym_to_string (keysym); + if (label) { + printf ("%s", label); + fflush (stdout); + } + } + return TRUE; + } + return FALSE; +} + +static void +on_resize (GObject *object, + GParamSpec *param_spec, + gpointer user_data) +{ + GValue value = {0}; + gfloat width, height, scale; + ClutterActor *stage = CLUTTER_ACTOR(object); + + g_object_get (G_OBJECT(stage), "width", &width, NULL); + g_object_get (G_OBJECT(stage), "height", &height, NULL); + + g_value_init (&value, G_TYPE_DOUBLE); + + scale = width > height ? width / stage_width : width / stage_height; + + g_value_set_double (&value, scale); + g_object_set_property (G_OBJECT (stage), + "scale-x", + &value); + + g_value_set_double (&value, scale); + g_object_set_property (G_OBJECT (stage), + "scale-y", + &value); +} + +int +main (int argc, char *argv[]) +{ + EekKeyboard *keyboard; + EekLayout *layout; + ClutterActor *stage; + ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff }; + GOptionContext *context; + + context = g_option_context_new ("test-xkb-clutter"); + g_option_context_add_main_entries (context, options, NULL); + g_option_context_parse (context, &argc, &argv, NULL); + g_option_context_free (context); + + clutter_init (&argc, &argv); + + gtk_init (&argc, &argv); + + layout = eek_xkb_layout_new (keycodes, geometry, symbols); + if (layout == NULL) { + fprintf (stderr, "Failed to create layout\n"); + exit(1); + } + g_object_ref_sink (layout); + + keyboard = eek_clutter_keyboard_new (CSW, CSH); + if (keyboard == NULL) { + fprintf (stderr, "Failed to create keyboard\n"); + exit(1); + } + g_object_ref_sink (keyboard); + + eek_keyboard_set_layout (keyboard, layout); + + stage = clutter_stage_get_default (); + + clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color); + clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); + clutter_actor_get_size (CLUTTER_ACTOR(keyboard), &stage_width, &stage_height); + clutter_actor_set_size (stage, stage_width, stage_height); + + clutter_group_add (CLUTTER_GROUP(stage), CLUTTER_ACTOR(keyboard)); + + clutter_actor_show_all (stage); + + g_signal_connect (stage, + "notify::width", + G_CALLBACK (on_resize), + NULL); + + g_signal_connect (stage, + "notify::height", + G_CALLBACK (on_resize), + NULL); + + g_signal_connect (stage, + "event", + G_CALLBACK (on_event), + NULL); + + clutter_main (); + + return 0; +} diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 00000000..714e6eb1 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,28 @@ +# Copyright (C) 2010 Daiki Ueno +# Copyright (C) 2010 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +INCLUDES = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(SIMPLE_CFLAGS) $(XKB_CFLAGS) + +TESTS = eek-simple-test eek-xkb-test +noinst_PROGRAMS = $(TESTS) + +eek_simple_test_SOURCES = eek-simple-test.c +eek_simple_test_LDADD = $(top_builddir)/eek/libeek.la + +eek_xkb_test_SOURCES = eek-xkb-test.c +eek_xkb_test_LDADD = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkb.la \ No newline at end of file diff --git a/tests/eek-simple-test.c b/tests/eek-simple-test.c new file mode 100644 index 00000000..be15f492 --- /dev/null +++ b/tests/eek-simple-test.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include "eek-simple-keyboard.h" + +static void +test_create (void) +{ + EekKeyboard *keyboard; + EekSection *section; + EekKey *key; + + EekOutline outline = {45.0, NULL, 0}; + EekBounds bounds = {0.1, 0.2, 3.0, 4.0}; + EekKeysymMatrix *matrix; + GValue value = {0}; + gint iv; + const gchar *sv; + gpointer bv; + guint keysyms[] = {'a', 'b', 'c', 'd', 'e', 'f'}; + + keyboard = eek_simple_keyboard_new (); + g_assert (keyboard); + g_assert (g_object_is_floating (keyboard)); + + section = eek_keyboard_create_section (keyboard, + "test-section", + 45, + &bounds); + g_assert (section); + g_value_init (&value, G_TYPE_STRING); + g_object_get_property (G_OBJECT(section), "name", &value); + sv = g_value_get_string (&value); + g_assert_cmpstr (sv, ==, "test-section"); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_INT); + g_object_get_property (G_OBJECT(section), "angle", &value); + iv = g_value_get_int (&value); + g_assert_cmpint (iv, ==, 45); + g_value_unset (&value); + + g_value_init (&value, EEK_TYPE_BOUNDS); + g_object_get_property (G_OBJECT(section), "bounds", &value); + bv = g_value_get_boxed (&value); + g_assert (bv); + g_assert_cmpfloat (((EekBounds *)bv)->x, ==, 0.1); + g_value_unset (&value); + + key = eek_section_create_key (section, + "test-key", + keysyms, + 3, + 2, + 1, + 2, + &outline, + &bounds); + g_assert (key); + g_value_init (&value, EEK_TYPE_KEYSYM_MATRIX); + g_object_get_property (G_OBJECT(key), "keysyms", &value); + matrix = g_value_get_boxed (&value); + g_assert_cmpint (matrix->data[0], ==, 'a'); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_POINTER); + g_object_get_property (G_OBJECT(key), "outline", &value); + bv = g_value_get_pointer (&value); + g_assert (bv == &outline); + g_value_unset (&value); + g_object_unref (keyboard); +} + +int +main (int argc, char **argv) +{ + g_type_init (); + g_test_init (&argc, &argv, NULL); + g_test_add_func ("/eek-simple-test/create", test_create); + return g_test_run (); +} diff --git a/tests/eek-xkb-test.c b/tests/eek-xkb-test.c new file mode 100644 index 00000000..f74d223b --- /dev/null +++ b/tests/eek-xkb-test.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Daiki Ueno + * Copyright (C) 2010 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include "eek-xkb.h" + +static void +test_create (void) +{ + EekLayout *layout; + const gchar *keycodes, *geometry, *symbols; + + layout = eek_xkb_layout_new (NULL, "winbook", NULL); + g_assert (layout); + keycodes = eek_xkb_layout_get_keycodes (EEK_XKB_LAYOUT(layout)); + g_assert (keycodes); + geometry = eek_xkb_layout_get_geometry (EEK_XKB_LAYOUT(layout)); + g_assert (geometry); + symbols = eek_xkb_layout_get_symbols (EEK_XKB_LAYOUT(layout)); + g_assert (symbols); + eek_xkb_layout_set_geometry (EEK_XKB_LAYOUT(layout), "winbook"); + geometry = eek_xkb_layout_get_geometry (EEK_XKB_LAYOUT(layout)); + g_assert_cmpstr (geometry, ==, "winbook"); + g_object_unref (layout); +} + +int +main (int argc, char **argv) +{ + g_type_init (); + g_test_init (&argc, &argv, NULL); + gtk_init (&argc, &argv); + g_test_add_func ("/eek-xkb-test/create", test_create); + return g_test_run (); +}