From bfbf55700091bb6084b3cbe151a762816db0e3f0 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Wed, 11 Apr 2012 03:12:40 +0200 Subject: initial import --- COPYING | 503 ++++++++ IMdkit/FrameMgr.c | 2467 +++++++++++++++++++++++++++++++++++++ IMdkit/FrameMgr.h | 131 ++ IMdkit/IMConn.c | 176 +++ IMdkit/IMMethod.c | 65 + IMdkit/IMValues.c | 124 ++ IMdkit/IMdkit.h | 144 +++ IMdkit/Makefile | 23 + IMdkit/Xi18n.h | 507 ++++++++ IMdkit/Xi18nX.h | 52 + IMdkit/XimFunc.h | 72 ++ IMdkit/XimProto.h | 230 ++++ IMdkit/Xtrans.h | 470 +++++++ IMdkit/i18nAttr.c | 175 +++ IMdkit/i18nClbk.c | 513 ++++++++ IMdkit/i18nIMProto.c | 773 ++++++++++++ IMdkit/i18nIc.c | 1106 +++++++++++++++++ IMdkit/i18nMethod.c | 1151 +++++++++++++++++ IMdkit/i18nPtHdr.c | 1911 ++++++++++++++++++++++++++++ IMdkit/i18nUtil.c | 277 +++++ IMdkit/i18nX.c | 520 ++++++++ IMdkit/libimdkit.a | Bin 0 -> 612988 bytes Makefile | 44 + context.c | 644 ++++++++++ context.h | 35 + main.c | 148 +++ meego/Makefile | 27 + meego/debug.h | 20 + meego/glue.h | 558 +++++++++ meego/meego-im-client.xml | 78 ++ meego/meego-im-connector.c | 111 ++ meego/meego-im-connector.h | 27 + meego/meego-im-defs.h | 91 ++ meego/meego-im-proxy-glue.h | 590 +++++++++ meego/meego-im-proxy.c | 328 +++++ meego/meego-im-proxy.h | 82 ++ meego/meego-imcontext-dbus-glue.h | 491 ++++++++ meego/meego-imcontext-dbus.c | 225 ++++ meego/meego-imcontext-dbus.h | 78 ++ meego/meego-imcontext-dbus.xml | 71 ++ meego/qt-keysym-map.cpp | 542 ++++++++ meego/qt-keysym-map.h | 13 + meego/qt-translate.cpp | 195 +++ meego/qt-translate.h | 34 + meego/src.pro | 71 ++ mimclient.c | 81 ++ mimclient.h | 8 + test.c | 200 +++ ximserver.c | 158 +++ ximserver.h | 17 + xmim.h | 15 + xmimd.config | 1 + xmimd.creator | 1 + xmimd.files | 47 + xmimd.includes | 6 + 55 files changed, 16427 insertions(+) create mode 100644 COPYING create mode 100644 IMdkit/FrameMgr.c create mode 100644 IMdkit/FrameMgr.h create mode 100644 IMdkit/IMConn.c create mode 100644 IMdkit/IMMethod.c create mode 100644 IMdkit/IMValues.c create mode 100644 IMdkit/IMdkit.h create mode 100644 IMdkit/Makefile create mode 100644 IMdkit/Xi18n.h create mode 100644 IMdkit/Xi18nX.h create mode 100644 IMdkit/XimFunc.h create mode 100644 IMdkit/XimProto.h create mode 100644 IMdkit/Xtrans.h create mode 100644 IMdkit/i18nAttr.c create mode 100644 IMdkit/i18nClbk.c create mode 100644 IMdkit/i18nIMProto.c create mode 100644 IMdkit/i18nIc.c create mode 100644 IMdkit/i18nMethod.c create mode 100644 IMdkit/i18nPtHdr.c create mode 100644 IMdkit/i18nUtil.c create mode 100644 IMdkit/i18nX.c create mode 100644 IMdkit/libimdkit.a create mode 100644 Makefile create mode 100644 context.c create mode 100644 context.h create mode 100644 main.c create mode 100644 meego/Makefile create mode 100644 meego/debug.h create mode 100644 meego/glue.h create mode 100644 meego/meego-im-client.xml create mode 100644 meego/meego-im-connector.c create mode 100644 meego/meego-im-connector.h create mode 100644 meego/meego-im-defs.h create mode 100644 meego/meego-im-proxy-glue.h create mode 100644 meego/meego-im-proxy.c create mode 100644 meego/meego-im-proxy.h create mode 100644 meego/meego-imcontext-dbus-glue.h create mode 100644 meego/meego-imcontext-dbus.c create mode 100644 meego/meego-imcontext-dbus.h create mode 100644 meego/meego-imcontext-dbus.xml create mode 100644 meego/qt-keysym-map.cpp create mode 100644 meego/qt-keysym-map.h create mode 100644 meego/qt-translate.cpp create mode 100644 meego/qt-translate.h create mode 100644 meego/src.pro create mode 100644 mimclient.c create mode 100644 mimclient.h create mode 100644 test.c create mode 100644 ximserver.c create mode 100644 ximserver.h create mode 100644 xmim.h create mode 100644 xmimd.config create mode 100644 xmimd.creator create mode 100644 xmimd.files create mode 100644 xmimd.includes diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..67cd97b --- /dev/null +++ b/COPYING @@ -0,0 +1,503 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/IMdkit/FrameMgr.c b/IMdkit/FrameMgr.c new file mode 100644 index 0000000..f50684b --- /dev/null +++ b/IMdkit/FrameMgr.c @@ -0,0 +1,2467 @@ +/****************************************************************** +Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts, + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + Author: Hiroyuki Miyamoto Digital Equipment Corporation + miyamoto@jrd.dec.com + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include +#include "FrameMgr.h" + +/* Convenient macro */ + +#define _UNIT(n) ((int)(n) & 0xFF) +#define _NUMBER(n) (((int)(n) >> 8) & 0xFF) + +/* For byte swapping */ + +#define Swap16(p, n) ((p)->byte_swap ? \ +(((n) << 8 & 0xFF00) | \ + ((n) >> 8 & 0xFF) \ +) : n) +#define Swap32(p, n) ((p)->byte_swap ? \ + (((n) << 24 & 0xFF000000) | \ + ((n) << 8 & 0xFF0000) | \ + ((n) >> 8 & 0xFF00) | \ + ((n) >> 24 & 0xFF) \ + ) : n) +#define Swap64(p, n) ((p)->byte_swap ? \ + (((n) << 56 & 0xFF00000000000000) | \ + ((n) << 40 & 0xFF000000000000) | \ + ((n) << 24 & 0xFF0000000000) | \ + ((n) << 8 & 0xFF00000000) | \ + ((n) >> 8 & 0xFF000000) | \ + ((n) >> 24 & 0xFF0000) | \ + ((n) >> 40 & 0xFF00) | \ + ((n) >> 56 & 0xFF) \ + ) : n) + +/* Type definition */ + +typedef struct _Iter *Iter; + +typedef struct _FrameInst *FrameInst; + +typedef union +{ + int num; /* For BARRAY */ + FrameInst fi; /* For POINTER */ + Iter iter; /* For ITER */ +} ExtraDataRec, *ExtraData; + +typedef struct _Chain +{ + ExtraDataRec d; + int frame_no; + struct _Chain *next; +} ChainRec, *Chain; + +typedef struct _ChainMgr +{ + Chain top; + Chain tail; +} ChainMgrRec, *ChainMgr; + +typedef struct _ChainIter +{ + Chain cur; +} ChainIterRec, *ChainIter; + +typedef struct _FrameIter +{ + Iter iter; + Bool counting; + unsigned int counter; + int end; + struct _FrameIter* next; +} FrameIterRec, *FrameIter; + +typedef struct _FrameInst +{ + XimFrame template; + ChainMgrRec cm; + int cur_no; +} FrameInstRec; + +typedef void (*IterStartWatchProc) (Iter it, void *client_data); + +typedef struct _Iter +{ + XimFrame template; + int max_count; + Bool allow_expansion; + ChainMgrRec cm; + int cur_no; + IterStartWatchProc start_watch_proc; + void *client_data; + Bool start_counter; +} IterRec; + +typedef struct _FrameMgr +{ + XimFrame frame; + FrameInst fi; + char *area; + int idx; + Bool byte_swap; + int total_size; + FrameIter iters; +} FrameMgrRec; + +typedef union +{ + int num; /* For BARRAY and PAD */ + struct + { /* For COUNTER_* */ + Iter iter; + Bool is_byte_len; + } counter; +} XimFrameTypeInfoRec, *XimFrameTypeInfo; + +/* Special values */ +#define NO_VALUE -1 +#define NO_VALID_FIELD -2 + +static FrameInst FrameInstInit(XimFrame frame); +static void FrameInstFree(FrameInst fi); +static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info); +static XimFrameType FrameInstPeekNextType(FrameInst fi, XimFrameTypeInfo info); +static FmStatus FrameInstSetSize(FrameInst fi, int num); +static FmStatus FrameInstSetIterCount(FrameInst fi, int num); +static int FrameInstGetTotalSize(FrameInst fi); +static void FrameInstReset(FrameInst fi); + +static Iter IterInit(XimFrame frame, int count); +static void IterFree(Iter it); +static int FrameInstGetSize(FrameInst fi); +static int IterGetSize(Iter it); +static XimFrameType IterGetNextType(Iter it, XimFrameTypeInfo info); +static XimFrameType IterPeekNextType(Iter it, XimFrameTypeInfo info); +static FmStatus IterSetSize(Iter it, int num); +static FmStatus IterSetIterCount(Iter it, int num); +static int IterGetTotalSize(Iter it); +static void IterReset(Iter it); +static Bool IterIsLoopEnd(Iter it, Bool* myself); +static void IterSetStartWatch(Iter it, IterStartWatchProc proc, void* client_data); +static void _IterStartWatch(Iter it, void* client_data); + +static ExtraData ChainMgrGetExtraData(ChainMgr cm, int frame_no); +static ExtraData ChainMgrSetData(ChainMgr cm, int frame_no, + ExtraDataRec data); +static Bool ChainIterGetNext(ChainIter ci, int* frame_no, ExtraData d); +static int _FrameInstIncrement(XimFrame frame, int count); +static int _FrameInstDecrement(XimFrame frame, int count); +static int _FrameInstGetItemSize(FrameInst fi, int cur_no); +static Bool FrameInstIsIterLoopEnd(FrameInst fi); + +static FrameIter _FrameMgrAppendIter(FrameMgr fm, Iter it, int end); +static FrameIter _FrameIterCounterIncr(FrameIter fitr, int i); +static void _FrameMgrRemoveIter(FrameMgr fm, FrameIter it); +static Bool _FrameMgrIsIterLoopEnd(FrameMgr fm); +static Bool _FrameMgrProcessPadding(FrameMgr fm, FmStatus* status); + +#define IterGetIterCount(it) ((it)->allow_expansion ? \ +NO_VALUE : (it)->max_count) + +#define IterFixIteration(it) ((it)->allow_expansion = False) + +#define IterSetStarter(it) ((it)->start_counter = True) + +#define ChainMgrInit(cm) (cm)->top = (cm)->tail = NULL +#define ChainMgrFree(cm) \ +{ \ + Chain tmp; \ + Chain cur = (cm)->top; \ + \ + while (cur) \ + { \ + tmp = cur->next; \ + Xfree (cur); \ + cur = tmp; \ + } \ +} + +#define ChainIterInit(ci, cm) \ +{ \ + (ci)->cur = (cm)->top; \ +} + +/* ChainIterFree has nothing to do. */ +#define ChainIterFree(ci) + +#define FrameInstIsEnd(fi) ((fi)->template[(fi)->cur_no].type == EOL) + +FrameMgr FrameMgrInit (XimFrame frame, char* area, Bool byte_swap) +{ + FrameMgr fm; + + fm = (FrameMgr) Xmalloc (sizeof (FrameMgrRec)); + + fm->frame = frame; + fm->fi = FrameInstInit (frame); + fm->area = (char *) area; + fm->idx = 0; + fm->byte_swap = byte_swap; + fm->total_size = NO_VALUE; + fm->iters = NULL; + + return fm; +} + +void FrameMgrInitWithData (FrameMgr fm, + XimFrame frame, + void * area, + Bool byte_swap) +{ + fm->frame = frame; + fm->fi = FrameInstInit (frame); + fm->area = (char *) area; + fm->idx = 0; + fm->byte_swap = byte_swap; + fm->total_size = NO_VALUE; +} + +void FrameMgrFree (FrameMgr fm) +{ + FrameIter p, cur; + + p = fm->iters; + cur = p; + + while (p) + { + p = p->next; + Xfree (cur); + cur = p; + } + /*endwhile*/ + + FrameInstFree (fm->fi); + Xfree (fm); +} + +FmStatus FrameMgrSetBuffer (FrameMgr fm, void* area) +{ + if (fm->area) + return FmBufExist; + fm->area = (char *) area; + return FmSuccess; +} + +FmStatus _FrameMgrPutToken (FrameMgr fm, void *data, int data_size) +{ + XimFrameType type; + XimFrameTypeInfoRec info; + + if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size) + return FmNoMoreData; + /*endif*/ + + type = FrameInstGetNextType(fm->fi, &info); + + if (type & COUNTER_MASK) + { + unsigned long input_length; + + if (info.counter.is_byte_len) + { + if ((input_length = IterGetTotalSize (info.counter.iter)) + == NO_VALUE) + { + return FmCannotCalc; + } + /*endif*/ + } + else + { + if ((input_length = IterGetIterCount (info.counter.iter)) + == NO_VALUE) + { + return FmCannotCalc; + } + /*endif*/ + } + /*endif*/ + switch (type) + { + case COUNTER_BIT8: + *(CARD8 *) (fm->area + fm->idx) = input_length; + fm->idx++; + break; + + case COUNTER_BIT16: + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, input_length); + fm->idx += 2; + break; + + case COUNTER_BIT32: + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, input_length); + fm->idx += 4; + break; + +#if defined(_NEED64BIT) + case COUNTER_BIT64: + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, input_length); + fm->idx += 8; + break; +#endif + default: + break; + } + /*endswitch*/ + _FrameMgrPutToken(fm, data, data_size); + return FmSuccess; + } + /*endif*/ + + switch (type) + { + case BIT8: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD8 *) (fm->area + fm->idx) = num; + } + else + { + ; /* Should never be reached */ + } + /*endif*/ + fm->idx++; + return FmSuccess; + + case BIT16: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD16*)(fm->area + fm->idx) = Swap16 (fm, num); + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num); + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num); + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD16 *) (fm->area + fm->idx) = Swap16 (fm, num); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 2; + return FmSuccess; + + case BIT32: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD32 *) (fm->area + fm->idx) = Swap32 (fm, num); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 4; + return FmSuccess; + +#if defined(_NEED64BIT) + case BIT64: + if (data_size == sizeof (unsigned char)) + { + unsigned long num = *(unsigned char *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else if (data_size == sizeof (unsigned short)) + { + unsigned long num = *(unsigned short *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else if (data_size == sizeof (unsigned int)) + { + unsigned long num = *(unsigned int *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else if (data_size == sizeof (unsigned long)) + { + unsigned long num = *(unsigned long *) data; + *(CARD64 *) (fm->area + fm->idx) = Swap64 (fm, num); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 4; + return FmSuccess; +#endif + + case BARRAY: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + if (info.num > 0) + { + memcpy(fm->area + fm->idx, *(char **) data, info.num); + fm->idx += info.num; + } + /*endif*/ + return FmSuccess; + + case PADDING: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + return _FrameMgrPutToken(fm, data, data_size); + + case ITER: + return FmInvalidCall; + + case EOL: + return FmEOD; + default: + break; + } + /*endswitch*/ + return (FmStatus) NULL; /* Should never be reached */ +} + +FmStatus _FrameMgrGetToken (FrameMgr fm , void* data, int data_size) +{ + XimFrameType type; + static XimFrameTypeInfoRec info; /* memory */ + FrameIter fitr; + + if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size) + return FmNoMoreData; + /*endif*/ + + type = FrameInstGetNextType(fm->fi, &info); + + if (type & COUNTER_MASK) + { + int end=0; + FrameIter client_data; + + type &= ~COUNTER_MASK; + switch (type) + { + case BIT8: + end = *(CARD8 *) (fm->area + fm->idx); + break; + + case BIT16: + end = Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + break; + + case BIT32: + end = Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + break; + +#if defined(_NEED64BIT) + case BIT64: + end = Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + break; +#endif + default: + break; + } + /*endswitch*/ + + if ((client_data = _FrameMgrAppendIter (fm, info.counter.iter, end))) + { + IterSetStarter (info.counter.iter); + IterSetStartWatch (info.counter.iter, + _IterStartWatch, + (void *) client_data); + } + /*endif*/ + } + /*endif*/ + + type &= ~COUNTER_MASK; + switch (type) + { + case BIT8: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char*) data = *(CARD8 *) (fm->area + fm->idx); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = *(CARD8 *) (fm->area + fm->idx); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = *(CARD8 *) (fm->area + fm->idx); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = *(CARD8 *) (fm->area + fm->idx); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx++; + if ((fitr = _FrameIterCounterIncr (fm->iters, 1/*BIT8*/))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return FmSuccess; + + case BIT16: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = + Swap16 (fm, *(CARD16 *) (fm->area + fm->idx)); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 2; + if ((fitr = _FrameIterCounterIncr (fm->iters, 2/*BIT16*/))) + _FrameMgrRemoveIter(fm, fitr); + /*endif*/ + return FmSuccess; + + case BIT32: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = + Swap32 (fm, *(CARD32 *) (fm->area + fm->idx)); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 4; + if ((fitr = _FrameIterCounterIncr (fm->iters, 4/*BIT32*/))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return FmSuccess; + +#if defined(_NEED64BIT) + case BIT64: + if (data_size == sizeof (unsigned char)) + { + *(unsigned char *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned short)) + { + *(unsigned short *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned int)) + { + *(unsigned int *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else if (data_size == sizeof (unsigned long)) + { + *(unsigned long *) data = + Swap64 (fm, *(CARD64 *) (fm->area + fm->idx)); + } + else + { + ; /* Should never reached */ + } + /*endif*/ + fm->idx += 8; + if ((fitr = _FrameIterCounterIncr (fm->iters, 8/*BIT64*/))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return FmSuccess; +#endif + + case BARRAY: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + if (info.num > 0) + { + *(char **) data = fm->area + fm->idx; + + fm->idx += info.num; + if ((fitr = _FrameIterCounterIncr (fm->iters, info.num))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + } + else + { + *(char **) data = NULL; + } + /*endif*/ + return FmSuccess; + + case PADDING: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + if ((fitr = _FrameIterCounterIncr (fm->iters, info.num))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + return _FrameMgrGetToken (fm, data, data_size); + + case ITER: + return FmInvalidCall; /* if comes here, it's a bug! */ + + case EOL: + return FmEOD; + default: + break; + } + /*endswitch*/ + return (FmStatus) NULL; /* Should never be reached */ +} + +FmStatus FrameMgrSetSize (FrameMgr fm, int barray_size) +{ + if (FrameInstSetSize (fm->fi, barray_size) == FmSuccess) + return FmSuccess; + /*endif*/ + return FmNoMoreData; +} + +FmStatus FrameMgrSetIterCount (FrameMgr fm, int count) +{ + if (FrameInstSetIterCount (fm->fi, count) == FmSuccess) + return FmSuccess; + /*endif*/ + return FmNoMoreData; +} + +FmStatus FrameMgrSetTotalSize (FrameMgr fm, int total_size) +{ + fm->total_size = total_size; + return FmSuccess; +} + +int FrameMgrGetTotalSize (FrameMgr fm) +{ + return FrameInstGetTotalSize (fm->fi); +} + +int FrameMgrGetSize (FrameMgr fm) +{ + register int ret_size; + + ret_size = FrameInstGetSize (fm->fi); + if (ret_size == NO_VALID_FIELD) + return NO_VALUE; + /*endif*/ + return ret_size; +} + +FmStatus FrameMgrSkipToken (FrameMgr fm, int skip_count) +{ + XimFrameType type; + XimFrameTypeInfoRec info; + register int i; + + if (fm->total_size != NO_VALUE && fm->idx >= fm->total_size) + return FmNoMoreData; + /*endif*/ + for (i = 0; i < skip_count; i++) + { + type = FrameInstGetNextType (fm->fi, &info); + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + fm->idx++; + break; + + case BIT16: + fm->idx += 2; + break; + + case BIT32: + fm->idx += 4; + break; + + case BIT64: + fm->idx += 8; + break; + + case BARRAY: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + break; + + case PADDING: + if (info.num == NO_VALUE) + return FmInvalidCall; + /*endif*/ + fm->idx += info.num; + return FrameMgrSkipToken (fm, skip_count); + + case ITER: + return FmInvalidCall; + + case EOL: + return FmEOD; + default: + break; + } + /*endswitch*/ + } + /*endfor*/ + return FmSuccess; +} + +void FrameMgrReset (FrameMgr fm) +{ + fm->idx = 0; + FrameInstReset (fm->fi); +} + +Bool FrameMgrIsIterLoopEnd (FrameMgr fm, FmStatus* status) +{ + do + { + if (_FrameMgrIsIterLoopEnd (fm)) + return True; + /*endif*/ + } + while (_FrameMgrProcessPadding (fm, status)); + + return False; +} + + +/* Internal routines */ + +static Bool _FrameMgrIsIterLoopEnd (FrameMgr fm) +{ + return FrameInstIsIterLoopEnd (fm->fi); +} + +static Bool _FrameMgrProcessPadding (FrameMgr fm, FmStatus* status) +{ + XimFrameTypeInfoRec info; + XimFrameType next_type = FrameInstPeekNextType (fm->fi, &info); + FrameIter fitr; + + if (next_type == PADDING) + { + if (info.num == NO_VALUE) + { + *status = FmInvalidCall; + return True; + } + /*endif*/ + next_type = FrameInstGetNextType (fm->fi, &info); + fm->idx += info.num; + if ((fitr = _FrameIterCounterIncr (fm->iters, info.num))) + _FrameMgrRemoveIter (fm, fitr); + /*endif*/ + *status = FmSuccess; + return True; + } + /*endif*/ + *status = FmSuccess; + return False; +} + +static FrameInst FrameInstInit (XimFrame frame) +{ + FrameInst fi; + + fi = (FrameInst) Xmalloc (sizeof (FrameInstRec)); + + fi->template = frame; + fi->cur_no = 0; + ChainMgrInit (&fi->cm); + return fi; +} + +static void FrameInstFree (FrameInst fi) +{ + ChainIterRec ci; + int frame_no; + ExtraDataRec d; + + ChainIterInit (&ci, &fi->cm); + + while (ChainIterGetNext (&ci, &frame_no, &d)) + { + register XimFrameType type; + type = fi->template[frame_no].type; + if (type == ITER) + { + if (d.iter) + IterFree (d.iter); + /*endif*/ + } + else if (type == POINTER) + { + if (d.fi) + FrameInstFree (d.fi); + /*endif*/ + } + /*endif*/ + } + /*endwhile*/ + ChainIterFree (&ci); + ChainMgrFree (&fi->cm); + Xfree (fi); +} + +static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info) +{ + XimFrameType ret_type; + + ret_type = fi->template[fi->cur_no].type; + + switch (ret_type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case EOL: + fi->cur_no = _FrameInstIncrement(fi->template, fi->cur_no); + break; + + case COUNTER_BIT8: + case COUNTER_BIT16: + case COUNTER_BIT32: + case COUNTER_BIT64: + if (info) + { + register int offset, iter_idx; + + info->counter.is_byte_len = + (((long) fi->template[fi->cur_no].data & 0xFF)) == FmCounterByte; + offset = ((long) fi->template[fi->cur_no].data) >> 8; + iter_idx = fi->cur_no + offset; + if (fi->template[iter_idx].type == ITER) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL) + { + dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, iter_idx, dr); + } + /*endif*/ + info->counter.iter = d->iter; + } + else + { + /* Should never reach here */ + } + /*endif*/ + } + /*endif*/ + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + break; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + break; + + case PADDING: + if (info) + { + register int unit; + register int number; + register int size; + register int i; + + unit = _UNIT ((long) fi->template[fi->cur_no].data); + number = _NUMBER ((long) fi->template[fi->cur_no].data); + + i = fi->cur_no; + size = 0; + while (number > 0) + { + i = _FrameInstDecrement (fi->template, i); + size += _FrameInstGetItemSize (fi, i); + number--; + } + /*endwhile*/ + info->num = (unit - (size%unit))%unit; + } + /*endif*/ + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + break; + + case ITER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = IterGetNextType (d->iter, info); + if (sub_type == EOL) + { + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + ret_type = FrameInstGetNextType (fi, info); + } + else + { + ret_type = sub_type; + } + /*endif*/ + } + break; + + case POINTER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = FrameInstGetNextType (d->fi, info); + if (sub_type == EOL) + { + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + ret_type = FrameInstGetNextType (fi, info); + } + else + { + ret_type = sub_type; + } + /*endif*/ + } + break; + default: + break; + } + /*endswitch*/ + return ret_type; +} + +static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info) +{ + XimFrameType ret_type; + + ret_type = fi->template[fi->cur_no].type; + + switch (ret_type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case EOL: + break; + + case COUNTER_BIT8: + case COUNTER_BIT16: + case COUNTER_BIT32: + case COUNTER_BIT64: + if (info) + { + register int offset; + register int iter_idx; + + info->counter.is_byte_len = + (((long) fi->template[fi->cur_no].data) & 0xFF) == FmCounterByte; + offset = ((long)fi->template[fi->cur_no].data) >> 8; + iter_idx = fi->cur_no + offset; + if (fi->template[iter_idx].type == ITER) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL) + { + dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, iter_idx, dr); + } + /*endif*/ + info->counter.iter = d->iter; + } + else + { + /* Should not be reached here */ + } + /*endif*/ + } + /*endif*/ + break; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + break; + + case PADDING: + if (info) + { + register int unit; + register int number; + register int size; + register int i; + + unit = _UNIT ((long) fi->template[fi->cur_no].data); + number = _NUMBER ((long) fi->template[fi->cur_no].data); + + i = fi->cur_no; + size = 0; + while (number > 0) + { + i = _FrameInstDecrement (fi->template, i); + size += _FrameInstGetItemSize (fi, i); + number--; + } + /*endwhile*/ + info->num = (unit - (size%unit))%unit; + } + /*endif*/ + break; + + case ITER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = IterPeekNextType (d->iter, info); + if (sub_type == EOL) + ret_type = FrameInstPeekNextType (fi, info); + else + ret_type = sub_type; + /*endif*/ + } + break; + + case POINTER: + { + ExtraData d; + ExtraDataRec dr; + XimFrameType sub_type; + + if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL) + { + dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data); + d = ChainMgrSetData (&fi->cm, fi->cur_no, dr); + } + /*endif*/ + sub_type = FrameInstPeekNextType (d->fi, info); + if (sub_type == EOL) + ret_type = FrameInstPeekNextType (fi, info); + else + ret_type = sub_type; + /*endif*/ + default: + break; + } + break; + } + /*endswitch*/ + return ret_type; +} + +static Bool FrameInstIsIterLoopEnd (FrameInst fi) +{ + Bool ret = False; + + if (fi->template[fi->cur_no].type == ITER) + { + ExtraData d = ChainMgrGetExtraData (&fi->cm, fi->cur_no); + Bool yourself; + + if (d) + { + ret = IterIsLoopEnd (d->iter, &yourself); + if (ret && yourself) + fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no); + /*endif*/ + } + /*endif*/ + } + /*endif*/ + return (ret); +} + +static FrameIter _FrameMgrAppendIter (FrameMgr fm, Iter it, int end) +{ + FrameIter p = fm->iters; + + while (p && p->next) + p = p->next; + /*endwhile*/ + + if (!p) + { + fm->iters = + p = (FrameIter) Xmalloc (sizeof (FrameIterRec)); + } + else + { + p->next = (FrameIter) Xmalloc (sizeof (FrameIterRec)); + p = p->next; + } + /*endif*/ + if (p) + { + p->iter = it; + p->counting = False; + p->counter = 0; + p->end = end; + p->next = NULL; + } + /*endif*/ + return (p); +} + +static void _FrameMgrRemoveIter (FrameMgr fm, FrameIter it) +{ + FrameIter prev; + FrameIter p; + + prev = NULL; + p = fm->iters; + while (p) + { + if (p == it) + { + if (prev) + prev->next = p->next; + else + fm->iters = p->next; + /*endif*/ + Xfree (p); + break; + } + /*endif*/ + prev = p; + p = p->next; + } + /*endwhile*/ +} + +static FrameIter _FrameIterCounterIncr (FrameIter fitr, int i) +{ + FrameIter p = fitr; + + while (p) + { + if (p->counting) + { + p->counter += i; + if (p->counter >= p->end) + { + IterFixIteration (p->iter); + return (p); + } + /*endif*/ + } + /*endif*/ + p = p->next; + } + /*endwhile*/ + return (NULL); +} + +static void _IterStartWatch (Iter it, void *client_data) +{ + FrameIter p = (FrameIter) client_data; + p->counting = True; +} + +static FmStatus FrameInstSetSize (FrameInst fi, int num) +{ + ExtraData d; + ExtraDataRec dr; + XimFrameType type; + register int i; + + i = 0; + while ((type = fi->template[i].type) != EOL) + { + switch (type) + { + case BARRAY: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.num = -1; + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + if (d->num == NO_VALUE) + { + d->num = num; + return FmSuccess; + } + /*endif*/ + break; + case ITER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.iter = IterInit (&fi->template[i + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + if (IterSetSize (d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + + case POINTER: + if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL) + { + dr.fi = FrameInstInit(fi->template[i + 1].data); + d = ChainMgrSetData(&fi->cm, i, dr); + } + /*endif*/ + if (FrameInstSetSize(d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + default: + break; + } + /*endswitch*/ + i = _FrameInstIncrement(fi->template, i); + } + /*endwhile*/ + return FmNoMoreData; +} + +static int FrameInstGetSize (FrameInst fi) +{ + XimFrameType type; + register int i; + ExtraData d; + ExtraDataRec dr; + int ret_size; + + i = fi->cur_no; + while ((type = fi->template[i].type) != EOL) + { + switch (type) + { + case BARRAY: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + return NO_VALUE; + /*endif*/ + return d->num; + + case ITER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.iter = IterInit (&fi->template[i + 1], NO_VALUE); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + ret_size = IterGetSize(d->iter); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + break; + + case POINTER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.fi = FrameInstInit (fi->template[i + 1].data); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + ret_size = FrameInstGetSize (d->fi); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + break; + default: + break; + } + /*endswitch*/ + i = _FrameInstIncrement (fi->template, i); + } + /*endwhile*/ + return NO_VALID_FIELD; +} + +static FmStatus FrameInstSetIterCount (FrameInst fi, int num) +{ + ExtraData d; + ExtraDataRec dr; + register int i; + XimFrameType type; + + i = 0; + while ((type = fi->template[i].type) != EOL) + { + switch (type) + { + case ITER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.iter = IterInit (&fi->template[i + 1], num); + (void)ChainMgrSetData (&fi->cm, i, dr); + return FmSuccess; + } + /*endif*/ + if (IterSetIterCount (d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + + case POINTER: + if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL) + { + dr.fi = FrameInstInit (fi->template[i + 1].data); + d = ChainMgrSetData (&fi->cm, i, dr); + } + /*endif*/ + if (FrameInstSetIterCount (d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + break; + + default: + break; + } + /*endswitch*/ + i = _FrameInstIncrement (fi->template, i); + } + /*endwhile*/ + return FmNoMoreData; +} + +static int FrameInstGetTotalSize (FrameInst fi) +{ + register int size; + register int i; + + size = 0; + i = 0; + + while (fi->template[i].type != EOL) + { + size += _FrameInstGetItemSize (fi, i); + i = _FrameInstIncrement (fi->template, i); + } + /*endwhile*/ + return size; +} + +static void FrameInstReset (FrameInst fi) +{ + ChainIterRec ci; + int frame_no; + ExtraDataRec d; + + ChainIterInit (&ci, &fi->cm); + + while (ChainIterGetNext (&ci, &frame_no, &d)) + { + register XimFrameType type; + type = fi->template[frame_no].type; + if (type == ITER) + { + if (d.iter) + IterReset (d.iter); + /*endif*/ + } + else if (type == POINTER) + { + if (d.fi) + FrameInstReset (d.fi); + /*endif*/ + } + /*endif*/ + } + /*endwhile*/ + ChainIterFree (&ci); + + fi->cur_no = 0; +} + +static Iter IterInit (XimFrame frame, int count) +{ + Iter it; + register XimFrameType type; + + it = (Iter) Xmalloc (sizeof (IterRec)); + it->template = frame; + it->max_count = (count == NO_VALUE) ? 0 : count; + it->allow_expansion = (count == NO_VALUE); + it->cur_no = 0; + it->start_watch_proc = NULL; + it->client_data = NULL; + it->start_counter = False; + + type = frame->type; + if (type & COUNTER_MASK) + { + /* COUNTER_XXX cannot be an item of a ITER */ + Xfree (it); + return NULL; + } + /*endif*/ + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + /* Do nothing */ + break; + + case BARRAY: + case ITER: + case POINTER: + ChainMgrInit (&it->cm); + break; + + default: + Xfree (it); + return NULL; /* This should never occur */ + } + /*endswitch*/ + return it; +} + +static void IterFree (Iter it) +{ + switch (it->template->type) + { + case BARRAY: + ChainMgrFree (&it->cm); + break; + + case ITER: + { + ChainIterRec ci; + int count; + ExtraDataRec d; + + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &d)) + IterFree (d.iter); + /*endwhile*/ + ChainIterFree (&ci); + ChainMgrFree (&it->cm); + } + break; + + case POINTER: + { + ChainIterRec ci; + int count; + ExtraDataRec dr; + + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &dr)) + FrameInstFree (dr.fi); + /*endwhile*/ + ChainIterFree (&ci); + ChainMgrFree (&it->cm); + } + break; + + default: + break; + } + /*endswitch*/ + Xfree (it); +} + +static Bool IterIsLoopEnd (Iter it, Bool *myself) +{ + Bool ret = False; + *myself = False; + + if (!it->allow_expansion && (it->cur_no == it->max_count)) + { + *myself = True; + return True; + } + /*endif*/ + + if (it->template->type == POINTER) + { + ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no); + if (d) + { + if (FrameInstIsIterLoopEnd (d->fi)) + { + ret = True; + } + else + { + if (FrameInstIsEnd (d->fi)) + { + it->cur_no++; + if (!it->allow_expansion && it->cur_no == it->max_count) + { + *myself = True; + ret = True; + } + /*endif*/ + } + /*endif*/ + } + /*endif*/ + } + /*endif*/ + } + else if (it->template->type == ITER) + { + ExtraData d = ChainMgrGetExtraData (&it->cm, it->cur_no); + if (d) + { + Bool yourself; + + if (IterIsLoopEnd (d->iter, &yourself)) + ret = True; + /*endif*/ + } + /*endif*/ + } + /*endif*/ + + return ret; +} + +static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info) +{ + XimFrameType type = it->template->type; + + if (it->start_counter) + { + (*it->start_watch_proc) (it, it->client_data); + it->start_counter = False; + } + /*endif*/ + if (it->cur_no >= it->max_count) + { + if (it->allow_expansion) + it->max_count = it->cur_no + 1; + else + return EOL; + /*endif*/ + } + /*endif*/ + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + it->cur_no++; + return type; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + it->cur_no++; + return BARRAY; + + case ITER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = IterGetNextType (d->iter, info); + if (ret_type == EOL) + { + it->cur_no++; + ret_type = IterGetNextType (it, info); + } + /*endif*/ + return ret_type; + } + + case POINTER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = FrameInstGetNextType (d->fi, info); + if (ret_type == EOL) + { + it->cur_no++; + ret_type = IterGetNextType (it, info); + } + /*endif*/ + return ret_type; + } + + default: + return (XimFrameType) NULL; + } + /*endswitch*/ + return (XimFrameType) NULL; /* This should never occur */ +} + +static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info) +{ + XimFrameType type = it->template->type; + + if (!it->allow_expansion && it->cur_no >= it->max_count) + return (EOL); + /*endif*/ + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + return type; + + case BARRAY: + if (info) + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + info->num = NO_VALUE; + else + info->num = d->num; + /*endif*/ + } + /*endif*/ + return BARRAY; + + case ITER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = IterPeekNextType (d->iter, info); + if (ret_type == EOL) + ret_type = IterPeekNextType (it, info); + /*endif*/ + return ret_type; + } + + case POINTER: + { + XimFrameType ret_type; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, it->cur_no, dr); + } + /*endif*/ + + ret_type = FrameInstPeekNextType (d->fi, info); + if (ret_type == EOL) + ret_type = IterPeekNextType (it, info); + /*endif*/ + return (ret_type); + } + + default: + break; + } + /*endswitch*/ + /* Reaching here is a bug! */ + return (XimFrameType) NULL; +} + +static FmStatus IterSetSize (Iter it, int num) +{ + XimFrameType type; + register int i; + + if (!it->allow_expansion && it->max_count == 0) + return FmNoMoreData; + /*endif*/ + + type = it->template->type; + switch (type) + { + case BARRAY: + { + ExtraData d; + ExtraDataRec dr; + + for (i = 0; i < it->max_count; i++) + { + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.num = NO_VALUE; + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (d->num == NO_VALUE) + { + d->num = num; + return FmSuccess; + } + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.num = num; + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + return FmSuccess; + } + /*endif*/ + } + return FmNoMoreData; + + case ITER: + { + ExtraData d; + ExtraDataRec dr; + + for (i = 0; i < it->max_count; i++) + { + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (IterSetSize (d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.iter = IterInit (it->template + 1, NO_VALUE); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + if (IterSetSize(dr.iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endif*/ + } + return FmNoMoreData; + + case POINTER: + { + ExtraData d; + ExtraDataRec dr; + + for (i = 0; i < it->max_count; i++) + { + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (FrameInstSetSize (d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.fi = FrameInstInit (it->template[1].data); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + if (FrameInstSetSize (dr.fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endif*/ + } + return FmNoMoreData; + + default: + break; + } + /*endswitch*/ + return FmNoMoreData; +} + +static int IterGetSize (Iter it) +{ + register int i; + ExtraData d; + ExtraDataRec dr; + + if (it->cur_no >= it->max_count) + return NO_VALID_FIELD; + /*endif*/ + + switch (it->template->type) + { + case BARRAY: + if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + return d->num; + + case ITER: + for (i = it->cur_no; i < it->max_count; i++) + { + int ret_size; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.iter = IterInit (it->template + 1, NO_VALUE); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + ret_size = IterGetSize (d->iter); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + } + /*endfor*/ + return NO_VALID_FIELD; + + case POINTER: + for (i = it->cur_no; i < it->max_count; i++) + { + int ret_size; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + ret_size = FrameInstGetSize (d->fi); + if (ret_size != NO_VALID_FIELD) + return ret_size; + /*endif*/ + } + /*endfor*/ + return NO_VALID_FIELD; + + default: + break; + } + /*endswitch*/ + return NO_VALID_FIELD; +} + +static FmStatus IterSetIterCount (Iter it, int num) +{ + register int i; + + if (it->allow_expansion) + { + it->max_count = num; + it->allow_expansion = False; + return FmSuccess; + } + /*endif*/ + + if (it->max_count == 0) + return FmNoMoreData; + /*endif*/ + + switch (it->template->type) + { + case ITER: + for (i = 0; i < it->max_count; i++) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL) + { + dr.iter = IterInit(it->template + 1, num); + (void)ChainMgrSetData(&it->cm, i, dr); + return FmSuccess; + } + /*endif*/ + if (IterSetIterCount(d->iter, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.iter = IterInit (it->template + 1, num); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + return FmSuccess; + } + /*endif*/ + break; + + case POINTER: + for (i = 0; i < it->max_count; i++) + { + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if (FrameInstSetIterCount (d->fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endfor*/ + if (it->allow_expansion) + { + ExtraDataRec dr; + + dr.fi = FrameInstInit (it->template[1].data); + ChainMgrSetData (&it->cm, it->max_count, dr); + it->max_count++; + + if (FrameInstSetIterCount (dr.fi, num) == FmSuccess) + return FmSuccess; + /*endif*/ + } + /*endif*/ + break; + + default: + break; + } + /*endswitch*/ + return FmNoMoreData; +} + +static int IterGetTotalSize (Iter it) +{ + register int size, i; + XimFrameType type; + + if (it->allow_expansion) + return NO_VALUE; + /*endif*/ + if (it->max_count == 0) + return 0; + /*endif*/ + + size = 0; + type = it->template->type; + + switch (type) + { + case BIT8: + size = it->max_count; + break; + + case BIT16: + size = it->max_count*2; + break; + + case BIT32: + size = it->max_count*4; + break; + + case BIT64: + size = it->max_count*8; + break; + + case BARRAY: + for (i = 0; i < it->max_count; i++) + { + register int num; + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + return NO_VALUE; + /*endif*/ + if ((num = d->num) == NO_VALUE) + return NO_VALUE; + /*endif*/ + size += num; + } + /*endfor*/ + break; + + case ITER: + for (i = 0; i < it->max_count; i++) + { + register int num; + ExtraData d; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + return NO_VALUE; + /*endif*/ + if ((num = IterGetTotalSize (d->iter)) == NO_VALUE) + return NO_VALUE; + /*endif*/ + size += num; + } + /*endfor*/ + break; + + case POINTER: + for (i = 0; i < it->max_count; i++) + { + register int num; + ExtraData d; + ExtraDataRec dr; + + if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL) + { + dr.fi = FrameInstInit (it->template[1].data); + d = ChainMgrSetData (&it->cm, i, dr); + } + /*endif*/ + if ((num = FrameInstGetTotalSize (d->fi)) == NO_VALUE) + return NO_VALUE; + /*endif*/ + size += num; + } + /*endfor*/ + break; + + default: + break; + } + /*endswitch*/ + return size; +} + +static void IterReset (Iter it) +{ + ChainIterRec ci; + int count; + ExtraDataRec d; + + switch (it->template->type) + { + case ITER: + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &d)) + IterReset (d.iter); + /*endwhile*/ + ChainIterFree (&ci); + break; + + case POINTER: + ChainIterInit (&ci, &it->cm); + while (ChainIterGetNext (&ci, &count, &d)) + FrameInstReset (d.fi); + /*endwhile*/ + ChainIterFree (&ci); + break; + + default: + break; + } + /*endswitch*/ + it->cur_no = 0; +} + +static void IterSetStartWatch (Iter it, + IterStartWatchProc proc, + void *client_data) +{ + it->start_watch_proc = proc; + it->client_data = client_data; +} + +static ExtraData ChainMgrSetData (ChainMgr cm, + int frame_no, + ExtraDataRec data) +{ + Chain cur = (Chain) Xmalloc (sizeof (ChainRec)); + + cur->frame_no = frame_no; + cur->d = data; + cur->next = NULL; + + if (cm->top == NULL) + { + cm->top = cm->tail = cur; + } + else + { + cm->tail->next = cur; + cm->tail = cur; + } + /*endif*/ + return &cur->d; +} + +static ExtraData ChainMgrGetExtraData (ChainMgr cm, int frame_no) +{ + Chain cur; + + cur = cm->top; + + while (cur) + { + if (cur->frame_no == frame_no) + return &cur->d; + /*endif*/ + cur = cur->next; + } + /*endwhile*/ + return NULL; +} + +static Bool ChainIterGetNext (ChainIter ci, int *frame_no, ExtraData d) +{ + if (ci->cur == NULL) + return False; + /*endif*/ + + *frame_no = ci->cur->frame_no; + *d = ci->cur->d; + + ci->cur = ci->cur->next; + + return True; +} + +static int _FrameInstIncrement (XimFrame frame, int count) +{ + XimFrameType type; + + type = frame[count].type; + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case BARRAY: + case PADDING: + return count + 1; + + case POINTER: + return count + 2; + + case ITER: + return _FrameInstIncrement (frame, count + 1); + default: + break; + } + /*endswitch*/ + return - 1; /* Error */ +} + +static int _FrameInstDecrement (XimFrame frame, int count) +{ + register int i; + XimFrameType type; + + if (count == 0) + return - 1; /* cannot decrement */ + /*endif*/ + + if (count == 1) + return 0; /* BOGUS - It should check the contents of data */ + /*endif*/ + + type = frame[count - 2].type; + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + case BIT16: + case BIT32: + case BIT64: + case BARRAY: + case PADDING: + case PTR_ITEM: + return count - 1; + + case POINTER: + case ITER: + i = count - 3; + while (i >= 0) + { + if (frame[i].type != ITER) + return i + 1; + /*endif*/ + i--; + } + /*endwhile*/ + return 0; + default: + break; + } + /*enswitch*/ + return - 1; /* Error */ +} + +static int _FrameInstGetItemSize (FrameInst fi, int cur_no) +{ + XimFrameType type; + + type = fi->template[cur_no].type; + type &= ~COUNTER_MASK; + + switch (type) + { + case BIT8: + return 1; + + case BIT16: + return 2; + + case BIT32: + return 4; + + case BIT64: + return 8; + + case BARRAY: + { + ExtraData d; + + if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + if (d->num == NO_VALUE) + return NO_VALUE; + /*endif*/ + return d->num; + } + + case PADDING: + { + register int unit; + register int number; + register int size; + register int i; + + unit = _UNIT ((long) fi->template[cur_no].data); + number = _NUMBER ((long) fi->template[cur_no].data); + + i = cur_no; + size = 0; + while (number > 0) + { + i = _FrameInstDecrement (fi->template, i); + size += _FrameInstGetItemSize (fi, i); + number--; + } + /*endwhile*/ + size = (unit - (size%unit))%unit; + return size; + } + + case ITER: + { + ExtraData d; + int sub_size; + + if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + sub_size = IterGetTotalSize (d->iter); + if (sub_size == NO_VALUE) + return NO_VALUE; + /*endif*/ + return sub_size; + } + + case POINTER: + { + ExtraData d; + int sub_size; + + if ((d = ChainMgrGetExtraData (&fi->cm, cur_no)) == NULL) + return NO_VALUE; + /*endif*/ + sub_size = FrameInstGetTotalSize (d->fi); + if (sub_size == NO_VALUE) + return NO_VALUE; + /*endif*/ + return sub_size; + } + + default: + break; + } + /*endswitch*/ + return NO_VALUE; +} diff --git a/IMdkit/FrameMgr.h b/IMdkit/FrameMgr.h new file mode 100644 index 0000000..ce7ed50 --- /dev/null +++ b/IMdkit/FrameMgr.h @@ -0,0 +1,131 @@ +/****************************************************************** +Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts, + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + Author: Hiroyuki Miyamoto Digital Equipment Corporation + miyamoto@jrd.dec.com + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef FRAMEMGR_H +#define FRAMEMGR_H + +#include +#include +#include + +#if defined(VAXC) && !defined(__DECC) +#define xim_externalref globalref +#define xim_externaldef globaldef +#else +#define xim_externalref extern +#define xim_externaldef +#endif + +/* Definitions for FrameMgr */ + +#define COUNTER_MASK 0x10 + +typedef enum +{ + BIT8 = 0x1, /* {CARD8* | INT8*} */ + BIT16 = 0x2, /* {CARD16* | INT16*} */ + BIT32 = 0x3, /* {CARD32* | INT32*} */ + BIT64 = 0x4, /* {CARD64* | INT64*} */ + BARRAY = 0x5, /* int*, void* */ + ITER = 0x6, /* int* */ + POINTER = 0x7, /* specifies next item is a PTR_ITEM */ + PTR_ITEM = 0x8, /* specifies the item has a pointer */ + /* BOGUS - POINTER and PTR_ITEM + * In the current implementation, PTR_ITEM should be lead by + * POINTER. But actually, it's just redundant logically. Someone + * may remove this redundancy and POINTER from the enum member but he + * should also modify the logic in FrameMgr program. + */ + PADDING = 0x9, /* specifies that a padding is needed. + * This requires extra data in data field. + */ + EOL = 0xA, /* specifies the end of list */ + + COUNTER_BIT8 = COUNTER_MASK | 0x1, + COUNTER_BIT16 = COUNTER_MASK | 0x2, + COUNTER_BIT32 = COUNTER_MASK | 0x3, + COUNTER_BIT64 = COUNTER_MASK | 0x4 +} XimFrameType; + +/* Convenient macro */ +#define _FRAME(a) {a, NULL} +#define _PTR(p) {PTR_ITEM, (void *)p} +/* PADDING's usage of data field + * B15-B8 : Shows the number of effective items. + * B7-B0 : Shows padding unit. ex) 04 shows 4 unit padding. + */ +#define _PAD2(n) {PADDING, (void*)((n)<<8|2)} +#define _PAD4(n) {PADDING, (void*)((n)<<8|4)} + +#define FmCounterByte 0 +#define FmCounterNumber 1 + +#define _BYTE_COUNTER(type, offset) \ + {(COUNTER_MASK|type), (void*)((offset)<<8|FmCounterByte)} + +#define _NUMBER_COUNTER(type, offset) \ + {(COUNTER_MASK|type), (void*)((offset)<<8|FmCounterNumber)} + +typedef struct _XimFrame +{ + XimFrameType type; + void* data; /* For PTR_ITEM and PADDING */ +} XimFrameRec, *XimFrame; + +typedef enum +{ + FmSuccess, + FmEOD, + FmInvalidCall, + FmBufExist, + FmCannotCalc, + FmNoMoreData +} FmStatus; + +typedef struct _FrameMgr *FrameMgr; + +FrameMgr FrameMgrInit(XimFrame frame, char* area, Bool byte_swap); +void FrameMgrInitWithData(FrameMgr fm, XimFrame frame, void* area, + Bool byte_swap); +void FrameMgrFree(FrameMgr fm); +FmStatus FrameMgrSetBuffer(FrameMgr, void*); +FmStatus _FrameMgrPutToken(FrameMgr, void*, int); +FmStatus _FrameMgrGetToken(FrameMgr, void*, int); +FmStatus FrameMgrSetSize(FrameMgr, int); +FmStatus FrameMgrSetIterCount(FrameMgr, int); +FmStatus FrameMgrSetTotalSize(FrameMgr, int); +int FrameMgrGetTotalSize(FrameMgr); +int FrameMgrGetSize(FrameMgr); +FmStatus FrameMgrSkipToken(FrameMgr, int); +void FrameMgrReset(FrameMgr); +Bool FrameMgrIsIterLoopEnd(FrameMgr, FmStatus*); + +#define FrameMgrPutToken(fm, obj) _FrameMgrPutToken((fm), &(obj), sizeof(obj)) +#define FrameMgrGetToken(fm, obj) _FrameMgrGetToken((fm), &(obj), sizeof(obj)) + +#endif /* FRAMEMGR_H */ diff --git a/IMdkit/IMConn.c b/IMdkit/IMConn.c new file mode 100644 index 0000000..6d36589 --- /dev/null +++ b/IMdkit/IMConn.c @@ -0,0 +1,176 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include +#include "IMdkit.h" +#include + +#define Va_start(a,b) va_start(a,b) + +static void _IMCountVaList(va_list var, int *total_count) +{ + char *attr; + + *total_count = 0; + + for (attr = va_arg (var, char*); attr; attr = va_arg (var, char*)) + { + (void)va_arg (var, XIMArg *); + ++(*total_count); + } + /*endfor*/ +} + +static void _IMVaToNestedList(va_list var, int max_count, XIMArg **args_return) +{ + XIMArg *args; + char *attr; + + if (max_count <= 0) + { + *args_return = (XIMArg *) NULL; + return; + } + /*endif*/ + + args = (XIMArg *) malloc ((unsigned) (max_count + 1)*sizeof (XIMArg)); + *args_return = args; + if (!args) + return; + /*endif*/ + + for (attr = va_arg (var, char*); attr; attr = va_arg (var, char *)) + { + args->name = attr; + args->value = va_arg (var, XPointer); + args++; + } + /*endfor*/ + args->name = (char*)NULL; +} + +static char *_FindModifiers (XIMArg *args) +{ + char *modifiers; + + while (args->name) + { + if (strcmp (args->name, IMModifiers) == 0) + { + modifiers = args->value; + return modifiers; + } + else + { + args++; + } + /*endif*/ + } + /*endwhile*/ + return NULL; +} + +XIMS _GetIMS (char *modifiers) +{ + XIMS ims; + extern IMMethodsRec Xi18n_im_methods; + + if ((ims = (XIMS) malloc (sizeof (XIMProtocolRec))) == (XIMS) NULL) + return ((XIMS) NULL); + /*endif*/ + memset ((void *) ims, 0, sizeof (XIMProtocolRec)); + + if (modifiers == NULL + || + modifiers[0] == '\0' + || + strcmp (modifiers, "Xi18n") == 0) + { + ims->methods = &Xi18n_im_methods; + return ims; + } + /*endif*/ + XFree (ims); + return (XIMS) NULL; +} + +XIMS IMOpenIM (Display *display, ...) +{ + va_list var; + int total_count; + XIMArg *args; + XIMS ims; + char *modifiers; + Status ret; + + Va_start (var, display); + _IMCountVaList (var, &total_count); + va_end (var); + + Va_start (var, display); + _IMVaToNestedList (var, total_count, &args); + va_end (var); + + modifiers = _FindModifiers (args); + + ims = _GetIMS (modifiers); + if (ims == (XIMS) NULL) + return (XIMS) NULL; + /*endif*/ + + ims->core.display = display; + + ims->protocol = (*ims->methods->setup) (display, args); + XFree (args); + if (ims->protocol == (void *) NULL) + { + XFree (ims); + return (XIMS) NULL; + } + /*endif*/ + ret = (ims->methods->openIM) (ims); + if (ret == False) + { + XFree (ims); + return (XIMS) NULL; + } + /*endif*/ + return (XIMS) ims; +} + +Status IMCloseIM (XIMS ims) +{ + (ims->methods->closeIM) (ims); + XFree (ims); + return True; +} diff --git a/IMdkit/IMMethod.c b/IMdkit/IMMethod.c new file mode 100644 index 0000000..5a33878 --- /dev/null +++ b/IMdkit/IMMethod.c @@ -0,0 +1,65 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" + +/* Public Function */ +void IMForwardEvent (XIMS ims, XPointer call_data) +{ + (ims->methods->forwardEvent) (ims, call_data); +} + +void IMCommitString (XIMS ims, XPointer call_data) +{ + (ims->methods->commitString) (ims, call_data); +} + +int IMCallCallback (XIMS ims, XPointer call_data) +{ + return (ims->methods->callCallback) (ims, call_data); +} + +int IMPreeditStart (XIMS ims, XPointer call_data) +{ + return (ims->methods->preeditStart) (ims, call_data); +} + +int IMPreeditEnd (XIMS ims, XPointer call_data) +{ + return (ims->methods->preeditEnd) (ims, call_data); +} + +int IMSyncXlib(XIMS ims, XPointer call_data) +{ + ims->sync = True; + return (ims->methods->syncXlib) (ims, call_data); +} diff --git a/IMdkit/IMValues.c b/IMdkit/IMValues.c new file mode 100644 index 0000000..687014a --- /dev/null +++ b/IMdkit/IMValues.c @@ -0,0 +1,124 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include "IMdkit.h" +#include + +#define Va_start(a,b) va_start(a,b) + +static void _IMCountVaList (va_list var, int *total_count) +{ + char *attr; + + *total_count = 0; + + for (attr = va_arg (var, char *); attr; attr = va_arg (var, char *)) + { + (void)va_arg (var, XIMArg *); + ++(*total_count); + } + /*endfor*/ +} + +static void _IMVaToNestedList (va_list var, int max_count, XIMArg **args_return) +{ + XIMArg *args; + char *attr; + + if (max_count <= 0) + { + *args_return = (XIMArg *) NULL; + return; + } + /*endif*/ + + args = (XIMArg *) malloc ((unsigned) (max_count + 1)*sizeof (XIMArg)); + *args_return = args; + if (!args) + return; + /*endif*/ + for (attr = va_arg (var, char *); attr; attr = va_arg (var, char *)) + { + args->name = attr; + args->value = va_arg (var, XPointer); + args++; + } + /*endfor*/ + args->name = (char *) NULL; +} + +char *IMGetIMValues (XIMS ims, ...) +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + Va_start (var, ims); + _IMCountVaList (var, &total_count); + va_end (var); + + Va_start (var, ims); + _IMVaToNestedList (var, total_count, &args); + va_end (var); + + ret = (*ims->methods->getIMValues) (ims, args); + + if (args) + XFree ((char *) args); + /*endif*/ + return ret; +} + +char *IMSetIMValues (XIMS ims, ...) +{ + va_list var; + int total_count; + XIMArg *args; + char *ret; + + Va_start (var, ims); + _IMCountVaList (var, &total_count); + va_end (var); + + Va_start (var, ims); + _IMVaToNestedList (var, total_count, &args); + va_end (var); + + ret = (*ims->methods->setIMValues) (ims, args); + + if (args) + XFree ((char *) args); + /*endif*/ + return ret; +} diff --git a/IMdkit/IMdkit.h b/IMdkit/IMdkit.h new file mode 100644 index 0000000..6f8d673 --- /dev/null +++ b/IMdkit/IMdkit.h @@ -0,0 +1,144 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _IMdkit_h +#define _IMdkit_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* IM Attributes Name */ +#define IMModifiers "modifiers" +#define IMServerWindow "serverWindow" +#define IMServerName "serverName" +#define IMServerTransport "serverTransport" +#define IMLocale "locale" +#define IMInputStyles "inputStyles" +#define IMProtocolHandler "protocolHandler" +#define IMOnKeysList "onKeysList" +#define IMOffKeysList "offKeysList" +#define IMEncodingList "encodingList" +#define IMFilterEventMask "filterEventMask" +#define IMProtocolDepend "protocolDepend" + +/* Masks for IM Attributes Name */ +#define I18N_IMSERVER_WIN 0x0001 /* IMServerWindow */ +#define I18N_IM_NAME 0x0002 /* IMServerName */ +#define I18N_IM_LOCALE 0x0004 /* IMLocale */ +#define I18N_IM_ADDRESS 0x0008 /* IMServerTransport */ +#define I18N_INPUT_STYLES 0x0010 /* IMInputStyles */ +#define I18N_ON_KEYS 0x0020 /* IMOnKeysList */ +#define I18N_OFF_KEYS 0x0040 /* IMOffKeysList */ +#define I18N_IM_HANDLER 0x0080 /* IMProtocolHander */ +#define I18N_ENCODINGS 0x0100 /* IMEncodingList */ +#define I18N_FILTERMASK 0x0200 /* IMFilterEventMask */ +#define I18N_PROTO_DEPEND 0x0400 /* IMProtoDepend */ + +typedef struct +{ + char *name; + XPointer value; +} XIMArg; + +typedef struct +{ + CARD32 keysym; + CARD32 modifier; + CARD32 modifier_mask; +} XIMTriggerKey; + +typedef struct +{ + unsigned short count_keys; + XIMTriggerKey *keylist; +} XIMTriggerKeys; + +typedef char *XIMEncoding; + +typedef struct +{ + unsigned short count_encodings; + XIMEncoding *supported_encodings; +} XIMEncodings; + +typedef struct _XIMS *XIMS; + +typedef struct +{ + void* (*setup) (Display *, XIMArg *); + Status (*openIM) (XIMS); + Status (*closeIM) (XIMS); + char* (*setIMValues) (XIMS, XIMArg *); + char* (*getIMValues) (XIMS, XIMArg *); + Status (*forwardEvent) (XIMS, XPointer); + Status (*commitString) (XIMS, XPointer); + int (*callCallback) (XIMS, XPointer); + int (*preeditStart) (XIMS, XPointer); + int (*preeditEnd) (XIMS, XPointer); + int (*syncXlib) (XIMS, XPointer); +} IMMethodsRec, *IMMethods; + +typedef struct +{ + Display *display; + int screen; +} IMCoreRec, *IMCore; + +typedef struct _XIMS +{ + IMMethods methods; + IMCoreRec core; + Bool sync; + void *protocol; +} XIMProtocolRec; + +/* + * X function declarations. + */ +extern XIMS IMOpenIM (Display *, ...); +extern Status IMCloseIM (XIMS); +extern char *IMSetIMValues (XIMS, ...); +extern char *IMGetIMValues (XIMS, ...); +void IMForwardEvent (XIMS, XPointer); +void IMCommitString (XIMS, XPointer); +int IMCallCallback (XIMS, XPointer); +int IMPreeditStart (XIMS, XPointer); +int IMPreeditEnd (XIMS, XPointer); +int IMSyncXlib (XIMS, XPointer); + +#ifdef __cplusplus +} +#endif + +#endif /* IMdkit_h */ diff --git a/IMdkit/Makefile b/IMdkit/Makefile new file mode 100644 index 0000000..dccafb1 --- /dev/null +++ b/IMdkit/Makefile @@ -0,0 +1,23 @@ +CFLAGS?=-g -O0 -Wall +LDFLAGS?=-Wl,-O1 + +XIMDKIT_TARGET:=libIMdkit.a + +XIMDKIT_OBJS:=FrameMgr.o IMConn.o IMMethod.o IMValues.o \ + i18nAttr.o i18nClbk.o i18nIc.o i18nIMProto.o i18nMethod.o i18nPtHdr.o i18nUtil.o i18nX.o +XIMDKIT_PKGCONFIG:=x11 +XIMDKIT_CFLAGS:=$(shell pkg-config --cflags $(XIMDKIT_PKGCONFIG)) -std=c99 + +all: $(XIMDKIT_TARGET) + +$(XIMDKIT_TARGET): $(XIMDKIT_OBJS) + ar rcs $@ $^ + +$(XIMDKIT_OBJS): %.o: %.c + $(CC) $(XIMDKIT_CFLAGS) $(CFLAGS) -o $@ -c $< + +clean: + rm -f $(XIMDKIT_TARGET) *.o + +.PHONY: all clean + diff --git a/IMdkit/Xi18n.h b/IMdkit/Xi18n.h new file mode 100644 index 0000000..e673f54 --- /dev/null +++ b/IMdkit/Xi18n.h @@ -0,0 +1,507 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _Xi18n_h +#define _Xi18n_h +#include +#include +#include +#include "XimProto.h" + +/* + * Minor Protocol Number for Extension Protocol + */ +#define XIM_EXTENSION 128 +#define XIM_EXT_SET_EVENT_MASK (0x30) +#define XIM_EXT_FORWARD_KEYEVENT (0x32) +#define XIM_EXT_MOVE (0x33) +#define COMMON_EXTENSIONS_NUM 3 + +#include +#include "IMdkit.h" + +/* XI18N Valid Attribute Name Definition */ +#define ExtForwardKeyEvent "extForwardKeyEvent" +#define ExtMove "extMove" +#define ExtSetEventMask "extSetEventMask" + +/* + * Padding macro + */ +#define IMPAD(length) ((4 - ((length)%4))%4) + +/* + * Target Atom for Transport Connection + */ +#define LOCALES "LOCALES" +#define TRANSPORT "TRANSPORT" + +#define I18N_OPEN 0 +#define I18N_SET 1 +#define I18N_GET 2 + +typedef struct +{ + char *transportname; + int namelen; + Bool (*checkAddr) (); +} TransportSW; + +typedef struct _XIMPending +{ + unsigned char *p; + struct _XIMPending *next; +} XIMPending; + +typedef struct _XimProtoHdr +{ + CARD8 major_opcode; + CARD8 minor_opcode; + CARD16 length; +} XimProtoHdr; + +typedef struct +{ + CARD16 attribute_id; + CARD16 type; + CARD16 length; + char *name; +} XIMAttr; + +typedef struct +{ + CARD16 attribute_id; + CARD16 type; + CARD16 length; + char *name; +} XICAttr; + +typedef struct +{ + int attribute_id; + CARD16 name_length; + char *name; + int value_length; + void *value; + int type; +} XIMAttribute; + +typedef struct +{ + int attribute_id; + CARD16 name_length; + char *name; + int value_length; + void *value; + int type; +} XICAttribute; + +typedef struct +{ + int length; + char *name; +} XIMStr; + +typedef struct +{ + CARD16 major_opcode; + CARD16 minor_opcode; + CARD16 length; + char *name; +} XIMExt; + +typedef struct _Xi18nClient +{ + int connect_id; + CARD8 byte_order; + /* + '?': initial value + 'B': for Big-Endian + 'l': for little-endian + */ + int sync; + XIMPending *pending; + /* property offset to read next data */ + long property_offset; + void *trans_rec; /* contains transport specific data */ + struct _Xi18nClient *next; +} Xi18nClient; + +typedef struct _Xi18nCore *Xi18n; + +/* + * Callback Struct for XIM Protocol + */ +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; +} IMAnyStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD8 byte_order; + CARD16 major_version; + CARD16 minor_version; +} IMConnectStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; +} IMDisConnectStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + XIMStr lang; +} IMOpenStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; +} IMCloseStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 number; + XIMStr *extension; +} IMQueryExtensionStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 number; + char **im_attr_list; +} IMGetIMValuesStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 preedit_attr_num; + CARD16 status_attr_num; + CARD16 ic_attr_num; + XICAttribute *preedit_attr; + XICAttribute *status_attr; + XICAttribute *ic_attr; +} IMChangeICStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMDestroyICStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 length; + char *commit_string; +} IMResetICStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMChangeFocusStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + BITMASK16 sync_bit; + CARD16 serial_number; + XEvent event; +} IMForwardEventStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 flag; + KeySym keysym; + char *commit_string; +} IMCommitStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD32 flag; + CARD32 key_index; + CARD32 event_mask; +} IMTriggerNotifyStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 encoding_number; + XIMStr *encoding; /* name information */ + CARD16 encoding_info_number; + XIMStr *encodinginfo; /* detailed information */ + CARD16 category; /* #0 for name, #1 for detail */ + INT16 enc_index; /* index of the encoding determined */ +} IMEncodingNegotiationStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD32 flag; + CARD32 forward_event_mask; + CARD32 sync_event_mask; +} IMSetEventMaskStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD32 filter_event_mask; + CARD32 intercept_event_mask; + CARD32 select_event_mask; + CARD32 forward_event_mask; + CARD32 sync_event_mask; +} IMExtSetEventMaskStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + CARD16 x; + CARD16 y; +} IMMoveStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + BITMASK16 flag; + CARD16 error_code; + CARD16 str_length; + CARD16 error_type; + char *error_detail; +} IMErrorStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMPreeditStateStruct; + +/* Callbacks */ +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMGeometryCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + union + { + int return_value; /* PreeditStart */ + XIMPreeditDrawCallbackStruct draw; /* PreeditDraw */ + XIMPreeditCaretCallbackStruct caret; /* PreeditCaret */ + } todo; +} IMPreeditCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + union + { + XIMStatusDrawCallbackStruct draw; /* StatusDraw */ + } todo; +} IMStatusCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; + XIMStringConversionCallbackStruct strconv; +} IMStrConvCBStruct; + +typedef struct +{ + int major_code; + int minor_code; + CARD16 connect_id; + CARD16 icid; +} IMSyncXlibStruct; + +typedef union _IMProtocol +{ + int major_code; + IMAnyStruct any; + IMConnectStruct imconnect; + IMDisConnectStruct imdisconnect; + IMOpenStruct imopen; + IMCloseStruct imclose; + IMQueryExtensionStruct queryext; + IMGetIMValuesStruct getim; + IMEncodingNegotiationStruct encodingnego; + IMExtSetEventMaskStruct extsetevent; + IMMoveStruct extmove; + IMSetEventMaskStruct setevent; + IMChangeICStruct changeic; + IMDestroyICStruct destroyic; + IMResetICStruct resetic; + IMChangeFocusStruct changefocus; + IMCommitStruct commitstring; + IMForwardEventStruct forwardevent; + IMTriggerNotifyStruct triggernotify; + IMPreeditStateStruct preedit_state; + IMErrorStruct imerror; + IMGeometryCBStruct geometry_callback; + IMPreeditCBStruct preedit_callback; + IMStatusCBStruct status_callback; + IMStrConvCBStruct strconv_callback; + IMSyncXlibStruct sync_xlib; + long pad[32]; +} IMProtocol; + +typedef int (*IMProtoHandler) (XIMS, IMProtocol*); + +#define DEFAULT_FILTER_MASK (KeyPressMask) + +/* Xi18nAddressRec structure */ +typedef struct _Xi18nAddressRec +{ + Display *dpy; + CARD8 im_byteOrder; /* byte order 'B' or 'l' */ + /* IM Values */ + long imvalue_mask; + Window im_window; /* IMServerWindow */ + char *im_name; /* IMServerName */ + char *im_locale; /* IMLocale */ + char *im_addr; /* IMServerTransport */ + XIMStyles input_styles; /* IMInputStyles */ + XIMTriggerKeys on_keys; /* IMOnKeysList */ + XIMTriggerKeys off_keys; /* IMOffKeysList */ + XIMEncodings encoding_list; /* IMEncodingList */ + IMProtoHandler improto; /* IMProtocolHander */ + long filterevent_mask; /* IMFilterEventMask */ + /* XIM_SERVERS target Atoms */ + Atom selection; + Atom Localename; + Atom Transportname; + /* XIM/XIC Attr */ + int im_attr_num; + XIMAttr *xim_attr; + int ic_attr_num; + XICAttr *xic_attr; + CARD16 preeditAttr_id; + CARD16 statusAttr_id; + CARD16 separatorAttr_id; + /* XIMExtension List */ + int ext_num; + XIMExt extension[COMMON_EXTENSIONS_NUM]; + /* transport specific connection address */ + void *connect_addr; + /* actual data is defined: + XSpecRec in Xi18nX.h for X-based connection. + TransSpecRec in Xi18nTr.h for Socket-based connection. + */ + /* clients table */ + Xi18nClient *clients; + Xi18nClient *free_clients; +} Xi18nAddressRec; + +typedef struct _Xi18nMethodsRec +{ + Bool (*begin) (XIMS); + Bool (*end) (XIMS); + Bool (*send) (XIMS, CARD16, unsigned char*, long); + Bool (*wait) (XIMS, CARD16, CARD8, CARD8); + Bool (*disconnect) (XIMS, CARD16); +} Xi18nMethodsRec; + +typedef struct _Xi18nCore +{ + Xi18nAddressRec address; + Xi18nMethodsRec methods; +} Xi18nCore; + +#endif + diff --git a/IMdkit/Xi18nX.h b/IMdkit/Xi18nX.h new file mode 100644 index 0000000..ff91b1a --- /dev/null +++ b/IMdkit/Xi18nX.h @@ -0,0 +1,52 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _Xi18nTrX_h +#define _Xi18nTrX_h + +#define _XIM_PROTOCOL "_XIM_PROTOCOL" +#define _XIM_XCONNECT "_XIM_XCONNECT" + +#define XCM_DATA_LIMIT 20 + +typedef struct _XClient +{ + Window client_win; /* client window */ + Window accept_win; /* accept window */ +} XClient; + +typedef struct +{ + Atom xim_request; + Atom connect_request; +} XSpecRec; + +#endif diff --git a/IMdkit/XimFunc.h b/IMdkit/XimFunc.h new file mode 100644 index 0000000..a9f4a04 --- /dev/null +++ b/IMdkit/XimFunc.h @@ -0,0 +1,72 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _XimFunc_h +#define _XimFunc_h + +/* i18nAttr.c */ +void _Xi18nInitAttrList (Xi18n i18n_core); +void _Xi18nInitExtension(Xi18n i18n_core); + +/* i18nClbk.c */ +int _Xi18nGeometryCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditStartCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditDrawCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditCaretCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nPreeditDoneCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStatusStartCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStatusDrawCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStatusDoneCallback (XIMS ims, IMProtocol *call_data); +int _Xi18nStringConversionCallback (XIMS ims, IMProtocol *call_data); + +/* i18nIc.c */ +void _Xi18nChangeIC (XIMS ims, IMProtocol *call_data, unsigned char *p, + int create_flag); +void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p); + +/* i18nUtil.c */ +int _Xi18nNeedSwap (Xi18n i18n_core, CARD16 connect_id); +Xi18nClient *_Xi18nNewClient(Xi18n i18n_core); +Xi18nClient *_Xi18nFindClient (Xi18n i18n_core, CARD16 connect_id); +void _Xi18nDeleteClient (Xi18n i18n_core, CARD16 connect_id); +void _Xi18nSendMessage (XIMS ims, CARD16 connect_id, CARD8 major_opcode, + CARD8 minor_opcode, unsigned char *data, long length); +void _Xi18nSendTriggerKey (XIMS ims, CARD16 connect_id); +void _Xi18nSetEventMask (XIMS ims, CARD16 connect_id, CARD16 im_id, + CARD16 ic_id, CARD32 forward_mask, CARD32 sync_mask); + +/* Xlib internal */ +void _XRegisterFilterByType(Display*, Window, int, int, + Bool (*filter)(Display*, Window, XEvent*, XPointer), XPointer); +void _XUnregisterFilter(Display*, Window, + Bool (*filter)(Display*, Window, XEvent*, XPointer), XPointer); + +#endif diff --git a/IMdkit/XimProto.h b/IMdkit/XimProto.h new file mode 100644 index 0000000..e3ed168 --- /dev/null +++ b/IMdkit/XimProto.h @@ -0,0 +1,230 @@ +/* $XConsortium: XimProto.h,v 1.2 94/01/20 18:02:24 rws Exp $ */ +/****************************************************************** + + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of FUJITSU LIMITED +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +FUJITSU LIMITED makes no representations about the suitability of +this software for any purpose. +It is provided "as is" without express or implied warranty. + +FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + Author: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#ifndef _XIMPROTO_H +#define _XIMPROTO_H + +/* + * Default Preconnection selection target + */ +#define XIM_SERVERS "XIM_SERVERS" +#define XIM_LOCALES "LOCALES" +#define XIM_TRANSPORT "TRANSPORT" + +/* + * categories in XIM_SERVERS + */ +#define XIM_SERVER_CATEGORY "@server=" +#define XIM_LOCAL_CATEGORY "@locale=" +#define XIM_TRANSPORT_CATEGORY "@transport=" + +/* + * Xim implementation revision + */ +#define PROTOCOLMAJORVERSION 0 +#define PROTOCOLMINORVERSION 0 + +/* + * Major Protocol number + */ +#define XIM_CONNECT 1 +#define XIM_CONNECT_REPLY 2 +#define XIM_DISCONNECT 3 +#define XIM_DISCONNECT_REPLY 4 + +#define XIM_AUTH_REQUIRED 10 +#define XIM_AUTH_REPLY 11 +#define XIM_AUTH_NEXT 12 +#define XIM_AUTH_SETUP 13 +#define XIM_AUTH_NG 14 + +#define XIM_ERROR 20 + +#define XIM_OPEN 30 +#define XIM_OPEN_REPLY 31 +#define XIM_CLOSE 32 +#define XIM_CLOSE_REPLY 33 +#define XIM_REGISTER_TRIGGERKEYS 34 +#define XIM_TRIGGER_NOTIFY 35 +#define XIM_TRIGGER_NOTIFY_REPLY 36 +#define XIM_SET_EVENT_MASK 37 +#define XIM_ENCODING_NEGOTIATION 38 +#define XIM_ENCODING_NEGOTIATION_REPLY 39 +#define XIM_QUERY_EXTENSION 40 +#define XIM_QUERY_EXTENSION_REPLY 41 +#define XIM_SET_IM_VALUES 42 +#define XIM_SET_IM_VALUES_REPLY 43 +#define XIM_GET_IM_VALUES 44 +#define XIM_GET_IM_VALUES_REPLY 45 + +#define XIM_CREATE_IC 50 +#define XIM_CREATE_IC_REPLY 51 +#define XIM_DESTROY_IC 52 +#define XIM_DESTROY_IC_REPLY 53 +#define XIM_SET_IC_VALUES 54 +#define XIM_SET_IC_VALUES_REPLY 55 +#define XIM_GET_IC_VALUES 56 +#define XIM_GET_IC_VALUES_REPLY 57 +#define XIM_SET_IC_FOCUS 58 +#define XIM_UNSET_IC_FOCUS 59 +#define XIM_FORWARD_EVENT 60 +#define XIM_SYNC 61 +#define XIM_SYNC_REPLY 62 +#define XIM_COMMIT 63 +#define XIM_RESET_IC 64 +#define XIM_RESET_IC_REPLY 65 + +#define XIM_GEOMETRY 70 +#define XIM_STR_CONVERSION 71 +#define XIM_STR_CONVERSION_REPLY 72 +#define XIM_PREEDIT_START 73 +#define XIM_PREEDIT_START_REPLY 74 +#define XIM_PREEDIT_DRAW 75 +#define XIM_PREEDIT_CARET 76 +#define XIM_PREEDIT_CARET_REPLY 77 +#define XIM_PREEDIT_DONE 78 +#define XIM_STATUS_START 79 +#define XIM_STATUS_DRAW 80 +#define XIM_STATUS_DONE 81 + +/* + * values for the flag of XIM_ERROR + */ +#define XIM_IMID_VALID 0x0001 +#define XIM_ICID_VALID 0x0002 + +/* + * XIM Error Code + */ +#define XIM_BadAlloc 1 +#define XIM_BadStyle 2 +#define XIM_BadClientWindow 3 +#define XIM_BadFocusWindow 4 +#define XIM_BadArea 5 +#define XIM_BadSpotLocation 6 +#define XIM_BadColormap 7 +#define XIM_BadAtom 8 +#define XIM_BadPixel 9 +#define XIM_BadPixmap 10 +#define XIM_BadName 11 +#define XIM_BadCursor 12 +#define XIM_BadProtocol 13 +#define XIM_BadForeground 14 +#define XIM_BadBackground 15 +#define XIM_LocaleNotSupported 16 +#define XIM_BadSomething 999 + +/* + * byte order + */ +#define BIGENDIAN (CARD8) 0x42 /* MSB first */ +#define LITTLEENDIAN (CARD8) 0x6c /* LSB first */ + +/* + * values for the type of XIMATTR & XICATTR + */ +#define XimType_SeparatorOfNestedList 0 +#define XimType_CARD8 1 +#define XimType_CARD16 2 +#define XimType_CARD32 3 +#define XimType_STRING8 4 +#define XimType_Window 5 +#define XimType_XIMStyles 10 +#define XimType_XRectangle 11 +#define XimType_XPoint 12 +#define XimType_XFontSet 13 +#define XimType_XIMOptions 14 +#define XimType_XIMHotKeyTriggers 15 +#define XimType_XIMHotKeyState 16 +#define XimType_XIMStringConversion 17 +#define XimType_XIMValuesList 18 +#define XimType_NEST 0x7FFF + +/* + * values for the category of XIM_ENCODING_NEGOTIATON_REPLY + */ +#define XIM_Encoding_NameCategory 0 +#define XIM_Encoding_DetailCategory 1 + +/* + * value for the index of XIM_ENCODING_NEGOTIATON_REPLY + */ +#define XIM_Default_Encoding_IDX -1 + +/* + * value for the flag of XIM_FORWARD_EVENT, XIM_COMMIT + */ +#define XimSYNCHRONUS 0x0001 +#define XimLookupChars 0x0002 +#define XimLookupKeySym 0x0004 +#define XimLookupBoth 0x0006 + +/* + * request packet header size + */ +#define XIM_HEADER_SIZE \ + sizeof(CARD8) /* sizeof mejor-opcode */ \ + + sizeof(CARD8) /* sizeof minor-opcode */ \ + + sizeof(INT16) /* sizeof length */ + +/* + * Client Message data size + */ +#define XIM_CM_DATA_SIZE 20 + +/* + * XIM data structure + */ +typedef CARD16 BITMASK16; +typedef CARD32 BITMASK32; +typedef CARD32 EVENTMASK; + +typedef CARD16 XIMID; /* Input Method ID */ +typedef CARD16 XICID; /* Input Context ID */ + +/* + * Padding macro + */ +#define XIM_PAD(length) ((4 - ((length) % 4)) % 4) + +#define XIM_SET_PAD(ptr, length) \ + { \ + register int Counter = XIM_PAD((int)length); \ + if (Counter) { \ + register char *Ptr = (char *)(ptr) + (length); \ + length += Counter; \ + for (; Counter; --Counter, ++Ptr) \ + *Ptr = '\0'; \ + } \ + } + +#endif + diff --git a/IMdkit/Xtrans.h b/IMdkit/Xtrans.h new file mode 100644 index 0000000..cae691c --- /dev/null +++ b/IMdkit/Xtrans.h @@ -0,0 +1,470 @@ +/* $XConsortium: Xtrans.h,v 1.24 94/05/02 10:45:32 mor Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +/* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name NCR not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. NCR makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _XTRANS_H_ +#define _XTRANS_H_ + +#include +#include + + +/* + * Set the functions names according to where this code is being compiled. + */ + +#ifdef X11_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _X11Trans##func +#else +#define TRANS(func) _X11Trans/**/func +#endif +#endif /* X11_t */ + +#ifdef XSERV_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _XSERVTrans##func +#else +#define TRANS(func) _XSERVTrans/**/func +#endif +#define X11_t +#endif /* X11_t */ + +#ifdef XIM_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _XimdXTrans##func +#else +#define TRANS(func) _XimdXTrans/**/func +#endif +#endif /* XIM_t */ + +#ifdef FS_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _FSTrans##func +#else +#define TRANS(func) _FSTrans/**/func +#endif +#endif /* FS_t */ + +#ifdef FONT_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _FontTrans##func +#else +#define TRANS(func) _FontTrans/**/func +#endif +#endif /* FONT_t */ + +#ifdef ICE_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _IceTrans##func +#else +#define TRANS(func) _IceTrans/**/func +#endif +#endif /* ICE_t */ + +#ifdef TEST_t +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _TESTTrans##func +#else +#define TRANS(func) _TESTTrans/**/func +#endif +#endif /* TEST_t */ + +#if !defined(TRANS) +#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP) +#define TRANS(func) _XTrans##func +#else +#define TRANS(func) _XTrans/**/func +#endif +#endif /* !TRANS */ + + +/* + * Create a single address structure that can be used wherever + * an address structure is needed. struct sockaddr is not big enough + * to hold a sockadd_un, so we create this definition to have a single + * structure that is big enough for all the structures we might need. + * + * This structure needs to be independent of the socket/TLI interface used. + */ + +#define XTRANS_MAX_ADDR_LEN 128 /* large enough to hold sun_path */ + +typedef struct { + unsigned char addr[XTRANS_MAX_ADDR_LEN]; +} Xtransaddr; + + +#ifdef LONG64 +typedef int BytesReadable_t; +#else +typedef long BytesReadable_t; +#endif + + +#if defined(WIN32) || (defined(USG) && !defined(CRAY) && !defined(umips) && !defined(MOTOROLA) && !defined(uniosu) && !defined(__sxg__)) + +/* + * TRANS(Readv) and TRANS(Writev) use struct iovec, normally found + * in Berkeley systems in . See the readv(2) and writev(2) + * manual pages for details. + */ + +struct iovec { + caddr_t iov_base; + int iov_len; +}; + +#else +#include +#endif + +typedef struct _XtransConnInfo *XtransConnInfo; + + +/* + * Transport Option definitions + */ + +#define TRANS_NONBLOCKING 1 +#define TRANS_CLOSEONEXEC 2 + + +/* + * Return values of Connect (0 is success) + */ + +#define TRANS_CONNECT_FAILED -1 +#define TRANS_TRY_CONNECT_AGAIN -2 + + +/* + * Return values of Accept (0 is success) + */ + +#define TRANS_ACCEPT_BAD_MALLOC -1 +#define TRANS_ACCEPT_FAILED -2 +#define TRANS_ACCEPT_MISC_ERROR -3 + + +/* + * ResetListener return values + */ + +#define TRANS_RESET_NOOP 1 +#define TRANS_RESET_NEW_FD 2 +#define TRANS_RESET_FAILURE 3 + + +/* + * Function prototypes for the exposed interface + */ + +#ifdef TRANS_CLIENT + +XtransConnInfo TRANS(OpenCOTSClient)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_CLIENT */ + +#ifdef TRANS_SERVER + +XtransConnInfo TRANS(OpenCOTSServer)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_SERVER */ + +#ifdef TRANS_CLIENT + +XtransConnInfo TRANS(OpenCLTSClient)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_CLIENT */ + +#ifdef TRANS_SERVER + +XtransConnInfo TRANS(OpenCLTSServer)( +#if NeedFunctionPrototypes + char * /* address */ +#endif +); + +#endif /* TRANS_SERVER */ + +#ifdef TRANS_REOPEN + +XtransConnInfo TRANS(ReopenCOTSServer)( +#if NeedFunctionPrototypes + int, /* trans_id */ + int, /* fd */ + char * /* port */ +#endif +); + +XtransConnInfo TRANS(ReopenCLTSServer)( +#if NeedFunctionPrototypes + int, /* trans_id */ + int, /* fd */ + char * /* port */ +#endif +); + +int TRANS(GetReopenInfo)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int *, /* trans_id */ + int *, /* fd */ + char ** /* port */ +#endif +); + +#endif /* TRANS_REOPEN */ + + +int TRANS(SetOption)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int, /* option */ + int /* arg */ +#endif +); + +#ifdef TRANS_SERVER + +int TRANS(CreateListener)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char * /* port */ +#endif +); + +int TRANS(ResetListener)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +XtransConnInfo TRANS(Accept)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int * /* status */ +#endif +); + +#endif /* TRANS_SERVER */ + +#ifdef TRANS_CLIENT + +int TRANS(Connect)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char * /* address */ +#endif +); + +#endif /* TRANS_CLIENT */ + +int TRANS(BytesReadable)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + BytesReadable_t * /* pend */ +#endif +); + +int TRANS(Read)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Write)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + char *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Readv)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + struct iovec *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Writev)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + struct iovec *, /* buf */ + int /* size */ +#endif +); + +int TRANS(Disconnect)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(Close)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(CloseForCloning)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(IsLocal)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +int TRANS(GetMyAddr)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int *, /* familyp */ + int *, /* addrlenp */ + Xtransaddr ** /* addrp */ +#endif +); + +int TRANS(GetPeerAddr)( +#if NeedFunctionPrototypes + XtransConnInfo, /* ciptr */ + int *, /* familyp */ + int *, /* addrlenp */ + Xtransaddr ** /* addrp */ +#endif +); + +int TRANS(GetConnectionNumber)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +#ifdef TRANS_SERVER + +int TRANS(MakeAllCOTSServerListeners)( +#if NeedFunctionPrototypes + char *, /* port */ + int *, /* partial */ + int *, /* count_ret */ + XtransConnInfo ** /* ciptrs_ret */ +#endif +); + +int TRANS(MakeAllCLTSServerListeners)( +#if NeedFunctionPrototypes + char *, /* port */ + int *, /* partial */ + int *, /* count_ret */ + XtransConnInfo ** /* ciptrs_ret */ +#endif +); + +#endif /* TRANS_SERVER */ + + +/* + * Function Prototypes for Utility Functions. + */ + +#ifdef X11_t + +int TRANS(ConvertAddress)( +#if NeedFunctionPrototypes + int *, /* familyp */ + int *, /* addrlenp */ + Xtransaddr * /* addrp */ +#endif +); + +#endif /* X11_t */ + +#ifdef ICE_t + +char * +TRANS(GetMyNetworkId)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +char * +TRANS(GetPeerNetworkId)( +#if NeedFunctionPrototypes + XtransConnInfo /* ciptr */ +#endif +); + +#endif /* ICE_t */ + +#endif /* _XTRANS_H_ */ diff --git a/IMdkit/i18nAttr.c b/IMdkit/i18nAttr.c new file mode 100644 index 0000000..a52370b --- /dev/null +++ b/IMdkit/i18nAttr.c @@ -0,0 +1,175 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "XimFunc.h" + +typedef struct +{ + char *name; + CARD16 type; +} IMListOfAttr; + +typedef struct +{ + char *name; + CARD8 major_opcode; + CARD8 minor_opcode; +} IMExtList; + +IMListOfAttr Default_IMattr[] = +{ + {XNQueryInputStyle, XimType_XIMStyles}, +/* {XNQueryIMValuesList, XimType_XIMValuesList}, */ + {(char *) NULL, (CARD16) 0} +}; + +IMListOfAttr Default_ICattr[] = +{ + {XNInputStyle, XimType_CARD32}, + {XNClientWindow, XimType_Window}, + {XNFocusWindow, XimType_Window}, + {XNFilterEvents, XimType_CARD32}, + {XNPreeditAttributes, XimType_NEST}, + {XNStatusAttributes, XimType_NEST}, + {XNFontSet, XimType_XFontSet}, + {XNArea, XimType_XRectangle}, + {XNAreaNeeded, XimType_XRectangle}, + {XNColormap, XimType_CARD32}, + {XNStdColormap, XimType_CARD32}, + {XNForeground, XimType_CARD32}, + {XNBackground, XimType_CARD32}, + {XNBackgroundPixmap, XimType_CARD32}, + {XNSpotLocation, XimType_XPoint}, + {XNLineSpace, XimType_CARD32}, + {XNPreeditState, XimType_CARD32}, + {XNSeparatorofNestedList, XimType_SeparatorOfNestedList}, + {(char *) NULL, 0} +}; + +IMExtList Default_Extension[] = +{ + {"XIM_EXT_MOVE", XIM_EXTENSION, XIM_EXT_MOVE}, + {"XIM_EXT_SET_EVENT_MASK", XIM_EXTENSION, XIM_EXT_SET_EVENT_MASK}, + {"XIM_EXT_FORWARD_KEYEVENT", XIM_EXTENSION, XIM_EXT_FORWARD_KEYEVENT}, + {(char *) NULL, 0, 0} +}; + +static void CountAttrList(IMListOfAttr *attr, int *total_count) +{ + *total_count = 0; + + while (attr->name != NULL) + { + attr++; + ++(*total_count); + } +} + +static XIMAttr *CreateAttrList (Xi18n i18n_core, + IMListOfAttr *attr, + int *total_count) +{ + XIMAttr *args, *p; + unsigned int buf_size; + + CountAttrList(attr, total_count); + + buf_size = (unsigned) (*total_count + 1)*sizeof (XIMAttr); + args = (XIMAttr *) malloc (buf_size); + if (!args) + return (XIMAttr *) NULL; + /*endif*/ + memset (args, 0, buf_size); + + for (p = args; attr->name != NULL; attr++, p++) + { + p->name = attr->name; + p->length = strlen (attr->name); + p->type = (CARD16) attr->type; + p->attribute_id = XrmStringToQuark (p->name); + if (strcmp (p->name, XNPreeditAttributes) == 0) + i18n_core->address.preeditAttr_id = p->attribute_id; + else if (strcmp (p->name, XNStatusAttributes) == 0) + i18n_core->address.statusAttr_id = p->attribute_id; + else if (strcmp (p->name, XNSeparatorofNestedList) == 0) + i18n_core->address.separatorAttr_id = p->attribute_id; + /*endif*/ + } + /*endfor*/ + p->name = (char *) NULL; + + return args; +} + +void _Xi18nInitAttrList (Xi18n i18n_core) +{ + XIMAttr *args; + int total_count; + + /* init IMAttr list */ + if (i18n_core->address.xim_attr) + XFree ((char *)i18n_core->address.xim_attr); + /*endif*/ + args = CreateAttrList (i18n_core, Default_IMattr, &total_count); + + i18n_core->address.im_attr_num = total_count; + i18n_core->address.xim_attr = (XIMAttr *)args; + + /* init ICAttr list */ + if (i18n_core->address.xic_attr) + XFree ((char *) i18n_core->address.xic_attr); + /*endif*/ + args = CreateAttrList (i18n_core, Default_ICattr, &total_count); + + i18n_core->address.ic_attr_num = total_count; + i18n_core->address.xic_attr = (XICAttr *) args; +} + +void _Xi18nInitExtension(Xi18n i18n_core) +{ + register int i; + IMExtList *extensions = (IMExtList *) Default_Extension; + XIMExt *ext_list = (XIMExt *) i18n_core->address.extension; + + for (i = 0; extensions->name; i++, ext_list++, extensions++) + { + ext_list->major_opcode = extensions->major_opcode; + ext_list->minor_opcode = extensions->minor_opcode; + ext_list->name = extensions->name; + ext_list->length = strlen(ext_list->name); + } + /*endfor*/ + i18n_core->address.ext_num = i; +} diff --git a/IMdkit/i18nClbk.c b/IMdkit/i18nClbk.c new file mode 100644 index 0000000..b3edf3a --- /dev/null +++ b/IMdkit/i18nClbk.c @@ -0,0 +1,513 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "FrameMgr.h" +#include "XimFunc.h" + +int _Xi18nGeometryCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec geometry_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMGeometryCBStruct *geometry_CB = + (IMGeometryCBStruct *) &call_data->geometry_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (geometry_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, geometry_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_GEOMETRY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_GEOMETRY is an asyncronous protocol, + so return immediately. */ + return True; +} + +int _Xi18nPreeditStartCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_start_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct*) &call_data->preedit_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (preedit_start_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage(ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_START, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + return True; +} + +int _Xi18nPreeditDrawCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_draw_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + XIMPreeditDrawCallbackStruct *draw = + (XIMPreeditDrawCallbackStruct *) &preedit_CB->todo.draw; + CARD16 connect_id = call_data->any.connect_id; + register int feedback_count; + register int i; + BITMASK32 status = 0x0; + + if (draw->text->length == 0) + status = 0x00000001; + else if (draw->text->feedback[0] == 0) + status = 0x00000002; + /*endif*/ + + fm = FrameMgrInit (preedit_draw_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set length of preedit string */ + FrameMgrSetSize (fm, draw->text->length); + + /* set iteration count for list of feedback */ + for (i = 0; draw->text->feedback[i] != 0; i++) + ; + /*endfor*/ + feedback_count = i; + FrameMgrSetIterCount (fm, feedback_count); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + FrameMgrPutToken (fm, draw->caret); + FrameMgrPutToken (fm, draw->chg_first); + FrameMgrPutToken (fm, draw->chg_length); + FrameMgrPutToken (fm, status); + FrameMgrPutToken (fm, draw->text->length); + FrameMgrPutToken (fm, draw->text->string); + for (i = 0; i < feedback_count; i++) + FrameMgrPutToken (fm, draw->text->feedback[i]); + /*endfor*/ + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_DRAW, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_PREEDIT_DRAW is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nPreeditCaretCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_caret_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct*) &call_data->preedit_callback; + XIMPreeditCaretCallbackStruct *caret = + (XIMPreeditCaretCallbackStruct *) &preedit_CB->todo.caret; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (preedit_caret_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + FrameMgrPutToken (fm, caret->position); + FrameMgrPutToken (fm, caret->direction); + FrameMgrPutToken (fm, caret->style); + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_CARET, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + return True; +} + +int _Xi18nPreeditDoneCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_done_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (preedit_done_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, preedit_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_PREEDIT_DONE, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_PREEDIT_DONE is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStatusStartCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec status_start_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMStatusCBStruct *status_CB = + (IMStatusCBStruct*) &call_data->status_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (status_start_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_STATUS_START, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STATUS_START is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStatusDrawCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm = (FrameMgr)0; + extern XimFrameRec status_draw_text_fr[]; + extern XimFrameRec status_draw_bitmap_fr[]; + register int total_size = 0; + unsigned char *reply = NULL; + IMStatusCBStruct *status_CB = + (IMStatusCBStruct *) &call_data->status_callback; + XIMStatusDrawCallbackStruct *draw = + (XIMStatusDrawCallbackStruct *) &status_CB->todo.draw; + CARD16 connect_id = call_data->any.connect_id; + register int feedback_count; + register int i; + BITMASK32 status = 0x0; + + switch (draw->type) + { + case XIMTextType: + fm = FrameMgrInit (status_draw_text_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + if (draw->data.text->length == 0) + status = 0x00000001; + else if (draw->data.text->feedback[0] == 0) + status = 0x00000002; + /*endif*/ + + /* set length of status string */ + FrameMgrSetSize(fm, draw->data.text->length); + /* set iteration count for list of feedback */ + for (i = 0; draw->data.text->feedback[i] != 0; i++) + ; + /*endfor*/ + feedback_count = i; + FrameMgrSetIterCount (fm, feedback_count); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + FrameMgrPutToken (fm, draw->type); + FrameMgrPutToken (fm, status); + FrameMgrPutToken (fm, draw->data.text->length); + FrameMgrPutToken (fm, draw->data.text->string); + for (i = 0; i < feedback_count; i++) + FrameMgrPutToken (fm, draw->data.text->feedback[i]); + /*endfor*/ + break; + + case XIMBitmapType: + fm = FrameMgrInit (status_draw_bitmap_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + FrameMgrPutToken (fm, draw->data.bitmap); + break; + } + /*endswitch*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_STATUS_DRAW, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STATUS_DRAW is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStatusDoneCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec status_done_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMStatusCBStruct *status_CB = + (IMStatusCBStruct *) &call_data->status_callback; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (status_done_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, status_CB->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_STATUS_DONE, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STATUS_DONE is an asyncronous protocol, so return immediately. */ + return True; +} + +int _Xi18nStringConversionCallback (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec str_conversion_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMStrConvCBStruct *call_back = + (IMStrConvCBStruct *) &call_data->strconv_callback; + XIMStringConversionCallbackStruct *strconv = + (XIMStringConversionCallbackStruct *) &call_back->strconv; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (str_conversion_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, connect_id); + FrameMgrPutToken (fm, call_back->icid); + FrameMgrPutToken (fm, strconv->position); + FrameMgrPutToken (fm, strconv->direction); + FrameMgrPutToken (fm, strconv->operation); + + _Xi18nSendMessage (ims, connect_id, + XIM_STR_CONVERSION, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + /* XIM_STR_CONVERSION is a syncronous protocol, + so should wait here for XIM_STR_CONVERSION_REPLY. */ + if (i18n_core->methods.wait (ims, + connect_id, + XIM_STR_CONVERSION_REPLY, + 0) == False) + { + return False; + } + /*endif*/ + return True; +} diff --git a/IMdkit/i18nIMProto.c b/IMdkit/i18nIMProto.c new file mode 100644 index 0000000..618da9d --- /dev/null +++ b/IMdkit/i18nIMProto.c @@ -0,0 +1,773 @@ +/****************************************************************** +Copyright 1993, 1994 by Digital Equipment Corporation, Maynard, Massachusetts, +Copyright 1993, 1994 by Hewlett-Packard Company + +Copyright 1994, 1995 by Sun Microsystems, Inc. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL DIGITAL AND HEWLETT-PACKARD COMPANY BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hiroyuki Miyamoto Digital Equipment Corporation + miyamoto@jrd.dec.com + Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +/* Protocol Packet frames */ + +#include "FrameMgr.h" + +/* Data type definitions */ + +static XimFrameRec ximattr_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* type of the value */ + _FRAME(BIT16), /* length of im-attribute */ + _FRAME(BARRAY), /* im-attribute */ + _PAD4(2), + _FRAME(EOL), +}; + +static XimFrameRec xicattr_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* type of the value */ + _FRAME(BIT16), /* length of ic-attribute */ + _FRAME(BARRAY), /* ic-attribute */ + _PAD4(2), + _FRAME(EOL), +}; + +static XimFrameRec ximattribute_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* value length */ + _FRAME(BARRAY), /* value */ + _PAD4(1), + _FRAME(EOL), +}; + +static XimFrameRec xicattribute_fr[] = +{ + _FRAME(BIT16), /* attribute ID */ + _FRAME(BIT16), /* value length */ + _FRAME(BARRAY), /* value */ + _PAD4(1), + _FRAME(EOL), +}; + +static XimFrameRec ximtriggerkey_fr[] = +{ + _FRAME(BIT32), /* keysym */ + _FRAME(BIT32), /* modifier */ + _FRAME(BIT32), /* modifier mask */ + _FRAME(EOL), +}; + +static XimFrameRec encodinginfo_fr[] = +{ + _FRAME(BIT16), /* length of encoding info */ + _FRAME(BARRAY), /* encoding info */ + _PAD4(2), + _FRAME(EOL), +}; + +static XimFrameRec str_fr[] = +{ + _FRAME(BIT8), /* number of byte */ + _FRAME(BARRAY), /* string */ + _FRAME(EOL), +}; + +static XimFrameRec xpcs_fr[] = +{ + _FRAME(BIT16), /* length of string in bytes */ + _FRAME(BARRAY), /* string */ + _PAD4(2), +}; + +static XimFrameRec ext_fr[] = +{ + _FRAME(BIT8), /* extension major-opcode */ + _FRAME(BIT8), /* extension minor-opcode */ + _FRAME(BIT16), /* length of extension name */ + _FRAME(BARRAY), /* extension name */ + _PAD4(1), + _FRAME(EOL), +}; + +static XimFrameRec inputstyle_fr[] = +{ + _FRAME(BIT32), /* inputstyle */ + _FRAME(EOL), +}; +/* Protocol definitions */ + +xim_externaldef XimFrameRec attr_head_fr[] = +{ + _FRAME(BIT16), /* attribute id */ + _FRAME(BIT16), /* attribute length */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec short_fr[] = +{ + _FRAME(BIT16), /* value */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec long_fr[] = +{ + _FRAME(BIT32), /* value */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec xrectangle_fr[] = +{ + _FRAME(BIT16), /* x */ + _FRAME(BIT16), /* y */ + _FRAME(BIT16), /* width */ + _FRAME(BIT16), /* height */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec xpoint_fr[] = +{ + _FRAME(BIT16), /* x */ + _FRAME(BIT16), /* y */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec fontset_fr[] = +{ + _FRAME(BIT16), /* length of base font name */ + _FRAME(BARRAY), /* base font name list */ + _PAD4(2), /* unused */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec input_styles_fr[] = +{ + _FRAME(BIT16), /* number of list */ + _PAD4(1), /* unused */ + _FRAME(ITER), /* XIMStyle list */ + _FRAME(POINTER), + _PTR(inputstyle_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec packet_header_fr[] = +{ + _FRAME(BIT8), /* major-opcode */ + _FRAME(BIT8), /* minor-opcode */ + _FRAME(BIT16), /* length */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec error_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* Error Code */ + _FRAME(BIT16), /* length of error detail */ + _FRAME(BIT16), /* type of error detail */ + _FRAME(BARRAY), /* error detail */ + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec connect_fr[] = +{ + _FRAME(BIT8), /* byte order */ + _PAD2(1), /* unused */ + _FRAME(BIT16), /* client-major-protocol-version */ + _FRAME(BIT16), /* client-minor-protocol-version */ + _BYTE_COUNTER(BIT16, 1), /* length of client-auth-protocol-names */ + _FRAME(ITER), /* client-auth-protocol-names */ + _FRAME(POINTER), + _PTR(xpcs_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec connect_reply_fr[] = +{ + _FRAME(BIT16), /* server-major-protocol-version */ + _FRAME(BIT16), /* server-minor-protocol-version */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_required_fr[] = +{ + _FRAME(BIT8), /* auth-protocol-index */ + _FRAME(BIT8), /* auth-data1 */ + _FRAME(BARRAY), /* auth-data2 */ + _PAD4(3), + _FRAME(EOL), +}; + + +xim_externaldef XimFrameRec auth_reply_fr[] = +{ + _FRAME(BIT8), + _FRAME(BARRAY), + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_next_fr[] = +{ + _FRAME(BIT8), /* auth-data1 */ + _FRAME(BARRAY), /* auth-data2 */ + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_setup_fr[] = +{ + _BYTE_COUNTER(BIT16, 2), /* number of client-auth-protocol-names */ + _PAD4(1), /* unused */ + _FRAME(ITER), /* server-auth-protocol-names */ + _FRAME(POINTER), + _PTR(xpcs_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec auth_ng_fr[] = +{ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec disconnect_fr[] = +{ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec disconnect_reply_fr[] = +{ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec open_fr[] = +{ + _FRAME(POINTER), /* locale name */ + _PTR(str_fr), + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec open_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of IM attributes supported */ + _FRAME(ITER), /* IM attribute supported */ + _FRAME(POINTER), + _PTR(ximattr_fr), + _BYTE_COUNTER(BIT16, 2), /* number of IC attribute supported */ + _PAD4(1), /* unused */ + _FRAME(ITER), /* IC attribute supported */ + _FRAME(POINTER), + _PTR(xicattr_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec close_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _PAD4(1), /* unused */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec close_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _PAD4(1), /* unused */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec register_triggerkeys_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _PAD4(1), /* unused */ + _BYTE_COUNTER(BIT32, 1), /* byte length of on-keys */ + _FRAME(ITER), /* on-keys list */ + _FRAME(POINTER), + _PTR(ximtriggerkey_fr), + _BYTE_COUNTER(BIT32, 1), /* byte length of off-keys */ + _FRAME(ITER), /* off-keys list */ + _FRAME(POINTER), + _PTR(ximtriggerkey_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec trigger_notify_fr[] = +{ + _FRAME(BIT16), /* input-mehotd-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* flag */ + _FRAME(BIT32), /* index of keys list */ + _FRAME(BIT32), /* client-select-event-mask */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec trigger_notify_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_event_mask_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* forward-event-mask */ + _FRAME(BIT32), /* synchronous-event-mask */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec encoding_negotiation_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of encodings listed by name */ + _FRAME(ITER), /* supported list of encoding in IM library */ + _FRAME(POINTER), + _PTR(str_fr), + _PAD4(1), + _BYTE_COUNTER(BIT16, 2), /* byte length of encodings listed by + detailed data */ + _PAD4(1), + _FRAME(ITER), /* list of encodings supported in the + IM library */ + _FRAME(POINTER), + _PTR(encodinginfo_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec encoding_negotiation_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* category of the encoding determined */ + _FRAME(BIT16), /* index of the encoding dterminated */ + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec query_extension_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of extensions supported + by the IM library */ + _FRAME(ITER), /* extensions supported by the IM library */ + _FRAME(POINTER), + _PTR(str_fr), + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec query_extension_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of extensions supported + by the IM server */ + _FRAME(ITER), /* list of extensions supported by the + IM server */ + _FRAME(POINTER), + _PTR(ext_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_im_values_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of im-attribute-id */ + _FRAME(ITER), /* im-attribute-id */ + _FRAME(BIT16), + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_im_values_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of im-attribute returned */ + _FRAME(ITER), /* im-attribute returned */ + _FRAME(POINTER), + _PTR(ximattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec create_ic_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of ic-attributes */ + _FRAME(ITER), /* ic-attributes */ + _FRAME(POINTER), + _PTR(xicattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec create_ic_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec destroy_ic_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec destroy_ic_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_ic_values_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _BYTE_COUNTER(BIT16, 2), /* byte length of ic-attributes */ + _PAD4(1), + _FRAME(ITER), /* ic-attribute */ + _FRAME(POINTER), + _PTR(xicattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_ic_values_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_ic_values_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _BYTE_COUNTER(BIT16, 1), /* byte length of ic-attribute-id */ + _FRAME(ITER), /* ic-attribute */ + _FRAME(BIT16), + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec get_ic_values_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _BYTE_COUNTER(BIT16, 2), /* byte length of ic-attribute */ + _PAD4(1), + _FRAME(ITER), /* ic-attribute */ + _FRAME(POINTER), + _PTR(xicattribute_fr), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec set_ic_focus_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec unset_ic_focus_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec forward_event_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* sequence number */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec wire_keyevent_fr[] = { + _FRAME(BIT8), /* type */ + _FRAME(BIT8), /* detail */ + _FRAME(BIT16), /* serial number */ + _FRAME(BIT32), /* time */ + _FRAME(BIT32), /* root */ + _FRAME(BIT32), /* window */ + _FRAME(BIT32), /* subwindow */ + _FRAME(BIT16), /* rootX */ + _FRAME(BIT16), /* rootY */ + _FRAME(BIT16), /* X */ + _FRAME(BIT16), /* Y */ + _FRAME(BIT16), /* state */ + _FRAME(BIT8), /* sameScreen */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec sync_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec sync_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +#if 0 +xim_externaldef XimFrameRec commit_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(1), + _BYTE_COUNTER(BIT16, 1), /* byte length of keysym */ + _FRAME(ITER), /* keysym */ + _FRAME(BIT32), + _PAD4(1), + _FRAME(EOL), +}; +#endif + +xim_externaldef XimFrameRec commit_chars_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(1), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec commit_both_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _PAD4(1), /* unused */ + _FRAME(BIT32), /* keysym */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec reset_ic_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec reset_ic_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* byte length of committed string */ + _FRAME(BARRAY), /* committed string */ + _PAD4(2), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec geometry_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec str_conversion_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* XIMStringConversionPosition */ + _FRAME(BIT32), /* XIMStringConversionType */ + _FRAME(BIT32), /* XIMStringConversionOperation */ + _FRAME(BIT16), /* length to multiply the + XIMStringConversionType */ + _FRAME(BIT16), /* length of the string to be + substituted */ +#if 0 + _FRAME(BARRAY), /* string */ + _PAD4(1), +#endif + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec str_conversion_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* XIMStringConversionFeedback */ + _FRAME(BIT16), /* length of the retrieved string */ + _FRAME(BARRAY), /* retrieved string */ + _PAD4(2), + _BYTE_COUNTER(BIT16, 2), /* number of feedback array */ + _PAD4(1), + _FRAME(ITER), /* feedback array */ + _FRAME(BIT32), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_start_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_start_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* return value */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_draw_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* caret */ + _FRAME(BIT32), /* chg_first */ + _FRAME(BIT32), /* chg_length */ + _FRAME(BIT32), /* status */ + _FRAME(BIT16), /* length of preedit string */ + _FRAME(BARRAY), /* preedit string */ + _PAD4(2), + _BYTE_COUNTER(BIT16, 2), /* number of feedback array */ + _PAD4(1), + _FRAME(ITER), /* feedback array */ + _FRAME(BIT32), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_caret_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* position */ + _FRAME(BIT32), /* direction */ + _FRAME(BIT32), /* style */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_caret_reply_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* position */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec preedit_done_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_start_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_draw_text_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* type */ + _FRAME(BIT32), /* status */ + _FRAME(BIT16), /* length of status string */ + _FRAME(BARRAY), /* status string */ + _PAD4(2), + _BYTE_COUNTER(BIT16, 2), /* number of feedback array */ + _PAD4(1), + _FRAME(ITER), /* feedback array */ + _FRAME(BIT32), + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_draw_bitmap_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* type */ + _FRAME(BIT32), /* pixmap data */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec status_done_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec ext_set_event_mask_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT32), /* filter-event-mask */ + _FRAME(BIT32), /* intercept-event-mask */ + _FRAME(BIT32), /* select-event-mask */ + _FRAME(BIT32), /* forward-event-mask */ + _FRAME(BIT32), /* synchronous-event-mask */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec ext_forward_keyevent_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* flag */ + _FRAME(BIT16), /* sequence number */ + _FRAME(BIT8), /* xEvent.u.u.type */ + _FRAME(BIT8), /* keycode */ + _FRAME(BIT16), /* state */ + _FRAME(BIT32), /* time */ + _FRAME(BIT32), /* window */ + _FRAME(EOL), +}; + +xim_externaldef XimFrameRec ext_move_fr[] = +{ + _FRAME(BIT16), /* input-method-ID */ + _FRAME(BIT16), /* input-context-ID */ + _FRAME(BIT16), /* X */ + _FRAME(BIT16), /* Y */ + _FRAME(EOL), +}; diff --git a/IMdkit/i18nIc.c b/IMdkit/i18nIc.c new file mode 100644 index 0000000..61b576f --- /dev/null +++ b/IMdkit/i18nIc.c @@ -0,0 +1,1106 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "FrameMgr.h" +#include "XimFunc.h" + +#define IC_SIZE 64 + +/* Set IC values */ +static void SetCardAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + FrameMgr fm; + + /*endif*/ + if (value_length == sizeof (CARD8)) + { + memmove (*value_buf, p, value_length); + } + else if (value_length == sizeof (CARD16)) + { + INT16 value; + extern XimFrameRec short_fr[]; + + fm = FrameMgrInit (short_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, value); + FrameMgrFree (fm); + memmove (*value_buf, &value, value_length); + } + else if (value_length == sizeof(CARD32)) + { + INT32 value; + extern XimFrameRec long_fr[]; + + fm = FrameMgrInit (long_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, value); + FrameMgrFree (fm); + memmove (*value_buf, &value, value_length); + } + /*endif*/ + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = *value_buf; + + *value_buf += value_length; +} + +static void SetFontAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + char *base_name; + CARD16 base_length; + FrameMgr fm; + extern XimFrameRec fontset_fr[]; + + fm = FrameMgrInit (fontset_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, base_length); + FrameMgrSetSize (fm, base_length); + + /*endif*/ + FrameMgrGetToken (fm, base_name); + FrameMgrFree(fm); + strncpy ((char *) (*value_buf), base_name, base_length); + ((char *) *value_buf)[base_length] = (char) 0; + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = *value_buf; + + *value_buf += (base_length + 1); +} + +static void SetPointAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + XPoint *buf; + FrameMgr fm; + extern XimFrameRec xpoint_fr[]; + + buf = (XPoint *) (*value_buf); + + fm = FrameMgrInit (xpoint_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, buf->x); + FrameMgrGetToken (fm, buf->y); + FrameMgrFree (fm); + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = (char *) buf; + + *value_buf += value_length; +} + +static void SetRectAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + XRectangle *buf; + FrameMgr fm; + extern XimFrameRec xrectangle_fr[]; + + buf = (XRectangle *) (*value_buf); + + fm = FrameMgrInit (xrectangle_fr, (char *) p, need_swap); + /* get data */ + FrameMgrGetToken (fm, buf->x); + FrameMgrGetToken (fm, buf->y); + FrameMgrGetToken (fm, buf->width); + FrameMgrGetToken (fm, buf->height); + FrameMgrFree (fm); + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = (char *) buf; + + *value_buf += value_length; +} + +#if 0 +static void SetHotKeyAttribute (XICAttribute *value_ret, + char *p, + XICAttr *ic_attr, + int value_length, + int need_swap, + void **value_buf) +{ + INT32 list_number; + XIMTriggerKey *hotkeys; + + memmove (&list_number, p, sizeof(INT32)); p += sizeof(INT32); + + hotkeys = (XIMTriggerKey *) (*value_buf); + + memmove (hotkeys, p, list_number*sizeof (XIMTriggerKey)); + + value_ret->attribute_id = ic_attr->attribute_id; + value_ret->name = ic_attr->name; + value_ret->name_length = ic_attr->length; + value_ret->type = ic_attr->type; + value_ret->value_length = value_length; + value_ret->value = (char *) hotkeys; + + *value_buf += value_length; +} +#endif + +/* get IC values */ +static void GetAttrHeader (unsigned char *rec, + XICAttribute *list, + int need_swap) +{ + FrameMgr fm; + extern XimFrameRec attr_head_fr[]; + + fm = FrameMgrInit (attr_head_fr, (char *) rec, need_swap); + /* put data */ + FrameMgrPutToken (fm, list->attribute_id); + FrameMgrPutToken (fm, list->value_length); + FrameMgrFree (fm); +} + +static void GetCardAttribute (char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof (CARD16)*2; + + if (list->value_length == sizeof (CARD8)) + { + memmove (recp, list->value, list->value_length); + } + else if (list->value_length == sizeof (CARD16)) + { + INT16 *value = (INT16 *) list->value; + extern XimFrameRec short_fr[]; + + fm = FrameMgrInit (short_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, *value); + FrameMgrFree (fm); + } + else if (list->value_length == sizeof (CARD32)) + { + INT32 *value = (INT32 *) list->value; + extern XimFrameRec long_fr[]; + + fm = FrameMgrInit (long_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, *value); + FrameMgrFree (fm); + } + /*endif*/ +} + +static void GetFontAttribute(char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + extern XimFrameRec fontset_fr[]; + char *base_name = (char *) list->value; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof (CARD16)*2; + + fm = FrameMgrInit (fontset_fr, (char *)recp, need_swap); + /* put data */ + FrameMgrSetSize (fm, list->value_length); + FrameMgrPutToken (fm, list->value_length); + FrameMgrPutToken (fm, base_name); + FrameMgrFree (fm); +} + +static void GetRectAttribute (char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + extern XimFrameRec xrectangle_fr[]; + XRectangle *rect = (XRectangle *) list->value; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof(CARD16)*2; + + fm = FrameMgrInit (xrectangle_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, rect->x); + FrameMgrPutToken (fm, rect->y); + FrameMgrPutToken (fm, rect->width); + FrameMgrPutToken (fm, rect->height); + FrameMgrFree (fm); +} + +static void GetPointAttribute (char *rec, XICAttribute *list, int need_swap) +{ + FrameMgr fm; + extern XimFrameRec xpoint_fr[]; + XPoint *rect = (XPoint *) list->value; + unsigned char *recp = (unsigned char *) rec; + + GetAttrHeader (recp, list, need_swap); + recp += sizeof(CARD16)*2; + + fm = FrameMgrInit (xpoint_fr, (char *) recp, need_swap); + /* put data */ + FrameMgrPutToken (fm, rect->x); + FrameMgrPutToken (fm, rect->y); + FrameMgrFree (fm); +} + +static int ReadICValue (Xi18n i18n_core, + CARD16 icvalue_id, + int value_length, + void *p, + XICAttribute *value_ret, + CARD16 *number_ret, + int need_swap, + void **value_buf) +{ + XICAttr *ic_attr = i18n_core->address.xic_attr; + int i; + + *number_ret = (CARD16) 0; + + for (i = 0; i < i18n_core->address.ic_attr_num; i++, ic_attr++) + { + if (ic_attr->attribute_id == icvalue_id) + break; + /*endif*/ + } + /*endfor*/ + switch (ic_attr->type) + { + case XimType_NEST: + { + int total_length = 0; + CARD16 attribute_ID; + INT16 attribute_length; + unsigned char *p1 = (unsigned char *) p; + CARD16 ic_len = 0; + CARD16 number; + FrameMgr fm; + extern XimFrameRec attr_head_fr[]; + + while (total_length < value_length) + { + fm = FrameMgrInit (attr_head_fr, (char *) p1, need_swap); + /* get data */ + FrameMgrGetToken (fm, attribute_ID); + FrameMgrGetToken (fm, attribute_length); + FrameMgrFree (fm); + p1 += sizeof (CARD16)*2; + ReadICValue (i18n_core, + attribute_ID, + attribute_length, + p1, + (value_ret + ic_len), + &number, + need_swap, + value_buf); + ic_len++; + *number_ret += number; + p1 += attribute_length; + p1 += IMPAD (attribute_length); + total_length += (CARD16) sizeof(CARD16)*2 + + (INT16) attribute_length + + IMPAD (attribute_length); + } + /*endwhile*/ + return ic_len; + } + + case XimType_CARD8: + case XimType_CARD16: + case XimType_CARD32: + case XimType_Window: + SetCardAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + + case XimType_XFontSet: + SetFontAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + + case XimType_XRectangle: + SetRectAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + + case XimType_XPoint: + SetPointAttribute(value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; + +#if 0 + case XimType_XIMHotKeyTriggers: + SetHotKeyAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf); + *number_ret = (CARD16) 1; + return *number_ret; +#endif + } + /*endswitch*/ + return 0; +} + +static XICAttribute *CreateNestedList (CARD16 attr_id, + XICAttribute *list, + int number, + int need_swap) +{ + XICAttribute *nest_list = NULL; + register int i; + char *values = NULL; + char *valuesp; + int value_length = 0; + + if (number == 0) + return NULL; + /*endif*/ + for (i = 0; i < number; i++) + { + value_length += sizeof (CARD16)*2; + value_length += list[i].value_length; + value_length += IMPAD (list[i].value_length); + } + /*endfor*/ + if ((values = (char *) malloc (value_length)) == NULL) + return NULL; + /*endif*/ + memset (values, 0, value_length); + + valuesp = values; + for (i = 0; i < number; i++) + { + switch (list[i].type) + { + case XimType_CARD8: + case XimType_CARD16: + case XimType_CARD32: + case XimType_Window: + GetCardAttribute (valuesp, &list[i], need_swap); + break; + + case XimType_XFontSet: + GetFontAttribute (valuesp, &list[i], need_swap); + break; + + case XimType_XRectangle: + GetRectAttribute (valuesp, &list[i], need_swap); + break; + + case XimType_XPoint: + GetPointAttribute (valuesp, &list[i], need_swap); + break; + +#if 0 + case XimType_XIMHotKeyTriggers: + GetHotKeyAttribute (valuesp, &list[i], need_swap); + break; +#endif + } + /*endswitch*/ + valuesp += sizeof (CARD16)*2; + valuesp += list[i].value_length; + valuesp += IMPAD(list[i].value_length); + } + /*endfor*/ + + nest_list = (XICAttribute *) malloc (sizeof (XICAttribute)); + if (nest_list == NULL) + return NULL; + /*endif*/ + memset (nest_list, 0, sizeof (XICAttribute)); + nest_list->value = (void *) malloc (value_length); + if (nest_list->value == NULL) + return NULL; + /*endif*/ + memset (nest_list->value, 0, sizeof (value_length)); + + nest_list->attribute_id = attr_id; + nest_list->value_length = value_length; + memmove (nest_list->value, values, value_length); + + XFree (values); + return nest_list; +} + +static Bool IsNestedList (Xi18n i18n_core, CARD16 icvalue_id) +{ + XICAttr *ic_attr = i18n_core->address.xic_attr; + int i; + + for (i = 0; i < i18n_core->address.ic_attr_num; i++, ic_attr++) + { + if (ic_attr->attribute_id == icvalue_id) + { + if (ic_attr->type == XimType_NEST) + return True; + /*endif*/ + return False; + } + /*endif*/ + } + /*endfor*/ + return False; +} + +static Bool IsSeparator (Xi18n i18n_core, CARD16 icvalue_id) +{ + return (i18n_core->address.separatorAttr_id == icvalue_id); +} + +static int GetICValue (Xi18n i18n_core, + XICAttribute *attr_ret, + CARD16 *id_list, + int list_num) +{ + XICAttr *xic_attr = i18n_core->address.xic_attr; + register int i; + register int j; + register int n; + + i = + n = 0; + if (IsNestedList (i18n_core, id_list[i])) + { + i++; + while (i < list_num && !IsSeparator (i18n_core, id_list[i])) + { + for (j = 0; j < i18n_core->address.ic_attr_num; j++) + { + if (xic_attr[j].attribute_id == id_list[i]) + { + attr_ret[n].attribute_id = xic_attr[j].attribute_id; + attr_ret[n].name_length = xic_attr[j].length; + attr_ret[n].name = malloc (xic_attr[j].length + 1); + strcpy(attr_ret[n].name, xic_attr[j].name); + attr_ret[n].type = xic_attr[j].type; + n++; + i++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endwhile*/ + } + else + { + for (j = 0; j < i18n_core->address.ic_attr_num; j++) + { + if (xic_attr[j].attribute_id == id_list[i]) + { + attr_ret[n].attribute_id = xic_attr[j].attribute_id; + attr_ret[n].name_length = xic_attr[j].length; + attr_ret[n].name = malloc (xic_attr[j].length + 1); + strcpy(attr_ret[n].name, xic_attr[j].name); + attr_ret[n].type = xic_attr[j].type; + n++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endif*/ + return n; +} + +static void SwapAttributes (XICAttribute *list, + int number){ + FrameMgr fm; + CARD16 c16; + extern XimFrameRec short_fr[]; + CARD32 c32; + extern XimFrameRec long_fr[]; + XPoint xpoint; + extern XimFrameRec xpoint_fr[]; + XRectangle xrect; + extern XimFrameRec xrectangle_fr[]; + int i; + + for (i = 0; i < number; ++i, ++list) { + if (list->value == NULL) + continue; + switch (list->type) { + case XimType_CARD16: + fm = FrameMgrInit (short_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, c16); + memmove(list->value, &c16, sizeof(CARD16)); + FrameMgrFree (fm); + break; + case XimType_CARD32: + case XimType_Window: + fm = FrameMgrInit (long_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, c32); + memmove(list->value, &c32, sizeof(CARD32)); + FrameMgrFree (fm); + break; + case XimType_XRectangle: + fm = FrameMgrInit (xrectangle_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, xrect); + memmove(list->value, &xrect, sizeof(XRectangle)); + FrameMgrFree (fm); + break; + case XimType_XPoint: + fm = FrameMgrInit (xpoint_fr, (char *)list->value, 1); + FrameMgrGetToken (fm, xpoint); + memmove(list->value, &xpoint, sizeof(XPoint)); + FrameMgrFree (fm); + break; + default: + break; + } + } +} + +/* called from CreateICMessageProc and SetICValueMessageProc */ +void _Xi18nChangeIC (XIMS ims, + IMProtocol *call_data, + unsigned char *p, + int create_flag) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + CARD16 byte_length; + register int total_size; + unsigned char *reply = NULL; + register int i; + register int attrib_num; + XICAttribute *attrib_list; + XICAttribute pre_attr[IC_SIZE]; + XICAttribute sts_attr[IC_SIZE]; + XICAttribute ic_attr[IC_SIZE]; + CARD16 preedit_ic_num = 0; + CARD16 status_ic_num = 0; + CARD16 ic_num = 0; + CARD16 connect_id = call_data->any.connect_id; + IMChangeICStruct *changeic = (IMChangeICStruct *) &call_data->changeic; + extern XimFrameRec create_ic_fr[]; + extern XimFrameRec create_ic_reply_fr[]; + extern XimFrameRec set_ic_values_fr[]; + extern XimFrameRec set_ic_values_reply_fr[]; + CARD16 input_method_ID; + + void *value_buf = NULL; + void *value_buf_ptr; + + register int total_value_length = 0; + + memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE); + + if (create_flag == True) + { + fm = FrameMgrInit (create_ic_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + } + else + { + fm = FrameMgrInit (set_ic_values_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, changeic->icid); + FrameMgrGetToken (fm, byte_length); + } + /*endif*/ + attrib_list = (XICAttribute *) malloc (sizeof (XICAttribute)*IC_SIZE); + if (!attrib_list) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (attrib_list, 0, sizeof(XICAttribute)*IC_SIZE); + + attrib_num = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + void *value; + int value_length; + + FrameMgrGetToken (fm, attrib_list[attrib_num].attribute_id); + FrameMgrGetToken (fm, value_length); + FrameMgrSetSize (fm, value_length); + attrib_list[attrib_num].value_length = value_length; + FrameMgrGetToken (fm, value); + attrib_list[attrib_num].value = (void *) malloc (value_length + 1); + memmove (attrib_list[attrib_num].value, value, value_length); + ((char *)attrib_list[attrib_num].value)[value_length] = '\0'; + attrib_num++; + total_value_length += (value_length + 1); + } + /*endwhile*/ + + value_buf = (void *) malloc (total_value_length); + value_buf_ptr = value_buf; + + if (!value_buf) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + for (i = 0; i < attrib_num; i++) + XFree (attrib_list[i].value); + /*endfor*/ + XFree (attrib_list); + return; + } + /*endif*/ + + for (i = 0; i < attrib_num; i++) + { + CARD16 number; + + if (IsNestedList (i18n_core, attrib_list[i].attribute_id)) + { + if (attrib_list[i].attribute_id + == i18n_core->address.preeditAttr_id) + { + ReadICValue (i18n_core, + attrib_list[i].attribute_id, + attrib_list[i].value_length, + attrib_list[i].value, + &pre_attr[preedit_ic_num], + &number, + _Xi18nNeedSwap(i18n_core, connect_id), + &value_buf_ptr); + preedit_ic_num += number; + } + else if (attrib_list[i].attribute_id == i18n_core->address.statusAttr_id) + { + ReadICValue (i18n_core, + attrib_list[i].attribute_id, + attrib_list[i].value_length, + attrib_list[i].value, + &sts_attr[status_ic_num], + &number, + _Xi18nNeedSwap (i18n_core, connect_id), + &value_buf_ptr); + status_ic_num += number; + } + else + { + /* another nested list.. possible? */ + } + /*endif*/ + } + else + { + ReadICValue (i18n_core, + attrib_list[i].attribute_id, + attrib_list[i].value_length, + attrib_list[i].value, + &ic_attr[ic_num], + &number, + _Xi18nNeedSwap (i18n_core, connect_id), + &value_buf_ptr); + ic_num += number; + } + /*endif*/ + } + /*endfor*/ + for (i = 0; i < attrib_num; i++) + XFree (attrib_list[i].value); + /*endfor*/ + XFree (attrib_list); + + FrameMgrFree (fm); + + changeic->preedit_attr_num = preedit_ic_num; + changeic->status_attr_num = status_ic_num; + changeic->ic_attr_num = ic_num; + changeic->preedit_attr = pre_attr; + changeic->status_attr = sts_attr; + changeic->ic_attr = ic_attr; + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) { + XFree (value_buf); + return; + } + /*endif*/ + } + + XFree (value_buf); + + /*endif*/ + if (create_flag == True) + { + fm = FrameMgrInit (create_ic_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + } + else + { + fm = FrameMgrInit (set_ic_values_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + } + /*endif*/ + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, changeic->icid); + + if (create_flag == True) + { + _Xi18nSendMessage (ims, + connect_id, + XIM_CREATE_IC_REPLY, + 0, + reply, + total_size); + } + else + { + _Xi18nSendMessage (ims, + connect_id, + XIM_SET_IC_VALUES_REPLY, + 0, + reply, + total_size); + } + /*endif*/ + if (create_flag == True) + { + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + + if (on_key_num == 0 && off_key_num == 0) + { + long mask; + + if (i18n_core->address.imvalue_mask & I18N_FILTERMASK) + mask = i18n_core->address.filterevent_mask; + else + mask = DEFAULT_FILTER_MASK; + /*endif*/ + /* static event flow is default */ + _Xi18nSetEventMask (ims, + connect_id, + input_method_ID, + changeic->icid, + mask, + ~mask); + } + /*endif*/ + } + /*endif*/ + FrameMgrFree (fm); + XFree(reply); +} + +/* called from GetICValueMessageProc */ +void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + extern XimFrameRec get_ic_values_fr[]; + extern XimFrameRec get_ic_values_reply_fr[]; + CARD16 byte_length; + register int total_size; + unsigned char *reply = NULL; + XICAttribute *preedit_ret = NULL; + XICAttribute *status_ret = NULL; + register int i; + register int number; + int iter_count; + CARD16 *attrID_list; + XICAttribute pre_attr[IC_SIZE]; + XICAttribute sts_attr[IC_SIZE]; + XICAttribute ic_attr[IC_SIZE]; + CARD16 pre_count = 0; + CARD16 sts_count = 0; + CARD16 ic_count = 0; + IMChangeICStruct *getic = (IMChangeICStruct *) &call_data->changeic; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE); + memset (ic_attr, 0, sizeof (XICAttribute)*IC_SIZE); + + fm = FrameMgrInit (get_ic_values_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, getic->icid); + FrameMgrGetToken (fm, byte_length); + + attrID_list = (CARD16 *) malloc (sizeof (CARD16)*IC_SIZE); /* bogus */ + memset (attrID_list, 0, sizeof (CARD16)*IC_SIZE); + + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + FrameMgrGetToken (fm, attrID_list[number++]); + /*endwhile*/ + FrameMgrFree (fm); + + i = 0; + while (i < number) + { + int read_number; + + if (IsNestedList (i18n_core, attrID_list[i])) + { + if (attrID_list[i] == i18n_core->address.preeditAttr_id) + { + read_number = GetICValue (i18n_core, + &pre_attr[pre_count], + &attrID_list[i], + number); + i += read_number + 1; + pre_count += read_number; + } + else if (attrID_list[i] == i18n_core->address.statusAttr_id) + { + read_number = GetICValue (i18n_core, + &sts_attr[sts_count], + &attrID_list[i], + number); + i += read_number + 1; + sts_count += read_number; + } + else + { + /* another nested list.. possible? */ + } + /*endif*/ + } + else + { + read_number = GetICValue (i18n_core, + &ic_attr[ic_count], + &attrID_list[i], + number); + i += read_number; + ic_count += read_number; + } + /*endif*/ + } + /*endwhile*/ + getic->preedit_attr_num = pre_count; + getic->status_attr_num = sts_count; + getic->ic_attr_num = ic_count; + getic->preedit_attr = pre_attr; + getic->status_attr = sts_attr; + getic->ic_attr = ic_attr; + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + if (_Xi18nNeedSwap (i18n_core, connect_id)) + SwapAttributes(getic->ic_attr, getic->ic_attr_num); + } + /*endif*/ + iter_count = getic->ic_attr_num; + + preedit_ret = CreateNestedList (i18n_core->address.preeditAttr_id, + getic->preedit_attr, + getic->preedit_attr_num, + _Xi18nNeedSwap (i18n_core, connect_id)); + if (preedit_ret) + iter_count++; + /*endif*/ + status_ret = CreateNestedList (i18n_core->address.statusAttr_id, + getic->status_attr, + getic->status_attr_num, + _Xi18nNeedSwap (i18n_core, connect_id)); + if (status_ret) + iter_count++; + /*endif*/ + + fm = FrameMgrInit (get_ic_values_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of ic_attribute */ + FrameMgrSetIterCount (fm, iter_count); + + /* set length of BARRAY item in xicattribute_fr */ + for (i = 0; i < (int) getic->ic_attr_num; i++) + FrameMgrSetSize (fm, ic_attr[i].value_length); + /*endfor*/ + + if (preedit_ret) + FrameMgrSetSize (fm, preedit_ret->value_length); + /*endif*/ + if (status_ret) + FrameMgrSetSize (fm, status_ret->value_length); + /*endif*/ + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (reply == NULL) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, getic->icid); + + for (i = 0; i < (int) getic->ic_attr_num; i++) + { + FrameMgrPutToken (fm, ic_attr[i].attribute_id); + FrameMgrPutToken (fm, ic_attr[i].value_length); + FrameMgrPutToken (fm, ic_attr[i].value); + } + /*endfor*/ + if (preedit_ret) + { + FrameMgrPutToken (fm, preedit_ret->attribute_id); + FrameMgrPutToken (fm, preedit_ret->value_length); + FrameMgrPutToken (fm, preedit_ret->value); + } + /*endif*/ + if (status_ret) + { + FrameMgrPutToken (fm, status_ret->attribute_id); + FrameMgrPutToken (fm, status_ret->value_length); + FrameMgrPutToken (fm, status_ret->value); + } + /*endif*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_GET_IC_VALUES_REPLY, + 0, + reply, + total_size); + XFree (reply); + XFree (attrID_list); + + for (i = 0; i < (int) getic->ic_attr_num; i++) + { + if (getic->ic_attr[i].name) + XFree (getic->ic_attr[i].name); + /*endif*/ + if (getic->ic_attr[i].value) + XFree (getic->ic_attr[i].value); + /*endif*/ + } + /*endfor*/ + for (i = 0; i < (int) getic->preedit_attr_num; i++) + { + if (getic->preedit_attr[i].name) + XFree (getic->preedit_attr[i].name); + /*endif*/ + if (getic->preedit_attr[i].value) + XFree (getic->preedit_attr[i].value); + /*endif*/ + } + /*endfor*/ + for (i = 0; i < (int) getic->status_attr_num; i++) + { + if (getic->status_attr[i].name) + XFree (getic->status_attr[i].name); + /*endif*/ + if (getic->status_attr[i].value) + XFree (getic->status_attr[i].value); + /*endif*/ + } + /*endfor*/ + + if (preedit_ret) + { + XFree (preedit_ret->value); + XFree (preedit_ret); + } + /*endif*/ + if (status_ret) + { + XFree (status_ret->value); + XFree (status_ret); + } + /*endif*/ + FrameMgrFree (fm); +} diff --git a/IMdkit/i18nMethod.c b/IMdkit/i18nMethod.c new file mode 100644 index 0000000..9106479 --- /dev/null +++ b/IMdkit/i18nMethod.c @@ -0,0 +1,1151 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include +#ifndef NEED_EVENTS +#define NEED_EVENTS +#endif +#include +#undef NEED_EVENTS +#include "FrameMgr.h" +#include "IMdkit.h" +#include "Xi18n.h" +#include "XimFunc.h" + +extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16); + +static void *xi18n_setup (Display *, XIMArg *); +static Status xi18n_openIM (XIMS); +static Status xi18n_closeIM (XIMS); +static char *xi18n_setIMValues (XIMS, XIMArg *); +static char *xi18n_getIMValues (XIMS, XIMArg *); +static Status xi18n_forwardEvent (XIMS, XPointer); +static Status xi18n_commit (XIMS, XPointer); +static int xi18n_callCallback (XIMS, XPointer); +static int xi18n_preeditStart (XIMS, XPointer); +static int xi18n_preeditEnd (XIMS, XPointer); +static int xi18n_syncXlib (XIMS, XPointer); + +#ifndef XIM_SERVERS +#define XIM_SERVERS "XIM_SERVERS" +#endif +static Atom XIM_Servers = None; + + +IMMethodsRec Xi18n_im_methods = +{ + xi18n_setup, + xi18n_openIM, + xi18n_closeIM, + xi18n_setIMValues, + xi18n_getIMValues, + xi18n_forwardEvent, + xi18n_commit, + xi18n_callCallback, + xi18n_preeditStart, + xi18n_preeditEnd, + xi18n_syncXlib, +}; + +extern Bool _Xi18nCheckXAddress (Xi18n, TransportSW *, char *); +extern Bool _Xi18nCheckTransAddress (Xi18n, TransportSW *, char *); + +TransportSW _TransR[] = +{ + {"X", 1, _Xi18nCheckXAddress}, +#ifdef TCPCONN + {"tcp", 3, _Xi18nCheckTransAddress}, + {"local", 5, _Xi18nCheckTransAddress}, +#endif +#ifdef DNETCONN + {"decnet", 6, _Xi18nCheckTransAddress}, +#endif + {(char *) NULL, 0, (Bool (*) ()) NULL} +}; + +static Bool GetInputStyles (Xi18n i18n_core, XIMStyles **p_style) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMStyles *p; + int i; + + p = &address->input_styles; + if ((*p_style = (XIMStyles *) malloc (sizeof (XIMStyles) + + p->count_styles*sizeof (XIMStyle))) + == NULL) + { + return False; + } + /*endif*/ + (*p_style)->count_styles = p->count_styles; + (*p_style)->supported_styles = (XIMStyle *) ((XPointer) *p_style + sizeof (XIMStyles)); + for (i = 0; i < (int) p->count_styles; i++) + (*p_style)->supported_styles[i] = p->supported_styles[i]; + /*endfor*/ + return True; +} + +static Bool GetOnOffKeys (Xi18n i18n_core, long mask, XIMTriggerKeys **p_key) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMTriggerKeys *p; + int i; + + if (mask & I18N_ON_KEYS) + p = &address->on_keys; + else + p = &address->off_keys; + /*endif*/ + if ((*p_key = (XIMTriggerKeys *) malloc (sizeof(XIMTriggerKeys) + + p->count_keys*sizeof(XIMTriggerKey))) + == NULL) + { + return False; + } + /*endif*/ + (*p_key)->count_keys = p->count_keys; + (*p_key)->keylist = + (XIMTriggerKey *) ((XPointer) *p_key + sizeof(XIMTriggerKeys)); + for (i = 0; i < (int) p->count_keys; i++) + { + (*p_key)->keylist[i].keysym = p->keylist[i].keysym; + (*p_key)->keylist[i].modifier = p->keylist[i].modifier; + (*p_key)->keylist[i].modifier_mask = p->keylist[i].modifier_mask; + } + /*endfor*/ + return True; +} + +static Bool GetEncodings(Xi18n i18n_core, XIMEncodings **p_encoding) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMEncodings *p; + int i; + + p = &address->encoding_list; + + if ((*p_encoding = (XIMEncodings *) malloc (sizeof (XIMEncodings) + + p->count_encodings*sizeof(XIMEncoding))) == NULL) + { + return False; + } + /*endif*/ + (*p_encoding)->count_encodings = p->count_encodings; + (*p_encoding)->supported_encodings = + (XIMEncoding *) ((XPointer)*p_encoding + sizeof (XIMEncodings)); + for (i = 0; i < (int) p->count_encodings; i++) + { + (*p_encoding)->supported_encodings[i] + = (char *) malloc (strlen (p->supported_encodings[i]) + 1); + strcpy ((*p_encoding)->supported_encodings[i], + p->supported_encodings[i]); + } + /*endif*/ + return True; +} + +static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) &i18n_core->address; + XIMArg *p; + + if (mode == I18N_OPEN || mode == I18N_SET) + { + for (p = args; p->name != NULL; p++) + { + if (strcmp (p->name, IMLocale) == 0) + { + if (address->imvalue_mask & I18N_IM_LOCALE) + return IMLocale; + /*endif*/ + address->im_locale = (char *) malloc (strlen (p->value) + 1); + if (!address->im_locale) + return IMLocale; + /*endif*/ + strcpy (address->im_locale, p->value); + address->imvalue_mask |= I18N_IM_LOCALE; + } + else if (strcmp (p->name, IMServerTransport) == 0) + { + if (address->imvalue_mask & I18N_IM_ADDRESS) + return IMServerTransport; + /*endif*/ + address->im_addr = (char *) malloc (strlen (p->value) + 1); + if (!address->im_addr) + return IMServerTransport; + /*endif*/ + strcpy(address->im_addr, p->value); + address->imvalue_mask |= I18N_IM_ADDRESS; + } + else if (strcmp (p->name, IMServerName) == 0) + { + if (address->imvalue_mask & I18N_IM_NAME) + return IMServerName; + /*endif*/ + address->im_name = (char *) malloc (strlen (p->value) + 1); + if (!address->im_name) + return IMServerName; + /*endif*/ + strcpy (address->im_name, p->value); + address->imvalue_mask |= I18N_IM_NAME; + } + else if (strcmp (p->name, IMServerWindow) == 0) + { + if (address->imvalue_mask & I18N_IMSERVER_WIN) + return IMServerWindow; + /*endif*/ + address->im_window = (Window) p->value; + address->imvalue_mask |= I18N_IMSERVER_WIN; + } + else if (strcmp (p->name, IMInputStyles) == 0) + { + if (address->imvalue_mask & I18N_INPUT_STYLES) + return IMInputStyles; + /*endif*/ + address->input_styles.count_styles = + ((XIMStyles*)p->value)->count_styles; + address->input_styles.supported_styles = + (XIMStyle *) malloc (sizeof (XIMStyle)*address->input_styles.count_styles); + if (address->input_styles.supported_styles == (XIMStyle *) NULL) + return IMInputStyles; + /*endif*/ + memmove (address->input_styles.supported_styles, + ((XIMStyles *) p->value)->supported_styles, + sizeof (XIMStyle)*address->input_styles.count_styles); + address->imvalue_mask |= I18N_INPUT_STYLES; + } + else if (strcmp (p->name, IMProtocolHandler) == 0) + { + address->improto = (IMProtoHandler) p->value; + address->imvalue_mask |= I18N_IM_HANDLER; + } + else if (strcmp (p->name, IMOnKeysList) == 0) + { + if (address->imvalue_mask & I18N_ON_KEYS) + return IMOnKeysList; + /*endif*/ + address->on_keys.count_keys = + ((XIMTriggerKeys *) p->value)->count_keys; + address->on_keys.keylist = + (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->on_keys.count_keys); + if (address->on_keys.keylist == (XIMTriggerKey *) NULL) + return IMOnKeysList; + /*endif*/ + memmove (address->on_keys.keylist, + ((XIMTriggerKeys *) p->value)->keylist, + sizeof (XIMTriggerKey)*address->on_keys.count_keys); + address->imvalue_mask |= I18N_ON_KEYS; + } + else if (strcmp (p->name, IMOffKeysList) == 0) + { + if (address->imvalue_mask & I18N_OFF_KEYS) + return IMOffKeysList; + /*endif*/ + address->off_keys.count_keys = + ((XIMTriggerKeys *) p->value)->count_keys; + address->off_keys.keylist = + (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->off_keys.count_keys); + if (address->off_keys.keylist == (XIMTriggerKey *) NULL) + return IMOffKeysList; + /*endif*/ + memmove (address->off_keys.keylist, + ((XIMTriggerKeys *) p->value)->keylist, + sizeof (XIMTriggerKey)*address->off_keys.count_keys); + address->imvalue_mask |= I18N_OFF_KEYS; + } + else if (strcmp (p->name, IMEncodingList) == 0) + { + if (address->imvalue_mask & I18N_ENCODINGS) + return IMEncodingList; + /*endif*/ + address->encoding_list.count_encodings = + ((XIMEncodings *) p->value)->count_encodings; + address->encoding_list.supported_encodings = + (XIMEncoding *) malloc (sizeof (XIMEncoding)*address->encoding_list.count_encodings); + if (address->encoding_list.supported_encodings + == (XIMEncoding *) NULL) + { + return IMEncodingList; + } + /*endif*/ + memmove (address->encoding_list.supported_encodings, + ((XIMEncodings *) p->value)->supported_encodings, + sizeof (XIMEncoding)*address->encoding_list.count_encodings); + address->imvalue_mask |= I18N_ENCODINGS; + } + else if (strcmp (p->name, IMFilterEventMask) == 0) + { + if (address->imvalue_mask & I18N_FILTERMASK) + return IMFilterEventMask; + /*endif*/ + address->filterevent_mask = (long) p->value; + address->imvalue_mask |= I18N_FILTERMASK; + } + /*endif*/ + } + /*endfor*/ + if (mode == I18N_OPEN) + { + /* check mandatory IM values */ + if (!(address->imvalue_mask & I18N_IM_LOCALE)) + { + /* locales must be set in IMOpenIM */ + return IMLocale; + } + /*endif*/ + if (!(address->imvalue_mask & I18N_IM_ADDRESS)) + { + /* address must be set in IMOpenIM */ + return IMServerTransport; + } + /*endif*/ + } + /*endif*/ + } + else if (mode == I18N_GET) + { + for (p = args; p->name != NULL; p++) + { + if (strcmp (p->name, IMLocale) == 0) + { + p->value = (char *) malloc (strlen (address->im_locale) + 1); + if (!p->value) + return IMLocale; + /*endif*/ + strcpy (p->value, address->im_locale); + } + else if (strcmp (p->name, IMServerTransport) == 0) + { + p->value = (char *) malloc (strlen (address->im_addr) + 1); + if (!p->value) + return IMServerTransport; + /*endif*/ + strcpy (p->value, address->im_addr); + } + else if (strcmp (p->name, IMServerName) == 0) + { + if (address->imvalue_mask & I18N_IM_NAME) + { + p->value = (char *) malloc (strlen (address->im_name) + 1); + if (!p->value) + return IMServerName; + /*endif*/ + strcpy (p->value, address->im_name); + } + else + { + return IMServerName; + } + /*endif*/ + } + else if (strcmp (p->name, IMServerWindow) == 0) + { + if (address->imvalue_mask & I18N_IMSERVER_WIN) + *((Window *) (p->value)) = address->im_window; + else + return IMServerWindow; + /*endif*/ + } + else if (strcmp (p->name, IMInputStyles) == 0) + { + if (GetInputStyles (i18n_core, + (XIMStyles **) p->value) == False) + { + return IMInputStyles; + } + /*endif*/ + } + else if (strcmp (p->name, IMProtocolHandler) == 0) + { + if (address->imvalue_mask & I18N_IM_HANDLER) + *((IMProtoHandler *) (p->value)) = address->improto; + else + return IMProtocolHandler; + /*endif*/ + } + else if (strcmp (p->name, IMOnKeysList) == 0) + { + if (address->imvalue_mask & I18N_ON_KEYS) + { + if (GetOnOffKeys (i18n_core, + I18N_ON_KEYS, + (XIMTriggerKeys **) p->value) == False) + { + return IMOnKeysList; + } + /*endif*/ + } + else + { + return IMOnKeysList; + } + /*endif*/ + } + else if (strcmp (p->name, IMOffKeysList) == 0) + { + if (address->imvalue_mask & I18N_OFF_KEYS) + { + if (GetOnOffKeys (i18n_core, + I18N_OFF_KEYS, + (XIMTriggerKeys **) p->value) == False) + { + return IMOffKeysList; + } + /*endif*/ + } + else + { + return IMOffKeysList; + } + /*endif*/ + } + else if (strcmp (p->name, IMEncodingList) == 0) + { + if (address->imvalue_mask & I18N_ENCODINGS) + { + if (GetEncodings (i18n_core, + (XIMEncodings **) p->value) == False) + { + return IMEncodingList; + } + /*endif*/ + } + else + { + return IMEncodingList; + } + /*endif*/ + } + else if (strcmp (p->name, IMFilterEventMask) == 0) + { + if (address->imvalue_mask & I18N_FILTERMASK) + *((long *) (p->value)) = address->filterevent_mask; + else + return IMFilterEventMask; + /*endif*/ + } + /*endif*/ + } + /*endfor*/ + } + /*endif*/ + return NULL; +} + +static int CheckIMName (Xi18n i18n_core) +{ + char *address = i18n_core->address.im_addr; + int i; + + for (i = 0; _TransR[i].transportname; i++) + { + while (*address == ' ' || *address == '\t') + address++; + /*endwhile*/ + if (strncmp (address, + _TransR[i].transportname, + _TransR[i].namelen) == 0 + && + address[_TransR[i].namelen] == '/') + { + if (_TransR[i].checkAddr (i18n_core, + &_TransR[i], + address + _TransR[i].namelen + 1) == True) + { + return True; + } + /*endif*/ + return False; + } + /*endif*/ + } + /*endfor*/ + return False; +} + +static int SetXi18nSelectionOwner(Xi18n i18n_core) +{ + Display *dpy = i18n_core->address.dpy; + Window ims_win = i18n_core->address.im_window; + Window root = RootWindow (dpy, DefaultScreen (dpy)); + Atom realtype; + int realformat; + unsigned long bytesafter; + long *data=NULL; + unsigned long length; + Atom atom; + int i; + int found; + int forse = False; + char buf[256]; + + (void)snprintf(buf, 256, "@server=%s", i18n_core->address.im_name); + if ((atom = XInternAtom(dpy, buf, False)) == 0) + return False; + i18n_core->address.selection = atom; + + if (XIM_Servers == None) + XIM_Servers = XInternAtom (dpy, XIM_SERVERS, False); + /*endif*/ + XGetWindowProperty (dpy, + root, + XIM_Servers, + 0L, + 1000000L, + False, + XA_ATOM, + &realtype, + &realformat, + &length, + &bytesafter, + (unsigned char **) (&data)); + if (realtype != None && (realtype != XA_ATOM || realformat != 32)) { + if (data != NULL) + XFree ((char *) data); + return False; + } + + found = False; + for (i = 0; i < length; i++) { + if (data[i] == atom) { + Window owner; + found = True; + if ((owner = XGetSelectionOwner (dpy, atom)) != ims_win) { + if (owner == None || forse == True) + XSetSelectionOwner (dpy, atom, ims_win, CurrentTime); + else + return False; + } + break; + } + } + + if (found == False) { + XSetSelectionOwner (dpy, atom, ims_win, CurrentTime); + XChangeProperty (dpy, + root, + XIM_Servers, + XA_ATOM, + 32, + PropModePrepend, + (unsigned char *) &atom, + 1); + } + else { + /* + * We always need to generate the PropertyNotify to the Root Window + */ + XChangeProperty (dpy, + root, + XIM_Servers, + XA_ATOM, + 32, + PropModePrepend, + (unsigned char *) data, + 0); + } + if (data != NULL) + XFree ((char *) data); + + /* Intern "LOCALES" and "TRANSOPORT" Target Atoms */ + i18n_core->address.Localename = XInternAtom (dpy, LOCALES, False); + i18n_core->address.Transportname = XInternAtom (dpy, TRANSPORT, False); + return (XGetSelectionOwner (dpy, atom) == ims_win); +} + +static int DeleteXi18nAtom(Xi18n i18n_core) +{ + Display *dpy = i18n_core->address.dpy; + Window root = RootWindow (dpy, DefaultScreen (dpy)); + Atom realtype; + int realformat; + unsigned long bytesafter; + long *data=NULL; + unsigned long length; + Atom atom; + int i, ret; + int found; + char buf[256]; + + (void)snprintf(buf, 256, "@server=%s", i18n_core->address.im_name); + if ((atom = XInternAtom(dpy, buf, False)) == 0) + return False; + i18n_core->address.selection = atom; + + if (XIM_Servers == None) + XIM_Servers = XInternAtom (dpy, XIM_SERVERS, False); + XGetWindowProperty (dpy, + root, + XIM_Servers, + 0L, + 1000000L, + False, + XA_ATOM, + &realtype, + &realformat, + &length, + &bytesafter, + (unsigned char **) (&data)); + if (realtype != XA_ATOM || realformat != 32) { + if (data != NULL) + XFree ((char *) data); + return False; + } + + found = False; + for (i = 0; i < length; i++) { + if (data[i] == atom) { + found = True; + break; + } + } + + if (found == True) { + for (i=i+1; iaddress.dpy = dpy; + + if (ParseArgs (i18n_core, I18N_OPEN, args) != NULL) + { + XFree (i18n_core); + return NULL; + } + /*endif*/ + if (*(char *) &endian) + i18n_core->address.im_byteOrder = 'l'; + else + i18n_core->address.im_byteOrder = 'B'; + /*endif*/ + + /* install IMAttr and ICAttr list in i18n_core */ + _Xi18nInitAttrList (i18n_core); + + /* install IMExtension list in i18n_core */ + _Xi18nInitExtension (i18n_core); + + return i18n_core; +} + +static void ReturnSelectionNotify (Xi18n i18n_core, XSelectionRequestEvent *ev) +{ + XEvent event; + Display *dpy = i18n_core->address.dpy; + char buf[4096]; + + event.type = SelectionNotify; + event.xselection.requestor = ev->requestor; + event.xselection.selection = ev->selection; + event.xselection.target = ev->target; + event.xselection.time = ev->time; + event.xselection.property = ev->property; + if (ev->target == i18n_core->address.Localename) + { + snprintf (buf, 4096, "@locale=%s", i18n_core->address.im_locale); + } + else if (ev->target == i18n_core->address.Transportname) + { + snprintf (buf, 4096, "@transport=%s", i18n_core->address.im_addr); + } + /*endif*/ + XChangeProperty (dpy, + event.xselection.requestor, + ev->target, + ev->target, + 8, + PropModeReplace, + (unsigned char *) buf, + strlen (buf)); + XSendEvent (dpy, event.xselection.requestor, False, NoEventMask, &event); + XFlush (i18n_core->address.dpy); +} + +static Bool WaitXSelectionRequest (Display *dpy, + Window win, + XEvent *ev, + XPointer client_data) +{ + XIMS ims = (XIMS) client_data; + Xi18n i18n_core = ims->protocol; + + if (((XSelectionRequestEvent *) ev)->selection + == i18n_core->address.selection) + { + ReturnSelectionNotify (i18n_core, (XSelectionRequestEvent *) ev); + return True; + } + /*endif*/ + return False; +} + +static Status xi18n_openIM(XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + + if (!CheckIMName (i18n_core) + || + !SetXi18nSelectionOwner (i18n_core) + || + !i18n_core->methods.begin (ims)) + { + XFree (i18n_core->address.im_name); + XFree (i18n_core->address.im_locale); + XFree (i18n_core->address.im_addr); + XFree (i18n_core); + return False; + } + /*endif*/ + + _XRegisterFilterByType (dpy, + i18n_core->address.im_window, + SelectionRequest, + SelectionRequest, + WaitXSelectionRequest, + (XPointer)ims); + XFlush(dpy); + return True; +} + +static Status xi18n_closeIM(XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + + DeleteXi18nAtom(i18n_core); + if (!i18n_core->methods.end (ims)) + return False; + + _XUnregisterFilter (dpy, + i18n_core->address.im_window, + WaitXSelectionRequest, + (XPointer)ims); + XFree (i18n_core->address.im_name); + XFree (i18n_core->address.im_locale); + XFree (i18n_core->address.im_addr); + XFree (i18n_core); + return True; +} + +static char *xi18n_setIMValues (XIMS ims, XIMArg *args) +{ + Xi18n i18n_core = ims->protocol; + char *ret; + + if ((ret = ParseArgs (i18n_core, I18N_SET, args)) != NULL) + return ret; + /*endif*/ + return NULL; +} + +static char *xi18n_getIMValues (XIMS ims, XIMArg *args) +{ + Xi18n i18n_core = ims->protocol; + char *ret; + + if ((ret = ParseArgs (i18n_core, I18N_GET, args)) != NULL) + return ret; + /*endif*/ + return NULL; +} + +static void EventToWireEvent (XEvent *ev, xEvent *event, + CARD16 *serial, Bool byte_swap) +{ + FrameMgr fm; + extern XimFrameRec wire_keyevent_fr[]; + extern XimFrameRec short_fr[]; + BYTE b; + CARD16 c16; + CARD32 c32; + + *serial = (CARD16)(ev->xany.serial >> 16); + switch (ev->type) { + case KeyPress: + case KeyRelease: + { + XKeyEvent *kev = (XKeyEvent*)ev; + /* create FrameMgr */ + fm = FrameMgrInit(wire_keyevent_fr, (char *)(&(event->u)), byte_swap); + + /* set values */ + b = (BYTE)kev->type; FrameMgrPutToken(fm, b); + b = (BYTE)kev->keycode; FrameMgrPutToken(fm, b); + c16 = (CARD16)(kev->serial & (unsigned long)0xffff); + FrameMgrPutToken(fm, c16); + c32 = (CARD32)kev->time; FrameMgrPutToken(fm, c32); + c32 = (CARD32)kev->root; FrameMgrPutToken(fm, c32); + c32 = (CARD32)kev->window; FrameMgrPutToken(fm, c32); + c32 = (CARD32)kev->subwindow; FrameMgrPutToken(fm, c32); + c16 = (CARD16)kev->x_root; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->y_root; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->x; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->y; FrameMgrPutToken(fm, c16); + c16 = (CARD16)kev->state; FrameMgrPutToken(fm, c16); + b = (BYTE)kev->same_screen; FrameMgrPutToken(fm, b); + } + break; + default: + /* create FrameMgr */ + fm = FrameMgrInit(short_fr, (char *)(&(event->u.u.sequenceNumber)), + byte_swap); + c16 = (CARD16)(ev->xany.serial & (unsigned long)0xffff); + FrameMgrPutToken(fm, c16); + break; + } + /* free FrameMgr */ + FrameMgrFree(fm); +} + +static Status xi18n_forwardEvent (XIMS ims, XPointer xp) +{ + Xi18n i18n_core = ims->protocol; + IMForwardEventStruct *call_data = (IMForwardEventStruct *)xp; + FrameMgr fm; + extern XimFrameRec forward_event_fr[]; + register int total_size; + unsigned char *reply = NULL; + unsigned char *replyp; + CARD16 serial; + int event_size; + Xi18nClient *client; + + client = (Xi18nClient *) _Xi18nFindClient (i18n_core, call_data->connect_id); + + /* create FrameMgr */ + fm = FrameMgrInit (forward_event_fr, + NULL, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + event_size = sizeof (xEvent); + reply = (unsigned char *) malloc (total_size + event_size); + if (!reply) + { + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_ERROR, + 0, + 0, + 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size + event_size); + FrameMgrSetBuffer (fm, reply); + replyp = reply; + + call_data->sync_bit = 1; /* always sync */ + client->sync = True; + + FrameMgrPutToken (fm, call_data->connect_id); + FrameMgrPutToken (fm, call_data->icid); + FrameMgrPutToken (fm, call_data->sync_bit); + + replyp += total_size; + EventToWireEvent (&(call_data->event), + (xEvent *) replyp, + &serial, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + + FrameMgrPutToken (fm, serial); + + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_FORWARD_EVENT, + 0, + reply, + total_size + event_size); + + XFree (reply); + FrameMgrFree (fm); + + return True; +} + +static Status xi18n_commit (XIMS ims, XPointer xp) +{ + Xi18n i18n_core = ims->protocol; + IMCommitStruct *call_data = (IMCommitStruct *)xp; + FrameMgr fm; + extern XimFrameRec commit_chars_fr[]; + extern XimFrameRec commit_both_fr[]; + register int total_size; + unsigned char *reply = NULL; + CARD16 str_length; + + call_data->flag |= XimSYNCHRONUS; /* always sync */ + + if (!(call_data->flag & XimLookupKeySym) + && + (call_data->flag & XimLookupChars)) + { + fm = FrameMgrInit (commit_chars_fr, + NULL, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + + /* set length of STRING8 */ + str_length = strlen (call_data->commit_string); + FrameMgrSetSize (fm, str_length); + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_ERROR, + 0, + 0, + 0); + return False; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + str_length = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, call_data->connect_id); + FrameMgrPutToken (fm, call_data->icid); + FrameMgrPutToken (fm, call_data->flag); + FrameMgrPutToken (fm, str_length); + FrameMgrPutToken (fm, call_data->commit_string); + } + else + { + fm = FrameMgrInit (commit_both_fr, + NULL, + _Xi18nNeedSwap (i18n_core, call_data->connect_id)); + /* set length of STRING8 */ + str_length = strlen (call_data->commit_string); + if (str_length > 0) + FrameMgrSetSize (fm, str_length); + /*endif*/ + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_ERROR, + 0, + 0, + 0); + return False; + } + /*endif*/ + FrameMgrSetBuffer (fm, reply); + FrameMgrPutToken (fm, call_data->connect_id); + FrameMgrPutToken (fm, call_data->icid); + FrameMgrPutToken (fm, call_data->flag); + FrameMgrPutToken (fm, call_data->keysym); + if (str_length > 0) + { + str_length = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, str_length); + FrameMgrPutToken (fm, call_data->commit_string); + } + /*endif*/ + } + /*endif*/ + _Xi18nSendMessage (ims, + call_data->connect_id, + XIM_COMMIT, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + return True; +} + +static int xi18n_callCallback (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + switch (call_data->major_code) + { + case XIM_GEOMETRY: + return _Xi18nGeometryCallback (ims, call_data); + + case XIM_PREEDIT_START: + return _Xi18nPreeditStartCallback (ims, call_data); + + case XIM_PREEDIT_DRAW: + return _Xi18nPreeditDrawCallback (ims, call_data); + + case XIM_PREEDIT_CARET: + return _Xi18nPreeditCaretCallback (ims, call_data); + + case XIM_PREEDIT_DONE: + return _Xi18nPreeditDoneCallback (ims, call_data); + + case XIM_STATUS_START: + return _Xi18nStatusStartCallback (ims, call_data); + + case XIM_STATUS_DRAW: + return _Xi18nStatusDrawCallback (ims, call_data); + + case XIM_STATUS_DONE: + return _Xi18nStatusDoneCallback (ims, call_data); + + case XIM_STR_CONVERSION: + return _Xi18nStringConversionCallback (ims, call_data); + } + /*endswitch*/ + return False; +} + +/* preeditStart and preeditEnd are used only for Dynamic Event Flow. */ +static int xi18n_preeditStart (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + Xi18n i18n_core = ims->protocol; + IMPreeditStateStruct *preedit_state = + (IMPreeditStateStruct *) &call_data->preedit_state; + long mask; + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + + if (on_key_num == 0 && off_key_num == 0) + return False; + /*endif*/ + if (i18n_core->address.imvalue_mask & I18N_FILTERMASK) + mask = i18n_core->address.filterevent_mask; + else + mask = DEFAULT_FILTER_MASK; + /*endif*/ + _Xi18nSetEventMask (ims, + preedit_state->connect_id, + preedit_state->connect_id, + preedit_state->icid, + mask, + ~mask); + return True; +} + +static int xi18n_preeditEnd (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + Xi18n i18n_core = ims->protocol; + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + IMPreeditStateStruct *preedit_state; + + preedit_state = (IMPreeditStateStruct *) &call_data->preedit_state; + + if (on_key_num == 0 && off_key_num == 0) + return False; + /*endif*/ + + _Xi18nSetEventMask (ims, + preedit_state->connect_id, + preedit_state->connect_id, + preedit_state->icid, + 0, + 0); + return True; +} + +static int xi18n_syncXlib (XIMS ims, XPointer xp) +{ + IMProtocol *call_data = (IMProtocol *)xp; + Xi18n i18n_core = ims->protocol; + IMSyncXlibStruct *sync_xlib; + + extern XimFrameRec sync_fr[]; + FrameMgr fm; + CARD16 connect_id = call_data->any.connect_id; + int total_size; + unsigned char *reply; + + sync_xlib = (IMSyncXlibStruct *) &call_data->sync_xlib; + fm = FrameMgrInit (sync_fr, NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + total_size = FrameMgrGetTotalSize(fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return False; + } + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + /* input input-method ID */ + FrameMgrPutToken (fm, connect_id); + /* input input-context ID */ + FrameMgrPutToken (fm, sync_xlib->icid); + _Xi18nSendMessage (ims, connect_id, XIM_SYNC, 0, reply, total_size); + + FrameMgrFree (fm); + XFree(reply); + return True; +} + diff --git a/IMdkit/i18nPtHdr.c b/IMdkit/i18nPtHdr.c new file mode 100644 index 0000000..c298fff --- /dev/null +++ b/IMdkit/i18nPtHdr.c @@ -0,0 +1,1911 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include +#ifndef NEED_EVENTS +#define NEED_EVENTS +#endif +#include +#undef NEED_EVENTS +#include "FrameMgr.h" +#include "IMdkit.h" +#include "Xi18n.h" +#include "XimFunc.h" + +#ifdef XIM_DEBUG +#include + +static void DebugLog(char * msg) +{ + fputs(msg, stderr); +} +#endif + +extern Xi18nClient *_Xi18nFindClient (Xi18n, CARD16); + +static void DiscardQueue (XIMS ims, CARD16 connect_id) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient *client = (Xi18nClient *) _Xi18nFindClient (i18n_core, + connect_id); + + if (client != NULL) { + client->sync = False; + while (client->pending != NULL) { + XIMPending* pending = client->pending; + + client->pending = pending->next; + + XFree(pending->p); + XFree(pending); + } + } +} + +static void DiscardAllQueue(XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient* client = i18n_core->address.clients; + + while (client != NULL) { + if (client->sync) { + DiscardQueue(ims, client->connect_id); + } + client = client->next; + } +} + +static void GetProtocolVersion (CARD16 client_major, + CARD16 client_minor, + CARD16 *server_major, + CARD16 *server_minor) +{ + *server_major = client_major; + *server_minor = client_minor; +} + +static void ConnectMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec connect_fr[], connect_reply_fr[]; + register int total_size; + CARD16 server_major_version, server_minor_version; + unsigned char *reply = NULL; + IMConnectStruct *imconnect = + (IMConnectStruct*) &call_data->imconnect; + CARD16 connect_id = call_data->any.connect_id; + + fm = FrameMgrInit (connect_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, imconnect->byte_order); + FrameMgrGetToken (fm, imconnect->major_version); + FrameMgrGetToken (fm, imconnect->minor_version); + + FrameMgrFree (fm); + + GetProtocolVersion (imconnect->major_version, + imconnect->minor_version, + &server_major_version, + &server_minor_version); +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + fm = FrameMgrInit (connect_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, server_major_version); + FrameMgrPutToken (fm, server_minor_version); + + _Xi18nSendMessage (ims, + connect_id, + XIM_CONNECT_REPLY, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree (reply); +} + +static void DisConnectMessageProc (XIMS ims, IMProtocol *call_data) +{ + Xi18n i18n_core = ims->protocol; + unsigned char *reply = NULL; + CARD16 connect_id = call_data->any.connect_id; + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + _Xi18nSendMessage (ims, + connect_id, + XIM_DISCONNECT_REPLY, + 0, + reply, + 0); + + i18n_core->methods.disconnect (ims, connect_id); +} + +static void OpenMessageProc(XIMS ims, IMProtocol *call_data, unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec open_fr[]; + extern XimFrameRec open_reply_fr[]; + unsigned char *reply = NULL; + int str_size; + register int i, total_size; + CARD16 connect_id = call_data->any.connect_id; + int str_length; + char *name; + IMOpenStruct *imopen = (IMOpenStruct *) &call_data->imopen; + + fm = FrameMgrInit (open_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + FrameMgrGetToken (fm, name); + imopen->lang.length = str_length; + imopen->lang.name = malloc (str_length + 1); + strncpy (imopen->lang.name, name, str_length); + imopen->lang.name[str_length] = (char) 0; + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + if ((i18n_core->address.imvalue_mask & I18N_ON_KEYS) + || + (i18n_core->address.imvalue_mask & I18N_OFF_KEYS)) + { + _Xi18nSendTriggerKey (ims, connect_id); + } + /*endif*/ + XFree (imopen->lang.name); + + fm = FrameMgrInit (open_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of imattr */ + FrameMgrSetIterCount (fm, i18n_core->address.im_attr_num); + + /* set length of BARRAY item in ximattr_fr */ + for (i = 0; i < i18n_core->address.im_attr_num; i++) + { + str_size = strlen (i18n_core->address.xim_attr[i].name); + FrameMgrSetSize (fm, str_size); + } + /*endfor*/ + /* set iteration count for list of icattr */ + FrameMgrSetIterCount (fm, i18n_core->address.ic_attr_num); + /* set length of BARRAY item in xicattr_fr */ + for (i = 0; i < i18n_core->address.ic_attr_num; i++) + { + str_size = strlen (i18n_core->address.xic_attr[i].name); + FrameMgrSetSize (fm, str_size); + } + /*endfor*/ + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + /* input input-method ID */ + FrameMgrPutToken (fm, connect_id); + + for (i = 0; i < i18n_core->address.im_attr_num; i++) + { + str_size = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].attribute_id); + FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].type); + FrameMgrPutToken (fm, str_size); + FrameMgrPutToken (fm, i18n_core->address.xim_attr[i].name); + } + /*endfor*/ + for (i = 0; i < i18n_core->address.ic_attr_num; i++) + { + str_size = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].attribute_id); + FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].type); + FrameMgrPutToken (fm, str_size); + FrameMgrPutToken (fm, i18n_core->address.xic_attr[i].name); + } + /*endfor*/ + + _Xi18nSendMessage (ims, + connect_id, + XIM_OPEN_REPLY, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree (reply); +} + +static void CloseMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec close_fr[]; + extern XimFrameRec close_reply_fr[]; + unsigned char *reply = NULL; + register int total_size; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (close_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + fm = FrameMgrInit (close_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + connect_id, + XIM_ERROR, + 0, + 0, + 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + + _Xi18nSendMessage (ims, + connect_id, + XIM_CLOSE_REPLY, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree (reply); +} + +static XIMExt *MakeExtensionList (Xi18n i18n_core, + XIMStr *lib_extension, + int number, + int *reply_number) +{ + XIMExt *ext_list; + XIMExt *im_ext = (XIMExt *) i18n_core->address.extension; + int im_ext_len = i18n_core->address.ext_num; + int i; + int j; + + *reply_number = 0; + + if (number == 0) + { + /* query all extensions */ + *reply_number = im_ext_len; + } + else + { + for (i = 0; i < im_ext_len; i++) + { + for (j = 0; j < (int) number; j++) + { + if (strcmp (lib_extension[j].name, im_ext[i].name) == 0) + { + (*reply_number)++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + } + /*endif*/ + + if (!(*reply_number)) + return NULL; + /*endif*/ + ext_list = (XIMExt *) malloc (sizeof (XIMExt)*(*reply_number)); + if (!ext_list) + return NULL; + /*endif*/ + memset (ext_list, 0, sizeof (XIMExt)*(*reply_number)); + + if (number == 0) + { + /* query all extensions */ + for (i = 0; i < im_ext_len; i++) + { + ext_list[i].major_opcode = im_ext[i].major_opcode; + ext_list[i].minor_opcode = im_ext[i].minor_opcode; + ext_list[i].length = im_ext[i].length; + ext_list[i].name = malloc (im_ext[i].length + 1); + strcpy (ext_list[i].name, im_ext[i].name); + } + /*endfor*/ + } + else + { + int n = 0; + + for (i = 0; i < im_ext_len; i++) + { + for (j = 0; j < (int)number; j++) + { + if (strcmp (lib_extension[j].name, im_ext[i].name) == 0) + { + ext_list[n].major_opcode = im_ext[i].major_opcode; + ext_list[n].minor_opcode = im_ext[i].minor_opcode; + ext_list[n].length = im_ext[i].length; + ext_list[n].name = malloc (im_ext[i].length + 1); + strcpy (ext_list[n].name, im_ext[i].name); + n++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + } + /*endif*/ + return ext_list; +} + +static void QueryExtensionMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + extern XimFrameRec query_extension_fr[]; + extern XimFrameRec query_extension_reply_fr[]; + unsigned char *reply = NULL; + int str_size; + register int i; + register int number; + register int total_size; + int byte_length; + int reply_number = 0; + XIMExt *ext_list; + IMQueryExtensionStruct *query_ext = + (IMQueryExtensionStruct *) &call_data->queryext; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (query_extension_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + query_ext->extension = (XIMStr *) malloc (sizeof (XIMStr)*10); + memset (query_ext->extension, 0, sizeof (XIMStr)*10); + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + char *name; + int str_length; + + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + query_ext->extension[number].length = str_length; + FrameMgrGetToken (fm, name); + query_ext->extension[number].name = malloc (str_length + 1); + strncpy (query_ext->extension[number].name, name, str_length); + query_ext->extension[number].name[str_length] = (char) 0; + number++; + } + /*endwhile*/ + query_ext->number = number; + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + FrameMgrFree (fm); + + ext_list = MakeExtensionList (i18n_core, + query_ext->extension, + number, + &reply_number); + + for (i = 0; i < number; i++) + XFree (query_ext->extension[i].name); + /*endfor*/ + XFree (query_ext->extension); + + fm = FrameMgrInit (query_extension_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of extensions */ + FrameMgrSetIterCount (fm, reply_number); + + /* set length of BARRAY item in ext_fr */ + for (i = 0; i < reply_number; i++) + { + str_size = strlen (ext_list[i].name); + FrameMgrSetSize (fm, str_size); + } + /*endfor*/ + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, + connect_id, + XIM_ERROR, + 0, + 0, + 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + + for (i = 0; i < reply_number; i++) + { + str_size = FrameMgrGetSize (fm); + FrameMgrPutToken (fm, ext_list[i].major_opcode); + FrameMgrPutToken (fm, ext_list[i].minor_opcode); + FrameMgrPutToken (fm, str_size); + FrameMgrPutToken (fm, ext_list[i].name); + } + /*endfor*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_QUERY_EXTENSION_REPLY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + for (i = 0; i < reply_number; i++) + XFree (ext_list[i].name); + /*endfor*/ + XFree ((char *) ext_list); +} + +static void SyncReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec sync_reply_fr[]; + CARD16 connect_id = call_data->any.connect_id; + Xi18nClient *client; + CARD16 input_method_ID; + CARD16 input_context_ID; + + client = (Xi18nClient *)_Xi18nFindClient (i18n_core, connect_id); + fm = FrameMgrInit (sync_reply_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, input_context_ID); + FrameMgrFree (fm); + + client->sync = False; + + if (ims->sync == True) { + ims->sync = False; + if (i18n_core->address.improto) { + call_data->sync_xlib.major_code = XIM_SYNC_REPLY; + call_data->sync_xlib.minor_code = 0; + call_data->sync_xlib.connect_id = input_method_ID; + call_data->sync_xlib.icid = input_context_ID; + i18n_core->address.improto(ims, call_data); + } + } +} + +static void GetIMValueFromName (Xi18n i18n_core, + CARD16 connect_id, + char *buf, + char *name, + int *length) +{ + register int i; + + if (strcmp (name, XNQueryInputStyle) == 0) + { + XIMStyles *styles = (XIMStyles *) &i18n_core->address.input_styles; + + *length = sizeof (CARD16)*2; /* count_styles, unused */ + *length += styles->count_styles*sizeof (CARD32); + + if (buf != NULL) + { + FrameMgr fm; + extern XimFrameRec input_styles_fr[]; + unsigned char *data = NULL; + int total_size; + + fm = FrameMgrInit (input_styles_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for list of input_style */ + FrameMgrSetIterCount (fm, styles->count_styles); + + total_size = FrameMgrGetTotalSize (fm); + data = (unsigned char *) malloc (total_size); + if (!data) + return; + /*endif*/ + memset (data, 0, total_size); + FrameMgrSetBuffer (fm, data); + + FrameMgrPutToken (fm, styles->count_styles); + for (i = 0; i < (int) styles->count_styles; i++) + FrameMgrPutToken (fm, styles->supported_styles[i]); + /*endfor*/ + memmove (buf, data, total_size); + FrameMgrFree (fm); + + /* ADDED BY SUZHE */ + free (data); + /* ADDED BY SUZHE */ + } + /*endif*/ + } + /*endif*/ + + else if (strcmp (name, XNQueryIMValuesList) == 0) { + } +} + +static XIMAttribute *MakeIMAttributeList (Xi18n i18n_core, + CARD16 connect_id, + CARD16 *list, + int *number, + int *length) +{ + XIMAttribute *attrib_list; + int list_num; + XIMAttr *attr = i18n_core->address.xim_attr; + int list_len = i18n_core->address.im_attr_num; + register int i; + register int j; + int value_length; + int number_ret = 0; + + *length = 0; + list_num = 0; + for (i = 0; i < *number; i++) + { + for (j = 0; j < list_len; j++) + { + if (attr[j].attribute_id == list[i]) + { + list_num++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + attrib_list = (XIMAttribute *) malloc (sizeof (XIMAttribute)*list_num); + if (!attrib_list) + return NULL; + /*endif*/ + memset (attrib_list, 0, sizeof (XIMAttribute)*list_num); + number_ret = list_num; + list_num = 0; + for (i = 0; i < *number; i++) + { + for (j = 0; j < list_len; j++) + { + if (attr[j].attribute_id == list[i]) + { + attrib_list[list_num].attribute_id = attr[j].attribute_id; + attrib_list[list_num].name_length = attr[j].length; + attrib_list[list_num].name = attr[j].name; + attrib_list[list_num].type = attr[j].type; + GetIMValueFromName (i18n_core, + connect_id, + NULL, + attr[j].name, + &value_length); + attrib_list[list_num].value_length = value_length; + attrib_list[list_num].value = (void *) malloc (value_length); + memset(attrib_list[list_num].value, 0, value_length); + GetIMValueFromName (i18n_core, + connect_id, + attrib_list[list_num].value, + attr[j].name, + &value_length); + *length += sizeof (CARD16)*2; + *length += value_length; + *length += IMPAD (value_length); + list_num++; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + *number = number_ret; + return attrib_list; +} + +static void GetIMValuesMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + extern XimFrameRec get_im_values_fr[]; + extern XimFrameRec get_im_values_reply_fr[]; + CARD16 byte_length; + int list_len, total_size; + unsigned char *reply = NULL; + int iter_count; + register int i; + register int j; + int number; + CARD16 *im_attrID_list; + char **name_list; + CARD16 name_number; + XIMAttribute *im_attribute_list; + IMGetIMValuesStruct *getim = (IMGetIMValuesStruct *)&call_data->getim; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + /* create FrameMgr */ + fm = FrameMgrInit (get_im_values_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + im_attrID_list = (CARD16 *) malloc (sizeof (CARD16)*20); + memset (im_attrID_list, 0, sizeof (CARD16)*20); + name_list = (char **)malloc(sizeof(char *) * 20); + memset(name_list, 0, sizeof(char *) * 20); + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + FrameMgrGetToken (fm, im_attrID_list[number]); + number++; + } + FrameMgrFree (fm); + + name_number = 0; + for (i = 0; i < number; i++) { + for (j = 0; j < i18n_core->address.im_attr_num; j++) { + if (i18n_core->address.xim_attr[j].attribute_id == + im_attrID_list[i]) { + name_list[name_number++] = + i18n_core->address.xim_attr[j].name; + break; + } + } + } + getim->number = name_number; + getim->im_attr_list = name_list; + XFree (name_list); + + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) { + if (!(i18n_core->address.improto (ims, call_data))) + return; + } +#endif /* PROTOCOL_RICH */ + + im_attribute_list = MakeIMAttributeList (i18n_core, + connect_id, + im_attrID_list, + &number, + &list_len); + if (im_attrID_list) + XFree (im_attrID_list); + /*endif*/ + + fm = FrameMgrInit (get_im_values_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + iter_count = number; + + /* set iteration count for list of im_attribute */ + FrameMgrSetIterCount (fm, iter_count); + + /* set length of BARRAY item in ximattribute_fr */ + for (i = 0; i < iter_count; i++) + FrameMgrSetSize (fm, im_attribute_list[i].value_length); + /*endfor*/ + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + + for (i = 0; i < iter_count; i++) + { + FrameMgrPutToken (fm, im_attribute_list[i].attribute_id); + FrameMgrPutToken (fm, im_attribute_list[i].value_length); + FrameMgrPutToken (fm, im_attribute_list[i].value); + } + /*endfor*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_GET_IM_VALUES_REPLY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree (reply); + + for (i = 0; i < iter_count; i++) + XFree(im_attribute_list[i].value); + XFree (im_attribute_list); +} + +static void CreateICMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + _Xi18nChangeIC (ims, call_data, p, True); +} + +static void SetICValuesMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + _Xi18nChangeIC (ims, call_data, p, False); +} + +static void GetICValuesMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + _Xi18nGetIC (ims, call_data, p); +} + +static void SetICFocusMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec set_ic_focus_fr[]; + IMChangeFocusStruct *setfocus; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + /* some buggy xim clients do not send XIM_SYNC_REPLY for synchronous + * events. In such case, xim server is waiting for XIM_SYNC_REPLY + * forever. So the xim server is blocked to waiting sync reply. + * It prevents further input. + * Usually it happens when a client calls XSetICFocus() with another ic + * before passing an event to XFilterEvent(), where the event is needed + * by the old focused ic to sync its state. + * To avoid such problem, remove the whole clients queue and set them + * as asynchronous. + * + * See: + * http://bugs.freedesktop.org/show_bug.cgi?id=7869 + */ + DiscardAllQueue(ims); + + setfocus = (IMChangeFocusStruct *) &call_data->changefocus; + + fm = FrameMgrInit (set_ic_focus_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, setfocus->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void UnsetICFocusMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec unset_ic_focus_fr[]; + IMChangeFocusStruct *unsetfocus; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + + /* some buggy clients unset focus ic before the ic answer the sync reply, + * so the xim server may be blocked to waiting sync reply. To avoid + * this problem, remove the client queue and set it asynchronous + * + * See: SetICFocusMessageProc + */ + if (client != NULL && client->sync) { + DiscardQueue(ims, client->connect_id); + } + + unsetfocus = (IMChangeFocusStruct *) &call_data->changefocus; + + fm = FrameMgrInit (unset_ic_focus_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, unsetfocus->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void DestroyICMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec destroy_ic_fr[]; + extern XimFrameRec destroy_ic_reply_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMDestroyICStruct *destroy = + (IMDestroyICStruct *) &call_data->destroyic; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (destroy_ic_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, destroy->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + fm = FrameMgrInit (destroy_ic_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, destroy->icid); + + _Xi18nSendMessage (ims, + connect_id, + XIM_DESTROY_IC_REPLY, + 0, + reply, + total_size); + XFree(reply); + FrameMgrFree (fm); +} + +static void ResetICMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec reset_ic_fr[]; + extern XimFrameRec reset_ic_reply_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMResetICStruct *resetic = + (IMResetICStruct *) &call_data->resetic; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (reset_ic_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, resetic->icid); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + /* create FrameMgr */ + fm = FrameMgrInit (reset_ic_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set length of STRING8 */ + FrameMgrSetSize (fm, resetic->length); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, resetic->icid); + FrameMgrPutToken(fm, resetic->length); + FrameMgrPutToken (fm, resetic->commit_string); + + if (resetic->commit_string) { + XFree(resetic->commit_string); + } + + _Xi18nSendMessage (ims, + connect_id, + XIM_RESET_IC_REPLY, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree(reply); + +} + +static int WireEventToEvent (Xi18n i18n_core, + xEvent *event, + CARD16 serial, + XEvent *ev, + Bool byte_swap) +{ + FrameMgr fm; + extern XimFrameRec wire_keyevent_fr[]; + BYTE b; + CARD16 c16; + CARD32 c32; + int ret = False; + + /* create FrameMgr */ + fm = FrameMgrInit(wire_keyevent_fr, (char *)(&(event->u)), byte_swap); + + + /* get & set type */ + FrameMgrGetToken(fm, b); + ev->type = (unsigned int)b; + /* get detail */ + FrameMgrGetToken(fm, b); + /* get & set serial */ + FrameMgrGetToken(fm, c16); + ev->xany.serial = (unsigned long)c16; + ev->xany.serial |= serial << 16; + ev->xany.send_event = False; + ev->xany.display = i18n_core->address.dpy; + + /* Remove SendEvent flag from event type to emulate KeyPress/Release */ + ev->type &= 0x7F; + + switch (ev->type) { + case KeyPress: + case KeyRelease: + { + XKeyEvent *kev = (XKeyEvent*)ev; + + /* set keycode (detail) */ + kev->keycode = (unsigned int)b; + + /* get & set values */ + FrameMgrGetToken(fm, c32); kev->time = (Time)c32; + FrameMgrGetToken(fm, c32); kev->root = (Window)c32; + FrameMgrGetToken(fm, c32); kev->window = (Window)c32; + FrameMgrGetToken(fm, c32); kev->subwindow = (Window)c32; + FrameMgrGetToken(fm, c16); kev->x_root = (int)c16; + FrameMgrGetToken(fm, c16); kev->y_root = (int)c16; + FrameMgrGetToken(fm, c16); kev->x = (int)c16; + FrameMgrGetToken(fm, c16); kev->y = (int)c16; + FrameMgrGetToken(fm, c16); kev->state = (unsigned int)c16; + FrameMgrGetToken(fm, b); kev->same_screen = (Bool)b; + } + ret = True; + break; + default: + break; + } + /* free FrameMgr */ + FrameMgrFree(fm); + return ret; +} + +static void ForwardEventMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec forward_event_fr[]; + xEvent wire_event; + IMForwardEventStruct *forward = + (IMForwardEventStruct*) &call_data->forwardevent; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (forward_event_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, forward->icid); + FrameMgrGetToken (fm, forward->sync_bit); + FrameMgrGetToken (fm, forward->serial_number); + p += sizeof (CARD16)*4; + memmove (&wire_event, p, sizeof (xEvent)); + + FrameMgrFree (fm); + + if (WireEventToEvent (i18n_core, + &wire_event, + forward->serial_number, + &forward->event, + _Xi18nNeedSwap (i18n_core, connect_id)) == True) + { + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + } + /*endif*/ +} + +static void ExtForwardKeyEventMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec ext_forward_keyevent_fr[]; + CARD8 type, keycode; + CARD16 state; + CARD32 ev_time, window; + IMForwardEventStruct *forward = + (IMForwardEventStruct *) &call_data->forwardevent; + XEvent *ev = (XEvent *) &forward->event; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (ext_forward_keyevent_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, forward->icid); + FrameMgrGetToken (fm, forward->sync_bit); + FrameMgrGetToken (fm, forward->serial_number); + FrameMgrGetToken (fm, type); + FrameMgrGetToken (fm, keycode); + FrameMgrGetToken (fm, state); + FrameMgrGetToken (fm, ev_time); + FrameMgrGetToken (fm, window); + + FrameMgrFree (fm); + + if (type != KeyPress) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + + /* make a faked keypress event */ + ev->type = (int)type; + ev->xany.send_event = True; + ev->xany.display = i18n_core->address.dpy; + ev->xany.serial = (unsigned long) forward->serial_number; + ((XKeyEvent *) ev)->keycode = (unsigned int) keycode; + ((XKeyEvent *) ev)->state = (unsigned int) state; + ((XKeyEvent *) ev)->time = (Time) ev_time; + ((XKeyEvent *) ev)->window = (Window) window; + ((XKeyEvent *) ev)->root = DefaultRootWindow (ev->xany.display); + ((XKeyEvent *) ev)->x = 0; + ((XKeyEvent *) ev)->y = 0; + ((XKeyEvent *) ev)->x_root = 0; + ((XKeyEvent *) ev)->y_root = 0; + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void ExtMoveMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec ext_move_fr[]; + IMMoveStruct *extmove = + (IMMoveStruct*) & call_data->extmove; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (ext_move_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, extmove->icid); + FrameMgrGetToken (fm, extmove->x); + FrameMgrGetToken (fm, extmove->y); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +static void ExtensionMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + switch (call_data->any.minor_code) + { + case XIM_EXT_FORWARD_KEYEVENT: + ExtForwardKeyEventMessageProc (ims, call_data, p); + break; + + case XIM_EXT_MOVE: + ExtMoveMessageProc (ims, call_data, p); + break; + } + /*endswitch*/ +} + +static void TriggerNotifyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec trigger_notify_fr[], trigger_notify_reply_fr[]; + register int total_size; + unsigned char *reply = NULL; + IMTriggerNotifyStruct *trigger = + (IMTriggerNotifyStruct *) &call_data->triggernotify; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + CARD32 flag; + + fm = FrameMgrInit (trigger_notify_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, trigger->icid); + FrameMgrGetToken (fm, trigger->flag); + FrameMgrGetToken (fm, trigger->key_index); + FrameMgrGetToken (fm, trigger->event_mask); + /* + In order to support Front End Method, this event_mask must be saved + per clients so that it should be restored by an XIM_EXT_SET_EVENT_MASK + call when preediting mode is reset to off. + */ + + flag = trigger->flag; + + FrameMgrFree (fm); + + fm = FrameMgrInit (trigger_notify_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, trigger->icid); + + /* NOTE: + XIM_TRIGGER_NOTIFY_REPLY should be sent before XIM_SET_EVENT_MASK + in case of XIM_TRIGGER_NOTIFY(flag == ON), while it should be + sent after XIM_SET_EVENT_MASK in case of + XIM_TRIGGER_NOTIFY(flag == OFF). + */ + if (flag == 0) + { + /* on key */ + _Xi18nSendMessage (ims, + connect_id, + XIM_TRIGGER_NOTIFY_REPLY, + 0, + reply, + total_size); + IMPreeditStart (ims, (XPointer)call_data); + } + /*endif*/ + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ + + if (flag == 1) + { + /* off key */ + IMPreeditEnd (ims, (XPointer) call_data); + _Xi18nSendMessage (ims, + connect_id, + XIM_TRIGGER_NOTIFY_REPLY, + 0, + reply, + total_size); + } + /*endif*/ + FrameMgrFree (fm); + XFree (reply); +} + +static INT16 ChooseEncoding (Xi18n i18n_core, + IMEncodingNegotiationStruct *enc_nego) +{ + Xi18nAddressRec *address = (Xi18nAddressRec *) & i18n_core->address; + XIMEncodings *p; + int i, j; + int enc_index=0; + + p = (XIMEncodings *) &address->encoding_list; + for (i = 0; i < (int) p->count_encodings; i++) + { + for (j = 0; j < (int) enc_nego->encoding_number; j++) + { + if (strcmp (p->supported_encodings[i], + enc_nego->encoding[j].name) == 0) + { + enc_index = j; + break; + } + /*endif*/ + } + /*endfor*/ + } + /*endfor*/ + + return (INT16) enc_index; +#if 0 + return (INT16) XIM_Default_Encoding_IDX; +#endif +} + +static void EncodingNegotiatonMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + FmStatus status; + CARD16 byte_length; + extern XimFrameRec encoding_negotiation_fr[]; + extern XimFrameRec encoding_negotiation_reply_fr[]; + register int i, total_size; + unsigned char *reply = NULL; + IMEncodingNegotiationStruct *enc_nego = + (IMEncodingNegotiationStruct *) &call_data->encodingnego; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (encoding_negotiation_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + + FrameMgrGetToken (fm, input_method_ID); + + /* get ENCODING STR field */ + FrameMgrGetToken (fm, byte_length); + if (byte_length > 0) + { + enc_nego->encoding = (XIMStr *) malloc (sizeof (XIMStr)*10); + memset (enc_nego->encoding, 0, sizeof (XIMStr)*10); + i = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + char *name; + int str_length; + + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + enc_nego->encoding[i].length = str_length; + FrameMgrGetToken (fm, name); + enc_nego->encoding[i].name = malloc (str_length + 1); + strncpy (enc_nego->encoding[i].name, name, str_length); + enc_nego->encoding[i].name[str_length] = '\0'; + i++; + } + /*endwhile*/ + enc_nego->encoding_number = i; + } + /*endif*/ + /* get ENCODING INFO field */ + FrameMgrGetToken (fm, byte_length); + if (byte_length > 0) + { + enc_nego->encodinginfo = (XIMStr *) malloc (sizeof (XIMStr)*10); + memset (enc_nego->encoding, 0, sizeof (XIMStr)*10); + i = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + char *name; + int str_length; + + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + enc_nego->encodinginfo[i].length = str_length; + FrameMgrGetToken (fm, name); + enc_nego->encodinginfo[i].name = malloc (str_length + 1); + strncpy (enc_nego->encodinginfo[i].name, name, str_length); + enc_nego->encodinginfo[i].name[str_length] = '\0'; + i++; + } + /*endwhile*/ + enc_nego->encoding_info_number = i; + } + /*endif*/ + + enc_nego->enc_index = ChooseEncoding (i18n_core, enc_nego); + enc_nego->category = 0; + +#ifdef PROTOCOL_RICH + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +#endif /* PROTOCOL_RICH */ + + FrameMgrFree (fm); + + fm = FrameMgrInit (encoding_negotiation_reply_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, input_method_ID); + FrameMgrPutToken (fm, enc_nego->category); + FrameMgrPutToken (fm, enc_nego->enc_index); + + _Xi18nSendMessage (ims, + connect_id, + XIM_ENCODING_NEGOTIATION_REPLY, + 0, + reply, + total_size); + XFree (reply); + + /* free data for encoding list */ + if (enc_nego->encoding) + { + for (i = 0; i < (int) enc_nego->encoding_number; i++) + XFree (enc_nego->encoding[i].name); + /*endfor*/ + XFree (enc_nego->encoding); + } + /*endif*/ + if (enc_nego->encodinginfo) + { + for (i = 0; i < (int) enc_nego->encoding_info_number; i++) + XFree (enc_nego->encodinginfo[i].name); + /*endfor*/ + XFree (enc_nego->encodinginfo); + } + /*endif*/ + FrameMgrFree (fm); +} + +void PreeditStartReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_start_reply_fr[]; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (preedit_start_reply_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, preedit_CB->icid); + FrameMgrGetToken (fm, preedit_CB->todo.return_value); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto (ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +void PreeditCaretReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec preedit_caret_reply_fr[]; + IMPreeditCBStruct *preedit_CB = + (IMPreeditCBStruct *) &call_data->preedit_callback; + XIMPreeditCaretCallbackStruct *caret = + (XIMPreeditCaretCallbackStruct *) & preedit_CB->todo.caret; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; + + fm = FrameMgrInit (preedit_caret_reply_fr, + (char *) p, + _Xi18nNeedSwap (i18n_core, connect_id)); + /* get data */ + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, preedit_CB->icid); + FrameMgrGetToken (fm, caret->position); + + FrameMgrFree (fm); + + if (i18n_core->address.improto) + { + if (!(i18n_core->address.improto(ims, call_data))) + return; + /*endif*/ + } + /*endif*/ +} + +void StrConvReplyMessageProc (XIMS ims, + IMProtocol *call_data, + unsigned char *p) +{ + return; +} + +static void AddQueue (Xi18nClient *client, unsigned char *p) +{ + XIMPending *new; + XIMPending *last; + + if ((new = (XIMPending *) malloc (sizeof (XIMPending))) == NULL) + return; + /*endif*/ + new->p = p; + new->next = (XIMPending *) NULL; + if (!client->pending) + { + client->pending = new; + } + else + { + for (last = client->pending; last->next; last = last->next) + ; + /*endfor*/ + last->next = new; + } + /*endif*/ + return; +} + +static void ProcessQueue (XIMS ims, CARD16 connect_id) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient *client = (Xi18nClient *) _Xi18nFindClient (i18n_core, + connect_id); + + while (client->sync == False && client->pending) + { + XimProtoHdr *hdr = (XimProtoHdr *) client->pending->p; + unsigned char *p1 = (unsigned char *) (hdr + 1); + IMProtocol call_data; + + call_data.major_code = hdr->major_opcode; + call_data.any.minor_code = hdr->minor_opcode; + call_data.any.connect_id = connect_id; + + switch (hdr->major_opcode) + { + case XIM_FORWARD_EVENT: + ForwardEventMessageProc(ims, &call_data, p1); + break; + } + /*endswitch*/ + XFree (hdr); + { + XIMPending *old = client->pending; + + client->pending = old->next; + XFree (old); + } + } + /*endwhile*/ + return; +} + + +void _Xi18nMessageHandler (XIMS ims, + CARD16 connect_id, + unsigned char *p, + Bool *delete) +{ + XimProtoHdr *hdr = (XimProtoHdr *)p; + unsigned char *p1 = (unsigned char *)(hdr + 1); + IMProtocol call_data; + Xi18n i18n_core = ims->protocol; + Xi18nClient *client; + + client = (Xi18nClient *) _Xi18nFindClient (i18n_core, connect_id); + if (hdr == (XimProtoHdr *) NULL) + return; + /*endif*/ + + memset (&call_data, 0, sizeof(IMProtocol)); + + call_data.major_code = hdr->major_opcode; + call_data.any.minor_code = hdr->minor_opcode; + call_data.any.connect_id = connect_id; + + switch (call_data.major_code) + { + case XIM_CONNECT: +#ifdef XIM_DEBUG + DebugLog("-- XIM_CONNECT\n"); +#endif + ConnectMessageProc (ims, &call_data, p1); + break; + + case XIM_DISCONNECT: +#ifdef XIM_DEBUG + DebugLog("-- XIM_DISCONNECT\n"); +#endif + DisConnectMessageProc (ims, &call_data); + break; + + case XIM_OPEN: +#ifdef XIM_DEBUG + DebugLog("-- XIM_OPEN\n"); +#endif + OpenMessageProc (ims, &call_data, p1); + break; + + case XIM_CLOSE: +#ifdef XIM_DEBUG + DebugLog("-- XIM_CLOSE\n"); +#endif + CloseMessageProc (ims, &call_data, p1); + break; + + case XIM_QUERY_EXTENSION: +#ifdef XIM_DEBUG + DebugLog("-- XIM_QUERY_EXTENSION\n"); +#endif + QueryExtensionMessageProc (ims, &call_data, p1); + break; + + case XIM_GET_IM_VALUES: +#ifdef XIM_DEBUG + DebugLog("-- XIM_GET_IM_VALUES\n"); +#endif + GetIMValuesMessageProc (ims, &call_data, p1); + break; + + case XIM_CREATE_IC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_CREATE_IC\n"); +#endif + CreateICMessageProc (ims, &call_data, p1); + break; + + case XIM_SET_IC_VALUES: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SET_IC_VALUES\n"); +#endif + SetICValuesMessageProc (ims, &call_data, p1); + break; + + case XIM_GET_IC_VALUES: +#ifdef XIM_DEBUG + DebugLog("-- XIM_GET_IC_VALUES\n"); +#endif + GetICValuesMessageProc (ims, &call_data, p1); + break; + + case XIM_SET_IC_FOCUS: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SET_IC_FOCUS\n"); +#endif + SetICFocusMessageProc (ims, &call_data, p1); + break; + + case XIM_UNSET_IC_FOCUS: +#ifdef XIM_DEBUG + DebugLog("-- XIM_UNSET_IC_FOCUS\n"); +#endif + UnsetICFocusMessageProc (ims, &call_data, p1); + break; + + case XIM_DESTROY_IC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_DESTROY_IC\n"); +#endif + DestroyICMessageProc (ims, &call_data, p1); + break; + + case XIM_RESET_IC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_RESET_IC\n"); +#endif + ResetICMessageProc (ims, &call_data, p1); + break; + + case XIM_FORWARD_EVENT: +#ifdef XIM_DEBUG + DebugLog("-- XIM_FORWARD_EVENT\n"); +#endif + if (client->sync == True) + { + AddQueue (client, p); + *delete = False; + } + else + { + ForwardEventMessageProc (ims, &call_data, p1); + } + break; + + case XIM_EXTENSION: +#ifdef XIM_DEBUG + DebugLog("-- XIM_EXTENSION\n"); +#endif + ExtensionMessageProc (ims, &call_data, p1); + break; + + case XIM_SYNC: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SYNC\n"); +#endif + break; + + case XIM_SYNC_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_SYNC_REPLY\n"); +#endif + SyncReplyMessageProc (ims, &call_data, p1); + ProcessQueue (ims, connect_id); + break; + + case XIM_TRIGGER_NOTIFY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_TRIGGER_NOTIFY\n"); +#endif + TriggerNotifyMessageProc (ims, &call_data, p1); + break; + + case XIM_ENCODING_NEGOTIATION: +#ifdef XIM_DEBUG + DebugLog("-- XIM_ENCODING_NEGOTIATION\n"); +#endif + EncodingNegotiatonMessageProc (ims, &call_data, p1); + break; + + case XIM_PREEDIT_START_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_PREEDIT_START_REPLY\n"); +#endif + PreeditStartReplyMessageProc (ims, &call_data, p1); + break; + + case XIM_PREEDIT_CARET_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_PREEDIT_CARET_REPLY\n"); +#endif + PreeditCaretReplyMessageProc (ims, &call_data, p1); + break; + + case XIM_STR_CONVERSION_REPLY: +#ifdef XIM_DEBUG + DebugLog("-- XIM_STR_CONVERSION_REPLY\n"); +#endif + StrConvReplyMessageProc (ims, &call_data, p1); + break; + } + /*endswitch*/ +} diff --git a/IMdkit/i18nUtil.c b/IMdkit/i18nUtil.c new file mode 100644 index 0000000..c07de48 --- /dev/null +++ b/IMdkit/i18nUtil.c @@ -0,0 +1,277 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include "IMdkit.h" +#include "Xi18n.h" +#include "FrameMgr.h" +#include "XimFunc.h" + +Xi18nClient *_Xi18nFindClient (Xi18n, CARD16); + +int +_Xi18nNeedSwap (Xi18n i18n_core, CARD16 connect_id) +{ + CARD8 im_byteOrder = i18n_core->address.im_byteOrder; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + + return (client->byte_order != im_byteOrder); +} + +Xi18nClient *_Xi18nNewClient(Xi18n i18n_core) +{ + static CARD16 connect_id = 0; + int new_connect_id; + Xi18nClient *client; + + if (i18n_core->address.free_clients) + { + client = i18n_core->address.free_clients; + i18n_core->address.free_clients = client->next; + new_connect_id = client->connect_id; + } + else + { + client = (Xi18nClient *) malloc (sizeof (Xi18nClient)); + new_connect_id = ++connect_id; + } + /*endif*/ + memset (client, 0, sizeof (Xi18nClient)); + client->connect_id = new_connect_id; + client->pending = (XIMPending *) NULL; + client->sync = False; + client->byte_order = '?'; /* initial value */ + memset (&client->pending, 0, sizeof (XIMPending *)); + client->property_offset = 0; + client->next = i18n_core->address.clients; + i18n_core->address.clients = client; + + return (Xi18nClient *) client; +} + +Xi18nClient *_Xi18nFindClient (Xi18n i18n_core, CARD16 connect_id) +{ + Xi18nClient *client = i18n_core->address.clients; + + while (client) + { + if (client->connect_id == connect_id) + return client; + /*endif*/ + client = client->next; + } + /*endwhile*/ + return NULL; +} + +void _Xi18nDeleteClient (Xi18n i18n_core, CARD16 connect_id) +{ + Xi18nClient *target = _Xi18nFindClient (i18n_core, connect_id); + Xi18nClient *ccp; + Xi18nClient *ccp0; + + for (ccp = i18n_core->address.clients, ccp0 = NULL; + ccp != NULL; + ccp0 = ccp, ccp = ccp->next) + { + if (ccp == target) + { + if (ccp0 == NULL) + i18n_core->address.clients = ccp->next; + else + ccp0->next = ccp->next; + /*endif*/ + /* put it back to free list */ + target->next = i18n_core->address.free_clients; + i18n_core->address.free_clients = target; + return; + } + /*endif*/ + } + /*endfor*/ +} + +void _Xi18nSendMessage (XIMS ims, + CARD16 connect_id, + CARD8 major_opcode, + CARD8 minor_opcode, + unsigned char *data, + long length) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec packet_header_fr[]; + unsigned char *reply_hdr = NULL; + int header_size; + unsigned char *reply = NULL; + unsigned char *replyp; + int reply_length; + long p_len = length/4; + + fm = FrameMgrInit (packet_header_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + header_size = FrameMgrGetTotalSize (fm); + reply_hdr = (unsigned char *) malloc (header_size); + if (reply_hdr == NULL) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + return; + } + /*endif*/ + FrameMgrSetBuffer (fm, reply_hdr); + + /* put data */ + FrameMgrPutToken (fm, major_opcode); + FrameMgrPutToken (fm, minor_opcode); + FrameMgrPutToken (fm, p_len); + + reply_length = header_size + length; + reply = (unsigned char *) malloc (reply_length); + replyp = reply; + memmove (reply, reply_hdr, header_size); + replyp += header_size; + memmove (replyp, data, length); + + i18n_core->methods.send (ims, connect_id, reply, reply_length); + + XFree (reply); + XFree (reply_hdr); + FrameMgrFree (fm); +} + +void _Xi18nSendTriggerKey (XIMS ims, CARD16 connect_id) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec register_triggerkeys_fr[]; + XIMTriggerKey *on_keys = i18n_core->address.on_keys.keylist; + XIMTriggerKey *off_keys = i18n_core->address.off_keys.keylist; + int on_key_num = i18n_core->address.on_keys.count_keys; + int off_key_num = i18n_core->address.off_keys.count_keys; + unsigned char *reply = NULL; + register int i, total_size; + CARD16 im_id; + + if (on_key_num == 0 && off_key_num == 0) + return; + /*endif*/ + + fm = FrameMgrInit (register_triggerkeys_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + /* set iteration count for on-keys list */ + FrameMgrSetIterCount (fm, on_key_num); + /* set iteration count for off-keys list */ + FrameMgrSetIterCount (fm, off_key_num); + + /* get total_size */ + total_size = FrameMgrGetTotalSize (fm); + + reply = (unsigned char *) malloc (total_size); + if (!reply) + return; + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + /* Right now XIM_OPEN_REPLY hasn't been sent to this new client, so + the input-method-id is still invalid, and should be set to zero... + Reter to $(XC)/lib/X11/imDefLkup.c:_XimRegisterTriggerKeysCallback + */ + im_id = 0; + FrameMgrPutToken (fm, im_id); /* input-method-id */ + for (i = 0; i < on_key_num; i++) + { + FrameMgrPutToken (fm, on_keys[i].keysym); + FrameMgrPutToken (fm, on_keys[i].modifier); + FrameMgrPutToken (fm, on_keys[i].modifier_mask); + } + /*endfor*/ + for (i = 0; i < off_key_num; i++) + { + FrameMgrPutToken (fm, off_keys[i].keysym); + FrameMgrPutToken (fm, off_keys[i].modifier); + FrameMgrPutToken (fm, off_keys[i].modifier_mask); + } + /*endfor*/ + _Xi18nSendMessage (ims, + connect_id, + XIM_REGISTER_TRIGGERKEYS, + 0, + reply, + total_size); + FrameMgrFree (fm); + XFree(reply); +} + +void _Xi18nSetEventMask (XIMS ims, + CARD16 connect_id, + CARD16 im_id, + CARD16 ic_id, + CARD32 forward_mask, + CARD32 sync_mask) +{ + Xi18n i18n_core = ims->protocol; + FrameMgr fm; + extern XimFrameRec set_event_mask_fr[]; + unsigned char *reply = NULL; + register int total_size; + + fm = FrameMgrInit (set_event_mask_fr, + NULL, + _Xi18nNeedSwap (i18n_core, connect_id)); + + total_size = FrameMgrGetTotalSize (fm); + reply = (unsigned char *) malloc (total_size); + if (!reply) + return; + /*endif*/ + memset (reply, 0, total_size); + FrameMgrSetBuffer (fm, reply); + + FrameMgrPutToken (fm, im_id); /* input-method-id */ + FrameMgrPutToken (fm, ic_id); /* input-context-id */ + FrameMgrPutToken (fm, forward_mask); + FrameMgrPutToken (fm, sync_mask); + + _Xi18nSendMessage (ims, + connect_id, + XIM_SET_EVENT_MASK, + 0, + reply, + total_size); + + FrameMgrFree (fm); + XFree(reply); +} diff --git a/IMdkit/i18nX.c b/IMdkit/i18nX.c new file mode 100644 index 0000000..df0edec --- /dev/null +++ b/IMdkit/i18nX.c @@ -0,0 +1,520 @@ +/****************************************************************** + + Copyright 1994, 1995 by Sun Microsystems, Inc. + Copyright 1993, 1994 by Hewlett-Packard Company + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Sun Microsystems, Inc. +and Hewlett-Packard not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. +Sun Microsystems, Inc. and Hewlett-Packard make no representations about +the suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc. + + This version tidied and debugged by Steve Underwood May 1999 + +******************************************************************/ + +#include +#include +#include +#include "FrameMgr.h" +#include "IMdkit.h" +#include "Xi18n.h" +#include "Xi18nX.h" +#include "XimFunc.h" + +extern Xi18nClient *_Xi18nFindClient(Xi18n, CARD16); +extern Xi18nClient *_Xi18nNewClient(Xi18n); +extern void _Xi18nDeleteClient(Xi18n, CARD16); +static Bool WaitXConnectMessage(Display*, Window, + XEvent*, XPointer); +static Bool WaitXIMProtocol(Display*, Window, XEvent*, XPointer); + +static XClient *NewXClient (Xi18n i18n_core, Window new_client) +{ + Display *dpy = i18n_core->address.dpy; + Xi18nClient *client = _Xi18nNewClient (i18n_core); + XClient *x_client; + + x_client = (XClient *) malloc (sizeof (XClient)); + x_client->client_win = new_client; + x_client->accept_win = XCreateSimpleWindow (dpy, + DefaultRootWindow(dpy), + 0, + 0, + 1, + 1, + 1, + 0, + 0); + client->trans_rec = x_client; + return ((XClient *) x_client); +} + +static unsigned char *ReadXIMMessage (XIMS ims, + XClientMessageEvent *ev, + int *connect_id) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient *client = i18n_core->address.clients; + XClient *x_client = NULL; + FrameMgr fm; + extern XimFrameRec packet_header_fr[]; + unsigned char *p = NULL; + unsigned char *p1; + + while (client != NULL) { + x_client = (XClient *) client->trans_rec; + if (x_client->accept_win == ev->window) { + *connect_id = client->connect_id; + break; + } + client = client->next; + } + + if (ev->format == 8) { + /* ClientMessage only */ + XimProtoHdr *hdr = (XimProtoHdr *) ev->data.b; + unsigned char *rec = (unsigned char *) (hdr + 1); + register int total_size; + CARD8 major_opcode; + CARD8 minor_opcode; + CARD16 length; + extern int _Xi18nNeedSwap (Xi18n, CARD16); + + if (client->byte_order == '?') + { + if (hdr->major_opcode != XIM_CONNECT) + return (unsigned char *) NULL; /* can do nothing */ + client->byte_order = (CARD8) rec[0]; + } + + fm = FrameMgrInit (packet_header_fr, + (char *) hdr, + _Xi18nNeedSwap (i18n_core, *connect_id)); + total_size = FrameMgrGetTotalSize (fm); + /* get data */ + FrameMgrGetToken (fm, major_opcode); + FrameMgrGetToken (fm, minor_opcode); + FrameMgrGetToken (fm, length); + FrameMgrFree (fm); + + if ((p = (unsigned char *) malloc (total_size + length * 4)) == NULL) + return (unsigned char *) NULL; + + p1 = p; + memmove (p1, &major_opcode, sizeof (CARD8)); + p1 += sizeof (CARD8); + memmove (p1, &minor_opcode, sizeof (CARD8)); + p1 += sizeof (CARD8); + memmove (p1, &length, sizeof (CARD16)); + p1 += sizeof (CARD16); + memmove (p1, rec, length * 4); + } + else if (ev->format == 32) { + /* ClientMessage and WindowProperty */ + unsigned long length = (unsigned long) ev->data.l[0]; + unsigned long get_length; + Atom atom = (Atom) ev->data.l[1]; + int return_code; + Atom actual_type_ret; + int actual_format_ret; + unsigned long bytes_after_ret; + unsigned char *prop; + unsigned long nitems; + + /* Round up length to next 4 byte value. */ + get_length = length + 3; + if (get_length > LONG_MAX) + get_length = LONG_MAX; + get_length /= 4; + if (get_length == 0) { + fprintf(stderr, "%s: invalid length 0\n", __FUNCTION__); + return NULL; + } + return_code = XGetWindowProperty (i18n_core->address.dpy, + x_client->accept_win, + atom, + client->property_offset / 4, + get_length, + True, + AnyPropertyType, + &actual_type_ret, + &actual_format_ret, + &nitems, + &bytes_after_ret, + &prop); + if (return_code != Success || actual_format_ret == 0 || nitems == 0) { + if (return_code == Success) + XFree (prop); + client->property_offset = 0; + return (unsigned char *) NULL; + } + /* Update the offset to read next time as needed */ + if (bytes_after_ret > 0) + client->property_offset += length; + else + client->property_offset = 0; + switch (actual_format_ret) { + case 8: + case 16: + case 32: + length = nitems * actual_format_ret / 8; + break; + default: + fprintf(stderr, "%s: unknown property return format: %d\n", + __FUNCTION__, actual_format_ret); + XFree(prop); + client->property_offset = 0; + return NULL; + } + /* if hit, it might be an error */ + if ((p = (unsigned char *) malloc (length)) == NULL) + return (unsigned char *) NULL; + + memmove (p, prop, length); + XFree (prop); + } + return (unsigned char *) p; +} + +static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev) +{ + Xi18n i18n_core = ims->protocol; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + XEvent event; + Display *dpy = i18n_core->address.dpy; + Window new_client = ev->data.l[0]; + CARD32 major_version = ev->data.l[1]; + CARD32 minor_version = ev->data.l[2]; + XClient *x_client = NewXClient (i18n_core, new_client); + + if (ev->window != i18n_core->address.im_window) + return; /* incorrect connection request */ + /*endif*/ + if (major_version != 0 || minor_version != 0) + { + major_version = + minor_version = 0; + /* Only supporting only-CM & Property-with-CM method */ + } + /*endif*/ + _XRegisterFilterByType (dpy, + x_client->accept_win, + ClientMessage, + ClientMessage, + WaitXIMProtocol, + (XPointer)ims); + event.xclient.type = ClientMessage; + event.xclient.display = dpy; + event.xclient.window = new_client; + event.xclient.message_type = spec->connect_request; + event.xclient.format = 32; + event.xclient.data.l[0] = x_client->accept_win; + event.xclient.data.l[1] = major_version; + event.xclient.data.l[2] = minor_version; + event.xclient.data.l[3] = XCM_DATA_LIMIT; + + XSendEvent (dpy, + new_client, + False, + NoEventMask, + &event); + XFlush (dpy); +} + +static Bool Xi18nXBegin (XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + + spec->xim_request = XInternAtom (i18n_core->address.dpy, + _XIM_PROTOCOL, + False); + spec->connect_request = XInternAtom (i18n_core->address.dpy, + _XIM_XCONNECT, + False); + + _XRegisterFilterByType (dpy, + i18n_core->address.im_window, + ClientMessage, + ClientMessage, + WaitXConnectMessage, + (XPointer)ims); + return True; +} + +static Bool Xi18nXEnd(XIMS ims) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + + _XUnregisterFilter (dpy, + i18n_core->address.im_window, + WaitXConnectMessage, + (XPointer)ims); + return True; +} + +static char *MakeNewAtom (CARD16 connect_id, char *atomName) +{ + static int sequence = 0; + + sprintf (atomName, + "_server%d_%d", + connect_id, + ((sequence > 20) ? (sequence = 0) : sequence++)); + return atomName; +} + +static Bool Xi18nXSend (XIMS ims, + CARD16 connect_id, + unsigned char *reply, + long length) +{ + Xi18n i18n_core = ims->protocol; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + XClient *x_client = (XClient *) client->trans_rec; + XEvent event; + + event.type = ClientMessage; + event.xclient.window = x_client->client_win; + event.xclient.message_type = spec->xim_request; + + if (length > XCM_DATA_LIMIT) + { + Atom atom; + char atomName[16]; + Atom actual_type_ret; + int actual_format_ret; + int return_code; + unsigned long nitems_ret; + unsigned long bytes_after_ret; + unsigned char *win_data; + + event.xclient.format = 32; + atom = XInternAtom (i18n_core->address.dpy, + MakeNewAtom (connect_id, atomName), + False); + return_code = XGetWindowProperty (i18n_core->address.dpy, + x_client->client_win, + atom, + 0L, + 10000L, + False, + XA_STRING, + &actual_type_ret, + &actual_format_ret, + &nitems_ret, + &bytes_after_ret, + &win_data); + if (return_code != Success) + return False; + /*endif*/ + if (win_data) + XFree ((char *) win_data); + /*endif*/ + XChangeProperty (i18n_core->address.dpy, + x_client->client_win, + atom, + XA_STRING, + 8, + PropModeAppend, + (unsigned char *) reply, + length); + event.xclient.data.l[0] = length; + event.xclient.data.l[1] = atom; + } + else + { + unsigned char buffer[XCM_DATA_LIMIT]; + int i; + + event.xclient.format = 8; + + /* Clear unused field with NULL */ + memmove(buffer, reply, length); + for (i = length; i < XCM_DATA_LIMIT; i++) + buffer[i] = (char) 0; + /*endfor*/ + length = XCM_DATA_LIMIT; + memmove (event.xclient.data.b, buffer, length); + } + XSendEvent (i18n_core->address.dpy, + x_client->client_win, + False, + NoEventMask, + &event); + XFlush (i18n_core->address.dpy); + return True; +} + +static Bool CheckCMEvent (Display *display, XEvent *event, XPointer xi18n_core) +{ + Xi18n i18n_core = (Xi18n) ((void *) xi18n_core); + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + + if ((event->type == ClientMessage) + && + (event->xclient.message_type == spec->xim_request)) + { + return True; + } + /*endif*/ + return False; +} + +static Bool Xi18nXWait (XIMS ims, + CARD16 connect_id, + CARD8 major_opcode, + CARD8 minor_opcode) +{ + Xi18n i18n_core = ims->protocol; + XEvent event; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + XClient *x_client = (XClient *) client->trans_rec; + + for (;;) + { + unsigned char *packet; + XimProtoHdr *hdr; + int connect_id_ret; + + XIfEvent (i18n_core->address.dpy, + &event, + CheckCMEvent, + (XPointer) i18n_core); + if (event.xclient.window == x_client->accept_win) + { + if ((packet = ReadXIMMessage (ims, + (XClientMessageEvent *) & event, + &connect_id_ret)) + == (unsigned char*) NULL) + { + return False; + } + /*endif*/ + hdr = (XimProtoHdr *)packet; + + if ((hdr->major_opcode == major_opcode) + && + (hdr->minor_opcode == minor_opcode)) + { + return True; + } + else if (hdr->major_opcode == XIM_ERROR) + { + return False; + } + /*endif*/ + } + /*endif*/ + } + /*endfor*/ +} + +static Bool Xi18nXDisconnect (XIMS ims, CARD16 connect_id) +{ + Xi18n i18n_core = ims->protocol; + Display *dpy = i18n_core->address.dpy; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + XClient *x_client = (XClient *) client->trans_rec; + + XDestroyWindow (dpy, x_client->accept_win); + _XUnregisterFilter (dpy, + x_client->accept_win, + WaitXIMProtocol, + (XPointer)ims); + XFree (x_client); + _Xi18nDeleteClient (i18n_core, connect_id); + return True; +} + +Bool _Xi18nCheckXAddress (Xi18n i18n_core, + TransportSW *transSW, + char *address) +{ + XSpecRec *spec; + + if (!(spec = (XSpecRec *) malloc (sizeof (XSpecRec)))) + return False; + /*endif*/ + + i18n_core->address.connect_addr = (XSpecRec *) spec; + i18n_core->methods.begin = Xi18nXBegin; + i18n_core->methods.end = Xi18nXEnd; + i18n_core->methods.send = Xi18nXSend; + i18n_core->methods.wait = Xi18nXWait; + i18n_core->methods.disconnect = Xi18nXDisconnect; + return True; +} + +static Bool WaitXConnectMessage (Display *dpy, + Window win, + XEvent *ev, + XPointer client_data) +{ + XIMS ims = (XIMS)client_data; + Xi18n i18n_core = ims->protocol; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + + if (((XClientMessageEvent *) ev)->message_type + == spec->connect_request) + { + ReadXConnectMessage (ims, (XClientMessageEvent *) ev); + return True; + } + /*endif*/ + return False; +} + +static Bool WaitXIMProtocol (Display *dpy, + Window win, + XEvent *ev, + XPointer client_data) +{ + extern void _Xi18nMessageHandler (XIMS, CARD16, unsigned char *, Bool *); + XIMS ims = (XIMS) client_data; + Xi18n i18n_core = ims->protocol; + XSpecRec *spec = (XSpecRec *) i18n_core->address.connect_addr; + Bool delete = True; + unsigned char *packet; + int connect_id; + + if (((XClientMessageEvent *) ev)->message_type + == spec->xim_request) + { + if ((packet = ReadXIMMessage (ims, + (XClientMessageEvent *) ev, + &connect_id)) + == (unsigned char *) NULL) + { + return False; + } + /*endif*/ + _Xi18nMessageHandler (ims, connect_id, packet, &delete); + if (delete == True) + XFree (packet); + /*endif*/ + return True; + } + /*endif*/ + return False; +} diff --git a/IMdkit/libimdkit.a b/IMdkit/libimdkit.a new file mode 100644 index 0000000..47f20ec Binary files /dev/null and b/IMdkit/libimdkit.a differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4ec1ed1 --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +CFLAGS?=-g -Wall -O0 +LDFLAGS?=-Wl,-O1 + +XMIMD_TARGET:=xmimd +XMIMD_OBJS:=main.o ximserver.o mimclient.o context.o +XMIMD_PKGCONFIG:=glib-2.0 gobject-2.0 dbus-glib-1 x11 +XMIMD_CFLAGS:=$(shell pkg-config --cflags $(XMIMD_PKGCONFIG)) -std=gnu99 -DG_LOG_DOMAIN=\"xmim\" +XMIMD_LDFLAGS:= +XMIMD_LIBS:=$(shell pkg-config --libs $(XMIMD_PKGCONFIG)) + +XMIMTEST_TARGET:=test +XMIMTEST_OBJS:=test.o +XMIMTEST_PKGCONFIG:=x11 +XMIMTEST_CFLAGS:=$(shell pkg-config --cflags $(XMIMTEST_PKGCONFIG)) -std=gnu99 +XMIMTEST_LDFLAGS:= +XMIMTEST_LIBS:=$(shell pkg-config --libs $(XMIMTEST_PKGCONFIG)) + +all: $(XMIMD_TARGET) $(XMIMTEST_TARGET) + +$(XMIMD_TARGET): $(XMIMD_OBJS) IMdkit/libIMdkit.a meego/libmeego-im-common.a + $(CC) $(XMIMD_LDFLAGS) $(LDFLAGS) -o $@ $+ $(XMIMD_LIBS) $(LIBS) + +$(XMIMTEST_TARGET): $(XMIMTEST_OBJS) + $(CC) $(XMIMTEST_LDFLAGS) $(LDFLAGS) -o $@ $+ $(XMIMTEST_LIBS) $(LIBS) + +$(XMIMD_OBJS): %.o: %.c + $(CC) $(XMIMD_CFLAGS) $(CFLAGS) -o $@ -c $< + +$(XMIMTEST_OBJS): %.o: %.c + $(CC) $(XMIMTEST_CFLAGS) $(CFLAGS) -o $@ -c $< + +IMdkit/libIMdkit.a: + $(MAKE) -C IMdkit all + +meego/libmeego-im-common.a: + $(MAKE) -C meego all + +clean: + rm -f *.o $(XMIMD_TARGET) $(XMIMTEST_TARGET) + $(MAKE) -C IMdkit clean + $(MAKE) -C meego clean + +.PHONY: all clean + diff --git a/context.c b/context.c new file mode 100644 index 0000000..6001e0a --- /dev/null +++ b/context.c @@ -0,0 +1,644 @@ +#include +#include +#include +#include "meego/meego-im-proxy.h" +#include "meego/qt-translate.h" +#include "meego/meego-im-defs.h" + +#include "ximserver.h" +#include "xmim.h" +#include "mimclient.h" +#include "context.h" + +typedef struct _Context +{ + guint16 connect_id; + guint16 icid; + XIMStyle style; + Window toplevel_window; + Window client_window; + Window focus_window; + GHashTable *info; + gboolean preediting; + GString *preedit_str; +} Context; + +static GHashTable *contexts; +static guint16 last_icid; +static guint16 focused_icid; + +static MeegoIMProxy *proxy; + +static char * utf8_to_compound_text(const char *string) +{ + XTextProperty tp; + + Xutf8TextListToTextProperty(x_dpy, (char **)&string, 1, XCompoundTextStyle, &tp); + + return (char*) tp.value; +} + +static GValue* context_info_value_new(GType type) +{ + GValue *val = g_slice_new0(GValue); + return g_value_init(val, type); +} + +static void context_info_value_destroy(GValue *val) +{ + g_value_unset(val); + g_slice_free(GValue, val); +} + +static GValue *context_info_lookup(Context *ctx, const char* name) +{ + return g_hash_table_lookup(ctx->info, name); +} + +static void context_info_unset(Context *ctx, const char *name) +{ + g_hash_table_remove(ctx->info, name); +} + +static void context_info_set_bool(Context *ctx, const char* name, gboolean value) +{ + GValue *val = context_info_lookup(ctx, name); + if (val) { + g_value_set_boolean(val, value); + } else { + val = context_info_value_new(G_TYPE_BOOLEAN); + g_value_set_boolean(val, value); + g_hash_table_insert(ctx->info, (gpointer)name, val); + } +} + +static void context_info_set_int(Context *ctx, const char* name, gint value) +{ + GValue *val = context_info_lookup(ctx, name); + if (val) { + g_value_set_int(val, value); + } else { + val = context_info_value_new(G_TYPE_INT); + g_value_set_int(val, value); + g_hash_table_insert(ctx->info, (gpointer)name, val); + } +} + +static void context_info_set_uint64(Context *ctx, const char* name, guint64 value) +{ + GValue *val = context_info_lookup(ctx, name); + if (val) { + g_value_set_uint64(val, value); + } else { + val = context_info_value_new(G_TYPE_UINT64); + g_value_set_uint64(val, value); + g_hash_table_insert(ctx->info, (gpointer)name, val); + } +} + +static void context_info_set_rect(Context *ctx, const char* name, int x, int y, int w, int h) +{ + GValue *val = context_info_lookup(ctx, name); + if (val) { + dbus_g_type_struct_set(val, 0, x, 1, y, 2, w, 3, h, G_MAXUINT); + } else { + GType type = dbus_g_type_get_struct("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); + GValueArray *arr = (GValueArray*) dbus_g_type_specialized_construct(type); + g_return_if_fail(arr); + + val = context_info_value_new(type); + g_value_take_boxed(val, arr); + + if (!dbus_g_type_struct_set(val, 0, x, 1, y, 2, w, 3, h, G_MAXUINT)) { + g_value_unset(val); + g_return_if_reached(); + } + + g_hash_table_insert(ctx->info, (gpointer)name, val); + } +} + +static Context* context_alloc() +{ + Context* ctx = g_slice_new0(Context); + g_return_val_if_fail(ctx, NULL); + ctx->info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, + (GDestroyNotify) context_info_value_destroy); + ctx->preedit_str = g_string_new(NULL); + + // TODO Move this somewhere else + context_info_set_int(ctx, "contentType", MeegoImFreeTextContentType); + + return ctx; +} + +static void context_free(Context *ctx) +{ + g_string_free(ctx->preedit_str, TRUE); + g_hash_table_destroy(ctx->info); + g_slice_free(Context, ctx); +} + +void contexts_init() +{ + contexts = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) context_free); + last_icid = 0; + focused_icid = 0; + + proxy = meego_im_proxy_get_singleton(); +} + +void contexts_destroy() +{ + g_hash_table_destroy(contexts); +} + +guint contexts_focused_icid() +{ + return focused_icid; +} + +static Context* contexts_lookup(guint icid) +{ + return g_hash_table_lookup(contexts, GUINT_TO_POINTER(icid)); +} + +static Window find_toplevel_window(Window win) +{ + Window root, parent; + Window *children = NULL; + unsigned int nchildren; + + if (XQueryTree(x_dpy, win, &root, &parent, &children, &nchildren)) { + if (children) XFree(children); + if (parent == root) { + return win; + } else { + g_return_val_if_fail(win != parent, win); + return find_toplevel_window(parent); + } + } + + g_warn_if_reached(); + return win; +} + +static gboolean context_update_style(Context *ctx, XIMStyle style) +{ + if (ctx->style != style) { + ctx->style = style; + + if (ctx->style & XIMPreeditNone) { + // No preedit? Set the virtual keyboard in direct/raw mode. + context_info_set_int(ctx, "inputMethodMode", MeegoImInputMethodModeDirect); + } else { + context_info_set_int(ctx, "inputMethodMode", MeegoImInputMethodModeNormal); + } + + return TRUE; + } else { + return FALSE; + } +} + +static gboolean context_update_client_window(Context *ctx, Window w) +{ + if (ctx->client_window != w) { + ctx->client_window = w; + + if (opt_xephyr) { + // Consider the passed window id the top level window id + // Remember NOT to use it!, it is not accessible from our X11 server! + ctx->toplevel_window = opt_xephyr; + } else { + ctx->toplevel_window = find_toplevel_window(w); + } + + if (ctx->toplevel_window) { + context_info_set_uint64(ctx, "winId", ctx->toplevel_window); + } else { + context_info_unset(ctx, "winId"); + } + + return TRUE; + } else { + return FALSE; + } +} + +static gboolean context_update_spot_location(Context *ctx, const XPoint *p) +{ + Window win = ctx->focus_window; + Window root = DefaultRootWindow(x_dpy); + int x, y; + Window child; + + if (!win) { + win = ctx->client_window; + } + g_warn_if_fail(win); + + if (win && XTranslateCoordinates(x_dpy, win, root, p->x, p->y, &x, &y, &child)) { + g_debug("Root coordinates %d %d", x, y); + context_info_set_rect(ctx, "cursorRectangle", x, y, 2, 20); + } else { + g_warn_if_reached(); + context_info_unset(ctx, "cursorRectangle"); + } + return TRUE; +} + +static gboolean context_parse_ic_values(Context *ctx, IMChangeICStruct *call_data) +{ + XICAttribute *attr; + int attr_num; + gboolean changed = FALSE; + + ctx->connect_id = call_data->connect_id; + + attr = call_data->ic_attr; + attr_num = call_data->ic_attr_num; + for (int i = 0; i < attr_num; ++i, ++attr) { + if (strcmp(XNInputStyle, attr->name) == 0) { + changed |= context_update_style(ctx, *(CARD32 *) attr->value); + } else if (strcmp(XNClientWindow, attr->name) == 0) { + changed |= context_update_client_window(ctx, *(CARD32 *) attr->value); + } else if (strcmp(XNFocusWindow, attr->name) == 0) { + ctx->focus_window = *(CARD32 *) attr->value; + } else { + g_warning("Ignoring unknown ic attribute: %s", attr->name); + } + } + + attr = call_data->preedit_attr; + attr_num = call_data->preedit_attr_num; + for (int i = 0; i < attr_num; ++i, ++attr) { + if (strcmp(XNSpotLocation, attr->name) == 0) { + changed |= context_update_spot_location(ctx, (XPoint*) attr->value); + } else { + g_debug("Ignoring unknown ic preedit attribute: %s", attr->name); + } + } + + return changed; +} + +static void context_start_preedit(Context *ctx) +{ + g_return_if_fail(!(ctx->style & XIMPreeditNone)); + if (!ctx->preediting) { + IMPreeditCBStruct pcb = {0}; + pcb.major_code = XIM_PREEDIT_START; + pcb.connect_id = ctx->connect_id; + pcb.icid = ctx->icid; + xims_call_callback((XPointer)&pcb); + ctx->preediting = TRUE; + } +} + +static void context_stop_preedit(Context *ctx, gboolean commit) +{ + if (ctx->preediting) { + IMPreeditCBStruct pcb = {0}; + pcb.major_code = XIM_PREEDIT_DONE; + pcb.connect_id = ctx->connect_id; + pcb.icid = ctx->icid; + xims_call_callback((XPointer)&pcb); + ctx->preediting = FALSE; + + if (commit) { + xims_commit(ctx->connect_id, ctx->icid, 0, ctx->preedit_str->str); + } + + g_string_truncate(ctx->preedit_str, 0); + } +} + +static void context_info_print_value(gpointer key, gpointer value, gpointer user_data) +{ + GValue *val = value; + const gchar *k = key; + gchar *v = g_strdup_value_contents(val); + g_debug(" %s: %s", k, v); +} + +static void context_info_print(Context *ctx) +{ + g_hash_table_foreach(ctx->info, context_info_print_value, NULL); +} + +gboolean context_create(IMChangeICStruct *call_data) +{ + // Safeguard against being overrun with entries + g_return_val_if_fail(g_hash_table_size(contexts) < G_MAXINT16, FALSE); + + Context *ctx = context_alloc(); + g_return_val_if_fail(ctx, FALSE); + + guint icid = ++last_icid; + while (g_hash_table_lookup(contexts, GUINT_TO_POINTER(icid))) { + // icid collision! Try luck with another one + icid = ++last_icid; + } + + ctx->connect_id = call_data->connect_id; + ctx->icid = icid; + + context_parse_ic_values(ctx, call_data); + + g_hash_table_insert(contexts, GUINT_TO_POINTER(icid), ctx); + + call_data->icid = icid; + + return TRUE; +} + +gboolean context_destroy(IMChangeICStruct *call_data) +{ + const guint icid = call_data->icid; + Context *ctx = g_hash_table_lookup(contexts, GUINT_TO_POINTER(icid)); + if (icid == focused_icid) { + g_message("Destroying focused context"); + focused_icid = 0; + } + if (ctx) { + g_hash_table_remove(contexts, GUINT_TO_POINTER(icid)); + return TRUE; + } else { + g_warn_if_reached(); + return FALSE; + } +} + +gboolean context_set_values(IMChangeICStruct *call_data) +{ + Context *ctx = contexts_lookup(call_data->icid); + g_return_val_if_fail(ctx, FALSE); + + gboolean changed = context_parse_ic_values(ctx, call_data); + if (focused_icid == ctx->icid && changed) { + meego_im_proxy_update_widget_info(proxy, ctx->info, FALSE); + } + + return TRUE; +} + +gboolean context_get_values(IMChangeICStruct *call_data) +{ + Context *ctx = contexts_lookup(call_data->icid); + g_return_val_if_fail(ctx, FALSE); + + XICAttribute *ic_attr = call_data->ic_attr; + for (int i = 0; i < (int)call_data->ic_attr_num; i++, ic_attr++) { + if (strcmp(XNFilterEvents, ic_attr->name) == 0) { + ic_attr->value_length = sizeof(CARD32); + ic_attr->value = (void *)malloc(sizeof(CARD32)); + if (ctx->style & XIMPreeditNone) { + // No need to filter events in direct mode + *(CARD32*)ic_attr->value = 0; + } else { + *(CARD32*)ic_attr->value = KeyPressMask | KeyReleaseMask; + } + } + } + return TRUE; +} + +gboolean context_set_focus(IMChangeFocusStruct *call_data) +{ + Context *ctx = contexts_lookup(call_data->icid); + g_return_val_if_fail(ctx, FALSE); + + context_info_set_bool(ctx, "focusState", TRUE); + + focused_icid = call_data->icid; + if (meego_im_proxy_activate_context(proxy)) { + meego_im_proxy_app_orientation_changed(proxy, MeegoImAngle0); + meego_im_proxy_update_widget_info(proxy, ctx->info, TRUE); + + if (!(ctx->style & XIMStatusNone)) { + meego_im_proxy_show_input_method(proxy); + } else g_debug("Not showing the keyboard because of XIMStatusNone"); + return TRUE; + } else { + g_warning("Failed to activate a Meego input context"); + return FALSE; + } +} + +gboolean context_unset_focus(IMChangeFocusStruct *call_data) +{ + Context *ctx = contexts_lookup(call_data->icid); + g_return_val_if_fail(ctx, FALSE); + + context_stop_preedit(ctx, TRUE); + context_info_set_bool(ctx, "focusState", FALSE); + + if (call_data->icid == focused_icid) { + meego_im_proxy_reset(proxy); + meego_im_proxy_hide_input_method(proxy); + focused_icid = 0; + } + + return TRUE; +} + +gboolean context_forward_event(IMForwardEventStruct *call_data) +{ + Context *ctx = contexts_lookup(call_data->icid); + g_return_val_if_fail(ctx, FALSE); + + if (!redirect_keys) { + g_debug("Not forwarding to mim"); + xims_forward_event(call_data); + return TRUE; + } + + if (call_data->event.type == KeyPress || call_data->event.type == KeyRelease) { + gint type, code, modifiers; + gchar *text; + MeegoImKeyEvent e; + char smallbuf[32+1]; + gchar *buf = NULL; + char *chars = smallbuf; + KeySym keysym; + Status status; + int len = Xutf8LookupString(x_ic, &call_data->event.xkey, smallbuf, 32, &keysym, &status); + if (status == XBufferOverflow) { + buf = g_malloc(len + 1); + len = Xutf8LookupString(x_ic, &call_data->event.xkey, buf, len, &keysym, &status); + chars = buf; + } + + e.release = call_data->event.type == KeyRelease; + e.state = call_data->event.xkey.state; + e.keysym = XLookupKeysym(&call_data->event.xkey, 0); + + switch (status) { + case XLookupBoth: + case XLookupChars: + chars[len] = '\0'; + e.text = chars; + break; + default: + e.text = NULL; + break; + } + + meego_im_key_event_encode(&e, &type, &code, &modifiers, &text); + g_debug("Forwarding to mim %d %d %d %s", type, code, modifiers, text); + meego_im_proxy_process_key_event(proxy, type, code, modifiers, text, + FALSE, 1, + call_data->event.xkey.keycode, e.state, + call_data->event.xkey.time); + if (buf) g_free(buf); + } + + return TRUE; +} + +gboolean context_reset(IMResetICStruct *call_data) +{ + Context *ctx = contexts_lookup(call_data->icid); + g_return_val_if_fail(ctx, FALSE); + + call_data->commit_string = utf8_to_compound_text(ctx->preedit_str->str); + call_data->length = strlen(call_data->commit_string); + meego_im_proxy_reset(proxy); + context_stop_preedit(ctx, FALSE); + + // Please note that I've patched IMdkit so that it will call XFree on + // call_data->commit_string. + // You probably haven't, so take care to avoid more leaks. + + return TRUE; +} + +gboolean context_commit(guint icid, const char *string, + int replace_start, int replace_length, int cursor_pos) +{ + Context *ctx = contexts_lookup(icid); + g_return_val_if_fail(ctx, FALSE); + g_return_val_if_fail(string, FALSE); + + context_stop_preedit(ctx, FALSE); + xims_commit(ctx->connect_id, icid, 0, string); + + return TRUE; +} + +gboolean context_update_preedit(guint icid, const char *string, + int preedit_format_count, const MeegoImPreeditFormat *preedit_formats, + int replace_start, int replace_length, int cursor_pos) +{ + Context *ctx = contexts_lookup(icid); + g_return_val_if_fail(ctx, FALSE); + g_return_val_if_fail(string, FALSE); + + if (!(ctx->style & XIMPreeditCallbacks)) { + g_message("Got update_preedit msg but preedit callbacks not supported"); + return TRUE; + } + glong string_len = g_utf8_strlen(string, -1); + if (string_len > 0) { + context_start_preedit(ctx); // Will start only if not already started + } else { + context_stop_preedit(ctx, FALSE); + return TRUE; + } + + IMPreeditCBStruct s = { 0 }; + XIMText text = { 0 }; + XIMFeedback feedback[string_len + 1]; + + for (int c = 0; c < string_len; c++) { + feedback[c] = XIMUnderline; + } + +#if 0 + for (int i = 0; i < preedit_format_count; i++) { + const MeegoImPreeditFormat * f = &preedit_formats[i]; + for (int c = f->start; c < f->start + f->length; c++) { + switch (f->face) { + case MeegoImPreeditDefault: + feedback[c] = XIMUnderline; + break; + default: + feedback[c] = 0; + break; + } + } + } +#endif + + feedback[string_len] = 0; + + char *ctext = utf8_to_compound_text(string); + + text.string.multi_byte = ctext; + text.length = strlen(ctext); + text.feedback = feedback; + + g_debug("Sending text '%s'(%u)", text.string.multi_byte, text.length); + + s.major_code = XIM_PREEDIT_DRAW; + s.connect_id = ctx->connect_id; + s.icid = icid; + + s.todo.draw.text = &text; + + if (replace_start == 0 && replace_length == 0) { + // Special case: Replace all the string + // TODO Is this true? Does start=0, len=0 mean that? + replace_start = 0; + replace_length = ctx->preedit_str->len; + + g_string_assign(ctx->preedit_str, string); + } else { + g_warn_if_fail(replace_start < 0); + g_warn_if_fail(replace_length < 0); + + g_string_erase(ctx->preedit_str, replace_start, replace_length); + g_string_insert(ctx->preedit_str, replace_start, string); + } + + s.todo.draw.chg_first = replace_start; + s.todo.draw.chg_length = replace_length; + + if (cursor_pos < 0) { + // Assume we mean at the end of the preedit string + cursor_pos = ctx->preedit_str->len; + } + s.todo.draw.caret = cursor_pos; + + g_debug(" chg %d %d caret %d", s.todo.draw.chg_first, s.todo.draw.chg_length, s.todo.draw.caret); + + xims_call_callback((XPointer)&s); + + XFree(ctext); + + return TRUE; +} + +gboolean context_send_key(guint icid, const MeegoImKeyEvent* e) +{ + Context *ctx = contexts_lookup(icid); + g_return_val_if_fail(ctx, FALSE); + + XEvent xev = { 0 }; + xev.xkey.type = e->release ? KeyRelease : KeyPress; + xev.xkey.send_event = True; + xev.xkey.display = x_dpy; + xev.xkey.window = ctx->client_window; + xev.xkey.root = DefaultRootWindow(x_dpy); + xev.xkey.subwindow = ctx->focus_window; + xev.xkey.time = CurrentTime; + xev.xkey.state = e->state; + xev.xkey.keycode = XKeysymToKeycode(x_dpy, e->keysym); + xev.xkey.same_screen = True; + + xims_insert_event(ctx->connect_id, icid, &xev); + + return TRUE; +} diff --git a/context.h b/context.h new file mode 100644 index 0000000..948840a --- /dev/null +++ b/context.h @@ -0,0 +1,35 @@ +#ifndef CONTEXT_H +#define CONTEXT_H + +#include +#include +#include "IMdkit/IMdkit.h" +#include "IMdkit/Xi18n.h" +#include "meego/meego-im-defs.h" + +void contexts_init(); +void contexts_destroy(); +guint contexts_focused_icid(); + +/* The following functions get the icid from call_data */ +gboolean context_create(IMChangeICStruct *call_data); +gboolean context_destroy(IMChangeICStruct *call_data); + +gboolean context_set_values(IMChangeICStruct *call_data); +gboolean context_get_values(IMChangeICStruct *call_data); + +gboolean context_set_focus(IMChangeFocusStruct *call_data); +gboolean context_unset_focus(IMChangeFocusStruct *call_data); + +gboolean context_forward_event(IMForwardEventStruct *call_data); + +gboolean context_reset(IMResetICStruct *call_data); + +gboolean context_commit(guint icid, const char *string, + int replace_start, int replace_length, int cursor_pos); +gboolean context_update_preedit(guint icid, const char *string, + int preedit_format_count, const MeegoImPreeditFormat *preedit_formats, + int replace_start, int replace_length, int cursor_pos); +gboolean context_send_key(guint icid, const MeegoImKeyEvent* e); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..e548777 --- /dev/null +++ b/main.c @@ -0,0 +1,148 @@ +/* + * xmim - X MeeGo Input Method bridge + * Copyright (c) 2012 Javier S. Pedro + * + * Portions from the Smart Common Input Method + * Copyright (c) 2002-2005 James Su + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include "meego/meego-im-connector.h" + +#include "ximserver.h" +#include "xmim.h" + +Display *x_dpy; +Window x_win; +XIM x_im; +XIC x_ic; + +char * opt_display = NULL; +gint64 opt_xephyr = 0; + +static GMainLoop *main_loop; +static MeegoImConnector *m_connector; + +static GIOChannel *x_chan; +static int x_watch; + +static GOptionEntry entries[] = +{ + { "display", 'd', 0, G_OPTION_ARG_STRING, &opt_display, "X11 display to use", "DISPLAY" }, + { "xephyr", 'x', 0, G_OPTION_ARG_INT64, &opt_xephyr, "Xephyr mode", "XEPHYR_WINDOW_ID" }, + { NULL } +}; + +static gboolean x_watch_cb(GIOChannel *source, GIOCondition condition, gpointer data) +{ + XEvent e; + while (XPending(x_dpy)) { + XNextEvent(x_dpy, &e); + if (XFilterEvent(&e, None)) { + continue; + } + } + + return TRUE; +} + +static Window create_im_window() +{ + int scr = DefaultScreen(x_dpy); + Window win = XCreateSimpleWindow(x_dpy, DefaultRootWindow(x_dpy), + -1, -1, 1, 1, 0, 0, + BlackPixel(x_dpy, scr)); + + XSetWindowAttributes attrs; + unsigned long attrmask; + + attrs.override_redirect = True; + attrmask = CWOverrideRedirect; + + XChangeWindowAttributes(x_dpy, win, attrmask, &attrs); + XSelectInput(x_dpy, win, KeyPressMask | KeyReleaseMask | StructureNotifyMask); + XMapWindow(x_dpy, win); + + return win; +} + +int main(int argc, char *argv[]) +{ + GError *error = NULL; + GOptionContext *context; + + setlocale(LC_ALL, ""); + g_type_init(); + + context = g_option_context_new("- X11 <-> Meego Input Method bridge daemon"); + g_option_context_add_main_entries(context, entries, NULL); + + if (!g_option_context_parse(context, &argc, &argv, &error)) { + g_printerr("option parsing failed: %s\n", error->message); + return EXIT_FAILURE; + } + + main_loop = g_main_loop_new(NULL, TRUE); + + XSetLocaleModifiers(""); // We will open the default IM as a "slave" + x_dpy = XOpenDisplay(opt_display); + if (!x_dpy) { + g_critical("Cannot open X display"); + return EXIT_FAILURE; + } + + x_chan = g_io_channel_unix_new(ConnectionNumber(x_dpy)); + x_watch = g_io_add_watch(x_chan, G_IO_IN | G_IO_ERR, x_watch_cb, NULL); + + g_warn_if_fail(XSupportsLocale()); + + // Open the slave input method + x_im = XOpenIM(x_dpy, NULL, NULL, NULL); + g_warn_if_fail(x_im); + + // Create the IM server window + x_win = create_im_window(); + g_warn_if_fail(x_win != None); + + // Create the slave input context + x_ic = XCreateIC(x_im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL); + g_warn_if_fail(x_ic); + + m_connector = meego_im_connector_get_singleton(); + g_warn_if_fail(m_connector); + + xims_open(); + + XFlush(x_dpy); // Flush X11 queue before blocking in the event loop + + g_main_loop_run(main_loop); + + xims_close(); + + g_source_remove(x_watch); + g_io_channel_unref(x_chan); + XDestroyIC(x_ic); + XCloseIM(x_im); + XCloseDisplay(x_dpy); + + return EXIT_SUCCESS; +} diff --git a/meego/Makefile b/meego/Makefile new file mode 100644 index 0000000..4992cad --- /dev/null +++ b/meego/Makefile @@ -0,0 +1,27 @@ +CFLAGS?=-g -O0 -Wall +LDFLAGS?=-Wl,-O1 + +MEEGOIMCOMMON_TARGET:=libmeego-im-common.a + +MEEGOIMCOMMON_OBJS:=meego-im-connector.o meego-imcontext-dbus.o meego-im-proxy.o \ + qt-keysym-map.o qt-translate.o +MEEGOIMCOMMON_PKGCONFIG:=x11 dbus-glib-1 QtCore QtGui +MEEGOIMCOMMON_CFLAGS:=$(shell pkg-config --cflags $(MEEGOIMCOMMON_PKGCONFIG)) -DQT_NO_KEYWORDS -std=c99 +MEEGOIMCOMMON_CXXFLAGS:=$(shell pkg-config --cflags $(MEEGOIMCOMMON_PKGCONFIG)) + +all: $(MEEGOIMCOMMON_TARGET) + +$(MEEGOIMCOMMON_TARGET): $(MEEGOIMCOMMON_OBJS) + ar rcs $@ $^ + +%.o: %.c + $(CC) $(MEEGOIMCOMMON_CFLAGS) $(CFLAGS) -o $@ -c $< + +%.o: %.cpp + $(CXX) $(MEEGOIMCOMMON_CXXFLAGS) $(CFLAGS) -o $@ -c $< + +clean: + rm -f $(MEEGOIMCOMMON_TARGET) *.o + +.PHONY: all clean + diff --git a/meego/debug.h b/meego/debug.h new file mode 100644 index 0000000..46f0766 --- /dev/null +++ b/meego/debug.h @@ -0,0 +1,20 @@ +#ifndef _DEBUG_H +#define _DEBUG_H + +#include +#include + +G_BEGIN_DECLS + +#if defined(ENABLE_DEBUG) +#define DBG(x, a...) g_fprintf (stderr, __FILE__ ",%d,%s: " x "\n", __LINE__, __func__, ##a) +#else +#define DBG(x, a...) do {} while (0) +#endif + +#define STEP() DBG("") + +#define UNUSED(v) (void)v; + +G_END_DECLS +#endif // _DEBUG_H diff --git a/meego/glue.h b/meego/glue.h new file mode 100644 index 0000000..974bd1d --- /dev/null +++ b/meego/glue.h @@ -0,0 +1,558 @@ +/* Generated by dbus-binding-tool; do not edit! */ + +#include +#include + +G_BEGIN_DECLS + +#ifndef _DBUS_GLIB_ASYNC_DATA_FREE +#define _DBUS_GLIB_ASYNC_DATA_FREE +static +#ifdef G_HAVE_INLINE +inline +#endif +void +_dbus_glib_async_data_free (gpointer stuff) +{ + g_slice_free (DBusGAsyncData, stuff); +} +#endif + +#ifndef DBUS_GLIB_CLIENT_WRAPPERS_com_meego_inputmethod_inputcontext1 +#define DBUS_GLIB_CLIENT_WRAPPERS_com_meego_inputmethod_inputcontext1 + +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_activation_lost_event (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "activationLostEvent", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_activation_lost_event_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_activation_lost_event_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_activation_lost_event_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_activation_lost_event_async (DBusGProxy *proxy, com_meego_inputmethod_inputcontext1_activation_lost_event_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "activationLostEvent", com_meego_inputmethod_inputcontext1_activation_lost_event_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_im_initiated_hide (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "imInitiatedHide", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_im_initiated_hide_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_im_initiated_hide_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_im_initiated_hide_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_im_initiated_hide_async (DBusGProxy *proxy, com_meego_inputmethod_inputcontext1_im_initiated_hide_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "imInitiatedHide", com_meego_inputmethod_inputcontext1_im_initiated_hide_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_commit_string (DBusGProxy *proxy, const char * IN_string, const gint IN_replaceStart, const gint IN_replaceLength, const gint IN_cursorPos, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "commitString", G_TYPE_STRING, IN_string, G_TYPE_INT, IN_replaceStart, G_TYPE_INT, IN_replaceLength, G_TYPE_INT, IN_cursorPos, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_commit_string_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_commit_string_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_commit_string_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_commit_string_async (DBusGProxy *proxy, const char * IN_string, const gint IN_replaceStart, const gint IN_replaceLength, const gint IN_cursorPos, com_meego_inputmethod_inputcontext1_commit_string_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "commitString", com_meego_inputmethod_inputcontext1_commit_string_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_STRING, IN_string, G_TYPE_INT, IN_replaceStart, G_TYPE_INT, IN_replaceLength, G_TYPE_INT, IN_cursorPos, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_update_preedit (DBusGProxy *proxy, const char * IN_string, const GPtrArray* IN_formatList, const gint IN_replaceStart, const gint IN_replaceLength, const gint IN_cursorPos, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "updatePreedit", G_TYPE_STRING, IN_string, dbus_g_type_get_collection ("GPtrArray", dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID)), IN_formatList, G_TYPE_INT, IN_replaceStart, G_TYPE_INT, IN_replaceLength, G_TYPE_INT, IN_cursorPos, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_update_preedit_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_update_preedit_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_update_preedit_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_update_preedit_async (DBusGProxy *proxy, const char * IN_string, const GPtrArray* IN_formatList, const gint IN_replaceStart, const gint IN_replaceLength, const gint IN_cursorPos, com_meego_inputmethod_inputcontext1_update_preedit_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "updatePreedit", com_meego_inputmethod_inputcontext1_update_preedit_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_STRING, IN_string, dbus_g_type_get_collection ("GPtrArray", dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID)), IN_formatList, G_TYPE_INT, IN_replaceStart, G_TYPE_INT, IN_replaceLength, G_TYPE_INT, IN_cursorPos, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_key_event (DBusGProxy *proxy, const gint IN_type, const gint IN_key, const gint IN_modifiers, const char * IN_text, const gboolean IN_autoRepeat, const gint IN_count, const guchar IN_requestType, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "keyEvent", G_TYPE_INT, IN_type, G_TYPE_INT, IN_key, G_TYPE_INT, IN_modifiers, G_TYPE_STRING, IN_text, G_TYPE_BOOLEAN, IN_autoRepeat, G_TYPE_INT, IN_count, G_TYPE_UCHAR, IN_requestType, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_key_event_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_key_event_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_key_event_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_key_event_async (DBusGProxy *proxy, const gint IN_type, const gint IN_key, const gint IN_modifiers, const char * IN_text, const gboolean IN_autoRepeat, const gint IN_count, const guchar IN_requestType, com_meego_inputmethod_inputcontext1_key_event_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "keyEvent", com_meego_inputmethod_inputcontext1_key_event_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_type, G_TYPE_INT, IN_key, G_TYPE_INT, IN_modifiers, G_TYPE_STRING, IN_text, G_TYPE_BOOLEAN, IN_autoRepeat, G_TYPE_INT, IN_count, G_TYPE_UCHAR, IN_requestType, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_update_input_method_area (DBusGProxy *proxy, const GArray* IN_data, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "updateInputMethodArea", dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), IN_data, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_update_input_method_area_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_update_input_method_area_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_update_input_method_area_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_update_input_method_area_async (DBusGProxy *proxy, const GArray* IN_data, com_meego_inputmethod_inputcontext1_update_input_method_area_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "updateInputMethodArea", com_meego_inputmethod_inputcontext1_update_input_method_area_async_callback, stuff, _dbus_glib_async_data_free, dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), IN_data, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_set_global_correction_enabled (DBusGProxy *proxy, const gboolean IN_enabled, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "setGlobalCorrectionEnabled", G_TYPE_BOOLEAN, IN_enabled, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_set_global_correction_enabled_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_set_global_correction_enabled_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_set_global_correction_enabled_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_set_global_correction_enabled_async (DBusGProxy *proxy, const gboolean IN_enabled, com_meego_inputmethod_inputcontext1_set_global_correction_enabled_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setGlobalCorrectionEnabled", com_meego_inputmethod_inputcontext1_set_global_correction_enabled_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_BOOLEAN, IN_enabled, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_copy (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "copy", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_copy_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_copy_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_copy_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_copy_async (DBusGProxy *proxy, com_meego_inputmethod_inputcontext1_copy_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "copy", com_meego_inputmethod_inputcontext1_copy_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_paste (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "paste", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_paste_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_paste_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_paste_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_paste_async (DBusGProxy *proxy, com_meego_inputmethod_inputcontext1_paste_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "paste", com_meego_inputmethod_inputcontext1_paste_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_set_redirect_keys (DBusGProxy *proxy, const gboolean IN_enabled, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "setRedirectKeys", G_TYPE_BOOLEAN, IN_enabled, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_inputcontext1_set_redirect_keys_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_set_redirect_keys_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_set_redirect_keys_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_set_redirect_keys_async (DBusGProxy *proxy, const gboolean IN_enabled, com_meego_inputmethod_inputcontext1_set_redirect_keys_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setRedirectKeys", com_meego_inputmethod_inputcontext1_set_redirect_keys_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_BOOLEAN, IN_enabled, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_preedit_rectangle (DBusGProxy *proxy, gboolean* OUT_valid, GValueArray** OUT_rect, GError **error) + +{ + return dbus_g_proxy_call (proxy, "preeditRectangle", error, G_TYPE_INVALID, G_TYPE_BOOLEAN, OUT_valid, dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID), OUT_rect, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_inputcontext1_preedit_rectangle_reply) (DBusGProxy *proxy, gboolean OUT_valid, GValueArray *OUT_rect, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_preedit_rectangle_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + gboolean OUT_valid; + GValueArray* OUT_rect; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_BOOLEAN, &OUT_valid, dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID), &OUT_rect, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_preedit_rectangle_reply)data->cb) (proxy, OUT_valid, OUT_rect, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_preedit_rectangle_async (DBusGProxy *proxy, com_meego_inputmethod_inputcontext1_preedit_rectangle_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "preeditRectangle", com_meego_inputmethod_inputcontext1_preedit_rectangle_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_set_detectable_auto_repeat (DBusGProxy *proxy, const gboolean IN_enabled, GError **error) + +{ + return dbus_g_proxy_call (proxy, "setDetectableAutoRepeat", error, G_TYPE_BOOLEAN, IN_enabled, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_inputcontext1_set_detectable_auto_repeat_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_set_detectable_auto_repeat_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_set_detectable_auto_repeat_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_set_detectable_auto_repeat_async (DBusGProxy *proxy, const gboolean IN_enabled, com_meego_inputmethod_inputcontext1_set_detectable_auto_repeat_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setDetectableAutoRepeat", com_meego_inputmethod_inputcontext1_set_detectable_auto_repeat_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_BOOLEAN, IN_enabled, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_set_selection (DBusGProxy *proxy, const gint IN_start, const gint IN_length, GError **error) + +{ + return dbus_g_proxy_call (proxy, "setSelection", error, G_TYPE_INT, IN_start, G_TYPE_INT, IN_length, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_inputcontext1_set_selection_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_set_selection_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_set_selection_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_set_selection_async (DBusGProxy *proxy, const gint IN_start, const gint IN_length, com_meego_inputmethod_inputcontext1_set_selection_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setSelection", com_meego_inputmethod_inputcontext1_set_selection_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_start, G_TYPE_INT, IN_length, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_inputcontext1_selection (DBusGProxy *proxy, gboolean* OUT_valid, char ** OUT_selectionText, GError **error) + +{ + return dbus_g_proxy_call (proxy, "selection", error, G_TYPE_INVALID, G_TYPE_BOOLEAN, OUT_valid, G_TYPE_STRING, OUT_selectionText, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_inputcontext1_selection_reply) (DBusGProxy *proxy, gboolean OUT_valid, char * OUT_selectionText, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_inputcontext1_selection_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + gboolean OUT_valid; + char * OUT_selectionText; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_BOOLEAN, &OUT_valid, G_TYPE_STRING, &OUT_selectionText, G_TYPE_INVALID); + (*(com_meego_inputmethod_inputcontext1_selection_reply)data->cb) (proxy, OUT_valid, OUT_selectionText, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_inputcontext1_selection_async (DBusGProxy *proxy, com_meego_inputmethod_inputcontext1_selection_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "selection", com_meego_inputmethod_inputcontext1_selection_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_com_meego_inputmethod_inputcontext1 */ + +G_END_DECLS diff --git a/meego/meego-im-client.xml b/meego/meego-im-client.xml new file mode 100644 index 0000000..a6024cb --- /dev/null +++ b/meego/meego-im-client.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/meego/meego-im-connector.c b/meego/meego-im-connector.c new file mode 100644 index 0000000..d316235 --- /dev/null +++ b/meego/meego-im-connector.c @@ -0,0 +1,111 @@ +/* * This file is part of meego-im-framework * + * + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * Contact: Nokia Corporation (directui@nokia.com) + * + * If you have questions regarding the use of this file, please contact + * Nokia at directui@nokia.com. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * and appearing in the file LICENSE.LGPL included in the packaging + * of this file. + */ + +#include "meego-im-connector.h" + +#include + +#define MEEGO_IM_SOCKET_PATH "unix:path=/tmp/meego-im-uiserver/imserver_dbus" + +MeegoImConnector *meego_im_connector_new(); + +static gboolean +try_reconnect(MeegoImConnector *connector) +{ + meego_im_connector_run(connector); + return FALSE; // _run is responsible for setting up a new timeout if needed +} + + +static void +connection_dropped(gpointer instance, MeegoImConnector *connector) +{ + if (connector->connection) { + dbus_g_connection_unref(connector->connection); + } + try_reconnect(connector); +} + + +/** + * MeegoImConnector: + * + * Connects and maintains the DBusConnection, and the objects + * that depend on it. Makes sure that MeegoIMProxy and MeegoIMDbusObj + * has the correct DBusConnection by calling _connect on them when + * the connection has changed. + * + * MeegoIMProxy is responsible for letting the connector know that the + * connection was dropped by emitting the "connection-dropped signal". + */ +MeegoImConnector * +meego_im_connector_new() +{ + MeegoImConnector *self = g_new(MeegoImConnector, 1); + + self->connection = NULL; + self->dbusobj = meego_imcontext_dbusobj_get_singleton(); + self->proxy = meego_im_proxy_get_singleton(); + + g_signal_connect(self->proxy, "connection-dropped", + G_CALLBACK(connection_dropped), (gpointer)self); + + return self; +} + +void +meego_im_connector_free(MeegoImConnector *self) +{ + if (self->connection) { + dbus_g_connection_unref(self->connection); + } + g_free(self); +} + +MeegoImConnector * +meego_im_connector_get_singleton() +{ + static MeegoImConnector *connector = NULL; + if (!connector) { + connector = meego_im_connector_new(); + meego_im_connector_run(connector); + } + return connector; +} + +void +meego_im_connector_run(MeegoImConnector *self) +{ + GError *error = NULL; + DBusGConnection *connection = NULL; + + g_return_if_fail(self != NULL); + + connection = dbus_g_connection_open(MEEGO_IM_SOCKET_PATH, &error); + + if (error != NULL) { + g_warning("Couldn't connect to Maliit server. Retrying..."); + g_error_free(error); + + g_timeout_add_seconds(2, (GSourceFunc)try_reconnect, self); + return; + } + + self->connection = connection; + + meego_im_proxy_connect(self->proxy, self->connection); + meego_imcontext_dbusobj_connect(self->dbusobj, self->connection); +} diff --git a/meego/meego-im-connector.h b/meego/meego-im-connector.h new file mode 100644 index 0000000..cb283a5 --- /dev/null +++ b/meego/meego-im-connector.h @@ -0,0 +1,27 @@ +/* * This file is part of meego-im-framework * + * + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * Contact: Nokia Corporation (directui@nokia.com) + * + * If you have questions regarding the use of this file, please contact + * Nokia at directui@nokia.com. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * and appearing in the file LICENSE.LGPL included in the packaging + * of this file. + */ + +#include "meego-im-proxy.h" +#include "meego-imcontext-dbus.h" + +typedef struct { + MeegoIMProxy *proxy; + MeegoIMContextDbusObj *dbusobj; + DBusGConnection *connection; +} MeegoImConnector; + +void meego_im_connector_run(MeegoImConnector *self); +MeegoImConnector *meego_im_connector_get_singleton(); diff --git a/meego/meego-im-defs.h b/meego/meego-im-defs.h new file mode 100644 index 0000000..85443bc --- /dev/null +++ b/meego/meego-im-defs.h @@ -0,0 +1,91 @@ +/* * This file partially from the meego-im-framework * + * + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * All rights reserved. + * Contact: Nokia Corporation (directui@nokia.com) + * + * If you have questions regarding the use of this file, please contact + * Nokia at directui@nokia.com. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * and appearing in the file LICENSE.LGPL included in the packaging + * of this file. + */ + +#ifndef MEEGO_IM_DEFS_H +#define MEEGO_IM_DEFS_H + +#include + +enum MeegoImOrientationAngle { + MeegoImAngle0 = 0, + MeegoImAngle90 = 90, + MeegoImAngle180 = 180, + MeegoImAngle270 = 270 +}; + +/*! + * This enum contains possible values for orientation of windows in the application. + * + * \sa OrientationAngle + */ +enum MeegoImOrientation { + MeegoImPortrait, //!< equal to either M::Angle90 or M::Angle270 orientation angles + MeegoImLandscape //!< equal to either M::Angle0 or M::Angle180 orientation angles +}; + +//! Content type for text entries. Used at least with MTextEdit +enum MeegoImTextContentType { + //! all characters allowed + MeegoImFreeTextContentType, + + //! only integer numbers allowed + MeegoImNumberContentType, + + //! allows numbers and certain other characters used in phone numbers + MeegoImPhoneNumberContentType, + + //! allows only characters permitted in email address + MeegoImEmailContentType, + + //! allows only character permitted in URL address + MeegoImUrlContentType, + + //! allows content with user defined format + MeegoImCustomContentType +}; + +enum MeegoImInputMethodMode { + //! Normal mode allows to use preedit and error correction + MeegoImInputMethodModeNormal, + + //! Virtual keyboard sends QKeyEvent for every key press or release + MeegoImInputMethodModeDirect, + + //! Used with proxy widget + MeegoImInputMethodModeProxy +}; + +typedef enum _MeegoImPreeditFace { + MeegoImPreeditDefault, + MeegoImPreeditNoCandidates, + MeegoImPreeditKeyPress //! Used for displaying the hwkbd key just pressed +} MeegoImPreeditFace; + +typedef struct _MeegoImPreeditFormat { + int start; + int length; + MeegoImPreeditFace face; +} MeegoImPreeditFormat; + +typedef struct _MeegoImKeyEvent +{ + gboolean release; + unsigned int state; + unsigned int keysym; + char *text; +} MeegoImKeyEvent; + +#endif diff --git a/meego/meego-im-proxy-glue.h b/meego/meego-im-proxy-glue.h new file mode 100644 index 0000000..948368c --- /dev/null +++ b/meego/meego-im-proxy-glue.h @@ -0,0 +1,590 @@ +/* Generated by dbus-binding-tool; do not edit! */ + +#include +#include + +G_BEGIN_DECLS + +#ifndef _DBUS_GLIB_ASYNC_DATA_FREE +#define _DBUS_GLIB_ASYNC_DATA_FREE +static +#ifdef G_HAVE_INLINE +inline +#endif +void +_dbus_glib_async_data_free (gpointer stuff) +{ + g_slice_free (DBusGAsyncData, stuff); +} +#endif + +#ifndef DBUS_GLIB_CLIENT_WRAPPERS_com_meego_inputmethod_uiserver1 +#define DBUS_GLIB_CLIENT_WRAPPERS_com_meego_inputmethod_uiserver1 + +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_show_input_method (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "showInputMethod", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_show_input_method_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_show_input_method_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_show_input_method_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_show_input_method_async (DBusGProxy *proxy, com_meego_inputmethod_uiserver1_show_input_method_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "showInputMethod", com_meego_inputmethod_uiserver1_show_input_method_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_hide_input_method (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "hideInputMethod", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_hide_input_method_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_hide_input_method_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_hide_input_method_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_hide_input_method_async (DBusGProxy *proxy, com_meego_inputmethod_uiserver1_hide_input_method_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "hideInputMethod", com_meego_inputmethod_uiserver1_hide_input_method_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit (DBusGProxy *proxy, const gint IN_posX, const gint IN_posY, const gint IN_preeditX, const gint IN_preeditY, const gint IN_preeditWidth, const gint IN_preeditHeight, GError **error) + +{ + return dbus_g_proxy_call (proxy, "mouseClickedOnPreedit", error, G_TYPE_INT, IN_posX, G_TYPE_INT, IN_posY, G_TYPE_INT, IN_preeditX, G_TYPE_INT, IN_preeditY, G_TYPE_INT, IN_preeditWidth, G_TYPE_INT, IN_preeditHeight, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit_async (DBusGProxy *proxy, const gint IN_posX, const gint IN_posY, const gint IN_preeditX, const gint IN_preeditY, const gint IN_preeditWidth, const gint IN_preeditHeight, com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "mouseClickedOnPreedit", com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_posX, G_TYPE_INT, IN_posY, G_TYPE_INT, IN_preeditX, G_TYPE_INT, IN_preeditY, G_TYPE_INT, IN_preeditWidth, G_TYPE_INT, IN_preeditHeight, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_set_preedit (DBusGProxy *proxy, const char * IN_text, const gint IN_cursorPos, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "setPreedit", G_TYPE_STRING, IN_text, G_TYPE_INT, IN_cursorPos, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_set_preedit_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_set_preedit_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_set_preedit_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_set_preedit_async (DBusGProxy *proxy, const char * IN_text, const gint IN_cursorPos, com_meego_inputmethod_uiserver1_set_preedit_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setPreedit", com_meego_inputmethod_uiserver1_set_preedit_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_STRING, IN_text, G_TYPE_INT, IN_cursorPos, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_update_widget_information (DBusGProxy *proxy, const GHashTable* IN_encodedState, const gboolean IN_focusChanged, GError **error) + +{ + return dbus_g_proxy_call (proxy, "updateWidgetInformation", error, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), IN_encodedState, G_TYPE_BOOLEAN, IN_focusChanged, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_uiserver1_update_widget_information_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_update_widget_information_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_update_widget_information_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_update_widget_information_async (DBusGProxy *proxy, const GHashTable* IN_encodedState, const gboolean IN_focusChanged, com_meego_inputmethod_uiserver1_update_widget_information_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "updateWidgetInformation", com_meego_inputmethod_uiserver1_update_widget_information_async_callback, stuff, _dbus_glib_async_data_free, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), IN_encodedState, G_TYPE_BOOLEAN, IN_focusChanged, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_reset (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "reset", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_reset_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_reset_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_reset_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_reset_async (DBusGProxy *proxy, com_meego_inputmethod_uiserver1_reset_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "reset", com_meego_inputmethod_uiserver1_reset_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_set_context_object (DBusGProxy *proxy, const char * IN_callbackObject, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "setContextObject", G_TYPE_STRING, IN_callbackObject, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_set_context_object_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_set_context_object_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_set_context_object_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_set_context_object_async (DBusGProxy *proxy, const char * IN_callbackObject, com_meego_inputmethod_uiserver1_set_context_object_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setContextObject", com_meego_inputmethod_uiserver1_set_context_object_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_STRING, IN_callbackObject, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_activate_context (DBusGProxy *proxy, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "activateContext", G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_activate_context_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_activate_context_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_activate_context_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_activate_context_async (DBusGProxy *proxy, com_meego_inputmethod_uiserver1_activate_context_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "activateContext", com_meego_inputmethod_uiserver1_activate_context_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_app_orientation_about_to_change (DBusGProxy *proxy, const gint IN_angle, GError **error) + +{ + return dbus_g_proxy_call (proxy, "appOrientationAboutToChange", error, G_TYPE_INT, IN_angle, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_uiserver1_app_orientation_about_to_change_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_app_orientation_about_to_change_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_app_orientation_about_to_change_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_app_orientation_about_to_change_async (DBusGProxy *proxy, const gint IN_angle, com_meego_inputmethod_uiserver1_app_orientation_about_to_change_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "appOrientationAboutToChange", com_meego_inputmethod_uiserver1_app_orientation_about_to_change_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_angle, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_app_orientation_changed (DBusGProxy *proxy, const gint IN_angle, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "appOrientationChanged", G_TYPE_INT, IN_angle, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_app_orientation_changed_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_app_orientation_changed_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_app_orientation_changed_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_app_orientation_changed_async (DBusGProxy *proxy, const gint IN_angle, com_meego_inputmethod_uiserver1_app_orientation_changed_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "appOrientationChanged", com_meego_inputmethod_uiserver1_app_orientation_changed_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_angle, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_set_copy_paste_state (DBusGProxy *proxy, const gboolean IN_copyAvailable, const gboolean IN_pasteAvailable, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "setCopyPasteState", G_TYPE_BOOLEAN, IN_copyAvailable, G_TYPE_BOOLEAN, IN_pasteAvailable, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_set_copy_paste_state_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_set_copy_paste_state_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_set_copy_paste_state_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_set_copy_paste_state_async (DBusGProxy *proxy, const gboolean IN_copyAvailable, const gboolean IN_pasteAvailable, com_meego_inputmethod_uiserver1_set_copy_paste_state_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setCopyPasteState", com_meego_inputmethod_uiserver1_set_copy_paste_state_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_BOOLEAN, IN_copyAvailable, G_TYPE_BOOLEAN, IN_pasteAvailable, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_process_key_event (DBusGProxy *proxy, const gint IN_keyType, const gint IN_keyCode, const gint IN_modifiers, const char * IN_text, const gboolean IN_autoRepeat, const gint IN_count, const guint IN_nativeScanCode, const guint IN_nativeModifiers, const guint IN_time, GError **error) + +{ + dbus_g_proxy_call_no_reply (proxy, "processKeyEvent", G_TYPE_INT, IN_keyType, G_TYPE_INT, IN_keyCode, G_TYPE_INT, IN_modifiers, G_TYPE_STRING, IN_text, G_TYPE_BOOLEAN, IN_autoRepeat, G_TYPE_INT, IN_count, G_TYPE_UINT, IN_nativeScanCode, G_TYPE_UINT, IN_nativeModifiers, G_TYPE_UINT, IN_time, G_TYPE_INVALID, G_TYPE_INVALID); + return TRUE; +} + +typedef void (*com_meego_inputmethod_uiserver1_process_key_event_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_process_key_event_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_process_key_event_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_process_key_event_async (DBusGProxy *proxy, const gint IN_keyType, const gint IN_keyCode, const gint IN_modifiers, const char * IN_text, const gboolean IN_autoRepeat, const gint IN_count, const guint IN_nativeScanCode, const guint IN_nativeModifiers, const guint IN_time, com_meego_inputmethod_uiserver1_process_key_event_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "processKeyEvent", com_meego_inputmethod_uiserver1_process_key_event_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_keyType, G_TYPE_INT, IN_keyCode, G_TYPE_INT, IN_modifiers, G_TYPE_STRING, IN_text, G_TYPE_BOOLEAN, IN_autoRepeat, G_TYPE_INT, IN_count, G_TYPE_UINT, IN_nativeScanCode, G_TYPE_UINT, IN_nativeModifiers, G_TYPE_UINT, IN_time, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_register_attribute_extension (DBusGProxy *proxy, const gint IN_id, const char * IN_fileName, GError **error) + +{ + return dbus_g_proxy_call (proxy, "registerAttributeExtension", error, G_TYPE_INT, IN_id, G_TYPE_STRING, IN_fileName, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_uiserver1_register_attribute_extension_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_register_attribute_extension_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_register_attribute_extension_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_register_attribute_extension_async (DBusGProxy *proxy, const gint IN_id, const char * IN_fileName, com_meego_inputmethod_uiserver1_register_attribute_extension_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "registerAttributeExtension", com_meego_inputmethod_uiserver1_register_attribute_extension_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_id, G_TYPE_STRING, IN_fileName, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_unregister_attribute_extension (DBusGProxy *proxy, const gint IN_id, GError **error) + +{ + return dbus_g_proxy_call (proxy, "unregisterAttributeExtension", error, G_TYPE_INT, IN_id, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_uiserver1_unregister_attribute_extension_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_unregister_attribute_extension_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_unregister_attribute_extension_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_unregister_attribute_extension_async (DBusGProxy *proxy, const gint IN_id, com_meego_inputmethod_uiserver1_unregister_attribute_extension_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "unregisterAttributeExtension", com_meego_inputmethod_uiserver1_unregister_attribute_extension_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_id, G_TYPE_INVALID); +} +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +com_meego_inputmethod_uiserver1_set_extended_attribute (DBusGProxy *proxy, const gint IN_id, const char * IN_target, const char * IN_targetItem, const char * IN_attribute, const GArray* IN_value, GError **error) + +{ + return dbus_g_proxy_call (proxy, "setExtendedAttribute", error, G_TYPE_INT, IN_id, G_TYPE_STRING, IN_target, G_TYPE_STRING, IN_targetItem, G_TYPE_STRING, IN_attribute, dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), IN_value, G_TYPE_INVALID, G_TYPE_INVALID); +} + +typedef void (*com_meego_inputmethod_uiserver1_set_extended_attribute_reply) (DBusGProxy *proxy, GError *error, gpointer userdata); + +static void +com_meego_inputmethod_uiserver1_set_extended_attribute_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + (*(com_meego_inputmethod_uiserver1_set_extended_attribute_reply)data->cb) (proxy, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +com_meego_inputmethod_uiserver1_set_extended_attribute_async (DBusGProxy *proxy, const gint IN_id, const char * IN_target, const char * IN_targetItem, const char * IN_attribute, const GArray* IN_value, com_meego_inputmethod_uiserver1_set_extended_attribute_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_slice_new (DBusGAsyncData); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "setExtendedAttribute", com_meego_inputmethod_uiserver1_set_extended_attribute_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_INT, IN_id, G_TYPE_STRING, IN_target, G_TYPE_STRING, IN_targetItem, G_TYPE_STRING, IN_attribute, dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), IN_value, G_TYPE_INVALID); +} +#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_com_meego_inputmethod_uiserver1 */ + +G_END_DECLS diff --git a/meego/meego-im-proxy.c b/meego/meego-im-proxy.c new file mode 100644 index 0000000..5326d3b --- /dev/null +++ b/meego/meego-im-proxy.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2010, Intel Corporation. + * + * Author: Raymond Liu + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "meego-im-proxy.h" +#include "meego-im-proxy-glue.h" +#include "debug.h" + +G_DEFINE_TYPE(MeegoIMProxy, meego_im_proxy, G_TYPE_OBJECT); + +#define MEEGO_IM_OBJECT_PATH "/com/meego/inputmethod/uiserver1" +#define MEEGO_IM_SERVICE_INTERFACE "com.meego.inputmethod.uiserver1" + +static void meego_im_proxy_finalize(GObject *object); +static void meego_im_proxy_class_init(MeegoIMProxyClass *klass); +static void meego_im_proxy_init(MeegoIMProxy *meego_im_proxy); + +enum { + SIGNAL_CONNECTION_DROPPED = 0, + N_SIGNALS +}; + +static guint meego_im_proxy_signals[N_SIGNALS]; + +static void +handle_disconnect(gpointer instance, MeegoIMProxy *im_proxy) +{ + g_return_if_fail(im_proxy); + + im_proxy->dbusproxy = NULL; + g_signal_emit(im_proxy, meego_im_proxy_signals[SIGNAL_CONNECTION_DROPPED], 0, NULL); + +} + +MeegoIMProxy * +meego_im_proxy_get_singleton(void) +{ + static MeegoIMProxy *proxy = NULL; + if (!proxy) + proxy = g_object_new(MEEGO_TYPE_IM_PROXY, NULL); + return proxy; +} + + +static void +meego_im_proxy_finalize(GObject *object) +{ + //MeegoIMProxy *im_proxy = MEEGO_IM_PROXY(object); + + G_OBJECT_CLASS(meego_im_proxy_parent_class)->finalize(object); +} + + +static void +meego_im_proxy_class_init(MeegoIMProxyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = meego_im_proxy_finalize; + + meego_im_proxy_signals[SIGNAL_CONNECTION_DROPPED] = + g_signal_new("connection-dropped", G_TYPE_FROM_CLASS(klass), + 0, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); +} + + +static void +meego_im_proxy_init(MeegoIMProxy *self) +{ + UNUSED(self); +} + +void +meego_im_proxy_connect(MeegoIMProxy *proxy, DBusGConnection *connection) +{ + DBusGProxy *dbusproxy; + g_return_if_fail(connection != NULL); + + if (proxy->dbusproxy) { + g_object_unref(proxy->dbusproxy); + } + + dbusproxy = dbus_g_proxy_new_for_peer(connection, + MEEGO_IM_OBJECT_PATH, /* obj path */ + MEEGO_IM_SERVICE_INTERFACE /* interface */); + + if (dbusproxy == NULL) { + g_warning("could not create dbus_proxy\n"); + } + + g_signal_connect(G_OBJECT(dbusproxy), "destroy", G_CALLBACK(handle_disconnect), proxy); + + proxy->dbusproxy = dbusproxy; +} + +gboolean +meego_im_proxy_activate_context(MeegoIMProxy *proxy) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_activate_context(proxy->dbusproxy, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + +gboolean +meego_im_proxy_app_orientation_changed(MeegoIMProxy *proxy, const gint angle) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_app_orientation_changed(proxy->dbusproxy, angle, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + +gboolean +meego_im_proxy_hide_input_method(MeegoIMProxy *proxy) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_hide_input_method(proxy->dbusproxy, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + +#if 0 +// Not yet really implemented + +gboolean +meego_im_proxy_mouse_clicked_on_preedit(MeegoIMProxy *proxy, const GValueArray *pos, + const GValueArray *preedit_rect) +{ + GError *error = NULL; + gboolean ret = TRUE; + + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_mouse_clicked_on_preedit(proxy->dbusproxy, + pos, preedit_rect, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} +#endif + +gboolean +meego_im_proxy_update_widget_info(MeegoIMProxy *proxy, const GHashTable *state_information, gboolean focus_changed) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_update_widget_information(proxy->dbusproxy, + state_information, focus_changed, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + + + +gboolean +meego_im_proxy_process_key_event(MeegoIMProxy *proxy, const gint type, const gint code, + const gint modifiers, const char *text, + const gboolean auto_repeat, const gint count, + const guint native_scan_code, + const guint native_modifiers, + const guint time) +{ + GError *error = NULL; + gboolean ret = TRUE; + + DBG("QT key event type=0x%x, code=0x%x, modifiers=0x%x, text=%s", + type, code, modifiers, text); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_process_key_event(proxy->dbusproxy, + type, code, modifiers, text, auto_repeat, + count, native_scan_code, native_modifiers, + time, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + +gboolean +meego_im_proxy_reset(MeegoIMProxy *proxy) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_reset(proxy->dbusproxy, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + +gboolean +meego_im_proxy_set_copy_paste_state(MeegoIMProxy *proxy, const gboolean copy_available, + const gboolean paste_available) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_set_copy_paste_state(proxy->dbusproxy, + copy_available, paste_available, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + +gboolean +meego_im_proxy_set_preedit(MeegoIMProxy *proxy, const char *text, gint cursor_pos) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_set_preedit(proxy->dbusproxy, text, cursor_pos, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} + + +gboolean +meego_im_proxy_show_input_method(MeegoIMProxy *proxy) +{ + GError *error = NULL; + gboolean ret = TRUE; + + STEP(); + if (!proxy || proxy->dbusproxy == NULL) + return FALSE; + + ret = com_meego_inputmethod_uiserver1_show_input_method(proxy->dbusproxy, &error); + + if (error != NULL) { + g_warning("%s", error->message); + } + + return ret; +} diff --git a/meego/meego-im-proxy.h b/meego/meego-im-proxy.h new file mode 100644 index 0000000..85dad7c --- /dev/null +++ b/meego/meego-im-proxy.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010, Intel Corporation. + * + * Author: Raymond Liu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _MEEGO_IM_PROXY_H +#define _MEEGO_IM_PROXY_H + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _MeegoIMProxy MeegoIMProxy; +typedef struct _MeegoIMProxyClass MeegoIMProxyClass; + +#define MEEGO_TYPE_IM_PROXY (meego_im_proxy_get_type()) +#define MEEGO_IM_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MEEGO_TYPE_IM_PROXY, MeegoIMProxy)) +#define MEEGO_IM_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MEEGO_TYPE_IM_PROXY, MeegoIMProxyClass)) +#define MEEGO_IS_IM_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MEEGO_TYPE_IM_PROXY)) +#define MEEGO_IS_IM_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MEEGO_TYPE_IM_PROXY)) +#define MEEGO_IM_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MEEGO_TYPE_IM_PROXY, MeegoIMProxyClass)) + + +struct _MeegoIMProxy { + GObject parent; + + DBusGProxy *dbusproxy; +}; + +struct _MeegoIMProxyClass { + GObjectClass parent; +}; + +GType meego_im_proxy_get_type(void); + +MeegoIMProxy *meego_im_proxy_get_singleton(void); +void meego_im_proxy_connect(MeegoIMProxy *proxy, DBusGConnection *connection); +gboolean meego_im_proxy_activate_context(MeegoIMProxy *proxy); +gboolean meego_im_proxy_app_orientation_changed(MeegoIMProxy *proxy, const gint angle); +gboolean meego_im_proxy_hide_input_method(MeegoIMProxy *proxy); +#if 0 +// Not yet really implemented +gboolean meego_im_proxy_mouse_clicked_on_preedit(MeegoIMProxy *proxy, const GValueArray *pos, + const GValueArray *preedit_rect); +#endif + +gboolean meego_im_proxy_update_widget_info(MeegoIMProxy *proxy, const GHashTable *state_information, gboolean focus_changed); + +gboolean meego_im_proxy_process_key_event(MeegoIMProxy *proxy, const gint type, const gint code, + const gint modifiers, const char *text, + const gboolean auto_repeat, const gint count, + const guint native_scan_code, + const guint native_modifiers, + const guint time); + +gboolean meego_im_proxy_reset(MeegoIMProxy *proxy); +gboolean meego_im_proxy_set_context_object(MeegoIMProxy *proxy, const char *object_name); +gboolean meego_im_proxy_set_copy_paste_state(MeegoIMProxy *proxy, const gboolean copy_available, + const gboolean paste_available); +gboolean meego_im_proxy_set_preedit(MeegoIMProxy *proxy, const char *text, const gint cursor_pos); +gboolean meego_im_proxy_show_input_method(MeegoIMProxy *proxy); + +G_END_DECLS + +#endif //_MEEGO_IM_PROXY_H diff --git a/meego/meego-imcontext-dbus-glue.h b/meego/meego-imcontext-dbus-glue.h new file mode 100644 index 0000000..ba7a1d5 --- /dev/null +++ b/meego/meego-imcontext-dbus-glue.h @@ -0,0 +1,491 @@ +/* Generated by dbus-binding-tool; do not edit! */ + + +#ifndef __dbus_glib_marshal_meego_imcontext_dbus_MARSHAL_H__ +#define __dbus_glib_marshal_meego_imcontext_dbus_MARSHAL_H__ + +#include + +G_BEGIN_DECLS + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_char (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* BOOLEAN:INT,INT,INT,STRING,BOOLEAN,INT,UCHAR,POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__INT_INT_INT_STRING_BOOLEAN_INT_UCHAR_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__INT_INT_INT_STRING_BOOLEAN_INT_UCHAR_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_INT_STRING_BOOLEAN_INT_UCHAR_POINTER) (gpointer data1, + gint arg_1, + gint arg_2, + gint arg_3, + gpointer arg_4, + gboolean arg_5, + gint arg_6, + guchar arg_7, + gpointer arg_8, + gpointer data2); + register GMarshalFunc_BOOLEAN__INT_INT_INT_STRING_BOOLEAN_INT_UCHAR_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 9); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__INT_INT_INT_STRING_BOOLEAN_INT_UCHAR_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + g_marshal_value_peek_string (param_values + 4), + g_marshal_value_peek_boolean (param_values + 5), + g_marshal_value_peek_int (param_values + 6), + g_marshal_value_peek_uchar (param_values + 7), + g_marshal_value_peek_pointer (param_values + 8), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:INT,INT,POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__INT_INT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__INT_INT_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_POINTER) (gpointer data1, + gint arg_1, + gint arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_BOOLEAN__INT_INT_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__INT_INT_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1, + gpointer arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:STRING,BOXED,INT,INT,INT,POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__STRING_BOXED_INT_INT_INT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__STRING_BOXED_INT_INT_INT_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_BOXED_INT_INT_INT_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gint arg_3, + gint arg_4, + gint arg_5, + gpointer arg_6, + gpointer data2); + register GMarshalFunc_BOOLEAN__STRING_BOXED_INT_INT_INT_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 7); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING_BOXED_INT_INT_INT_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boxed (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + g_marshal_value_peek_int (param_values + 4), + g_marshal_value_peek_int (param_values + 5), + g_marshal_value_peek_pointer (param_values + 6), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:BOXED,POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOXED_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOXED_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_BOOLEAN__BOXED_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_boxed (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:POINTER,POINTER,POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER_POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER_POINTER_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:STRING,INT,INT,INT,POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__STRING_INT_INT_INT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__STRING_INT_INT_INT_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_INT_INT_INT_POINTER) (gpointer data1, + gpointer arg_1, + gint arg_2, + gint arg_3, + gint arg_4, + gpointer arg_5, + gpointer data2); + register GMarshalFunc_BOOLEAN__STRING_INT_INT_INT_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 6); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING_INT_INT_INT_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + g_marshal_value_peek_int (param_values + 4), + g_marshal_value_peek_pointer (param_values + 5), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:BOOLEAN,POINTER */ +extern void dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOOLEAN_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOOLEAN_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__BOOLEAN_POINTER) (gpointer data1, + gboolean arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_BOOLEAN__BOOLEAN_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__BOOLEAN_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_boolean (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +G_END_DECLS + +#endif /* __dbus_glib_marshal_meego_imcontext_dbus_MARSHAL_H__ */ + +#include +static const DBusGMethodInfo dbus_glib_meego_imcontext_dbus_methods[] = { + { (GCallback) meego_imcontext_dbus_activation_lost_event, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER, 0 }, + { (GCallback) meego_imcontext_dbus_im_initiated_hide, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER, 59 }, + { (GCallback) meego_imcontext_dbus_commit_string, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__STRING_INT_INT_INT_POINTER, 114 }, + { (GCallback) meego_imcontext_dbus_update_preedit, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__STRING_BOXED_INT_INT_INT_POINTER, 226 }, + { (GCallback) meego_imcontext_dbus_key_event, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__INT_INT_INT_STRING_BOOLEAN_INT_UCHAR_POINTER, 359 }, + { (GCallback) meego_imcontext_dbus_update_input_method_area, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOXED_POINTER, 488 }, + { (GCallback) meego_imcontext_dbus_set_global_correction_enabled, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOOLEAN_POINTER, 559 }, + { (GCallback) meego_imcontext_dbus_copy, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER, 637 }, + { (GCallback) meego_imcontext_dbus_paste, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER, 681 }, + { (GCallback) meego_imcontext_dbus_set_redirect_keys, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOOLEAN_POINTER, 726 }, + { (GCallback) meego_imcontext_dbus_preedit_rectangle, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER_POINTER_POINTER, 793 }, + { (GCallback) meego_imcontext_dbus_set_detectable_auto_repeat, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__BOOLEAN_POINTER, 881 }, + { (GCallback) meego_imcontext_dbus_set_selection, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__INT_INT_POINTER, 956 }, + { (GCallback) meego_imcontext_dbus_selection, dbus_glib_marshal_meego_imcontext_dbus_BOOLEAN__POINTER_POINTER_POINTER, 1029 }, +}; + +const DBusGObjectInfo dbus_glib_meego_imcontext_dbus_object_info = { 1, + dbus_glib_meego_imcontext_dbus_methods, + 14, +"com.meego.inputmethod.inputcontext1\0activationLostEvent\0S\0\0com.meego.inputmethod.inputcontext1\0imInitiatedHide\0S\0\0com.meego.inputmethod.inputcontext1\0commitString\0S\0string\0I\0s\0replaceStart\0I\0i\0replaceLength\0I\0i\0cursorPos\0I\0i\0\0com.meego.inputmethod.inputcontext1\0updatePreedit\0S\0string\0I\0s\0formatList\0I\0a(iii)\0replaceStart\0I\0i\0replaceLength\0I\0i\0cursorPos\0I\0i\0\0com.meego.inputmethod.inputcontext1\0keyEvent\0S\0type\0I\0i\0key\0I\0i\0modifiers\0I\0i\0text\0I\0s\0autoRepeat\0I\0b\0count\0I\0i\0requestType\0I\0y\0\0com.meego.inputmethod.inputcontext1\0updateInputMethodArea\0S\0data\0I\0ay\0\0com.meego.inputmethod.inputcontext1\0setGlobalCorrectionEnabled\0S\0enabled\0I\0b\0\0com.meego.inputmethod.inputcontext1\0copy\0S\0\0com.meego.inputmethod.inputcontext1\0paste\0S\0\0com.meego.inputmethod.inputcontext1\0setRedirectKeys\0S\0enabled\0I\0b\0\0com.meego.inputmethod.inputcontext1\0preeditRectangle\0S\0valid\0O\0F\0N\0b\0rect\0O\0F\0N\0(iiii)\0\0com.meego.inputmethod.inputcontext1\0setDetectableAutoRepeat\0S\0enabled\0I\0b\0\0com.meego.inputmethod.inputcontext1\0setSelection\0S\0start\0I\0i\0length\0I\0i\0\0com.meego.inputmethod.inputcontext1\0selection\0S\0valid\0O\0F\0N\0b\0selectionText\0O\0F\0N\0s\0\0\0", +"\0", +"\0" +}; + diff --git a/meego/meego-imcontext-dbus.c b/meego/meego-imcontext-dbus.c new file mode 100644 index 0000000..625fbe4 --- /dev/null +++ b/meego/meego-imcontext-dbus.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2010 Intel Corporation + * + * Author: Raymond Liu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#include "meego-imcontext-dbus.h" +#include "debug.h" + +#define MEEGO_IMCONTEXT_DBUSOBJ_SERVICE_OBJECT_PATH "/com/meego/inputmethod/inputcontext" + +G_DEFINE_TYPE(MeegoIMContextDbusObj, meego_imcontext_dbusobj, G_TYPE_OBJECT) + +gboolean meego_imcontext_dbus_activation_lost_event(MeegoIMContextDbusObj *obj, GError **error); +gboolean meego_imcontext_dbus_im_initiated_hide(MeegoIMContextDbusObj *obj, GError **error); +gboolean meego_imcontext_dbus_commit_string(MeegoIMContextDbusObj *obj, char *string, gint replacement_start, + int replacement_length, int cursor_pos, GError **error); +gboolean meego_imcontext_dbus_update_preedit(MeegoIMContextDbusObj *obj, + const char * string, const GPtrArray* formatList, + const gint replaceStart, const gint replaceLength, const gint cursorPos, + GError **error); +gboolean meego_imcontext_dbus_key_event(MeegoIMContextDbusObj *obj, + int type, int key, int modifiers, char *text, + gboolean auto_repeat, int count, + GError **error); +gboolean meego_imcontext_dbus_update_input_method_area(MeegoIMContextDbusObj *obj, GPtrArray *data, GError **error); +gboolean meego_imcontext_dbus_set_global_correction_enabled(MeegoIMContextDbusObj *obj, gboolean correction, GError **error); +gboolean meego_imcontext_dbus_copy(MeegoIMContextDbusObj *obj, GError **error); +gboolean meego_imcontext_dbus_paste(MeegoIMContextDbusObj *obj, GError **error); +gboolean meego_imcontext_dbus_set_redirect_keys(MeegoIMContextDbusObj *obj, gboolean enabled, GError **error); +gboolean meego_imcontext_dbus_preedit_rectangle(MeegoIMContextDbusObj *obj, GValueArray **rect, gboolean *valid, GError **error); + + +#include "meego-imcontext-dbus-glue.h" + + +static void +meego_imcontext_dbusobj_init(MeegoIMContextDbusObj *obj) +{ + STEP(); + g_assert(obj != NULL); +} + + +static void +meego_imcontext_dbusobj_class_init(MeegoIMContextDbusObjClass *klass) +{ + g_assert(klass != NULL); + + dbus_g_object_type_install_info(MEEGO_IMCONTEXT_TYPE_DBUSOBJ, + &dbus_glib_meego_imcontext_dbus_object_info); +} + + + +void +meego_imcontext_dbusobj_connect(MeegoIMContextDbusObj *obj, DBusGConnection *connection) +{ + dbus_g_connection_register_g_object(connection, + MEEGO_IMCONTEXT_DBUSOBJ_SERVICE_OBJECT_PATH, + G_OBJECT(obj)); +} + +MeegoIMContextDbusObj * +meego_imcontext_dbusobj_get_singleton(void) +{ + static MeegoIMContextDbusObj *dbusobj = NULL; + + if (!dbusobj) + dbusobj = g_object_new(MEEGO_IMCONTEXT_TYPE_DBUSOBJ, NULL); + return dbusobj; +} + + +gboolean +meego_imcontext_dbus_activation_lost_event(MeegoIMContextDbusObj *obj, GError **error) +{ + STEP(); + return TRUE; +} + + +gboolean +meego_imcontext_dbus_im_initiated_hide(MeegoIMContextDbusObj *obj, GError **error) +{ + STEP(); + return TRUE; +} + + +gboolean +meego_imcontext_dbus_commit_string(MeegoIMContextDbusObj *obj, char *string, gint replacement_start, + int replacement_length, int cursor_pos, GError **error) +{ + DBG("string is:%s", string); + return meego_imcontext_client_commit_string(obj, string, replacement_start, replacement_length, cursor_pos); +} + + +gboolean +meego_imcontext_dbus_update_preedit(MeegoIMContextDbusObj *obj, + const char * string, const GPtrArray* formatList, + const gint replaceStart, const gint replaceLength, const gint cursorPos, + GError **error) +{ + int i; + int preeditFormatCount = formatList->len; + MeegoImPreeditFormat *preeditFormat = g_new0(MeegoImPreeditFormat, preeditFormatCount); + + for (i = 0; i < preeditFormatCount; i++) { + GValueArray *valarr = formatList->pdata[i]; + g_return_val_if_fail(valarr, FALSE); + g_return_val_if_fail(valarr->n_values == 3, FALSE); + g_return_val_if_fail(G_VALUE_HOLDS_INT(g_value_array_get_nth(valarr, 0)), FALSE); + g_return_val_if_fail(G_VALUE_HOLDS_INT(g_value_array_get_nth(valarr, 1)), FALSE); + g_return_val_if_fail(G_VALUE_HOLDS_INT(g_value_array_get_nth(valarr, 2)), FALSE); + preeditFormat[i].start = g_value_get_int(g_value_array_get_nth(valarr, 0)); + preeditFormat[i].length = g_value_get_int(g_value_array_get_nth(valarr, 0)); + preeditFormat[i].face = g_value_get_int(g_value_array_get_nth(valarr, 0)); + } + + return meego_imcontext_client_update_preedit(obj, string, preeditFormatCount, preeditFormat, + replaceStart, replaceLength, cursorPos); +} + + +gboolean +meego_imcontext_dbus_key_event(MeegoIMContextDbusObj *obj, int type, int key, int modifiers, char *text, + gboolean auto_repeat, int count, GError **error) +{ + DBG("type=0x%x, key=0x%x, modifiers=0x%x, text = %s, auto_repeat=%d, count=%d", + type, key, modifiers, text, auto_repeat, count); + return meego_imcontext_client_key_event(obj, type, key, modifiers, text, auto_repeat, count); +} + + +gboolean +meego_imcontext_dbus_update_input_method_area(MeegoIMContextDbusObj *obj, GPtrArray *data, GError **error) +{ + STEP(); + return TRUE; +} + + +gboolean +meego_imcontext_dbus_set_global_correction_enabled(MeegoIMContextDbusObj *obj, gboolean correction, GError **error) +{ + STEP(); + return TRUE; +} + + +gboolean +meego_imcontext_dbus_copy(MeegoIMContextDbusObj *obj, GError **error) +{ + STEP(); + return meego_imcontext_client_copy(obj); + return TRUE; +} + + +gboolean +meego_imcontext_dbus_paste(MeegoIMContextDbusObj *obj, GError **error) +{ + STEP(); + return meego_imcontext_client_paste(obj); + return TRUE; +} + + +gboolean +meego_imcontext_dbus_set_redirect_keys(MeegoIMContextDbusObj *obj, gboolean enabled, GError **error) +{ + STEP(); + meego_imcontext_client_set_redirect_keys(obj, enabled); + return TRUE; +} + + +gboolean +meego_imcontext_dbus_preedit_rectangle(MeegoIMContextDbusObj *obj, GValueArray **rect, gboolean *valid, GError **error) +{ + STEP(); + return TRUE; +} + +gboolean +meego_imcontext_dbus_set_detectable_auto_repeat(MeegoIMContextDbusObj *obj, gboolean enabled, GError **error) +{ + STEP(); + return TRUE; +} + +gboolean +meego_imcontext_dbus_set_selection(MeegoIMContextDbusObj *obj, int start, int length, GError **error) +{ + STEP(); + return TRUE; +} + +gboolean +meego_imcontext_dbus_selection(MeegoIMContextDbusObj *obj, gboolean *valid, gchar **gdata, GError **error) +{ + STEP(); + return TRUE; +} + diff --git a/meego/meego-imcontext-dbus.h b/meego/meego-imcontext-dbus.h new file mode 100644 index 0000000..4836aaa --- /dev/null +++ b/meego/meego-imcontext-dbus.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Intel Corporation + * + * Author: Raymond Liu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef _MEEGO_IMCONTEXT_DBUS_H +#define _MEEGO_IMCONTEXT_DBUS_H + +#include +#include "meego-im-defs.h" + +typedef struct { + GObject parent; + + DBusGConnection *connection; +} MeegoIMContextDbusObj; + +typedef struct { + GObjectClass parent; +} MeegoIMContextDbusObjClass; + +GType meego_imcontext_dbusobj_get_type(void); + + +#define MEEGO_IMCONTEXT_TYPE_DBUSOBJ (meego_imcontext_dbusobj_get_type()) +#define MEEGO_IMCONTEXT_DBUSOBJ(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), MEEGO_IMCONTEXT_TYPE_DBUSOBJ, MeegoIMContextDbusObj)) +#define MEEGO_IMCONTEXT_DBUSOBJ_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), MEEGO_IMCONTEXT_TYPE_DBUSOBJ, MeegoIMContextDbusObjClass)) +#define MEEGO_IMCONTEXT_IS_DBUSOBJ(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), MEEGO_IMCONTEXT_TYPE_DBUSOBJ)) +#define MEEGO_IMCONTEXT_IS_DBUSOBJ_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), MEEGO_IMCONTEXT_TYPE_DBUSOBJ)) +#define MEEGO_IMCONTEXT_DBUSOBJ_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), MEEGO_IMCONTEXT_TYPE_DBUSOBJ, MeegoIMContextDbusObjClass)) + + +MeegoIMContextDbusObj *meego_imcontext_dbusobj_get_singleton(void); +void meego_imcontext_dbusobj_connect(MeegoIMContextDbusObj *obj, DBusGConnection *connection); + +// Call back functions for dbus obj, need to be implemented in imcontext client side + +gboolean meego_imcontext_client_activation_lost_event(MeegoIMContextDbusObj *obj); +gboolean meego_imcontext_client_im_initiated_hide(MeegoIMContextDbusObj *obj); +gboolean meego_imcontext_client_commit_string(MeegoIMContextDbusObj *obj, const char *string, + int replace_start, int replace_length, int cursor_pos); +gboolean meego_imcontext_client_update_preedit(MeegoIMContextDbusObj *obj, const char *string, + int preedit_format_count, const MeegoImPreeditFormat *preedit_formats, + int replace_start, int replace_length, int cursor_pos); +gboolean meego_imcontext_client_key_event(MeegoIMContextDbusObj *obj, int type, int key, int modifiers, char *text, + gboolean auto_repeat, int count); +gboolean meego_imcontext_client_update_input_method_area(MeegoIMContextDbusObj *obj, GPtrArray *data); +gboolean meego_imcontext_client_set_global_correction_enabled(MeegoIMContextDbusObj *obj, gboolean correction); +gboolean meego_imcontext_client_copy(MeegoIMContextDbusObj *obj); +gboolean meego_imcontext_client_paste(MeegoIMContextDbusObj *obj); +gboolean meego_imcontext_client_set_redirect_keys(MeegoIMContextDbusObj *obj, gboolean enabled); +gboolean meego_imcontext_client_preedit_rectangle(MeegoIMContextDbusObj *obj, GValueArray **rect, gboolean *valid); +gboolean meego_imcontext_dbus_set_detectable_auto_repeat(MeegoIMContextDbusObj *obj, gboolean enabled, GError **error); +gboolean meego_imcontext_dbus_set_selection(MeegoIMContextDbusObj *obj, int start, int length, GError **error); +gboolean meego_imcontext_dbus_selection(MeegoIMContextDbusObj *obj, gboolean *valid, gchar **gdata, GError **error); + +#endif /* _MEEGO_IMCONTEXT_DBUS_H */ diff --git a/meego/meego-imcontext-dbus.xml b/meego/meego-imcontext-dbus.xml new file mode 100644 index 0000000..80ac29c --- /dev/null +++ b/meego/meego-imcontext-dbus.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/meego/qt-keysym-map.cpp b/meego/qt-keysym-map.cpp new file mode 100644 index 0000000..e114fef --- /dev/null +++ b/meego/qt-keysym-map.cpp @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2001 Ellis Whitehead + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010, Intel Corporation. + * + * Author: Raymond Liu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + +#include +#include + +#include "qt-keysym-map.h" +#include "debug.h" + + +#if 0 + +typedef struct { + int QtKey; + uint XKeySym; +} KeySymMap; + +static const KeySymMap QtKeyXSymMaps[] = +{ + { '/', XK_KP_Divide }, + { '*', XK_KP_Multiply }, + { '-', XK_KP_Subtract }, + { '+', XK_KP_Add }, + { Qt::Key_Escape, XK_Escape }, + { Qt::Key_Tab, XK_Tab }, + { Qt::Key_Backtab, XK_ISO_Left_Tab }, + { Qt::Key_Backspace, XK_BackSpace }, + { Qt::Key_Return, XK_Return }, + { Qt::Key_Enter, XK_KP_Enter }, + { Qt::Key_Insert, XK_Insert }, + { Qt::Key_Delete, XK_Delete }, + { Qt::Key_Pause, XK_Pause }, + { Qt::Key_Print, XK_Print }, + { Qt::Key_SysReq, XK_Sys_Req }, + { Qt::Key_Home, XK_Home }, + { Qt::Key_End, XK_End }, + { Qt::Key_Left, XK_Left }, + { Qt::Key_Up, XK_Up }, + { Qt::Key_Right, XK_Right }, + { Qt::Key_Down, XK_Down }, + { Qt::Key_CapsLock, XK_Caps_Lock }, + { Qt::Key_NumLock, XK_Num_Lock }, + { Qt::Key_ScrollLock, XK_Scroll_Lock }, + { Qt::Key_F1, XK_F1 }, + { Qt::Key_F2, XK_F2 }, + { Qt::Key_F3, XK_F3 }, + { Qt::Key_F4, XK_F4 }, + { Qt::Key_F5, XK_F5 }, + { Qt::Key_F6, XK_F6 }, + { Qt::Key_F7, XK_F7 }, + { Qt::Key_F8, XK_F8 }, + { Qt::Key_F9, XK_F9 }, + { Qt::Key_F10, XK_F10 }, + { Qt::Key_F11, XK_F11 }, + { Qt::Key_F12, XK_F12 }, + { Qt::Key_F13, XK_F13 }, + { Qt::Key_F14, XK_F14 }, + { Qt::Key_F15, XK_F15 }, + { Qt::Key_F16, XK_F16 }, + { Qt::Key_F17, XK_F17 }, + { Qt::Key_F18, XK_F18 }, + { Qt::Key_F19, XK_F19 }, + { Qt::Key_F20, XK_F20 }, + { Qt::Key_F21, XK_F21 }, + { Qt::Key_F22, XK_F22 }, + { Qt::Key_F23, XK_F23 }, + { Qt::Key_F24, XK_F24 }, + { Qt::Key_F25, XK_F25 }, + { Qt::Key_F26, XK_F26 }, + { Qt::Key_F27, XK_F27 }, + { Qt::Key_F28, XK_F28 }, + { Qt::Key_F29, XK_F29 }, + { Qt::Key_F30, XK_F30 }, + { Qt::Key_F31, XK_F31 }, + { Qt::Key_F32, XK_F32 }, + { Qt::Key_F33, XK_F33 }, + { Qt::Key_F34, XK_F34 }, + { Qt::Key_F35, XK_F35 }, + { Qt::Key_Super_L, XK_Super_L }, + { Qt::Key_Super_R, XK_Super_R }, + { Qt::Key_Menu, XK_Menu }, + { Qt::Key_Hyper_L, XK_Hyper_L }, + { Qt::Key_Hyper_R, XK_Hyper_R }, + { Qt::Key_Help, XK_Help }, + { Qt::Key_Return, XK_KP_Enter }, + + { Qt::Key_Multi_key, XK_Multi_key }, + { Qt::Key_Codeinput, XK_Codeinput }, + { Qt::Key_SingleCandidate, XK_SingleCandidate }, + { Qt::Key_MultipleCandidate, XK_MultipleCandidate }, + { Qt::Key_PreviousCandidate, XK_PreviousCandidate }, + { Qt::Key_Mode_switch, XK_Mode_switch }, + { Qt::Key_Kanji, XK_Kanji }, + { Qt::Key_Muhenkan, XK_Muhenkan }, + { Qt::Key_Henkan, XK_Henkan }, + { Qt::Key_Romaji, XK_Romaji }, + { Qt::Key_Hiragana, XK_Hiragana }, + { Qt::Key_Katakana, XK_Katakana }, + { Qt::Key_Hiragana_Katakana, XK_Hiragana_Katakana }, + { Qt::Key_Zenkaku, XK_Zenkaku }, + { Qt::Key_Hankaku, XK_Hankaku }, + { Qt::Key_Zenkaku_Hankaku, XK_Zenkaku_Hankaku }, + { Qt::Key_Touroku, XK_Touroku }, + { Qt::Key_Massyo, XK_Massyo }, + { Qt::Key_Kana_Lock, XK_Kana_Lock }, + { Qt::Key_Kana_Shift, XK_Kana_Shift }, + { Qt::Key_Eisu_Shift, XK_Eisu_Shift }, + { Qt::Key_Eisu_toggle, XK_Eisu_toggle }, + { Qt::Key_Hangul, XK_Hangul }, + { Qt::Key_Hangul_Start, XK_Hangul_Start }, + { Qt::Key_Hangul_End, XK_Hangul_End }, + { Qt::Key_Hangul_Hanja, XK_Hangul_Hanja }, + { Qt::Key_Hangul_Jamo, XK_Hangul_Jamo }, + { Qt::Key_Hangul_Romaja, XK_Hangul_Romaja }, + { Qt::Key_Hangul_Jeonja, XK_Hangul_Jeonja }, + { Qt::Key_Hangul_Banja, XK_Hangul_Banja }, + { Qt::Key_Hangul_PreHanja, XK_Hangul_PreHanja }, + { Qt::Key_Hangul_Special, XK_Hangul_Special }, + + { 0, 0 } +}; + +#else + +typedef struct { + uint XKeySym; + int QtKey; +} KeySymMap; + +// keyboard mapping table, modified from QKeymapper_x11.cpp +static const KeySymMap QtKeyXSymMaps[] = { + +// misc keys + + { XK_Escape, Qt::Key_Escape }, + { XK_Tab, Qt::Key_Tab }, + { XK_ISO_Left_Tab, Qt::Key_Backtab }, + { XK_BackSpace, Qt::Key_Backspace }, + { XK_Return, Qt::Key_Return }, + { XK_Insert, Qt::Key_Insert }, + { XK_Delete, Qt::Key_Delete }, + { XK_Clear, Qt::Key_Delete }, + { XK_Pause, Qt::Key_Pause }, + { XK_Print, Qt::Key_Print }, + { 0x1005FF60, Qt::Key_SysReq }, // hardcoded Sun SysReq + { 0x1007ff00, Qt::Key_SysReq }, // hardcoded X386 SysReq + +// cursor movement + + { XK_Home, Qt::Key_Home }, + { XK_End, Qt::Key_End }, + { XK_Left, Qt::Key_Left }, + { XK_Up, Qt::Key_Up }, + { XK_Right, Qt::Key_Right }, + { XK_Down, Qt::Key_Down }, + { XK_Prior, Qt::Key_PageUp }, + { XK_Next, Qt::Key_PageDown }, + +// modifiers + + { XK_Shift_L, Qt::Key_Shift }, + { XK_Shift_R, Qt::Key_Shift }, + { XK_Shift_Lock, Qt::Key_Shift }, + { XK_Control_L, Qt::Key_Control }, + { XK_Control_R, Qt::Key_Control }, + { XK_Meta_L, Qt::Key_Meta }, + { XK_Meta_R, Qt::Key_Meta }, + { XK_Alt_L, Qt::Key_Alt }, + { XK_Alt_R, Qt::Key_Alt }, + { XK_Caps_Lock, Qt::Key_CapsLock }, + { XK_Num_Lock, Qt::Key_NumLock }, + { XK_Scroll_Lock, Qt::Key_ScrollLock }, + { XK_Super_L, Qt::Key_Super_L }, + { XK_Super_R, Qt::Key_Super_R }, + { XK_Menu, Qt::Key_Menu }, + { XK_Hyper_L, Qt::Key_Hyper_L }, + { XK_Hyper_R, Qt::Key_Hyper_R }, + { XK_Help, Qt::Key_Help }, + { 0x1000FF74, Qt::Key_Backtab }, // hardcoded HP backtab + { 0x1005FF10, Qt::Key_F11 }, // hardcoded Sun F36 (labeled F11) + { 0x1005FF11, Qt::Key_F12 }, // hardcoded Sun F37 (labeled F12) + +// function keys + + { XK_F1, Qt::Key_F1 }, + { XK_F2, Qt::Key_F2 }, + { XK_F3, Qt::Key_F3 }, + { XK_F4, Qt::Key_F4 }, + { XK_F5, Qt::Key_F5 }, + { XK_F6, Qt::Key_F6 }, + { XK_F7, Qt::Key_F7 }, + { XK_F8, Qt::Key_F8 }, + { XK_F9, Qt::Key_F9 }, + { XK_F10, Qt::Key_F10 }, + { XK_F11, Qt::Key_F11 }, + { XK_F12, Qt::Key_F12 }, + { XK_F13, Qt::Key_F13 }, + { XK_F14, Qt::Key_F14 }, + { XK_F15, Qt::Key_F15 }, + { XK_F16, Qt::Key_F16 }, + { XK_F17, Qt::Key_F17 }, + { XK_F18, Qt::Key_F18 }, + { XK_F19, Qt::Key_F19 }, + { XK_F20, Qt::Key_F20 }, + +// numeric and function keypad keys + + { XK_KP_Space, Qt::Key_Space }, + { XK_KP_Tab, Qt::Key_Tab }, + { XK_KP_Enter, Qt::Key_Enter }, + { XK_KP_F1, Qt::Key_F1 }, + { XK_KP_F2, Qt::Key_F2 }, + { XK_KP_F3, Qt::Key_F3 }, + { XK_KP_F4, Qt::Key_F4 }, + + { XK_KP_Home, Qt::Key_Home }, + { XK_KP_Left, Qt::Key_Left }, + { XK_KP_Up, Qt::Key_Up }, + { XK_KP_Right, Qt::Key_Right }, + { XK_KP_Down, Qt::Key_Down }, + { XK_KP_Prior, Qt::Key_PageUp }, + { XK_KP_Next, Qt::Key_PageDown }, + { XK_KP_End, Qt::Key_End }, + { XK_KP_Begin, Qt::Key_Clear }, + { XK_KP_Insert, Qt::Key_Insert }, + { XK_KP_Delete, Qt::Key_Delete }, + { XK_KP_Equal, Qt::Key_Equal }, + { XK_KP_Multiply, Qt::Key_Asterisk }, + { XK_KP_Add, Qt::Key_Plus }, + { XK_KP_Separator, Qt::Key_Comma }, + { XK_KP_Subtract, Qt::Key_Minus }, + { XK_KP_Decimal, Qt::Key_Period }, + { XK_KP_Divide, Qt::Key_Slash }, + + { XK_KP_0, Qt::Key_0 }, + { XK_KP_1, Qt::Key_1 }, + { XK_KP_2, Qt::Key_2 }, + { XK_KP_3, Qt::Key_3 }, + { XK_KP_4, Qt::Key_4 }, + { XK_KP_5, Qt::Key_5 }, + { XK_KP_6, Qt::Key_6 }, + { XK_KP_7, Qt::Key_7 }, + { XK_KP_8, Qt::Key_8 }, + { XK_KP_9, Qt::Key_9 }, + +//International input method support keys +//International & multi-key character composition + + { XK_ISO_Level3_Shift, Qt::Key_AltGr }, + { XK_Multi_key, Qt::Key_Multi_key }, + { XK_Codeinput, Qt::Key_Codeinput }, + { XK_SingleCandidate, Qt::Key_SingleCandidate }, + { XK_MultipleCandidate, Qt::Key_MultipleCandidate }, + { XK_PreviousCandidate, Qt::Key_PreviousCandidate }, + +// Misc Functions + { XK_Mode_switch, Qt::Key_Mode_switch }, + { XK_script_switch, Qt::Key_Mode_switch }, + +// Japanese keyboard support + { XK_Kanji, Qt::Key_Kanji }, + { XK_Muhenkan, Qt::Key_Muhenkan }, + //{ XK_Henkan_Mode, Qt::Key_Henkan_Mode }, + { XK_Henkan_Mode, Qt::Key_Henkan }, + { XK_Henkan, Qt::Key_Henkan }, + { XK_Romaji, Qt::Key_Romaji }, + { XK_Hiragana, Qt::Key_Hiragana }, + { XK_Katakana, Qt::Key_Katakana }, + { XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana }, + { XK_Zenkaku, Qt::Key_Zenkaku }, + { XK_Hankaku, Qt::Key_Hankaku }, + { XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku }, + { XK_Touroku, Qt::Key_Touroku }, + { XK_Massyo, Qt::Key_Massyo }, + { XK_Kana_Lock, Qt::Key_Kana_Lock }, + { XK_Kana_Shift, Qt::Key_Kana_Shift }, + { XK_Eisu_Shift, Qt::Key_Eisu_Shift }, + { XK_Eisu_toggle, Qt::Key_Eisu_toggle }, + //{ XK_Kanji_Bangou, Qt::Key_Kanji_Bangou }, + //{ XK_Zen_Koho, Qt::Key_Zen_Koho }, + //{ XK_Mae_Koho, Qt::Key_Mae_Koho }, + { XK_Kanji_Bangou, Qt::Key_Codeinput }, + { XK_Zen_Koho, Qt::Key_MultipleCandidate }, + { XK_Mae_Koho, Qt::Key_PreviousCandidate }, + +#ifdef XK_KOREAN +// Korean keyboard support + { XK_Hangul, Qt::Key_Hangul }, + { XK_Hangul_Start, Qt::Key_Hangul_Start }, + { XK_Hangul_End, Qt::Key_Hangul_End }, + { XK_Hangul_Hanja, Qt::Key_Hangul_Hanja }, + { XK_Hangul_Jamo, Qt::Key_Hangul_Jamo }, + { XK_Hangul_Romaja, Qt::Key_Hangul_Romaja }, + //{ XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput }, + { XK_Hangul_Codeinput, Qt::Key_Codeinput }, + { XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja }, + { XK_Hangul_Banja, Qt::Key_Hangul_Banja }, + { XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja }, + { XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja }, + //{ XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate }, + //{ XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate }, + //{ XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate }, + { XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate }, + { XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate }, + { XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate }, + { XK_Hangul_Special, Qt::Key_Hangul_Special }, + //{ XK_Hangul_switch, Qt::Key_Hangul_switch }, + { XK_Hangul_switch, Qt::Key_Mode_switch }, +#endif // XK_KOREAN + +// dead keys + { XK_dead_grave, Qt::Key_Dead_Grave }, + { XK_dead_acute, Qt::Key_Dead_Acute }, + { XK_dead_circumflex, Qt::Key_Dead_Circumflex }, + { XK_dead_tilde, Qt::Key_Dead_Tilde }, + { XK_dead_macron, Qt::Key_Dead_Macron }, + { XK_dead_breve, Qt::Key_Dead_Breve }, + { XK_dead_abovedot, Qt::Key_Dead_Abovedot }, + { XK_dead_diaeresis, Qt::Key_Dead_Diaeresis }, + { XK_dead_abovering, Qt::Key_Dead_Abovering }, + { XK_dead_doubleacute, Qt::Key_Dead_Doubleacute }, + { XK_dead_caron, Qt::Key_Dead_Caron }, + { XK_dead_cedilla, Qt::Key_Dead_Cedilla }, + { XK_dead_ogonek, Qt::Key_Dead_Ogonek }, + { XK_dead_iota, Qt::Key_Dead_Iota }, + { XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound }, + { XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound }, + { XK_dead_belowdot, Qt::Key_Dead_Belowdot }, + { XK_dead_hook, Qt::Key_Dead_Hook }, + { XK_dead_horn, Qt::Key_Dead_Horn }, + +// Special keys from X.org - This include multimedia keys, +// wireless/bluetooth/uwb keys , special launcher keys, etc. + +#if 0 + { XF86XK_Back, Qt::Key_Back }, + { XF86XK_Forward, Qt::Key_Forward }, + { XF86XK_Stop, Qt::Key_Stop }, + { XF86XK_Refresh, Qt::Key_Refresh }, + { XF86XK_Favorites, Qt::Key_Favorites }, + { XF86XK_AudioMedia, Qt::Key_LaunchMedia }, + { XF86XK_OpenURL, Qt::Key_OpenUrl }, + { XF86XK_HomePage, Qt::Key_HomePage }, + { XF86XK_Search, Qt::Key_Search }, + { XF86XK_AudioLowerVolume, Qt::Key_VolumeDown }, + { XF86XK_AudioMute, Qt::Key_VolumeMute }, + { XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp }, + { XF86XK_AudioPlay, Qt::Key_MediaPlay }, + { XF86XK_AudioStop, Qt::Key_MediaStop }, + { XF86XK_AudioPrev, Qt::Key_MediaPrevious }, + { XF86XK_AudioNext, Qt::Key_MediaNext }, + { XF86XK_AudioRecord, Qt::Key_MediaRecord }, + { XF86XK_Mail, Qt::Key_LaunchMail }, + { XF86XK_MyComputer, Qt::Key_Launch0 }, + { XF86XK_Calculator, Qt::Key_Calculator }, + { XF86XK_Memo, Qt::Key_Memo }, + { XF86XK_ToDoList, Qt::Key_ToDoList }, + { XF86XK_Calendar, Qt::Key_Calendar }, + { XF86XK_PowerDown, Qt::Key_PowerDown }, + { XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust }, + { XF86XK_Standby, Qt::Key_Standby }, + { XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp }, + { XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown }, + { XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff }, + { XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp }, + { XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown }, + { XF86XK_PowerOff, Qt::Key_PowerOff }, + { XF86XK_WakeUp, Qt::Key_WakeUp }, + { XF86XK_Eject, Qt::Key_Eject }, + { XF86XK_ScreenSaver, Qt::Key_ScreenSaver }, + { XF86XK_WWW, Qt::Key_WWW }, + { XF86XK_Sleep, Qt::Key_Sleep }, + { XF86XK_LightBulb, Qt::Key_LightBulb }, + { XF86XK_Shop, Qt::Key_Shop }, + { XF86XK_History, Qt::Key_History }, + { XF86XK_AddFavorite, Qt::Key_AddFavorite }, + { XF86XK_HotLinks, Qt::Key_HotLinks }, + { XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust }, + { XF86XK_Finance, Qt::Key_Finance }, + { XF86XK_Community, Qt::Key_Community }, + { XF86XK_AudioRewind, Qt::Key_AudioRewind }, + { XF86XK_BackForward, Qt::Key_BackForward }, + { XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft }, + { XF86XK_ApplicationRight, Qt::Key_ApplicationRight }, + { XF86XK_Book, Qt::Key_Book }, + { XF86XK_CD, Qt::Key_CD }, + { XF86XK_Calculater, Qt::Key_Calculator }, + { XF86XK_Clear, Qt::Key_Clear }, + { XF86XK_ClearGrab, Qt::Key_ClearGrab }, + { XF86XK_Close, Qt::Key_Close }, + { XF86XK_Copy, Qt::Key_Copy }, + { XF86XK_Cut, Qt::Key_Cut }, + { XF86XK_Display, Qt::Key_Display }, + { XF86XK_DOS, Qt::Key_DOS }, + { XF86XK_Documents, Qt::Key_Documents }, + { XF86XK_Excel, Qt::Key_Excel }, + { XF86XK_Explorer, Qt::Key_Explorer }, + { XF86XK_Game, Qt::Key_Game }, + { XF86XK_Go, Qt::Key_Go }, + { XF86XK_iTouch, Qt::Key_iTouch }, + { XF86XK_LogOff, Qt::Key_LogOff }, + { XF86XK_Market, Qt::Key_Market }, + { XF86XK_Meeting, Qt::Key_Meeting }, + { XF86XK_MenuKB, Qt::Key_MenuKB }, + { XF86XK_MenuPB, Qt::Key_MenuPB }, + { XF86XK_MySites, Qt::Key_MySites }, + { XF86XK_News, Qt::Key_News }, + { XF86XK_OfficeHome, Qt::Key_OfficeHome }, + { XF86XK_Option, Qt::Key_Option }, + { XF86XK_Paste, Qt::Key_Paste }, + { XF86XK_Phone, Qt::Key_Phone }, + { XF86XK_Reply, Qt::Key_Reply }, + { XF86XK_Reload, Qt::Key_Reload }, + { XF86XK_RotateWindows, Qt::Key_RotateWindows }, + { XF86XK_RotationPB, Qt::Key_RotationPB }, + { XF86XK_RotationKB, Qt::Key_RotationKB }, + { XF86XK_Save, Qt::Key_Save }, + { XF86XK_Send, Qt::Key_Send }, + { XF86XK_Spell, Qt::Key_Spell }, + { XF86XK_SplitScreen, Qt::Key_SplitScreen }, + { XF86XK_Support, Qt::Key_Support }, + { XF86XK_TaskPane, Qt::Key_TaskPane }, + { XF86XK_Terminal, Qt::Key_Terminal }, + { XF86XK_Tools, Qt::Key_Tools }, + { XF86XK_Travel, Qt::Key_Travel }, + { XF86XK_Video, Qt::Key_Video }, + { XF86XK_Word, Qt::Key_Word }, + { XF86XK_Xfer, Qt::Key_Xfer }, + { XF86XK_ZoomIn, Qt::Key_ZoomIn }, + { XF86XK_ZoomOut, Qt::Key_ZoomOut }, + { XF86XK_Away, Qt::Key_Away }, + { XF86XK_Messenger, Qt::Key_Messenger }, + { XF86XK_WebCam, Qt::Key_WebCam }, + { XF86XK_MailForward, Qt::Key_MailForward }, + { XF86XK_Pictures, Qt::Key_Pictures }, + { XF86XK_Music, Qt::Key_Music }, + { XF86XK_Battery, Qt::Key_Battery }, + { XF86XK_Bluetooth, Qt::Key_Bluetooth }, + { XF86XK_WLAN, Qt::Key_WLAN }, + { XF86XK_UWB, Qt::Key_UWB }, + { XF86XK_AudioForward, Qt::Key_AudioForward }, + { XF86XK_AudioRepeat, Qt::Key_AudioRepeat }, + { XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay }, + { XF86XK_Subtitle, Qt::Key_Subtitle }, + { XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack }, + { XF86XK_Time, Qt::Key_Time }, + { XF86XK_Select, Qt::Key_Select }, + { XF86XK_View, Qt::Key_View }, + { XF86XK_TopMenu, Qt::Key_TopMenu }, + { XF86XK_Bluetooth, Qt::Key_Bluetooth }, + { XF86XK_Suspend, Qt::Key_Suspend }, + { XF86XK_Hibernate, Qt::Key_Hibernate }, + { XF86XK_Launch0, Qt::Key_Launch2 }, + { XF86XK_Launch1, Qt::Key_Launch3 }, + { XF86XK_Launch2, Qt::Key_Launch4 }, + { XF86XK_Launch3, Qt::Key_Launch5 }, + { XF86XK_Launch4, Qt::Key_Launch6 }, + { XF86XK_Launch5, Qt::Key_Launch7 }, + { XF86XK_Launch6, Qt::Key_Launch8 }, + { XF86XK_Launch7, Qt::Key_Launch9 }, + { XF86XK_Launch8, Qt::Key_LaunchA }, + { XF86XK_Launch9, Qt::Key_LaunchB }, + { XF86XK_LaunchA, Qt::Key_LaunchC }, + { XF86XK_LaunchB, Qt::Key_LaunchD }, + { XF86XK_LaunchC, Qt::Key_LaunchE }, + { XF86XK_LaunchD, Qt::Key_LaunchF }, +#endif + + { 0, 0} +}; + +#endif + + +int +QtKeyToXKeySym(int qtKey) { + + // TODO: Need to complete this function for all scenario. + int i; + int count = sizeof(QtKeyXSymMaps)/sizeof(KeySymMap); + + if (qtKey < 0x1000) { + //return QChar(qtKey).toLower().unicode(); + return qtKey; + } + + for(i = 0; i < count; i++ ) { + if( QtKeyXSymMaps[i].QtKey == qtKey ) { + return QtKeyXSymMaps[i].XKeySym; + } + } + + return 0; +} + + +int +XKeySymToQTKey(uint keySym) +{ + int i; + int count = sizeof(QtKeyXSymMaps)/sizeof(KeySymMap); + + if ((keySym < 0x1000)) { + //if (keySym >= 'a' && keySym <= 'z') + // return QChar(keySym).toUpper().toAscii(); + return keySym; + } + +#ifdef Q_WS_WIN + if(keySym < 0x3000) + return keySym; +#else + if (keySym < 0x3000 ) + return keySym | Qt::UNICODE_ACCEL; + + for(i = 0; i < count; i++) + if(QtKeyXSymMaps[i].XKeySym == keySym) + return QtKeyXSymMaps[i].QtKey; +#endif + return Qt::Key_unknown; +} + diff --git a/meego/qt-keysym-map.h b/meego/qt-keysym-map.h new file mode 100644 index 0000000..bfd1a96 --- /dev/null +++ b/meego/qt-keysym-map.h @@ -0,0 +1,13 @@ +#ifndef _QT_KEYSYM_MAP_H +#define _QT_KEYSYM_MAP_H + +#include + +G_BEGIN_DECLS + +int QtKeyToXKeySym(int qtKey); +int XKeySymToQTKey(guint keySym); + +G_END_DECLS + +#endif //_QT_KEYSYM_MAP_H diff --git a/meego/qt-translate.cpp b/meego/qt-translate.cpp new file mode 100644 index 0000000..866610c --- /dev/null +++ b/meego/qt-translate.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2010, Intel Corporation. + * + * Author: Raymond Liu + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "debug.h" + +#include +#include + +#include "qt-keysym-map.h" + +#include "qt-translate.h" + +enum { + ShiftModifier = 1 << 0, + ControlModifier = 1 << 2, + AltModifier = 1 << 3 +}; +#define SHIFT_MASK 1 << 0) + +void meego_im_key_event_decode(MeegoImKeyEvent *e, int type, int key, int modifiers, char *text) +{ + g_warn_if_fail(type == QEvent::KeyPress || type == QEvent::KeyRelease); + e->release = type == QEvent::KeyRelease; + + e->state = 0; + if (modifiers & Qt::ShiftModifier) + e->state |= ShiftModifier; + if (modifiers & Qt::ControlModifier) + e->state |= ControlModifier; + if (modifiers & Qt::AltModifier) + e->state |= AltModifier; + + e->keysym = QtKeyToXKeySym(key); + + if (text && strlen(text) > 0) { + e->text = text; + } +} + +void meego_im_key_event_encode(const MeegoImKeyEvent *e, int *type, int *key, int *modifiers, char **text) +{ + *type = e->release ? QEvent::KeyRelease : QEvent::KeyPress; + *key = XKeySymToQTKey(e->keysym); + *modifiers = Qt::NoModifier; + if (e->state & ShiftModifier) + *modifiers |= Qt::ShiftModifier; + if (e->state & ControlModifier) + *modifiers |= Qt::ControlModifier; + if (e->state & AltModifier) + *modifiers |= Qt::AltModifier; + *text = e->text && strlen(e->text) > 0 ? e->text : NULL; +} + +#if 0 +GdkEventKey * +compose_gdk_keyevent(GdkEventType type, guint keyval, guint state, GdkWindow *window) +{ + GdkEventKey *event = NULL; +#if GTK_CHECK_VERSION (3, 0, 0) + GdkDisplay *display; + GdkDeviceManager *device_manager; + GdkDevice *client_pointer; +#endif + if ((type != GDK_KEY_PRESS) && (type != GDK_KEY_RELEASE)) + return NULL; + + event = (GdkEventKey *)(gdk_event_new(type)); + event->length = 0; + event->string = 0; + event->is_modifier = 0; + event->time = GDK_CURRENT_TIME; + event->state = state; + +#if GTK_CHECK_VERSION (3, 0, 0) + display = gdk_window_get_display (window); + device_manager = gdk_display_get_device_manager (display); + client_pointer = gdk_device_manager_get_client_pointer (device_manager); + + gdk_event_set_device ((GdkEvent *)event, + gdk_device_get_associated_device (client_pointer)); +#endif + + if (type == GDK_KEY_RELEASE) + event->state |= GDK_RELEASE_MASK; + event->keyval = keyval; + event->window = window; + + if (event->window) { + GdkKeymap *key_map = gdk_keymap_get_default(); + GdkKeymapKey *keys; + gint n; + + g_object_ref(event->window); // seems when event is freed, the event->window will be unref + + if (gdk_keymap_get_entries_for_keyval(key_map, event->keyval, &keys, &n)) { + event->hardware_keycode = keys[0].keycode; + event->group = keys[0].group; + } else { + event->hardware_keycode = 0; + event->group = 0; + } + } + + DBG("event type=0x%x, state=0x%x, keyval=0x%x, keycode=0x%x, group=%d", + event->type, event->state, event->keyval, event->hardware_keycode, event->group); + + return event; +} + + + +GdkEventKey * +qt_key_event_to_gdk(int type, int key, int modifiers, char *text, GdkWindow *window) +{ + Q_UNUSED(text); + guint state = 0; + guint keyval; + + STEP(); + if ((type != QEvent::KeyPress) && (type != QEvent::KeyRelease)) + return NULL; + + if (modifiers & Qt::ShiftModifier) + state |= GDK_SHIFT_MASK; + if (modifiers & Qt::ControlModifier) + state |= GDK_CONTROL_MASK; + if (modifiers & Qt::AltModifier) + state |= GDK_MOD1_MASK; + + keyval = QtKeyToXKeySym(key); + + if (type == QEvent::KeyPress) { + return compose_gdk_keyevent(GDK_KEY_PRESS, keyval, state, window); + } else { + return compose_gdk_keyevent(GDK_KEY_RELEASE, keyval, state, window); + } + +} + + +gboolean +gdk_key_event_to_qt(GdkEventKey *event, int *type, int *key, int *modifier) +{ + + switch (event->type) { + case GDK_KEY_PRESS: + *type = QEvent::KeyPress; + break; + case GDK_KEY_RELEASE: + *type = QEvent::KeyRelease; + break; + default: + return FALSE; + } + + *key = XKeySymToQTKey(event->keyval); + if (*key == Qt::Key_unknown) { + qWarning("Unkonwn key"); + return FALSE; + } + + *modifier = Qt::NoModifier; + if (event->state & GDK_SHIFT_MASK) + *modifier |= Qt::ShiftModifier; + if (event->state & GDK_CONTROL_MASK) + *modifier |= Qt::ControlModifier; + if (event->state & GDK_MOD1_MASK) + *modifier |= Qt::AltModifier; + if (event->state & GDK_META_MASK) + *modifier |= Qt::MetaModifier; + + DBG("qtkey type =%d, qtkey=0x%x, modifier=0x%x", *type, *key, *modifier); + + return TRUE; +} + +#endif diff --git a/meego/qt-translate.h b/meego/qt-translate.h new file mode 100644 index 0000000..178683f --- /dev/null +++ b/meego/qt-translate.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010, Intel Corporation. + * + * Author: Raymond Liu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _QT_TRANSLATE_H +#define _QT_TRANSLATE_H + +#include +#include "meego-im-defs.h" + +G_BEGIN_DECLS + +void meego_im_key_event_decode(MeegoImKeyEvent *e, int type, int key, int modifiers, char *text); +void meego_im_key_event_encode(const MeegoImKeyEvent *e, int *type, int *key, int *modifiers, char **text); + +G_END_DECLS + +#endif //_QT_GTK_TRANSLATE_H diff --git a/meego/src.pro b/meego/src.pro new file mode 100644 index 0000000..8e140dd --- /dev/null +++ b/meego/src.pro @@ -0,0 +1,71 @@ +include(../../config.pri) + +TEMPLATE = lib +TARGET = maliit-im-common + +CONFIG += link_pkgconfig +PKGCONFIG += glib-2.0 gthread-2.0 dbus-glib-1 + +debug{ + DEFINES += ENABLE_DEBUG +} + +# Generated dbus glue code has warnings of this type, so disable them +QMAKE_CFLAGS_DEBUG += -Wno-unused-parameter +QMAKE_CFLAGS_RELEASE += -Wno-unused-parameter + +HEADERS += \ + meego-im-proxy.h \ + meego-imcontext-dbus.h \ + meego-im-connector.h \ + qt-keysym-map.h \ + debug.h \ + +SOURCES += \ + meego-im-proxy.c \ + meego-imcontext-dbus.c \ + meego-im-connector.c \ + qt-keysym-map.cpp \ + +GTK3_IM_MODULEDIR = + +target.path = $$M_IM_INSTALL_LIBS + +INSTALLS += target + +EXTRA_FILES = \ + meego-im-client.xml \ + meego-imcontext-dbus.xml + + +# improxy +# Generate dbus glue +QMAKE_EXTRA_TARGETS += dbus_glue_improxy +dbus_glue_improxy.target = $$OUT_PWD/meego-im-proxy-glue.h +dbus_glue_improxy.output = $$OUT_PWD/meego-im-proxy-glue.h +dbus_glue_improxy.depends = $$IN_PWD/meego-im-client.xml +dbus_glue_improxy.commands = \ + dbus-binding-tool --prefix=meego_im_proxy --mode=glib-client \ + --output=$$OUT_PWD/meego-im-proxy-glue.h \ + meego-im-client.xml + +# Use to work around the fact that qmake looks up the target for the generated header wrong +QMAKE_EXTRA_TARGETS += fake_dbus_glue_improxy +fake_dbus_glue_improxy.target = meego-im-proxy-glue.h +fake_dbus_glue_improxy.depends = dbus_glue_improxy + +# imcontext +# Generate dbus glue +QMAKE_EXTRA_TARGETS += dbus_glue_imcontext +dbus_glue_imcontext.target = $$OUT_PWD/meego-imcontext-dbus-glue.h +dbus_glue_imcontext.output = $$OUT_PWD/meego-imcontext-dbus-glue.h +dbus_glue_imcontext.depends = $$IN_PWD/meego-imcontext-dbus.xml +dbus_glue_imcontext.commands = \ + dbus-binding-tool --prefix=meego_imcontext_dbus --mode=glib-server \ + --output=$$OUT_PWD/meego-imcontext-dbus-glue.h \ + meego-imcontext-dbus.xml + +# Use to work around the fact that qmake looks up the target for the generated header wrong +QMAKE_EXTRA_TARGETS += fake_dbus_glue_imcontext +fake_dbus_glue_imcontext.target = meego-imcontext-dbus-glue.h +fake_dbus_glue_imcontext.depends = dbus_glue_imcontext diff --git a/mimclient.c b/mimclient.c new file mode 100644 index 0000000..06d72aa --- /dev/null +++ b/mimclient.c @@ -0,0 +1,81 @@ +#include +#include "meego/meego-imcontext-dbus.h" +#include "meego/qt-translate.h" + +#include "context.h" +#include "mimclient.h" + +gboolean redirect_keys = FALSE; + +gboolean meego_imcontext_client_activation_lost_event(MeegoIMContextDbusObj *obj) +{ + g_debug("Got %s", __func__); + return TRUE; +} + +gboolean meego_imcontext_client_im_initiated_hide(MeegoIMContextDbusObj *obj) +{ + g_debug("Got %s", __func__); + return TRUE; +} + +gboolean meego_imcontext_client_commit_string(MeegoIMContextDbusObj *obj, + const char *string, + int replace_start, int replace_length, int cursor_pos) +{ + return context_commit(contexts_focused_icid(), string, + replace_start, replace_length, cursor_pos); +} + +gboolean meego_imcontext_client_update_preedit(MeegoIMContextDbusObj *obj, const char *string, + int preedit_format_count, const MeegoImPreeditFormat preedit_formats[], + int replace_start, int replace_length, int cursor_pos) +{ + return context_update_preedit(contexts_focused_icid(), + string, preedit_format_count, preedit_formats, + replace_start, replace_length, cursor_pos); +} + +gboolean meego_imcontext_client_key_event(MeegoIMContextDbusObj *obj, int type, int key, int modifiers, char *text, + gboolean auto_repeat, int count) +{ + MeegoImKeyEvent e; + meego_im_key_event_decode(&e, type, key, modifiers, text); + return context_send_key(contexts_focused_icid(), &e); +} + +gboolean meego_imcontext_client_update_input_method_area(MeegoIMContextDbusObj *obj, GPtrArray *data) +{ + g_debug("Got %s", __func__); + return TRUE; +} + +gboolean meego_imcontext_client_set_global_correction_enabled(MeegoIMContextDbusObj *obj, gboolean correction) +{ + g_debug("Got %s", __func__); + return TRUE; +} + +gboolean meego_imcontext_client_copy(MeegoIMContextDbusObj *obj) +{ + g_debug("Got %s", __func__); + return TRUE; +} + +gboolean meego_imcontext_client_paste(MeegoIMContextDbusObj *obj) +{ + g_debug("Got %s", __func__); + return TRUE; +} + +gboolean meego_imcontext_client_set_redirect_keys(MeegoIMContextDbusObj *obj, gboolean enabled) +{ + redirect_keys = enabled; + return TRUE; +} + +gboolean meego_imcontext_client_preedit_rectangle(MeegoIMContextDbusObj *obj, GValueArray **rect, gboolean *valid) +{ + g_debug("Got %s", __func__); + return TRUE; +} diff --git a/mimclient.h b/mimclient.h new file mode 100644 index 0000000..ce44cd5 --- /dev/null +++ b/mimclient.h @@ -0,0 +1,8 @@ +#ifndef MIMSERVER_H +#define MIMSERVER_H + +#include + +extern gboolean redirect_keys; + +#endif diff --git a/test.c b/test.c new file mode 100644 index 0000000..bacd442 --- /dev/null +++ b/test.c @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static Atom atom_wm_protocols; +static Atom atom_wm_delete; +static Atom atom_wm_state; +static Atom atom_wm_fullscreen; +static Display *dpy; +static Window win; +static GC gc; +static XIM im; +static XIC ic; + +static void set_fullscreen() +{ + XEvent e = { 0 }; + e.type = ClientMessage; + e.xclient.window = win; + e.xclient.message_type = atom_wm_state; + e.xclient.format = 32; + e.xclient.data.l[0] = 1; + e.xclient.data.l[1] = atom_wm_fullscreen; + e.xclient.data.l[2] = 0; + + XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask, &e); +} + +static int preedit_start_cb(XIC ic, XPointer client_data, XPointer p) +{ + printf("start preedit\n"); + return -1; +} + +static int preedit_stop_cb(XIC ic, XPointer client_data, XPointer p) +{ + printf("stop preedit\n"); + return 0; +} + +static int preedit_draw_cb(XIC ic, XPointer client_data, XIMPreeditDrawCallbackStruct *s) +{ + printf("draw preedit %d'%s'\n", s->text->length, s->text->string.multi_byte); + return 0; +} + +int main(int argc, char ** argv) +{ + bool quit = false; + setlocale(LC_ALL, ""); + XSetLocaleModifiers("@im=xmim"); + + char *nl = nl_langinfo(CODESET); + printf("codeset %s\n", nl); + + dpy = XOpenDisplay(NULL); + assert(dpy); + int scr = DefaultScreen(dpy); + + atom_wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", True); + atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True); + atom_wm_state = XInternAtom(dpy, "_NET_WM_STATE", True); + atom_wm_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", True); + + win = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), 0, 0, 400, 400, 0, + WhitePixel(dpy, scr), WhitePixel(dpy, scr)); + + im = XOpenIM(dpy, NULL, NULL, NULL); + assert(im); + + XIMStyles *xim_styles = NULL; + if (XGetIMValues(im, XNQueryInputStyle, &xim_styles, NULL) == 0) { + printf("styles: (%u)\n", xim_styles->count_styles); + for (int i = 0; i < xim_styles->count_styles; i++) { + const XIMStyle style = xim_styles->supported_styles[i]; + printf(" style %lu\n", style); + } + } + + XIMCallback preedit_start = { NULL, (XIMProc) preedit_start_cb }; + XIMCallback preedit_stop = { NULL, (XIMProc) preedit_stop_cb }; + XIMCallback preedit_draw = { NULL, (XIMProc) preedit_draw_cb }; + + XVaNestedList preedit_list = + XVaCreateNestedList(0, + XNPreeditStartCallback, &preedit_start, + XNPreeditDoneCallback, &preedit_stop, + XNPreeditDrawCallback, &preedit_draw, + NULL); + + ic = XCreateIC(im, + XNInputStyle, XIMPreeditCallbacks | XIMStatusNothing, + XNClientWindow, win, XNFocusWindow, win, + XNPreeditAttributes, preedit_list, + NULL); + assert(ic); + + XGCValues gc_values; + gc = XCreateGC(dpy, win, 0, &gc_values); + + unsigned long im_event_mask; + XGetICValues(ic, XNFilterEvents, &im_event_mask, NULL); + printf("im event mask 0x%lx\n", im_event_mask); + + im_event_mask |= KeyPressMask | KeyReleaseMask | ButtonPressMask | FocusChangeMask | ClientMessage; + XSelectInput(dpy, win, im_event_mask); + XSetWMProtocols(dpy, win, &atom_wm_delete, 1); + + set_fullscreen(); + + XMapWindow(dpy, win); + + while (!quit) { + XEvent e; + XNextEvent(dpy, &e); + if (XFilterEvent(&e, None)) { + continue; + } + switch (e.type) { + case KeyPress: { + printf("key press\n"); + KeySym keysym; + Status status; + int buflength; + static int bufsize = 16; + static char *buf; + if (buf == NULL) { + buf = malloc(bufsize + 1); + assert(buf); + } + buflength = Xutf8LookupString(ic, &e.xkey, buf, bufsize, &keysym, &status); + if (status == XBufferOverflow) { + bufsize = buflength; + buf = realloc(buf, bufsize + 1); + assert(buf); + buflength = Xutf8LookupString(ic, &e.xkey, buf, bufsize, &keysym, &status); + } + switch(status) { + case XLookupKeySym: + printf("keysim(0x%lx)\n", keysym); + break; + case XLookupBoth: + printf("keysim(0x%lx)+", keysym); + // Fallthrough + case XLookupChars: + buf[buflength] = '\0'; + printf("string(%d'%s')\n", buflength, buf); + break; + case XLookupNone: + printf("none\n"); + break; + default: + printf("weirdo\n"); + break; + } + } break; + case KeyRelease: + printf("key release\n"); + break; + case ButtonPress: + printf("button press\n"); + break; + case FocusIn: + printf("focus in\n"); + XSetICFocus(ic); + break; + case FocusOut: + printf("focus out\n"); + XUnsetICFocus(ic); + break; + case ClientMessage: + printf("client message\n"); + if (e.xclient.message_type == atom_wm_protocols) { + if (e.xclient.data.l[0] == atom_wm_delete) { + quit = true; + } + } + break; + default: + printf("unknown event\n"); + break; + } + } + + XFreeGC(dpy, gc); + XDestroyIC(ic); + XCloseIM(im); + XDestroyWindow(dpy, win); + XFlush(dpy); + XCloseDisplay(dpy); + + return EXIT_SUCCESS; +} diff --git a/ximserver.c b/ximserver.c new file mode 100644 index 0000000..5fc3bd3 --- /dev/null +++ b/ximserver.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include "IMdkit/IMdkit.h" +#include "IMdkit/Xi18n.h" + +#include "xmim.h" +#include "context.h" +#include "ximserver.h" + +static XIMS xims; + +#define ALL_LOCALES \ + "aa,af,am,an,ar,as,ast,az,be,ber,bg,bn,bo,br,bs,byn,C,ca,crh,cs,csb,cy,da,de,dz,el,en,es,et,eu,fa,fi,fil,fo,fr,fur,fy,ga,gd,gez,gl,gu,gv,ha,he,hi,hne,hr,hsb,ht,hu,hy,id,ig,ik,is,it,iu,iw,ja,ka,kk,kl,km,kn,ko,ks,ku,kw,ky,lg,li,lo,lt,lv,mai,mg,mi,mk,ml,mn,mr,ms,mt,nan,nb,nds,ne,nl,nn,no,nr,nso,oc,om,or,pa,pa,pap,pl,pt,ro,ru,rw,sa,sc,sd,se,shs,si,sid,sk,sl,so,sq,sr,ss,st,sv,ta,te,tg,th,ti,tig,tk,tl,tn,tr,ts,tt,ug,uk,ur,uz,ve,vi,wa,wo,xh,yi,yo,zh,zu" + +static int xims_protocol_handler(XIMS ims, IMProtocol *call_data) +{ + switch (call_data->major_code) { + case XIM_OPEN: + g_debug("XIM_OPEN"); + return True; + case XIM_CLOSE: + g_debug("XIM_CLOSE"); + return True; + case XIM_CREATE_IC: + g_debug("XIM_CREATE_IC"); + return context_create(&call_data->changeic); + case XIM_DESTROY_IC: + g_debug("XIM_DESTROY_IC"); + return context_destroy(&call_data->changeic); + case XIM_SET_IC_VALUES: + g_debug("XIM_SET_IC_VALUES"); + return context_set_values(&call_data->changeic); + case XIM_GET_IC_VALUES: + g_debug("XIM_GET_IC_VALUES"); + return context_get_values(&call_data->changeic); + case XIM_SET_IC_FOCUS: + g_debug("XIM_SET_IC_FOCUS"); + return context_set_focus(&call_data->changefocus); + case XIM_UNSET_IC_FOCUS: + g_debug("XIM_UNSET_IC_FOCUS"); + return context_unset_focus(&call_data->changefocus); + case XIM_FORWARD_EVENT: + g_debug("XIM_FORWARD_EVENT"); + return context_forward_event(&call_data->forwardevent); + case XIM_RESET_IC: + g_debug("XIM_RESET_IC"); + return context_reset(&call_data->resetic); + case XIM_PREEDIT_START_REPLY: + g_debug("XIM_PREEDIT_START_REPLY"); + return True; + default: + g_message("Unknown or unsupport XIM protocol message with major: %d", + call_data->major_code); + return False; + } +} + +void xims_open() +{ + static XIMStyle ims_styles[] = { + XIMPreeditCallbacks | XIMStatusNothing, + XIMPreeditCallbacks | XIMStatusNone, + XIMPreeditPosition | XIMStatusNothing, + XIMPreeditPosition | XIMStatusNone, + XIMPreeditNothing | XIMStatusNothing, + XIMPreeditNothing | XIMStatusNone, + XIMPreeditNone | XIMStatusNothing, + XIMPreeditNone | XIMStatusNone, + 0 + }; + static XIMEncoding ims_encodings[] = { + "COMPOUND_TEXT", + NULL + }; + + XIMStyles styles = { + .count_styles = G_N_ELEMENTS(ims_styles) - 1, + .supported_styles = ims_styles + }; + XIMEncodings encodings = { + .count_encodings = G_N_ELEMENTS(ims_encodings) - 1, + .supported_encodings = ims_encodings + }; + + contexts_init(); + xims = IMOpenIM(x_dpy, + IMModifiers, "Xi18n", + IMServerWindow, x_win, + IMServerName, "xmim", + IMLocale, ALL_LOCALES, + IMServerTransport, "X/", + IMInputStyles, &styles, + IMEncodingList, &encodings, + IMProtocolHandler, xims_protocol_handler, + IMFilterEventMask, KeyPressMask | KeyReleaseMask, + NULL); +} + +void xims_close() +{ + contexts_destroy(); + IMCloseIM(xims); +} + +void xims_commit(guint imid, guint icid, guint keysym, const char *text) +{ + g_return_if_fail(icid != 0); + + XTextProperty tp; + IMCommitStruct cms = {0}; + + Xutf8TextListToTextProperty(x_dpy, (char**)&text, 1, XCompoundTextStyle, &tp); + + cms.major_code = XIM_COMMIT; + cms.connect_id = imid; + cms.icid = icid; + cms.commit_string = ""; // Need to always put an string, even if empty + + if (keysym) { + cms.flag |= XimLookupKeySym; + cms.keysym = keysym; + } + if (text && text[0]) { + cms.flag |= XimLookupChars; + cms.commit_string = (gchar *)tp.value; + } + g_warn_if_fail(cms.flag); + + IMCommitString(xims, (XPointer)&cms); + + XFree(tp.value); +} + +void xims_forward_event(IMForwardEventStruct *call_data) +{ + IMForwardEvent(xims, (XPointer)call_data); +} + +void xims_call_callback(XPointer data) +{ + IMCallCallback(xims, data); +} + +void xims_insert_event(guint imid, guint icid, const XEvent *xev) +{ + IMForwardEventStruct s = {0}; + + s.major_code = XIM_FORWARD_EVENT; + s.connect_id = imid; + s.icid = icid; + s.sync_bit = 0; + s.serial_number = 0; + + s.event = *xev; + + xims_forward_event(&s); +} diff --git a/ximserver.h b/ximserver.h new file mode 100644 index 0000000..3991d00 --- /dev/null +++ b/ximserver.h @@ -0,0 +1,17 @@ +#ifndef XIMSERVER_H +#define XIMSERVER_H + +#include "IMdkit/IMdkit.h" +#include "IMdkit/Xi18n.h" +#include "meego/qt-translate.h" + +void xims_open(); +void xims_close(); + +void xims_commit(guint imid, guint icid, guint keysym, const char *text); +void xims_forward_event(IMForwardEventStruct *call_data); +void xims_call_callback(XPointer data); + +void xims_insert_event(guint imid, guint icid, const XEvent *xev); + +#endif diff --git a/xmim.h b/xmim.h new file mode 100644 index 0000000..2e0283f --- /dev/null +++ b/xmim.h @@ -0,0 +1,15 @@ +#ifndef XMIM_H +#define XMIM_H + +#include +#include + +extern Display *x_dpy; +extern Window x_win; +extern XIM x_im; +extern XIC x_ic; + +extern char * opt_display; +extern gint64 opt_xephyr; + +#endif diff --git a/xmimd.config b/xmimd.config new file mode 100644 index 0000000..8cec188 --- /dev/null +++ b/xmimd.config @@ -0,0 +1 @@ +// ADD PREDEFINED MACROS HERE! diff --git a/xmimd.creator b/xmimd.creator new file mode 100644 index 0000000..e94cbbd --- /dev/null +++ b/xmimd.creator @@ -0,0 +1 @@ +[General] diff --git a/xmimd.files b/xmimd.files new file mode 100644 index 0000000..80e54a1 --- /dev/null +++ b/xmimd.files @@ -0,0 +1,47 @@ +Makefile +context.c +context.h +main.c +mimclient.c +mimclient.h +test.c +ximserver.c +ximserver.h +xmim.h +IMdkit/Makefile +IMdkit/FrameMgr.c +IMdkit/FrameMgr.h +IMdkit/i18nAttr.c +IMdkit/i18nClbk.c +IMdkit/i18nIc.c +IMdkit/i18nIMProto.c +IMdkit/i18nMethod.c +IMdkit/i18nPtHdr.c +IMdkit/i18nUtil.c +IMdkit/i18nX.c +IMdkit/IMConn.c +IMdkit/IMdkit.h +IMdkit/IMMethod.c +IMdkit/IMValues.c +IMdkit/Xi18n.h +IMdkit/Xi18nX.h +IMdkit/XimFunc.h +IMdkit/XimProto.h +IMdkit/Xtrans.h +meego/debug.h +meego/Makefile +meego/meego-im-client.xml +meego/meego-im-connector.c +meego/meego-im-connector.h +meego/meego-imcontext-dbus.c +meego/meego-imcontext-dbus-glue.h +meego/meego-imcontext-dbus.h +meego/meego-imcontext-dbus.xml +meego/meego-im-defs.h +meego/meego-im-proxy.c +meego/meego-im-proxy-glue.h +meego/meego-im-proxy.h +meego/qt-keysym-map.cpp +meego/qt-keysym-map.h +meego/qt-translate.cpp +meego/qt-translate.h diff --git a/xmimd.includes b/xmimd.includes new file mode 100644 index 0000000..2c70029 --- /dev/null +++ b/xmimd.includes @@ -0,0 +1,6 @@ +/usr/include/dbus-1.0/ +/usr/include/glib-2.0/ +/usr/include/qt4/ +/usr/include/qt4/Qt/ +/usr/include/qt4/QtCore/ +/usr/include/qt4/QtGui/ -- cgit v1.2.3