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_XIMSERVER_H 35 #define UIM_XIM_XIMSERVER_H 36 37 #include <X11/X.h> 38 #include <X11/Xlib.h> 39 40 #include <list> 41 #include <vector> 42 #include <map> 43 44 #include "uim/uim.h" 45 #include "compose.h" 46 47 #define UIM_XIM_USE_NEW_PAGE_HANDLING 1 48 #define UIM_XIM_USE_DELAY 1 49 50 // preedit ornament 51 #define PE_NORMAL 0 52 #define PE_REVERSE 1 53 #define PE_UNDERLINE 2 54 #define PE_HILIGHT 4 55 56 typedef wchar_t uchar; 57 typedef std::list<uchar> uString; 58 #if UIM_XIM_USE_NEW_PAGE_HANDLING 59 typedef std::vector<const char *> CandList; 60 #endif 61 struct pe_ustring { 62 uString s; 63 int stat; 64 }; 65 typedef enum { 66 Caret, 67 Left, 68 Right 69 } CandWinPosType; 70 71 typedef enum { 72 Vertical, 73 Horizontal, 74 Table 75 } CandWinStyle; 76 77 // state of preedit. 78 // created in the constructor of InputContext, and deleted in the 79 // destructor of it. 80 class pe_stat { 81 public: 82 pe_stat(class InputContext *); 83 void clear(); 84 void new_segment(int s); 85 void push_uchar(uchar); 86 int get_char_count(); 87 int caret_pos; 88 std::list<pe_ustring> ustrings; // separated with segments 89 class InputContext *cont; 90 }; 91 92 void print_ustring(uString *s); 93 void erase_ustring(uString *s); 94 void append_ustring(uString *d, uString *s); 95 96 // user interfaces 97 void init_convdisp(); 98 void init_modifier_keys(); 99 #if HAVE_XFT_UTF8_STRING 100 void init_default_xftfont(); 101 void update_default_xftfont(); 102 #endif 103 void reload_uim(int x); 104 void check_candwin_style(); 105 void check_candwin_pos_type(); 106 #if UIM_XIM_USE_DELAY 107 void timer_set(int seconds, void (*timeout_cb)(void *ptr), void *ptr); 108 void timer_cancel(); 109 #endif 110 111 112 // for command line option 113 // trace comunication between client 114 #define OPT_TRACE 1 115 // trace XIM connection 116 #define OPT_TRACE_XIM 2 117 // use on-demand-synchronous XIM event flow (not safe for Tcl/Tk 8.{3,4}) 118 #define OPT_ON_DEMAND_SYNC 4 119 120 121 // byte order 122 #define BYTEORDER_UNKNOWN 0 123 #define LSB_FIRST 1 124 #define MSB_FIRST 2 125 126 127 // 128 extern int host_byte_order; 129 extern int g_option_mask; 130 extern int scr_width, scr_height; 131 132 #define DO_NOTHING 0 133 #define COMMIT_RAW 1 134 #define UPDATE_MODE 2 135 136 // do convert from original event into uim event 137 class keyState { 138 public: 139 keyState(class XimIC *); 140 ~keyState(); 141 void check_key(class keyEventX *); 142 bool check_compose(); 143 int key(); 144 int modifier(); 145 KeySym xkeysym(); 146 int xkeystate(); 147 void reset(); 148 149 bool is_push(); // for distinguish from release 150 void print(); 151 private: 152 int mKey; 153 int mModifier; 154 KeySym mXKeySym; 155 int mXKeyState; 156 bool m_bPush; 157 int mModState; 158 int mPreModState; 159 Compose *mCompose; 160 XimIC *mIc; 161 }; 162 163 class XimIC; 164 class Convdisp; 165 class XimServer; 166 class InputContext { 167 public: 168 InputContext(XimServer *, XimIC *, const char *); 169 ~InputContext(); 170 uim_context getUC(); 171 int pushKey(keyState *e); 172 void clear(); 173 void setConvdisp(Convdisp *); 174 void focusIn(); 175 void focusOut(); 176 XimIC *get_ic(); 177 XimServer *getServer(); 178 void extra_input(char *s); 179 void clear_preedit(); 180 uString get_preedit_string(); 181 void pushback_preedit_string(int attr, const char *str); 182 void update_preedit(); 183 void candidate_activate(int nr, int display_limit); 184 #if UIM_XIM_USE_DELAY 185 void candidate_activate_with_delay(int delay); 186 void candidate_activate_timeout(); 187 #endif 188 void candidate_select(int index); 189 void candidate_shift_page(int direction); 190 void candidate_deactivate(); 191 void candidate_update(); 192 #if UIM_XIM_USE_NEW_PAGE_HANDLING 193 void prepare_page_candidates(int page); 194 int prepare_page_candidates_by_index(int index); 195 #endif 196 void update_prop_list(const char *str); 197 void update_prop_label(const char *str); 198 bool hasActiveCandwin(); 199 bool isCaretStateShown(); 200 const char *get_engine_name(); 201 const char *get_locale_name(); 202 void changeContext(const char *engine); 203 void customContext(const char *custom, const char *val); 204 void createUimContext(const char *engine); 205 void configuration_changed(); 206 void switch_app_global_im(const char *name); 207 void switch_system_global_im(const char *name); 208 void set_need_hilite_selected_cand(bool set); 209 public: 210 static void commit_cb(void *ptr, const char *str); 211 static void clear_cb(void *ptr); 212 static void pushback_cb(void *ptr, int attr, const char *str); 213 static void update_cb(void *ptr); 214 static void candidate_activate_cb(void *ptr, int nr, int index); 215 #if UIM_XIM_USE_DELAY 216 static void candidate_activate_with_delay_cb(void *ptr, int delay); 217 static void candidate_activate_timeout_cb(void *ptr); 218 #endif 219 static void candidate_select_cb(void *ptr, int index); 220 static void candidate_shift_page_cb(void *ptr, int direction); 221 static void candidate_deactivate_cb(void *ptr); 222 static void update_prop_list_cb(void *ptr, const char *str); 223 static void update_prop_label_cb(void *ptr, const char *str); 224 static void configuration_changed_cb(void *ptr); 225 static void switch_app_global_im_cb(void *ptr, const char *name); 226 static void switch_system_global_im_cb(void *ptr, const char *name); 227 static InputContext *focusedContext(); 228 static void deletefocusedContext(); 229 private: 230 void commit_string(char *); 231 void clear_pe_stat(); 232 void review_im(const char *engine); 233 char *get_caret_state_label_from_prop_list(const char *str); 234 235 XimIC *mXic; 236 XimServer *mServer; 237 pe_stat *m_pe; 238 Convdisp *mConvdisp; 239 uim_context mUc; 240 bool mCandwinActive; 241 int mDisplayLimit; 242 #if UIM_XIM_USE_NEW_PAGE_HANDLING 243 int mNumCandidates; 244 #endif 245 int mNumPage; 246 int current_cand_selection; 247 int current_page; 248 bool need_hilite_selected_cand; 249 std::vector<const char *> active_candidates; 250 #if UIM_XIM_USE_NEW_PAGE_HANDLING 251 std::vector<CandList> mCandidateSlot; 252 #endif 253 char *mEngineName; 254 char *mLocaleName; 255 bool mCaretStateShown; 256 private: 257 static InputContext *mFocusedContext; 258 }; 259 260 class Locale { 261 public: 262 virtual ~Locale(); 263 virtual char *uStringToCtext(uString *us) = 0; 264 virtual char *utf8_to_native_str(char *str) = 0; 265 virtual bool supportOverTheSpot(); 266 }; 267 268 Locale *createLocale(const char *encoding); 269 const char *compose_localenames_from_im_lang(const char *im_lang); 270 bool is_locale_included(const char *locales, const char *locale); 271 // Sring returned by get_first_locale() is allocated with strdup(). 272 char *get_prefered_locale(const char *locales); 273 const char *find_localename_from_encoding(const char *encoding); 274 int utf8_mbtowc(uchar *wc, const unsigned char *src, int src_len); 275 int utf8_wctomb(unsigned char *dest, uchar wc); // dest must have size 6 276 int mb_string_to_utf8(char *utf8, const char *str, int to_len, const char *enc); 277 278 class XimServer { 279 public: 280 XimServer(const char *name, const char *lang); ~XimServer()281 ~XimServer() {}; 282 InputContext *createContext(XimIC *, const char *engine); 283 void deleteContext(InputContext *); 284 285 bool setupConnection(bool useDefaultIM); 286 void setupNewConnection(XClientMessageEvent *ev); 287 char *uStringToCtext(uString *js, const char *encoding); 288 void strToUstring(uString *d, const char *s); 289 const char *getIMName(); 290 const char *getIMLang(); 291 void set_im(const char *name); 292 void changeContext(const char *engine); 293 void customContext(const char *custom, const char *val); 294 void reloadConfigs(); 295 std::list<InputContext *> ic_list; 296 public: 297 static XimServer *findServer(Window w); 298 static Display *gDpy; 299 static std::map<Window, XimServer *> gServerMap; 300 static CandWinPosType gCandWinPosType; 301 static CandWinStyle gCandWinStyle; 302 static bool gCandWinStyleUpdated; 303 private: 304 Window mSelectionWin; 305 Atom mServerAtom; 306 char *mIMName; 307 const char *mIMLang; 308 }; 309 310 struct UIMInfo { 311 char *lang; 312 char *name; 313 char *desc; 314 }; 315 extern std::list<UIMInfo> uim_info; 316 317 const char *get_im_lang_from_engine(const char *engine); 318 319 #endif 320 /* 321 * Local variables: 322 * c-indent-level: 4 323 * c-basic-offset: 4 324 * End: 325 */ 326