1 /*
2 
3   Copyright (c) 2003-2013 uim Project https://github.com/uim/uim
4 
5   All rights reserved.
6 
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions
9   are met:
10 
11   1. Redistributions of source code must retain the above copyright
12      notice, this list of conditions and the following disclaimer.
13   2. Redistributions in binary form must reproduce the above copyright
14      notice, this list of conditions and the following disclaimer in the
15      documentation and/or other materials provided with the distribution.
16   3. Neither the name of authors nor the names of its contributors
17      may be used to endorse or promote products derived from this software
18      without specific prior written permission.
19 
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30   SUCH DAMAGE.
31 */
32 
33 // -*- C++ -*-
34 #ifndef UIM_XIM_XIM_H
35 #define UIM_XIM_XIM_H
36 
37 #include <X11/X.h>
38 #include <X11/Xlib.h>
39 #include <X11/keysym.h>
40 #include <X11/Xos.h>
41 #include <cstdio>
42 #include <list>
43 #include "ximserver.h"
44 #include "ximpn.h"
45 #include "compose.h"
46 
47 // The header file contains about connection of XIM protocol, and the
48 // definition of IM and IC.
49 
50 typedef unsigned char C8;
51 typedef unsigned short C16;
52 typedef unsigned int C32;
53 
54 class XimIC;
55 
56 // translate into host order
57 C16 readC16(unsigned char *val, int byte_order);
58 C32 readC32(unsigned char *val, int byte_order);
59 
60 class TxPacket {
61 public:
~TxPacket()62     virtual ~TxPacket() {};
63 
64     virtual int get_length() = 0;
65     virtual int write_to_buf(unsigned char *buf, int buflen, int byte_order) = 0;
66 
67     virtual void dump(int byte_order) = 0;
68     virtual C8 get_major() = 0;
69 
70     virtual int pushC8(C8) = 0;
71     virtual int pushC16(C16) = 0;
72     virtual int pushC32(C32) = 0;
73     virtual int pushSTRING(char *) = 0;
74     virtual int pushBytes(const char *, int) = 0;
75 
76     virtual int pop_back() = 0;
77 };
78 
79 class RxPacket {
80 public:
~RxPacket()81     virtual ~RxPacket() {};
82 
83     virtual void rewind() = 0;
84     virtual C8 getC8() = 0;
85     virtual C16 getC16() = 0;
86     virtual C32 getC32() = 0;
87     // this Str means STRING in xim.PS
88     virtual int getStrLen() = 0;
89     virtual void getStr(char *buf) = 0;
90     // STR
91     virtual int getStr8Len() = 0;
92     virtual void getStr8(char *buf) = 0;
93 
94     virtual int getMajor() = 0;
95 
96     virtual bool isOverRun() = 0;
97     virtual void dump() = 0;
98     static int getPacketLength(unsigned char *, int byte_order);
99 };
100 
101 TxPacket *createTxPacket(C8 major, C8 minor);
102 RxPacket *createRxPacket(unsigned char *buf, int byte_order);
103 RxPacket *copyRxPacket(RxPacket *packet);
104 
105 class Connection {
106 public:
107     Connection(XimServer *);
108     virtual ~Connection();
109     void OnRecv();
110     void OnSend();
111     void OnClose();
112     void push_packet(TxPacket *); // for normal packet for reply
113     void push_passive_packet(TxPacket *); // for preceding packet for reply
byte_order()114     int byte_order() {return mByteorder;};
115     void push_error_packet(C16 imid, C16 icid, C16 er, const char *str);
116 
117     unsigned short to_hs(unsigned short s);
118     unsigned int to_hl(unsigned int l);
119     void terminate();
120     XimServer *getXimServer();
121 protected:
122     virtual void setSyncFlag();
123     virtual void unsetSyncFlag();
124     virtual bool hasSyncFlag();
125     virtual void setPreeditStartSyncFlag();
126     virtual void unsetPreeditStartSyncFlag();
127     virtual bool hasPreeditStartSyncFlag();
128     virtual void setPreeditCaretSyncFlag();
129     virtual void unsetPreeditCaretSyncFlag();
130     virtual bool hasPreeditCaretSyncFlag();
131 
132     std::list<RxPacket *> mRxQ;
133     std::list<TxPacket *> mTxQ;
134     std::list<TxPacket *> mPTxQ;
135     std::list<TxPacket *> mPendingTxQ; // pending queue for mTxQ and mPTxQ
136     int mByteorder;
137     bool mIsCloseWait; // true when the last packet has handled
138 private:
139     void xim_connect(RxPacket *);
140     void xim_disconnect();
141     void xim_open(RxPacket *);
142     void xim_query_extension(RxPacket *);
143     void xim_encoding_negotiation(RxPacket *);
144     void xim_close(RxPacket *);
145     void xim_get_im_values(RxPacket *);
146     void xim_set_ic_values(RxPacket *);
147     void xim_get_ic_values(RxPacket *);
148 
149     void xim_create_ic(RxPacket *);
150     void xim_destroy_ic(RxPacket *);
151 
152     void xim_set_ic_focus(RxPacket *);
153     void xim_unset_ic_focus(RxPacket *);
154     void xim_reset_ic(RxPacket *);
155 
156     void xim_forward_event(RxPacket *);
157     void xim_sync_reply();
158     void xim_preedit_start_reply();
159     void xim_preedit_caret_reply();
160     void xim_error(RxPacket *);
161 
162     bool is_xim_sync_reply_timeout();
163     void clear_pending_queue();
164 private:
165     XimIC *get_ic(RxPacket *);
166     std::list<C16> mCreatedIm;
167     XimServer *mServer;
168     bool mSyncFlag;
169     bool mPreeditStartSyncFlag;
170     bool mPreeditCaretSyncFlag;
171     struct timeval mSyncStartTime;
172 };
173 
174 // definition of IM
175 class XimIM {
176 public:
177     XimIM(Connection *, C16 id);
178     virtual ~XimIM();
179 
180     virtual void create_ic(RxPacket *) = 0;
181     virtual void destroy_ic(C16) = 0;
182     virtual void set_ic_focus(C16 icid) = 0;
183     virtual void set_ic_values(RxPacket *) = 0;
184     virtual void get_ic_values(RxPacket *) = 0;
185     virtual void unset_ic_focus(C16 icid) = 0;
186     virtual void forward_event(RxPacket *) = 0;
187     virtual void send_sync_reply(C16 icid) = 0;
188     virtual void send_sync(C16 icid) = 0;
189     virtual XimIC *get_ic_by_id(C16 icid) = 0;
190     virtual void onSendPacket() = 0;
191     virtual void changeContext(const char *engine) = 0;
192     void set_encoding(const char *encoding);
193     const char *get_encoding();
194     void set_lang_region(const char *name);
195     const char *get_lang_region();
196     char *uStringToCtext(uString *us);
197     char *utf8_to_native_str(char *str);
198     struct input_style *getInputStyles();
199     // for Compose
200     void create_compose_tree();
201     DefTree *get_compose_tree();
202 
203 protected:
204     Connection *mConn;
205     Locale *mLocale;
206     C16 mID;
207     char *mEncoding;
208     char *mLangRegion;
209 
210     // for Compose
211     int get_compose_filename(char *filename, size_t len);
212     int TransFileName(char *transname, const char *name, size_t len);
213     void ParseComposeStringFile(FILE *fp);
214     void FreeComposeTree(DefTree *top);
215     int parse_compose_line(FILE *fp, char **tokenbuf, size_t *buflen);
216     int get_mb_string(char *buf, KeySym ks);
217     DefTree *mTreeTop;
218 };
219 
220 C16 unused_im_id();
221 XimIM *create_im(Connection *, C16 id);
222 XimIM *get_im_by_id(C16 id);
223 void close_im(C16 id);
224 
225 
226 struct keyEventX {
227     KeySym key_sym; // keysym of X
228     int state;
229     bool press;
230     int serial;
231     XEvent ev;
232 };
233 
234 class InputContext;
235 class Convdisp;
236 
237 // icxatr is put in XimIC
238 class icxatr {
239 public:
240     icxatr();
241     ~icxatr();
242     void set_atr(C16 id, C8 *v, int byte_order);
243     bool has_atr(C16 id);
244     bool is_changed(C16 id);
245     void unset_change_mask(C16 id);
246     void print();
247     C16 getSize(C16 id);
248     void set_locale_name(const char *locale);
249     bool use_xft();
250 
251     unsigned long input_style;
252     Window client_window;
253     Window focus_window;
254 
255     C32 foreground_pixel; // Actually Pixel type
256     C32 background_pixel;
257 
258     XPoint spot_location;
259     XRectangle area;
260 
261     XFontSet font_set;
262     char *font_set_name;
263     C16 line_space;
264 
265 private:
266     char *m_locale;
267     int atr_mask;
268     int change_mask;
269     bool m_use_xft;
270 };
271 
272 // definition of IC
273 class XimIC {
274 public:
275     XimIC(Connection *, C16 imid, C16 icid, const char *engine);
276     ~XimIC();
277     void setFocus();
278     void unsetFocus();
279     C16 get_icid();
280     C16 get_imid();
281 
282     void OnKeyEvent(keyEventX );
283     void setICAttrs(void *, int);
284     C16 get_ic_atr(C16, TxPacket *);
285     void commit_string(const char *s);
286     void extra_input(char *t);
287     void reset_ic();
288     Convdisp *get_convdisp();
289     void onSendPacket();
290     bool isActive();
291     void force_send_packet();
292     void changeContext(const char *engine);
293     const char *get_encoding();
294     const char *get_lang_region();
295 
296 public:
297     static XimIC *get_current_ic();
298     static bool isAnyActive();
299 
300 private:
301     // m_kkContext is created when XimIC is constructed, and deleted
302     // when the XimIC is destructed.
303     InputContext *m_kkContext;
304     icxatr m_xatr;
305     void send_key_event(XKeyEvent *k);
306     int lookup_style(unsigned long);
307     void set_ic_attr(C16, C8 *, int);
308     void send_sync();
309 
310     Connection *mConn;
311     // mConvdisp is NULL until getting enough icxatr.  Need to delete
312     // this after deletion of m_kkContext since it is also refered by
313     // m_kkContext.
314     Convdisp *mConvdisp;
315     C16 mICid;
316     C16 mIMid;
317     uString mPending;
318     bool mIsActive;
319     keyState *m_keyState;
320 private:
321     static XimIC *current_ic;
322     static int nrActiveIC;
323 };
324 
325 struct input_style {
326     int x_style;
327     int style;
328 };
329 
330 XimIC *create_ic(Connection *, RxPacket *, C16 imid, C16 id, const char *engine);
331 void procXClientMessage(XClientMessageEvent *m);
332 
333 #endif
334 /*
335  * Local variables:
336  *  c-indent-level: 4
337  *  c-basic-offset: 4
338  * End:
339  */
340