1 /******************************************************************
2
3 Copyright 1994, 1995 by Sun Microsystems, Inc.
4 Copyright 1993, 1994 by Hewlett-Packard Company
5
6 Permission to use, copy, modify, distribute, and sell this software
7 and its documentation for any purpose is hereby granted without fee,
8 provided that the above copyright notice appear in all copies and
9 that both that copyright notice and this permission notice appear
10 in supporting documentation, and that the name of Sun Microsystems, Inc.
11 and Hewlett-Packard not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior permission.
13 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
14 the suitability of this software for any purpose. It is provided "as is"
15 without express or implied warranty.
16
17 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
18 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
22 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
23 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
24 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
26 Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
27
28 ******************************************************************/
29 #include <X11/Xlib.h>
30 #include <X11/Xmd.h>
31
32 #include "Xi18n.h"
33 #include "IC.h"
34 #include "fcitx-utils/log.h"
35 #include "xim.h"
36 #include "fcitx-utils/utils.h"
37 #include "ximhandler.h"
38 #include "fcitx/instance.h"
39
40 /**
41 * @file IC.c
42 *
43 * Process XIM Input Context
44 */
45
46 static int Is(char *attr, XICAttribute * attr_list);
47 static void StoreIC(FcitxXimIC * rec, IMChangeICStruct * call_data);
48
Is(char * attr,XICAttribute * attr_list)49 static int Is(char *attr, XICAttribute * attr_list)
50 {
51 return !strcmp(attr, attr_list->name);
52 }
53
XimCheckIC(void * arg,FcitxInputContext * context,void * priv)54 boolean XimCheckIC(void* arg, FcitxInputContext* context, void* priv)
55 {
56 FCITX_UNUSED(arg);
57 CARD16* picid = (CARD16*) priv;
58 FcitxXimIC* rec = (FcitxXimIC*) context->privateic;
59 if (rec->id == *picid)
60 return true;
61 else
62 return false;
63 }
64
StoreIC(FcitxXimIC * rec,IMChangeICStruct * call_data)65 static void StoreIC(FcitxXimIC * rec, IMChangeICStruct * call_data)
66 {
67 XICAttribute *ic_attr = call_data->ic_attr;
68 XICAttribute *pre_attr = call_data->preedit_attr;
69 XICAttribute *sts_attr = call_data->status_attr;
70 register int i;
71
72 for (i = 0; i < (int) call_data->ic_attr_num; i++, ic_attr++) {
73 if (Is(XNInputStyle, ic_attr))
74 rec->input_style = *(INT32 *) ic_attr->value;
75
76 else if (Is(XNClientWindow, ic_attr)) {
77 CARD32 value = *(CARD32*) ic_attr->value;
78 rec->client_win = (Window) value;
79 } else if (Is(XNFocusWindow, ic_attr)) {
80 CARD32 value = *(CARD32*) ic_attr->value;
81 rec->focus_win = (Window) value;
82 }
83 }
84
85 for (i = 0; i < (int) call_data->preedit_attr_num; i++, pre_attr++) {
86 if (Is(XNArea, pre_attr)) {
87 rec->pre_attr.area = *(XRectangle *) pre_attr->value;
88 } else if (Is(XNAreaNeeded, pre_attr)) {
89 rec->pre_attr.area_needed = *(XRectangle *) pre_attr->value;
90 } else if (Is(XNSpotLocation, pre_attr)) {
91 rec->pre_attr.spot_location = *(XPoint *) pre_attr->value;
92 } else if (Is(XNColormap, pre_attr))
93 rec->pre_attr.cmap = *(Colormap *) pre_attr->value;
94
95 else if (Is(XNStdColormap, pre_attr))
96 rec->pre_attr.cmap = *(Colormap *) pre_attr->value;
97
98 else if (Is(XNForeground, pre_attr)) {
99 rec->pre_attr.foreground = *(CARD32 *) pre_attr->value;
100 } else if (Is(XNBackground, pre_attr)) {
101 rec->pre_attr.background = *(CARD32 *) pre_attr->value;
102 } else if (Is(XNBackgroundPixmap, pre_attr))
103 rec->pre_attr.bg_pixmap = *(Pixmap *) pre_attr->value;
104
105 else if (Is(XNFontSet, pre_attr)) {
106 int size = strlen((char*)pre_attr->value);
107 if (rec->pre_attr.base_font != NULL) {
108 if (Is(rec->pre_attr.base_font, pre_attr)) {
109 continue;
110 }
111 rec->pre_attr.base_font = realloc(rec->pre_attr.base_font,
112 size);
113 } else {
114 rec->pre_attr.base_font = malloc(size);
115 }
116 memcpy(rec->pre_attr.base_font, pre_attr->value, size);
117 } else if (Is(XNLineSpace, pre_attr))
118 rec->pre_attr.line_space = *(CARD32 *) pre_attr->value;
119 else if (Is(XNCursor, pre_attr))
120 rec->pre_attr.cursor = *(Cursor *) pre_attr->value;
121 }
122
123 for (i = 0; i < (int) call_data->status_attr_num; i++, sts_attr++) {
124 if (Is(XNArea, sts_attr)) {
125 rec->sts_attr.area = *(XRectangle *) sts_attr->value;
126 } else if (Is(XNAreaNeeded, sts_attr)) {
127 rec->sts_attr.area_needed = *(XRectangle *) sts_attr->value;
128 } else if (Is(XNColormap, sts_attr)) {
129 rec->sts_attr.cmap = *(Colormap *) sts_attr->value;
130 } else if (Is(XNStdColormap, sts_attr))
131 rec->sts_attr.cmap = *(Colormap *) sts_attr->value;
132
133 else if (Is(XNForeground, sts_attr)) {
134 rec->sts_attr.foreground = *(CARD32 *) sts_attr->value;
135 } else if (Is(XNBackground, sts_attr)) {
136 rec->sts_attr.background = *(CARD32 *) sts_attr->value;
137 }
138
139 else if (Is(XNBackgroundPixmap, sts_attr))
140 rec->sts_attr.bg_pixmap = *(Pixmap *) sts_attr->value;
141
142 else if (Is(XNFontSet, sts_attr)) {
143 int size = strlen((char*)sts_attr->value) + 1;
144 if (rec->sts_attr.base_font != NULL) {
145 if (Is(rec->sts_attr.base_font, sts_attr))
146 continue;
147 rec->sts_attr.base_font = realloc(rec->sts_attr.base_font,
148 size);
149 } else {
150 rec->sts_attr.base_font = malloc(size);
151 }
152 memcpy(rec->sts_attr.base_font, sts_attr->value, size);
153 } else if (Is(XNLineSpace, sts_attr)) {
154 rec->sts_attr.line_space = *(CARD32 *) sts_attr->value;
155 } else if (Is(XNCursor, sts_attr)) {
156 rec->sts_attr.cursor = *(Cursor *) sts_attr->value;
157 }
158 }
159 }
160
161 /**
162 * Interface for XIM Create Input Context
163 *
164 * @param context Input Context
165 * @param priv private data passed by CreateIC
166 * @return void
167 **/
XimCreateIC(void * arg,FcitxInputContext * context,void * priv)168 void XimCreateIC(void* arg, FcitxInputContext* context, void *priv)
169 {
170 FcitxXimFrontend* xim = (FcitxXimFrontend*) arg;
171 IMChangeICStruct * call_data = (IMChangeICStruct *)priv;
172 context->privateic = fcitx_utils_malloc0(sizeof(FcitxXimIC));
173 FcitxXimIC* privic = (FcitxXimIC*) context->privateic;
174 FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(xim->owner);
175
176 privic->connect_id = call_data->connect_id;
177 privic->id = ++ xim->icid;
178 privic->offset_x = -1;
179 privic->offset_y = -1;
180 StoreIC(privic, call_data);
181 SetTrackPos(xim, context, call_data);
182 call_data->icid = privic->id;
183
184 if (config->shareState == ShareState_PerProgram)
185 FcitxInstanceSetICStateFromSameApplication(xim->owner, xim->frontendid, context);
186
187 if (privic->input_style & XIMPreeditCallbacks)
188 context->contextCaps |= CAPACITY_PREEDIT;
189 else
190 context->contextCaps &= ~CAPACITY_PREEDIT;
191
192 return;
193 }
194
195 /**
196 * Destroy Input Context for XIM
197 *
198 * @param context Input Context to Destroy
199 * @return void
200 **/
XimDestroyIC(void * arg,FcitxInputContext * context)201 void XimDestroyIC(void* arg, FcitxInputContext* context)
202 {
203 FCITX_UNUSED(arg);
204 //free resource
205 FcitxXimIC* privic = (FcitxXimIC*) context->privateic;
206 if (privic->resource_name)
207 free(privic->resource_name);
208 if (privic->resource_class)
209 free(privic->resource_class);
210
211 context->privateic = NULL;
212 free(privic);
213 return;
214 }
215
216 /**
217 * Set Input Context Data
218 *
219 * @param call_data
220 * @return void
221 **/
XimSetIC(FcitxXimFrontend * xim,IMChangeICStruct * call_data)222 void XimSetIC(FcitxXimFrontend* xim, IMChangeICStruct * call_data)
223 {
224 FcitxInputContext *ic = FcitxInstanceFindIC(xim->owner, xim->frontendid, &call_data->icid);
225
226 if (ic == NULL)
227 return;
228 FcitxXimIC* rec = (FcitxXimIC*) ic->privateic;
229 StoreIC(rec, call_data);
230
231 if (rec->input_style & XIMPreeditCallbacks)
232 ic->contextCaps |= CAPACITY_PREEDIT;
233 else
234 ic->contextCaps &= ~CAPACITY_PREEDIT;
235
236 return;
237 }
238
239 /**
240 * Fetch Input Context Data
241 *
242 * @param call_data
243 * @return void
244 **/
XimGetIC(FcitxXimFrontend * xim,IMChangeICStruct * call_data)245 void XimGetIC(FcitxXimFrontend* xim, IMChangeICStruct * call_data)
246 {
247 XICAttribute *ic_attr = call_data->ic_attr;
248 XICAttribute *pre_attr = call_data->preedit_attr;
249 XICAttribute *sts_attr = call_data->status_attr;
250 register int i;
251 FcitxInputContext *ic = FcitxInstanceFindIC(xim->owner, xim->frontendid, &call_data->icid);
252 if (ic == NULL)
253 return;
254 FcitxXimIC* rec = (FcitxXimIC*) ic->privateic;
255
256 if (rec == NULL)
257 return;
258 for (i = 0; i < (int) call_data->ic_attr_num; i++, ic_attr++) {
259 if (Is(XNFilterEvents, ic_attr)) {
260 ic_attr->value = (void *) malloc(sizeof(CARD32));
261 *(CARD32 *) ic_attr->value = KeyPressMask | KeyReleaseMask;
262 ic_attr->value_length = sizeof(CARD32);
263 }
264 }
265
266 /* preedit attributes */
267 for (i = 0; i < (int) call_data->preedit_attr_num; i++, pre_attr++) {
268 if (Is(XNArea, pre_attr)) {
269 pre_attr->value = (void *) malloc(sizeof(XRectangle));
270 *(XRectangle *) pre_attr->value = rec->pre_attr.area;
271 pre_attr->value_length = sizeof(XRectangle);
272
273 } else if (Is(XNAreaNeeded, pre_attr)) {
274 pre_attr->value = (void *) malloc(sizeof(XRectangle));
275 *(XRectangle *) pre_attr->value = rec->pre_attr.area_needed;
276 pre_attr->value_length = sizeof(XRectangle);
277
278 } else if (Is(XNSpotLocation, pre_attr)) {
279 pre_attr->value = (void *) malloc(sizeof(XPoint));
280 *(XPoint *) pre_attr->value = rec->pre_attr.spot_location;
281 pre_attr->value_length = sizeof(XPoint);
282
283 } else if (Is(XNFontSet, pre_attr)) {
284 CARD16 base_len = (CARD16) strlen(rec->pre_attr.base_font);
285 int total_len = sizeof(CARD16) + (CARD16) base_len;
286 char *p;
287
288 pre_attr->value = (void *) malloc(total_len);
289 p = (char *) pre_attr->value;
290 memcpy(p, &base_len, sizeof(CARD16));
291 p += sizeof(CARD16);
292 strncpy(p, rec->pre_attr.base_font, base_len);
293 pre_attr->value_length = total_len;
294
295 } else if (Is(XNForeground, pre_attr)) {
296 pre_attr->value = (void *) malloc(sizeof(long));
297 *(long *) pre_attr->value = rec->pre_attr.foreground;
298 pre_attr->value_length = sizeof(long);
299
300 } else if (Is(XNBackground, pre_attr)) {
301 pre_attr->value = (void *) malloc(sizeof(long));
302 *(long *) pre_attr->value = rec->pre_attr.background;
303 pre_attr->value_length = sizeof(long);
304
305 } else if (Is(XNLineSpace, pre_attr)) {
306 pre_attr->value = (void *) malloc(sizeof(long));
307 *(long *) pre_attr->value = 18;
308 pre_attr->value_length = sizeof(long);
309 }
310 }
311
312 /* status attributes */
313 for (i = 0; i < (int) call_data->status_attr_num; i++, sts_attr++) {
314 if (Is(XNArea, sts_attr)) {
315 sts_attr->value = (void *) malloc(sizeof(XRectangle));
316 *(XRectangle *) sts_attr->value = rec->sts_attr.area;
317 sts_attr->value_length = sizeof(XRectangle);
318
319 } else if (Is(XNAreaNeeded, sts_attr)) {
320 sts_attr->value = (void *) malloc(sizeof(XRectangle));
321 *(XRectangle *) sts_attr->value = rec->sts_attr.area_needed;
322 sts_attr->value_length = sizeof(XRectangle);
323
324 } else if (Is(XNFontSet, sts_attr)) {
325 CARD16 base_len = (CARD16) strlen(rec->sts_attr.base_font);
326 int total_len = sizeof(CARD16) + (CARD16) base_len;
327 char *p;
328
329 sts_attr->value = (void *) malloc(total_len);
330 p = (char *) sts_attr->value;
331 memcpy(p, &base_len, sizeof(CARD16));
332 p += sizeof(CARD16);
333 strncpy(p, rec->sts_attr.base_font, base_len);
334 sts_attr->value_length = total_len;
335
336 } else if (Is(XNForeground, sts_attr)) {
337 sts_attr->value = (void *) malloc(sizeof(long));
338 *(long *) sts_attr->value = rec->sts_attr.foreground;
339 sts_attr->value_length = sizeof(long);
340
341 } else if (Is(XNBackground, sts_attr)) {
342 sts_attr->value = (void *) malloc(sizeof(long));
343 *(long *) sts_attr->value = rec->sts_attr.background;
344 sts_attr->value_length = sizeof(long);
345
346 } else if (Is(XNLineSpace, sts_attr)) {
347 sts_attr->value = (void *) malloc(sizeof(long));
348 *(long *) sts_attr->value = 18;
349 sts_attr->value_length = sizeof(long);
350 }
351 }
352 }
353
XimCheckICFromSameApplication(void * arg,FcitxInputContext * icToCheck,FcitxInputContext * ic)354 boolean XimCheckICFromSameApplication(void* arg, FcitxInputContext* icToCheck, FcitxInputContext* ic)
355 {
356 FCITX_UNUSED(arg);
357 FcitxXimIC* ximictoCheck = GetXimIC(icToCheck);
358 FcitxXimIC* ximic = GetXimIC(ic);
359
360 return ximictoCheck->connect_id == ximic->connect_id;
361 }
362
363 // kate: indent-mode cstyle; space-indent on; indent-width 0;
364