Git init
[framework/uifw/isf.git] / ism / src / scim_compose_key.cpp
1 /** @file scim_compose_key.cpp
2  *  @brief Implementation of class ComposeKeyFactory and ComposeKeyInstance.
3  */
4
5 /* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */
6
7 /*
8  * Smart Common Input Method
9  *
10  * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn>
11  *
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this program; if not, write to the
25  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
26  * Boston, MA  02111-1307  USA
27  *
28  * $Id: scim_compose_key.cpp,v 1.7 2005/08/16 07:26:54 suzhe Exp $
29  *
30  */
31
32 #define Uses_SCIM_COMPOSE_KEY
33 #define Uses_C_CTYPE
34
35 #include "scim_private.h"
36 #include "scim.h"
37
38 namespace scim {
39
40 #define SCIM_MAX_COMPOSE_LEN 5
41
42 struct ComposeSequence
43 {
44     uint32 keys [SCIM_MAX_COMPOSE_LEN];
45     ucs4_t unicode;
46 };
47
48 class ComposeSequenceLessByKeys
49 {
50 public:
51     bool operator () (const ComposeSequence &lhs, const ComposeSequence &rhs) const {
52         for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) {
53             if (lhs.keys [i] < rhs.keys [i]) return true;
54             else if (lhs.keys [i] > rhs.keys [i]) return false;
55         }
56         return false;
57     }
58
59     bool operator () (const ComposeSequence &lhs, const uint32 *rhs) const {
60         for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) {
61             if (lhs.keys [i] < rhs [i]) return true;
62             else if (lhs.keys [i] > rhs [i]) return false;
63         }
64         return false;
65     }
66
67     bool operator () (const uint32 *lhs, const ComposeSequence &rhs) const {
68         for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) {
69             if (lhs [i] < rhs.keys [i]) return true;
70             else if (lhs [i] > rhs.keys [i]) return false;
71         }
72         return false;
73     }
74
75     bool operator () (const uint32 *lhs, const uint32 *rhs) const {
76         for (size_t i = 0; i < SCIM_MAX_COMPOSE_LEN; ++i) {
77             if (lhs [i] < rhs [i]) return true;
78             else if (lhs [i] > rhs [i]) return false;
79         }
80         return false;
81     }
82
83 };
84
85 // Generated from /usr/X11R6/lib/X11/locale/en_US.UTF-8/Compose
86 // Get rid off all keys with unicode value.
87 // Merged with the table in gtk+2.x
88 static const ComposeSequence __scim_compose_seqs[] = {
89 #include "scim_compose_key_data.h"
90 };
91
92 #define SCIM_NUM_COMPOSE_SEQS (sizeof (__scim_compose_seqs) / sizeof (__scim_compose_seqs [0]))
93
94 static uint16 __scim_compose_ignores [] = {
95     SCIM_KEY_Mode_switch,
96     SCIM_KEY_Shift_L,
97     SCIM_KEY_Shift_R,
98     SCIM_KEY_Control_L,
99     SCIM_KEY_Control_R,
100     SCIM_KEY_Caps_Lock,
101     SCIM_KEY_Shift_Lock,
102     SCIM_KEY_Meta_L,
103     SCIM_KEY_Meta_R,
104     SCIM_KEY_Alt_L,
105     SCIM_KEY_Alt_R,
106     SCIM_KEY_Super_L,
107     SCIM_KEY_Super_R,
108     SCIM_KEY_Hyper_L,
109     SCIM_KEY_Hyper_R
110 };
111
112 #define SCIM_NUM_COMPOSE_IGNORES (sizeof (__scim_compose_ignores) / sizeof (__scim_compose_ignores [0]))
113
114 ComposeKeyFactory::ComposeKeyFactory ()
115 {
116     set_locales ("C");
117 }
118
119 ComposeKeyFactory::~ComposeKeyFactory ()
120 {
121 }
122
123 WideString
124 ComposeKeyFactory::get_name () const
125 {
126     return utf8_mbstowcs (_("English/Keyboard"));
127 }
128
129 WideString
130 ComposeKeyFactory::get_authors () const
131 {
132     return utf8_mbstowcs ("James Su <suzhe@tsinghua.org.cn>");
133 }
134
135 WideString
136 ComposeKeyFactory::get_credits () const
137 {
138     return WideString ();
139 }
140
141 WideString
142 ComposeKeyFactory::get_help () const
143 {
144     //return WideString ();
145     return utf8_mbstowcs (_("English input service"));
146 }
147
148 String
149 ComposeKeyFactory::get_uuid () const
150 {
151     return String (SCIM_COMPOSE_KEY_FACTORY_UUID);
152 }
153
154 String
155 ComposeKeyFactory::get_icon_file () const
156 {
157     return String (SCIM_KEYBOARD_ICON_FILE);
158 }
159
160 bool
161 ComposeKeyFactory::validate_encoding (const String& encoding) const
162 {
163     return true;
164 }
165
166 bool
167 ComposeKeyFactory::validate_locale (const String& locale) const
168 {
169     return true;
170 }
171
172 IMEngineInstancePointer
173 ComposeKeyFactory::create_instance (const String& encoding, int id)
174 {
175     return new ComposeKeyInstance (this, encoding, id);
176 }
177
178 ComposeKeyInstance::ComposeKeyInstance (ComposeKeyFactory *factory,
179                                         const String& encoding,
180                                         int id)
181     : IMEngineInstanceBase (factory, encoding, id)
182 {
183     m_compose_buffer [0] = m_compose_buffer [1] = m_compose_buffer [2] = m_compose_buffer [3] = 0;
184     m_compose_buffer [4] = m_compose_buffer [5] = m_compose_buffer [6] = m_compose_buffer [7] = 0;
185 }
186
187 ComposeKeyInstance::~ComposeKeyInstance ()
188 {
189 }
190
191 bool
192 ComposeKeyInstance::process_key_event (const KeyEvent& key)
193 {
194     if (key.is_key_release ()) return false;
195
196     // Ignore modifier key presses.
197     if (std::binary_search (__scim_compose_ignores, __scim_compose_ignores + SCIM_NUM_COMPOSE_IGNORES, (uint16) key.code))
198         return false;
199
200     // Ignore the key if ctrl or alt is down.
201     if (key.is_control_down () || key.is_alt_down ())
202         return false;
203
204     int n_compose = 0;
205
206     while (m_compose_buffer [n_compose] != 0 && n_compose < SCIM_MAX_COMPOSE_LEN)
207         ++ n_compose;
208
209     // The buffer is full, then reset the buffer first.
210     if (n_compose == SCIM_MAX_COMPOSE_LEN) {
211         reset ();
212         n_compose = 0;
213     }
214
215     m_compose_buffer [n_compose] = (uint32) key.code;
216
217     const ComposeSequence *it = std::lower_bound (__scim_compose_seqs,
218                                                   __scim_compose_seqs + SCIM_NUM_COMPOSE_SEQS,
219                                                   m_compose_buffer,
220                                                   ComposeSequenceLessByKeys ());
221
222     // Not result found, reset the buffer and return false.
223     if (it == __scim_compose_seqs + SCIM_NUM_COMPOSE_SEQS) {
224         reset ();
225         return false;
226     }
227
228     // Check if the compose sequence is match.
229     for (n_compose = 0; n_compose < SCIM_MAX_COMPOSE_LEN; ++ n_compose) {
230         if (m_compose_buffer [n_compose] == 0)
231             break;
232
233         // Not match, reset the buffer and return.
234         // If it's the first key press, then return false to forward it.
235         // Otherwise return true to ignore it.
236         if (m_compose_buffer [n_compose] != it->keys [n_compose]) {
237             reset ();
238             return n_compose != 0;
239         }
240     }
241
242     // Match exactly, commit the result.
243     if (n_compose == SCIM_MAX_COMPOSE_LEN || it->keys [n_compose] == 0) {
244         WideString wstr;
245         wstr.push_back (it->unicode);
246         commit_string (wstr);
247         reset ();
248     }
249
250     return true;
251 }
252
253 void
254 ComposeKeyInstance::move_preedit_caret (unsigned int /*pos*/)
255 {
256 }
257
258 void
259 ComposeKeyInstance::select_candidate (unsigned int /*item*/)
260 {
261 }
262
263 void
264 ComposeKeyInstance::update_lookup_table_page_size (unsigned int /*page_size*/)
265 {
266 }
267
268 void
269 ComposeKeyInstance::lookup_table_page_up ()
270 {
271 }
272
273 void
274 ComposeKeyInstance::lookup_table_page_down ()
275 {
276 }
277
278 void
279 ComposeKeyInstance::reset ()
280 {
281     m_compose_buffer [0] = m_compose_buffer [1] = m_compose_buffer [2] = m_compose_buffer [3] = 0;
282     m_compose_buffer [4] = m_compose_buffer [5] = m_compose_buffer [6] = m_compose_buffer [7] = 0;
283 }
284
285 void
286 ComposeKeyInstance::focus_in ()
287 {
288     register_properties (PropertyList ());
289     reset ();
290 }
291
292 void
293 ComposeKeyInstance::focus_out ()
294 {
295 }
296
297 void
298 ComposeKeyInstance::trigger_property (const String & /*property*/)
299 {
300 }
301
302 } // namespace scim
303
304 /*
305 vi:ts=4:nowrap:ai:expandtab
306 */