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 }