1 /* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */
4 * Smart Common Input Method
6 * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this program; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22 * Boston, MA 02111-1307 USA
24 * $Id: scim_event.cpp,v 1.29 2005/07/13 08:54:55 suzhe Exp $
27 #define Uses_SCIM_EVENT
28 #define Uses_SCIM_GLOBAL_CONFIG
29 #define Uses_SCIM_CONFIG_PATH
32 #include "scim_private.h"
34 #include "scim_stl_map.h"
56 class __Uint16PairLessByFirst
59 bool operator ()(const __Uint16Pair &lhs, const __Uint16Pair &rhs) const {
60 return lhs.first < rhs.first;
63 bool operator ()(const __Uint16Pair &lhs, const uint16 &rhs) const {
64 return lhs.first < rhs;
67 bool operator ()(const uint16 &lhs, const __Uint16Pair &rhs) const {
68 return lhs < rhs.first;
72 class __KeyNameLessByCode
75 bool operator ()(const __KeyName &lhs, const __KeyName &rhs) const {
76 return lhs.value < rhs.value;
79 bool operator ()(const __KeyName &lhs, const uint16 &rhs) const {
80 return lhs.value < rhs;
83 bool operator ()(const uint16 &lhs, const __KeyName &rhs) const {
84 return lhs < rhs.value;
88 class __KeyNameLessByName
91 bool operator ()(const __KeyName &lhs, const __KeyName &rhs) const {
92 return strcmp (lhs.name, rhs.name) < 0;
95 bool operator ()(const __KeyName &lhs, const char *rhs) const {
96 return strcmp (lhs.name, rhs) < 0;
99 bool operator ()(const char *lhs, const __KeyName &rhs) const {
100 return strcmp (lhs, rhs.name) < 0;
104 // Keyboard Layout data
105 #include "scim_keyboard_layout_data.h"
108 #include "scim_keyevent_data.h"
111 KeyEvent::get_ascii_code () const
113 if (code >= SCIM_KEY_space && code <= SCIM_KEY_asciitilde)
116 if (code >= SCIM_KEY_KP_0 && code <= SCIM_KEY_KP_9)
117 return (char) (code - SCIM_KEY_KP_0 + SCIM_KEY_0);
119 if (code == SCIM_KEY_Return)
121 if (code == SCIM_KEY_Linefeed)
123 if (code == SCIM_KEY_Tab)
125 if (code == SCIM_KEY_BackSpace)
127 if (code == SCIM_KEY_Escape)
134 KeyEvent::get_unicode_code () const
136 /* First check for Latin-1 characters (1:1 mapping) */
137 if ((code >= 0x0020 && code <= 0x007e) ||
138 (code >= 0x00a0 && code <= 0x00ff))
141 /* Also check for directly encoded 24-bit UCS characters:
143 if ((code & 0xff000000) == 0x01000000)
144 return code & 0x00ffffff;
146 /* Translation of KP_Decimal depends on locale.
147 if (code == SCIM_KP_Decimal)
148 return get_decimal_char ();
151 /* Invalid keyevent code. */
155 /* binary search in table */
156 __Uint16Pair * it = std::lower_bound (__scim_key_to_unicode_tab,
157 __scim_key_to_unicode_tab + SCIM_NUM_KEY_UNICODES,
159 __Uint16PairLessByFirst ());
161 if (it != __scim_key_to_unicode_tab + SCIM_NUM_KEY_UNICODES && it->first == (uint16) code)
164 /* No matching Unicode value found */
169 KeyEvent::get_key_string () const
174 uint16 mask_skip = 0;
176 for (i=0; i < SCIM_NUM_KEY_MASKS; ++i) {
177 if ((__scim_key_mask_names [i].value & mask) && !(__scim_key_mask_names [i].value & mask_skip)) {
178 if (maskstr.length ())
179 maskstr += (String ("+") + String (__scim_key_mask_names [i].name));
181 maskstr += String (__scim_key_mask_names [i].name);
183 mask_skip |= __scim_key_mask_names [i].value;
186 if (code == 0xFFFFFF) {
187 codestr = String ("VoidSymbol");
188 } else if (code <= 0xFFFF){
189 __KeyName *it = std::lower_bound (__scim_keys_by_code,
190 __scim_keys_by_code + SCIM_NUM_KEY_NAMES,
192 __KeyNameLessByCode ());
194 if (it != __scim_keys_by_code + SCIM_NUM_KEY_NAMES && it->value == code)
195 codestr = String (it->name);
198 if (!codestr.length () && code) {
200 snprintf (buf, 20, ((code <= 0xFFFF) ? "0x%04x" : "0x%06x"), code);
201 codestr = String (buf);
204 if (maskstr.length () && codestr.length ())
205 return maskstr + String ("+") + codestr;
206 if (maskstr.length())
208 if (codestr.length ())
215 inline __remap_keycode (uint16 from, const __KeyCodeMap &map)
217 if (map.size == 0) return from;
219 __Uint16Pair *it = std::lower_bound (map.map, map.map + map.size, from, __Uint16PairLessByFirst ());
221 if (it != map.map + map.size && it->first == from)
228 KeyEvent::map_to_layout (KeyboardLayout new_layout) const
230 if (layout == SCIM_KEYBOARD_Unknown || new_layout == SCIM_KEYBOARD_Unknown || layout == new_layout ||
231 layout >= SCIM_KEYBOARD_NUM_LAYOUTS || new_layout >= SCIM_KEYBOARD_NUM_LAYOUTS || new_layout < 0 ||
235 KeyEvent evt (code, mask, new_layout);
237 uint16 new_code = (uint16) code;
239 switch (mask & (SCIM_KEY_CapsLockMask | SCIM_KEY_ShiftMask)) {
241 new_code = __remap_keycode (new_code, __normal_map [layout]);
242 new_code = __remap_keycode (new_code, __normal_invert_map [new_layout]);
244 case SCIM_KEY_CapsLockMask:
245 new_code = __remap_keycode (new_code, __caps_map [layout]);
246 new_code = __remap_keycode (new_code, __caps_invert_map [new_layout]);
248 case SCIM_KEY_ShiftMask:
249 new_code = __remap_keycode (new_code, __shift_map [layout]);
250 new_code = __remap_keycode (new_code, __shift_invert_map [new_layout]);
252 case (SCIM_KEY_ShiftMask | SCIM_KEY_CapsLockMask):
253 new_code = __remap_keycode (new_code, __caps_shift_map [layout]);
254 new_code = __remap_keycode (new_code, __caps_shift_invert_map [new_layout]);
258 evt.code = (uint32) new_code;
264 scim_key_to_string (String &str, const KeyEvent & key)
266 str = key.get_key_string ();
267 return str.length () != 0;
271 scim_string_to_key (KeyEvent &key, const String & str)
273 std::vector <String> list;
280 scim_split_string_list (list, str, '+');
282 for (std::vector <String>::iterator it=list.begin (); it!=list.end (); ++it) {
284 for (i = 0; i < SCIM_NUM_KEY_MASKS; ++i) {
285 if (*it == String (__scim_key_mask_names [i].name)) {
286 key.mask |= __scim_key_mask_names [i].value;
294 __KeyName *p = std::lower_bound (__scim_keys_by_name,
295 __scim_keys_by_name + SCIM_NUM_KEY_NAMES,
297 __KeyNameLessByName ());
299 if (p != __scim_keys_by_name + SCIM_NUM_KEY_NAMES && strcmp (p->name, it->c_str ()) == 0) {
301 } else if (it->length () >= 6 && (*it)[0] == '0' && ((*it)[1] == 'x' || (*it)[1] == 'X')){
302 key.code = strtol (it->c_str () + 2, NULL, 16);
303 } else if (strcmp (p->name, "VoidSymbol") == 0) {
304 key.code = SCIM_KEY_VoidSymbol;
308 return key.code != 0;
312 scim_key_list_to_string (String &str, const std::vector<KeyEvent> & keylist)
314 std::vector<String> strlist;
316 for (std::vector<KeyEvent>::const_iterator it = keylist.begin (); it != keylist.end (); ++it) {
317 if (scim_key_to_string (str, *it))
318 strlist.push_back (str);
321 str = scim_combine_string_list (strlist, ',');
323 return str.length () != 0;
327 scim_string_to_key_list (std::vector<KeyEvent> &keylist, const String &str)
329 std::vector <String> strlist;
330 scim_split_string_list (strlist, str, ',');
334 for (std::vector <String>::iterator it = strlist.begin (); it != strlist.end (); ++it) {
336 if (scim_string_to_key (key, *it))
337 keylist.push_back (key);
339 return keylist.size () > 0;
344 scim_keyboard_layout_to_string (KeyboardLayout layout)
346 if (layout >= 0 && layout < SCIM_KEYBOARD_NUM_LAYOUTS)
347 return String (__scim_keyboard_layout_ids_by_code [layout].name);
349 return String (__scim_keyboard_layout_ids_by_code [0].name);
353 scim_string_to_keyboard_layout (const String &str)
355 if (str == __scim_keyboard_layout_ids_by_code [0].name) return SCIM_KEYBOARD_Unknown;
356 if (str == __scim_keyboard_layout_ids_by_code [1].name || str == String ("US") || str == String ("Default")) return SCIM_KEYBOARD_Default;
359 std::lower_bound (__scim_keyboard_layout_ids_by_name + 2,
360 __scim_keyboard_layout_ids_by_name + SCIM_KEYBOARD_NUM_LAYOUTS,
362 __KeyNameLessByName());
364 if (it != __scim_keyboard_layout_ids_by_name + SCIM_KEYBOARD_NUM_LAYOUTS && strcmp (it->name, str.c_str ()) == 0)
365 return static_cast <KeyboardLayout> (it->value);
367 return SCIM_KEYBOARD_Unknown;
371 scim_keyboard_layout_get_display_name (KeyboardLayout layout)
373 if (layout >= 0 && layout < SCIM_KEYBOARD_NUM_LAYOUTS)
374 return String (_(__scim_keyboard_layout_names [layout]));
376 return String (_(__scim_keyboard_layout_names [0]));
380 scim_get_default_keyboard_layout ()
382 String layout_name (__scim_keyboard_layout_ids_by_code [0].name);
383 layout_name = scim_global_config_read (SCIM_GLOBAL_CONFIG_DEFAULT_KEYBOARD_LAYOUT, layout_name);
385 return scim_string_to_keyboard_layout (layout_name);
389 scim_set_default_keyboard_layout (KeyboardLayout layout)
391 String layout_name = scim_keyboard_layout_to_string (layout);
392 scim_global_config_write (SCIM_GLOBAL_CONFIG_DEFAULT_KEYBOARD_LAYOUT, layout_name);
398 vi:ts=4:nowrap:ai:expandtab