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