Mercurial > kinput2.yaz
comparison lib/imlib/imic.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: imic.c,v 1.12 2002/01/24 09:07:20 ishisone Exp $"; | |
3 #endif | |
4 /* | |
5 * Copyright (c) 1994 Software Research Associates, Inc. | |
6 * | |
7 * Permission to use, copy, modify, and distribute this software and its | |
8 * documentation for any purpose and without fee is hereby granted, provided | |
9 * that the above copyright notice appear in all copies and that both that | |
10 * copyright notice and this permission notice appear in supporting | |
11 * documentation, and that the name of Software Research Associates not be | |
12 * used in advertising or publicity pertaining to distribution of the | |
13 * software without specific, written prior permission. Software Research | |
14 * Associates makes no representations about the suitability of this software | |
15 * for any purpose. It is provided "as is" without express or implied | |
16 * warranty. | |
17 * | |
18 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
19 */ | |
20 | |
21 #include "im.h" | |
22 | |
23 #define IMHASHVAL(imp) ((imp)->id % IM_HASH_SIZE) | |
24 #define ICHASHVAL(icp) ((icp)->id % IC_HASH_SIZE) | |
25 | |
26 static IMIM *id2IM _Pt_((IMConnection *conn, unsigned int id)); | |
27 static IMIC *id2IC _Pt_((IMIM *imp, unsigned int id)); | |
28 static unsigned int newIMID _Pt_((IMConnection *conn)); | |
29 static unsigned int newICID _Pt_((IMIM *imp)); | |
30 static void registerIM _Pt_((IMIM *imp)); | |
31 static void registerIC _Pt_((IMIC *icp)); | |
32 static int unregisterIM _Pt_((IMIM *imp)); | |
33 static int unregisterIC _Pt_((IMIC *icp)); | |
34 static int removeIM _Pt_((IMIM *imp)); | |
35 static int removeIC _Pt_((IMIC *icp)); | |
36 | |
37 /*- id2IM: input-method ID to IM converter -*/ | |
38 static IMIM * | |
39 id2IM(conn, id) | |
40 IMConnection *conn; | |
41 unsigned int id; | |
42 { | |
43 IMIM **imHash = IMIMHash(conn->proto_widget); | |
44 IMIM *imp; | |
45 | |
46 imp = imHash[id % IM_HASH_SIZE]; | |
47 while (imp != NULL) { | |
48 if (imp->id == id) return imp; | |
49 imp = imp->hash_next; | |
50 } | |
51 return NULL; | |
52 } | |
53 | |
54 /*- id2IC: input-context ID to IC converter -*/ | |
55 static IMIC * | |
56 id2IC(imp, id) | |
57 IMIM *imp; | |
58 unsigned int id; | |
59 { | |
60 IMIC **icHash = IMICHash(imp->connection->proto_widget); | |
61 IMIC *icp; | |
62 | |
63 icp = icHash[id % IC_HASH_SIZE]; | |
64 while (icp != NULL) { | |
65 if (icp->id == id) return icp; | |
66 icp = icp->hash_next; | |
67 } | |
68 return NULL; | |
69 } | |
70 | |
71 /*- newIMID: return unused input-method ID -*/ | |
72 static unsigned int | |
73 newIMID(conn) | |
74 IMConnection *conn; | |
75 { | |
76 Widget w = conn->proto_widget; | |
77 unsigned int id, id_start; | |
78 | |
79 id = id_start = IMNextIMID(w); | |
80 do { | |
81 if (id2IM(conn, id) == NULL) return id; /* unused ID */ | |
82 } while ((id = IMNextIMID(w)) != id_start); | |
83 return 0; | |
84 } | |
85 | |
86 /*- newICID: return unused input-context ID -*/ | |
87 static unsigned int | |
88 newICID(imp) | |
89 IMIM *imp; | |
90 { | |
91 Widget w = imp->connection->proto_widget; | |
92 unsigned int id, id_start; | |
93 | |
94 id = id_start = IMNextICID(w); | |
95 do { | |
96 if (id2IC(imp, id) == NULL) return id; /* unused ID */ | |
97 } while ((id = IMNextICID(w)) != id_start); | |
98 return 0; | |
99 } | |
100 | |
101 /*- registerIM: register IM to hash table -*/ | |
102 static void | |
103 registerIM(imp) | |
104 IMIM *imp; | |
105 { | |
106 IMIM **imHash = IMIMHash(imp->connection->proto_widget); | |
107 | |
108 imp->hash_next = imHash[IMHASHVAL(imp)]; | |
109 imHash[IMHASHVAL(imp)] = imp; | |
110 } | |
111 | |
112 /*- registerIC: register IC to hash table -*/ | |
113 static void | |
114 registerIC(icp) | |
115 IMIC *icp; | |
116 { | |
117 IMIC **icHash = IMICHash(icp->im->connection->proto_widget); | |
118 | |
119 icp->hash_next = icHash[ICHASHVAL(icp)]; | |
120 icHash[ICHASHVAL(icp)] = icp; | |
121 } | |
122 | |
123 /*- unregisterIM: remove IM from hash table -*/ | |
124 static int | |
125 unregisterIM(imp) | |
126 IMIM *imp; | |
127 { | |
128 IMIM **imHash = IMIMHash(imp->connection->proto_widget); | |
129 IMIM *p, *q; | |
130 | |
131 p = imHash[IMHASHVAL(imp)]; | |
132 q = NULL; | |
133 | |
134 while (p != NULL && p != imp) { | |
135 q = p; | |
136 p = p->hash_next; | |
137 } | |
138 if (p == NULL) return 0; | |
139 | |
140 if (q != NULL) { | |
141 q->hash_next = p->hash_next; | |
142 } else { | |
143 imHash[IMHASHVAL(imp)] = p->hash_next; | |
144 } | |
145 return 1; | |
146 } | |
147 | |
148 /*- unregisterIC: remove IC from hash table -*/ | |
149 static int | |
150 unregisterIC(icp) | |
151 IMIC *icp; | |
152 { | |
153 IMIC **icHash = IMICHash(icp->im->connection->proto_widget); | |
154 IMIC *p, *q; | |
155 | |
156 p = icHash[ICHASHVAL(icp)]; | |
157 q = NULL; | |
158 | |
159 while (p != NULL && p != icp) { | |
160 q = p; | |
161 p = p->hash_next; | |
162 } | |
163 if (p == NULL) return 0; | |
164 | |
165 if (q != NULL) { | |
166 q->hash_next = p->hash_next; | |
167 } else { | |
168 icHash[ICHASHVAL(icp)] = p->hash_next; | |
169 } | |
170 return 1; | |
171 } | |
172 | |
173 /* removeIM: remove IM from IM list which connection holds */ | |
174 static int | |
175 removeIM(imp) | |
176 IMIM *imp; | |
177 { | |
178 IMConnection *conn = imp->connection; | |
179 IMIM *p, *q; | |
180 | |
181 p = conn->im_list; | |
182 q = NULL; | |
183 while (p != NULL) { | |
184 if (p == imp) break; | |
185 q = p; | |
186 p = p->next; | |
187 } | |
188 | |
189 if (p == NULL) return 0; | |
190 | |
191 if (q == NULL) { | |
192 conn->im_list = p->next; | |
193 } else { | |
194 q->next = p->next; | |
195 } | |
196 return 1; | |
197 } | |
198 | |
199 /* removeIC: remove IC from IC list which IM holds */ | |
200 static int | |
201 removeIC(icp) | |
202 IMIC *icp; | |
203 { | |
204 IMIM *imp = icp->im; | |
205 IMIC *p, *q; | |
206 | |
207 p = imp->ic_list; | |
208 q = NULL; | |
209 while (p != NULL) { | |
210 if (p == icp) break; | |
211 q = p; | |
212 p = p->next; | |
213 } | |
214 | |
215 if (p == NULL) return 0; | |
216 | |
217 if (q == NULL) { | |
218 imp->ic_list = p->next; | |
219 } else { | |
220 q->next = p->next; | |
221 } | |
222 return 1; | |
223 } | |
224 | |
225 /* | |
226 * Public functions | |
227 */ | |
228 | |
229 IMIM * | |
230 IMGetIM(conn, arglen) | |
231 IMConnection *conn; | |
232 int arglen; | |
233 { | |
234 unsigned int id; | |
235 IMIM *imp; | |
236 | |
237 /* Check argument length */ | |
238 if (arglen < 2) { | |
239 IMSendError(conn, IMBadSomething, 0, 0, "input-method ID expected"); | |
240 return NULL; | |
241 } | |
242 | |
243 id = IMGetC16(conn, 0); | |
244 imp = id2IM(conn, id); | |
245 if (imp != NULL && imp->connection == conn) return imp; | |
246 IMSendError(conn, IMBadSomething, 0, 0, "invalid input-method ID"); | |
247 return NULL; | |
248 } | |
249 | |
250 IMIC * | |
251 IMGetIC(conn, arglen) | |
252 IMConnection *conn; | |
253 int arglen; | |
254 { | |
255 unsigned int imid, icid; | |
256 IMIM *imp; | |
257 IMIC *icp; | |
258 | |
259 /* Check argument length */ | |
260 if (arglen < 4) { | |
261 IMSendError(conn, IMBadSomething, 0, 0, "input-method ID expected"); | |
262 return NULL; | |
263 } else if (arglen < 4) { | |
264 IMSendError(conn, IMBadSomething, 0, 0, "input-context ID expected"); | |
265 return NULL; | |
266 } | |
267 | |
268 imid = IMGetC16(conn, 0); | |
269 icid = IMGetC16(conn, 2); | |
270 | |
271 if ((imp = id2IM(conn, imid)) == NULL || imp->connection != conn) { | |
272 IMSendError(conn, IMBadSomething, 0, 0, "invalid input-method ID"); | |
273 return NULL; | |
274 } | |
275 if ((icp = id2IC(imp, icid)) == NULL || icp->im != imp) { | |
276 IMSendError(conn, IMBadSomething, 0, 0, "invalid input-context ID"); | |
277 return NULL; | |
278 } | |
279 return icp; | |
280 } | |
281 | |
282 IMIM * | |
283 IMCreateIM(conn, converter) | |
284 IMConnection *conn; | |
285 IMConverter *converter; | |
286 { | |
287 IMIM *imp; | |
288 | |
289 imp = XtNew(IMIM); | |
290 | |
291 imp->id = newIMID(conn); | |
292 imp->connection = conn; | |
293 imp->converter = converter; | |
294 imp->mask = 0; | |
295 imp->ic_list = NULL; | |
296 | |
297 registerIM(imp); | |
298 imp->next = conn->im_list; | |
299 conn->im_list = imp; | |
300 | |
301 return imp; | |
302 } | |
303 | |
304 | |
305 IMIC * | |
306 IMCreateIC(imp) | |
307 IMIM *imp; | |
308 { | |
309 IMIC *icp; | |
310 | |
311 icp = XtNew(IMIC); | |
312 | |
313 icp->id = newICID(imp); | |
314 | |
315 /* | |
316 * Initialize data | |
317 */ | |
318 icp->im = imp; | |
319 icp->conversion = NULL; | |
320 icp->state = 0; | |
321 icp->pending_events = NULL; | |
322 icp->style = IMSTYLE_SEPARATE; | |
323 icp->common_attr.set_mask = icp->common_attr.change_mask = 0; | |
324 icp->preedit_attr.set_mask = icp->preedit_attr.change_mask = 0; | |
325 icp->status_attr.set_mask = icp->status_attr.change_mask = 0; | |
326 icp->fonts = NULL; | |
327 icp->num_fonts = 0; | |
328 icp->status_fonts = NULL; | |
329 icp->num_status_fonts = 0; | |
330 | |
331 registerIC(icp); | |
332 icp->next = imp->ic_list; | |
333 imp->ic_list = icp; | |
334 | |
335 return icp; | |
336 } | |
337 | |
338 void | |
339 IMDestroyIM(imp) | |
340 IMIM *imp; | |
341 { | |
342 IMIC *icp = imp->ic_list; | |
343 IMIC *icp_next; | |
344 | |
345 /* | |
346 * Destroy all the ICs belonging to this IM. | |
347 */ | |
348 while (icp != NULL) { | |
349 icp_next = icp->next; | |
350 IMDestroyIC(icp); | |
351 icp = icp_next; | |
352 } | |
353 | |
354 (void)unregisterIM(imp); | |
355 (void)removeIM(imp); | |
356 | |
357 XtFree((char *)imp); | |
358 } | |
359 | |
360 void | |
361 IMDestroyIC(icp) | |
362 IMIC *icp; | |
363 { | |
364 IMPendingEvent *pending; | |
365 | |
366 if (icp->state & IC_DESTROYING) return; | |
367 icp->state |= IC_DESTROYING; | |
368 | |
369 /* | |
370 * Stop conversion. | |
371 */ | |
372 if (icp->state & IC_CONVERTING) { | |
373 IMStopConversion(icp); | |
374 } | |
375 | |
376 /* | |
377 * Free pending event queue. | |
378 */ | |
379 pending = icp->pending_events; | |
380 while (pending != NULL) { | |
381 IMPendingEvent *next = pending->next; | |
382 | |
383 XtFree((char *)pending); | |
384 pending = next; | |
385 } | |
386 | |
387 /* | |
388 * Free IC attributes. | |
389 */ | |
390 IMFreeICAttributes(icp); | |
391 | |
392 (void)unregisterIC(icp); | |
393 (void)removeIC(icp); | |
394 | |
395 XtFree((char *)icp); | |
396 } |