diff options
author | Javier S. Pedro <maemo@javispedro.com> | 2012-04-11 03:12:40 +0200 |
---|---|---|
committer | Javier S. Pedro <maemo@javispedro.com> | 2012-04-11 03:12:40 +0200 |
commit | bfbf55700091bb6084b3cbe151a762816db0e3f0 (patch) | |
tree | bf7605926a6e8fb06c85b1d1a605d889ca67a79f | |
download | xmimd-bfbf55700091bb6084b3cbe151a762816db0e3f0.tar.gz xmimd-bfbf55700091bb6084b3cbe151a762816db0e3f0.zip |
initial import
55 files changed, 16427 insertions, 0 deletions
@@ -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. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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. + + <signature of Ty Coon>, 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 <X11/Xlibint.h> +#include <stdlib.h> +#include <string.h> +#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 <X11/Xmd.h> +#include <X11/Xlib.h> +#include <stdio.h> + +#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 <X11/Xlib.h> +#include <stdlib.h> +#include <string.h> +#include "IMdkit.h" +#include <stdarg.h> + +#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 <X11/Xlib.h> +#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 <stdlib.h> +#include <X11/Xlib.h> +#include "IMdkit.h" +#include <stdarg.h> + +#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 <X11/Xmd.h> + +#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 <X11/Xlib.h> +#include <X11/Xfuncs.h> +#include <X11/Xos.h> +#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 <stdlib.h> +#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 <X11/Xfuncproto.h> +#include <X11/Xos.h> + + +/* + * 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 <sys/uio.h>. See the readv(2) and writev(2) + * manual pages for details. + */ + +struct iovec { + caddr_t iov_base; + int iov_len; +}; + +#else +#include <sys/uio.h> +#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 <X11/Xlib.h> +#include <X11/Xresource.h> +#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 <X11/Xlib.h> +#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 <X11/Xlib.h> +#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 <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#ifndef NEED_EVENTS +#define NEED_EVENTS +#endif +#include <X11/Xproto.h> +#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; i<length; i++) + data[i-1] = data[i]; + XChangeProperty (dpy, + root, + XIM_Servers, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char *)data, + length-1); + ret = True; + } + else { + XChangeProperty (dpy, + root, + XIM_Servers, + XA_ATOM, + 32, + PropModePrepend, + (unsigned char *)data, + 0); + ret = False; + } + if (data != NULL) + XFree ((char *) data); + return ret; +} + + +/* XIM protocol methods */ +static void *xi18n_setup (Display *dpy, XIMArg *args) +{ + Xi18n i18n_core; + CARD16 endian = 1; + + if ((i18n_core = (Xi18n) malloc (sizeof (Xi18nCore))) == (Xi18n) NULL) + return NULL; + /*endif*/ + + memset (i18n_core, 0, sizeof (Xi18nCore)); + + i18n_core->address.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 <stdlib.h> +#include <sys/param.h> +#include <X11/Xlib.h> +#ifndef NEED_EVENTS +#define NEED_EVENTS +#endif +#include <X11/Xproto.h> +#undef NEED_EVENTS +#include "FrameMgr.h" +#include "IMdkit.h" +#include "Xi18n.h" +#include "XimFunc.h" + +#ifdef XIM_DEBUG +#include <stdio.h> + +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 <X11/Xlib.h> +#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 <limits.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#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 Binary files differnew file mode 100644 index 0000000..47f20ec --- /dev/null +++ b/IMdkit/libimdkit.a 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 <glib.h> +#include <glib-object.h> +#include <X11/Xutil.h> +#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 <glib.h> +#include <X11/Xlib.h> +#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 @@ -0,0 +1,148 @@ +/* + * xmim - X MeeGo Input Method bridge + * Copyright (c) 2012 Javier S. Pedro <maemo@javispedro.com> + * + * Portions from the Smart Common Input Method + * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn> + * + * 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 <stdlib.h> +#include <locale.h> +#include <glib.h> +#include <glib-object.h> +#include <X11/Xlib.h> +#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 <glib.h> +#include <glib/gprintf.h> + +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 <glib.h> +#include <dbus/dbus-glib.h> + +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 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<node> + <interface name="com.meego.inputmethod.uiserver1"> + <method name="showInputMethod"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="hideInputMethod"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="mouseClickedOnPreedit"> + <arg name="posX" type="i"/> + <arg name="posY" type="i"/> + <arg name="preeditX" type="i"/> + <arg name="preeditY" type="i"/> + <arg name="preeditWidth" type="i"/> + <arg name="preeditHeight" type="i"/> + </method> + <method name="setPreedit"> + <arg name="text" type="s" direction="in"/> + <arg name="cursorPos" type="i"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="updateWidgetInformation"> + <arg name="encodedState" type="a{sv}"/> + <arg name="focusChanged" type="b"/> + </method> + <method name="reset"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="setContextObject"> + <arg name="callbackObject" type="s" direction="in"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="activateContext"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="appOrientationAboutToChange"> + <arg name="angle" type="i"/> + </method> + <method name="appOrientationChanged"> + <arg name="angle" type="i" direction="in"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="setCopyPasteState"> + <arg name="copyAvailable" type="b" direction="in"/> + <arg name="pasteAvailable" type="b" direction="in"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="processKeyEvent"> + <arg name="keyType" type="i" direction="in"/> + <arg name="keyCode" type="i" direction="in"/> + <arg name="modifiers" type="i" direction="in"/> + <arg name="text" type="s" direction="in"/> + <arg name="autoRepeat" type="b" direction="in"/> + <arg name="count" type="i" direction="in"/> + <arg name="nativeScanCode" type="u" direction="in"/> + <arg name="nativeModifiers" type="u" direction="in"/> + <arg name="time" type="u" /> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="registerAttributeExtension"> + <arg name="id" type="i"/> + <arg name="fileName" type="s"/> + </method> + <method name="unregisterAttributeExtension"> + <arg name="id" type="i"/> + </method> + <method name="setExtendedAttribute"> + <arg name="id" type="i"/> + <arg name="target" type="s"/> + <arg name="targetItem" type="s"/> + <arg name="attribute" type="s"/> + <arg name="value" type="ay"/> + </method> + </interface> +</node> + 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 <glib.h> + +#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 <glib.h> + +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 <glib.h> +#include <dbus/dbus-glib.h> + +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 <raymond.liu@intel.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. + * + * 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 <raymond.liu@intel.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. + * + * 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 <glib.h> +#include <glib-object.h> +#include <dbus/dbus-glib.h> + +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 <glib-object.h> + +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 <dbus/dbus-glib.h> +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 <raymond.li@intel.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. + * + * 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 <stdlib.h> +#include <glib.h> + +#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 <raymond.liu@intel.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. + * + * 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 <dbus/dbus-glib.h> +#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 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<node> + <interface name="com.meego.inputmethod.inputcontext1"> + <method name="activationLostEvent"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="imInitiatedHide"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="commitString"> + <arg name="string" type="s" direction="in"/> + <arg name="replaceStart" type="i" direction="in" /> + <arg name="replaceLength" type="i" direction="in" /> + <arg name="cursorPos" type="i" direction="in" /> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="updatePreedit"> + <arg name="string" type="s" direction="in"/> + <arg name="formatList" type="a(iii)" direction="in" /> + <arg name="replaceStart" type="i" direction="in" /> + <arg name="replaceLength" type="i" direction="in" /> + <arg name="cursorPos" type="i" direction="in" /> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="keyEvent"> + <arg name="type" type="i" direction="in"/> + <arg name="key" type="i" direction="in"/> + <arg name="modifiers" type="i" direction="in"/> + <arg name="text" type="s" direction="in"/> + <arg name="autoRepeat" type="b" direction="in"/> + <arg name="count" type="i" direction="in"/> + <arg name="requestType" type="y" direction="in"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="updateInputMethodArea"> + <arg name="data" type="ay" direction="in"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="setGlobalCorrectionEnabled"> + <arg name="enabled" type="b" direction="in"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="copy"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="paste"> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="setRedirectKeys"> + <arg name="enabled" type="b" direction="in"/> + <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> + </method> + <method name="preeditRectangle"> + <arg name="valid" type="b" direction="out"/> + <arg name="rect" type="(iiii)" direction="out"/> + </method> + <method name="setDetectableAutoRepeat"> + <arg name="enabled" type="b"/> + </method> + <method name="setSelection"> + <arg name="start" type="i"/> + <arg name="length" type="i"/> + </method> + <method name="selection"> + <arg name="valid" type="b" direction="out"/> + <arg name="selectionText" type="s" direction="out"/> + </method> + </interface> +</node> + 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 <ellis@kde.org> + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010, Intel Corporation. + * + * Author: Raymond Liu <raymond.liu@intel.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. + * + * 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 <X11/keysym.h> +#include <qstring.h> + +#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 <glib.h> + +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 <raymond.liu@intel.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. + * + * 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 <QEvent> +#include <QKeyEvent> + +#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 <raymond.liu@intel.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. + * + * 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 <glib.h> +#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 <glib.h> +#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 <glib.h> + +extern gboolean redirect_keys; + +#endif @@ -0,0 +1,200 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <locale.h> +#include <langinfo.h> +#include <assert.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> + +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 <glib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#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 @@ -0,0 +1,15 @@ +#ifndef XMIM_H +#define XMIM_H + +#include <glib.h> +#include <X11/Xlib.h> + +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/ |