1 /*
2  * Copyright © 2014  Red Hat, Inc. All rights reserved.
3  * Copyright © 2014  Ding-Yi Chen <dchen@redhat.com>
4  *
5  * This file is part of the ibus-chewing Project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  */
21 
22 /**
23  * SECTION:IBusChewingPreEdit
24  * @short_description: Pre-edit string buffer.
25  * @title: IBusChewingPreEdit
26  * @stability: Stable
27  * @include: IbusChewingPreedit
28  *
29  * IBusChewingPreEdit is core of ibus-chewing.
30  * It processes incoming key events and manage pre-edit and outgoing buffer.
31  *
32  * IBusChewingEngine uses the pre-edit and outgoing buffer to show to the end user.
33  */
34 
35 #ifndef _IBUS_CHEWING_PRE_EDIT_H_
36 #define _IBUS_CHEWING_PRE_EDIT_H_
37 #include <glib.h>
38 #include <chewing.h>
39 #include <ibus.h>
40 #include "MakerDialogBackend.h"
41 #include "IBusChewingUtil.h"
42 #include "IBusChewingLookupTable.h"
43 #include "IBusChewingProperties.h"
44 
45 #define UTF8_MAX_BYTES 6
46 #ifndef IBUS_CHEWING_MAX_WORD
47 #define IBUS_CHEWING_MAX_WORD 100
48 #endif
49 #define IBUS_CHEWING_MAX_BYTES UTF8_MAX_BYTES * IBUS_CHEWING_MAX_WORD
50 
51 /**
52  * IBusChewingPreEditFlag:
53  * @FLAG_SYNC_FROM_IM: Sync the Chinese mode with input method
54  * @FLAG_SYNC_FROM_KEYBOARD: Sync the Chinese mode with Caps Lock status
55  * @FLAG_TABLE_SHOW: Lookup table is shown.
56  * @FLAG_UPDATED_OUTGOING: The commit string is already send to outgoing, to avoid double committing.
57  *
58  */
59 typedef enum {
60     FLAG_SYNC_FROM_IM = 1,
61     FLAG_SYNC_FROM_KEYBOARD = 1 << 1,
62     FLAG_TABLE_SHOW = 1 << 2,
63     FLAG_UPDATED_OUTGOING = 1 << 3,
64 } IBusChewingPreEditFlag;
65 
66 /**
67  * IBusChewingPreEdit:
68  * @context:   chewing input context.
69  * @preEdit:   String that are not ready to be committed to engine.
70  * @outgoing:  String to be committed to engine. (Usually means completed string).
71  * @flags:     Misc flags.
72  * @keyLast:   Last effective key.
73  * @bpmfLen:   Length of bopomofo chars in unicode characters.
74  * @wordLen:   Length of preEdit in unicode characters.
75  *
76  * An IBusChewingPreEdit.
77  */
78 typedef struct {
79     IBusChewingProperties *iProperties;
80     /*< public > */
81     ChewingContext *context;
82     GString *preEdit;
83     GString *outgoing;
84     IBusKeymap *keymap;
85     IBusLookupTable *iTable;
86     IBusChewingPreEditFlag flags;
87     KSym keyLast;
88     gint bpmfLen;
89     gint wordLen;
90     IBusEngine *engine;
91 } IBusChewingPreEdit;
92 
93 IBusChewingPreEdit *ibus_chewing_pre_edit_new(MkdgBackend * backend);
94 
95 void ibus_chewing_pre_edit_free(IBusChewingPreEdit * self);
96 
97 #define ibus_chewing_pre_edit_get_property(self,propertyKey) mkdg_properties_find_by_key(self->iProperties->properties, propertyKey)
98 
99 #define ibus_chewing_pre_edit_get_property_boolean(self,propertyKey) mkdg_properties_get_boolean_by_key(self->iProperties->properties, propertyKey)
100 
101 #define ibus_chewing_pre_edit_get_property_int(self,propertyKey) mkdg_properties_get_int_by_key(self->iProperties->properties, propertyKey)
102 
103 #define ibus_chewing_pre_edit_get_property_string(self,propertyKey) mkdg_properties_get_string_by_key(self->iProperties->properties, propertyKey)
104 
105 #define ibus_chewing_pre_edit_set_property_boolean(self,propertyKey,boolValue) mkdg_properties_set_boolean_by_key(self->iProperties->properties, propertyKey, boolValue)
106 
107 #define ibus_chewing_pre_edit_set_property_int(self,propertyKey,intValue) mkdg_properties_set_int_by_key(self->iProperties->properties, propertyKey, intValue)
108 
109 #define ibus_chewing_pre_edit_set_property_string(self,propertyKey,strValue) mkdg_properties_set_string_by_key(self->iProperties->properties,propertyKey,strValue)
110 
111 #define ibus_chewing_pre_edit_is_system_keyboard_layout(self) ibus_chewing_properties_read_boolean_general(self->iProperties, "ibus/general", "use-system-keyboard-layout", NULL)
112 
113 #define ibus_chewing_pre_edit_apply_property(self,propertyKey) mkdg_properties_apply_by_key(self->iProperties->properties, propertyKey, NULL)
114 
115 #define ibus_chewing_pre_edit_save_property_boolean(self,propertyKey,boolValue) mkdg_properties_save_boolean_by_key(self->iProperties->properties, propertyKey, boolValue, NULL)
116 
117 #define ibus_chewing_pre_edit_save_property_int(self,propertyKey,intValue) mkdg_properties_save_int_by_key(self->iProperties->properties, propertyKey, intValue, NULL)
118 
119 #define ibus_chewing_pre_edit_save_property_string(self,propertyKey,strValue) mkdg_properties_save_string_by_key(self->iProperties->properties,propertyKey,strValue, NULL)
120 
121 #define ibus_chewing_pre_edit_set_apply_property_boolean(self, propertyKey,boolValue) ibus_chewing_pre_edit_set_property_boolean(self,propertyKey,boolValue); ibus_chewing_pre_edit_apply_property(self,propertyKey)
122 
123 #define ibus_chewing_pre_edit_set_apply_property_int(self, propertyKey,intValue) ibus_chewing_pre_edit_set_property_int(self,propertyKey,intValue); ibus_chewing_pre_edit_apply_property(self,propertyKey)
124 
125 #define ibus_chewing_pre_edit_set_apply_property_string(self, propertyKey,stringValue) ibus_chewing_pre_edit_set_property_string(self,propertyKey,stringValue); ibus_chewing_pre_edit_apply_property(self,propertyKey)
126 
127 void ibus_chewing_pre_edit_use_all_configure(IBusChewingPreEdit * self);
128 
129 guint ibus_chewing_pre_edit_length(IBusChewingPreEdit * self);
130 
131 guint ibus_chewing_pre_edit_word_length(IBusChewingPreEdit * self);
132 
133 guint ibus_chewing_pre_edit_word_limit(IBusChewingPreEdit * self);
134 
135 #define ibus_chewing_pre_edit_is_empty(self) (ibus_chewing_pre_edit_length(self) ==0)
136 
137 #define ibus_chewing_pre_edit_is_full(self) (self->wordLen >= ibus_chewing_pre_edit_word_limit(self))
138 
139 #define ibus_chewing_pre_edit_is_outgoing_empty(self) (self->outgoing->len==0)
140 
141 /**
142  * ibus_chewing_pre_edit_get_pre_edit:
143  * @self: An IBusChewingPreEdit.
144  * @returns: Content of pre-edit buffer.
145  *
146  * Return the content of pre-edit buffer in UTF-8 encoded string format.
147  * No need to free it.
148  */
149 gchar *ibus_chewing_pre_edit_get_pre_edit(IBusChewingPreEdit * self);
150 
151 /**
152  * ibus_chewing_pre_edit_get_outgoing:
153  * @self: An IBusChewingPreEdit.
154  * @returns: Content of outgoing buffer.
155  *
156  * Return the content of outgoing buffer in UTF-8 encoded string format.
157  * No need to free it.
158  */
159 gchar *ibus_chewing_pre_edit_get_outgoing(IBusChewingPreEdit * self);
160 
161 #define ibus_chewing_pre_edit_has_flag(self,f) mkdg_has_flag(self->flags,f)
162 #define ibus_chewing_pre_edit_set_flag(self,f) mkdg_set_flag(self->flags,f)
163 #define ibus_chewing_pre_edit_clear_flag(self,f) mkdg_clear_flag(self->flags,f)
164 
165 void ibus_chewing_pre_edit_force_commit(IBusChewingPreEdit * self);
166 void ibus_chewing_pre_edit_clear(IBusChewingPreEdit * self);
167 void ibus_chewing_pre_edit_clear_bopomofo(IBusChewingPreEdit * self);
168 void ibus_chewing_pre_edit_clear_pre_edit(IBusChewingPreEdit * self);
169 void ibus_chewing_pre_edit_clear_outgoing(IBusChewingPreEdit * self);
170 
171 gboolean ibus_chewing_pre_edit_get_chi_eng_mode(IBusChewingPreEdit * self);
172 gboolean ibus_chewing_pre_edit_get_full_half_mode(IBusChewingPreEdit * self);
173 
174 void ibus_chewing_pre_edit_set_chi_eng_mode(IBusChewingPreEdit * self,gboolean chineseMode);
175 void ibus_chewing_pre_edit_set_full_half_mode(IBusChewingPreEdit * self,gboolean fullShapeMode);
176 
177 #define ibus_chewing_pre_edit_toggle_chi_eng_mode(self)     ibus_chewing_pre_edit_set_chi_eng_mode(self, !ibus_chewing_pre_edit_get_chi_eng_mode(self))
178 #define ibus_chewing_pre_edit_toggle_full_half_mode(self) ibus_chewing_pre_edit_set_full_half_mode(self, !ibus_chewing_pre_edit_get_full_half_mode(self))
179 
180 gboolean ibus_chewing_pre_edit_process_key(IBusChewingPreEdit * self,
181 					   KSym kSym,
182 					   KeyModifiers unmaskedMod);
183 
184 
185 /**
186  * ibus_chewing_pre_edit_key_code_to_key_sym:
187  *
188  * Convert keycode to key_sym.
189  */
190 KSym ibus_chewing_pre_edit_key_code_to_key_sym(IBusChewingPreEdit * self,
191 					       KSym keySym, guint keyCode,
192 					       KeyModifiers unmaskedMod);
193 
194 /**
195  * ibus_chewing_bopomofo_check(ChewingContext *context)
196  * @returns: 1 if bopomofo buffer is non-empty; 0 if bopomofo buffer is empty.
197  *
198  */
199 #if CHEWING_CHECK_VERSION(0,4,0)
200 #define ibus_chewing_bopomofo_check chewing_bopomofo_Check
201 #else
202 #define ibus_chewing_bopomofo_check !chewing_zuin_Check
203 #endif
204 gchar *ibus_chewing_pre_edit_get_bopomofo_string(IBusChewingPreEdit *self);
205 
206 typedef enum {
207     EVENT_RESPONSE_PROCESS = 0,	/* Event process by IM */
208     EVENT_RESPONSE_ABSORB,	/* Event throw away by IM (e.g. Release event) */
209     EVENT_RESPONSE_IGNORE,	/* Event that should be passed to application, but not process by IM */
210     EVENT_RESPONSE_UNDECIDED,
211 } EventResponse;
212 
213 typedef EventResponse(*KeyHandlingFunc) (IBusChewingPreEdit * self,
214 					 KSym kSym,
215 					 KeyModifiers unmaskedMod);
216 
217 typedef struct {
218     KSym kSymLower;
219     KSym kSymUpper;
220     KeyHandlingFunc keyFunc;
221 } KeyHandlingRule;
222 
223 
224 #endif				/* _IBUS_CHEWING_PRE_EDIT_H_ */
225