Mercurial > kinput2.yaz
comparison lib/imlib/imattr.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 | 1f9e9cb00c6c |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: imattr.c,v 1.18 2002/01/10 15:04:05 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 #ifndef XNSeparatorofNestedList | |
24 #define XNSeparatorofNestedList "separatorofNesttedList" | |
25 #endif | |
26 #ifndef XNPreeditState | |
27 #define XNPreeditState "preeditState" | |
28 #endif | |
29 #ifndef XIMPreeditEnable | |
30 #define XIMPreeditEnable 1L | |
31 #define XIMPreeditDisable 2L | |
32 #endif | |
33 #ifndef XNResetState | |
34 #define XNResetState "resetState" | |
35 #endif | |
36 #ifndef XIMInitialState | |
37 #define XIMInitialState 1L | |
38 #define XIMPreserveState 2L | |
39 #endif | |
40 | |
41 #define PAD4(n) ((((n) + 3) / 4) * 4) | |
42 | |
43 /* | |
44 * List of supported input styles. | |
45 */ | |
46 | |
47 typedef struct { | |
48 XIMStyle xim_style; /* X11R5 spec. */ | |
49 int conversion_style; /* kinput2 spec. */ | |
50 } InputStyle; | |
51 | |
52 static InputStyle styles[] = { | |
53 { XIMPreeditPosition|XIMStatusArea, IMSTYLE_OVER_THE_SPOT }, | |
54 { XIMPreeditPosition|XIMStatusNothing, IMSTYLE_OVER_THE_SPOT }, | |
55 { XIMPreeditArea|XIMStatusArea, IMSTYLE_OFF_THE_SPOT }, | |
56 { XIMPreeditCallbacks|XIMStatusCallbacks, IMSTYLE_ON_THE_SPOT }, | |
57 { XIMPreeditCallbacks|XIMStatusNothing, IMSTYLE_ON_THE_SPOT }, | |
58 { XIMPreeditNothing|XIMStatusNothing, IMSTYLE_SEPARATE }, | |
59 { 0 }, | |
60 }; | |
61 | |
62 #define NEST_NONE 0 | |
63 #define NEST_PREEDIT 1 | |
64 #define NEST_STATUS 2 | |
65 | |
66 #define CHECK_ICATTR_SIZE(validsize, code) \ | |
67 if (len != validsize) { badSizeError(icp, code); return -1; } | |
68 | |
69 #undef OP_C | |
70 #undef OP_S | |
71 #undef OP_G | |
72 | |
73 #define OP_C 1 /* Create */ | |
74 #define OP_S 2 /* SetValues */ | |
75 #define OP_G 4 /* GetValues */ | |
76 | |
77 typedef struct { | |
78 char *name; /* attribute name */ | |
79 int type; /* type of attribute value */ | |
80 int valid_ops; /* valid operations for this attribute */ | |
81 int (*set_proc) _Pt_((IMIM *, char *, int)); | |
82 int (*get_proc) _Pt_((IMIM *, unsigned int, int)); | |
83 } IMAttribute; | |
84 | |
85 typedef struct { | |
86 char *name; /* attribute name */ | |
87 int type; /* type of attribute value */ | |
88 int valid_ops; /* valid operations for this attribute */ | |
89 int (*set_proc) _Pt_((IMIC *, char *, int, int, int, int)); | |
90 int (*get_proc) _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
91 } ICAttribute; | |
92 | |
93 | |
94 /* | |
95 * IM attributes | |
96 */ | |
97 | |
98 static int getQueryInputStyle _Pt_((IMIM *imp, unsigned int id, int offset)); | |
99 | |
100 static IMAttribute imAttributes[] = { | |
101 { XNQueryInputStyle, TYPE_XIM_STYLES, OP_G, | |
102 NULL, getQueryInputStyle }, | |
103 }; | |
104 | |
105 static int numImAttributes = XtNumber(imAttributes); | |
106 | |
107 | |
108 /* | |
109 * IC attributes | |
110 */ | |
111 | |
112 static int setInputStyle _Pt_((IMIC *, char *, int, int, int, int)); | |
113 static int setClientWindow _Pt_((IMIC *, char *, int, int, int, int)); | |
114 static int setFocusWindow _Pt_((IMIC *, char *, int, int, int, int)); | |
115 static int setPreeditAttributes _Pt_((IMIC *, char *, int, int, int, int)); | |
116 static int setStatusAttributes _Pt_((IMIC *, char *, int, int, int, int)); | |
117 static int setArea _Pt_((IMIC *, char *, int, int, int, int)); | |
118 static int setAreaNeeded _Pt_((IMIC *, char *, int, int, int, int)); | |
119 static int setForeground _Pt_((IMIC *, char *, int, int, int, int)); | |
120 static int setBackground _Pt_((IMIC *, char *, int, int, int, int)); | |
121 static int setColormap _Pt_((IMIC *, char *, int, int, int, int)); | |
122 static int setBgPixmap _Pt_((IMIC *, char *, int, int, int, int)); | |
123 static int setLineSpace _Pt_((IMIC *, char *, int, int, int, int)); | |
124 static int setCursor _Pt_((IMIC *, char *, int, int, int, int)); | |
125 static int setSpotLocation _Pt_((IMIC *, char *, int, int, int, int)); | |
126 static int setStdColormap _Pt_((IMIC *, char *, int, int, int, int)); | |
127 static int setFontSet _Pt_((IMIC *, char *, int, int, int, int)); | |
128 static int setPreeditState _Pt_((IMIC *, char *, int, int, int, int)); | |
129 static int setResetState _Pt_((IMIC *, char *, int, int, int, int)); | |
130 | |
131 static int getPreeditAttributes _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
132 static int getStatusAttributes _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
133 static int getInputStyle _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
134 static int getClientWindow _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
135 static int getFocusWindow _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
136 static int getFilterEvents _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
137 static int getArea _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
138 static int getAreaNeeded _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
139 static int getSpotLocation _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
140 static int getColormap _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
141 static int getStdColormap _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
142 static int getForeground _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
143 static int getBackground _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
144 static int getBgPixmap _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
145 static int getFontSet _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
146 static int getLineSpace _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
147 static int getCursor _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
148 static int getPreeditState _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
149 static int getResetState _Pt_((IMIC *, unsigned int, int, int, char *, int)); | |
150 | |
151 static ICAttribute icAttributes[] = { | |
152 { XNInputStyle, TYPE_CARD32, OP_C|OP_G, | |
153 setInputStyle, getInputStyle }, | |
154 { XNClientWindow, TYPE_WINDOW, OP_C|OP_S|OP_G, | |
155 setClientWindow, getClientWindow }, | |
156 { XNFocusWindow, TYPE_WINDOW, OP_C|OP_S|OP_G, | |
157 setFocusWindow, getFocusWindow }, | |
158 { XNFilterEvents, TYPE_CARD32, OP_G, | |
159 NULL, getFilterEvents }, | |
160 { XNPreeditAttributes, TYPE_NESTED_LIST, OP_C|OP_S|OP_G, | |
161 setPreeditAttributes, getPreeditAttributes }, | |
162 { XNStatusAttributes, TYPE_NESTED_LIST, OP_C|OP_S|OP_G, | |
163 setStatusAttributes, getStatusAttributes }, | |
164 { XNArea, TYPE_XRECTANGLE, OP_C|OP_S|OP_G, | |
165 setArea, getArea }, | |
166 { XNAreaNeeded, TYPE_XRECTANGLE, OP_C|OP_S|OP_G, | |
167 setAreaNeeded, getAreaNeeded }, | |
168 { XNSpotLocation, TYPE_XPOINT, OP_C|OP_S|OP_G, | |
169 setSpotLocation, getSpotLocation }, | |
170 { XNColormap, TYPE_CARD32, OP_C|OP_S|OP_G, | |
171 setColormap, getColormap }, | |
172 { XNStdColormap, TYPE_CARD32, OP_C|OP_S|OP_G, | |
173 setStdColormap, getStdColormap }, | |
174 { XNForeground, TYPE_CARD32, OP_C|OP_S|OP_G, | |
175 setForeground, getForeground }, | |
176 { XNBackground, TYPE_CARD32, OP_C|OP_S|OP_G, | |
177 setBackground, getBackground }, | |
178 { XNBackgroundPixmap, TYPE_CARD32, OP_C|OP_S|OP_G, | |
179 setBgPixmap, getBgPixmap }, | |
180 { XNFontSet, TYPE_XFONTSET, OP_C|OP_S|OP_G, | |
181 setFontSet, getFontSet }, | |
182 { XNLineSpace, TYPE_CARD16, OP_C|OP_S|OP_G, /* should be TYPE_INT16 */ | |
183 setLineSpace, getLineSpace }, | |
184 { XNCursor, TYPE_CARD32, OP_C|OP_S|OP_G, | |
185 setCursor, getCursor }, | |
186 { XNSeparatorofNestedList, TYPE_SEPARATOR, OP_G, | |
187 NULL, NULL }, | |
188 { XNPreeditState, TYPE_CARD32, OP_C|OP_S|OP_G, | |
189 setPreeditState, getPreeditState }, | |
190 { XNResetState, TYPE_CARD32, OP_C|OP_S|OP_G, | |
191 setResetState, getResetState }, | |
192 }; | |
193 | |
194 static int numIcAttributes = XtNumber(icAttributes); | |
195 | |
196 | |
197 static unsigned int getC16 _Pt_((char *data, int order)); | |
198 static int getI16 _Pt_((char *data, int order)); | |
199 static unsigned long getC32 _Pt_((char *data, int order)); | |
200 static int validateClientWindow _Pt_((IMIC *icp)); | |
201 static int validateFocusWindow _Pt_((IMIC *icp)); | |
202 static void badSizeError _Pt_((IMIC *icp, int code)); | |
203 static void unnestedError _Pt_((IMIC *icp)); | |
204 static IMPSAttributes *getPSPtr _Pt_((IMIC *icp, int type)); | |
205 static int getIMValues _Pt_((IMIM *imp, char *data, int len, int offset)); | |
206 static int getICValues _Pt_((IMIC *icp, char *data, int len, int nest, | |
207 int offset, int *sepp)); | |
208 static int setICValues _Pt_((IMIC *icp, char *data, int len, | |
209 int major, int op)); | |
210 static int getPSAttributes _Pt_((IMIC *icp, unsigned int id, int nest, | |
211 int offset, char *data, int len)); | |
212 static void changeFonts _Pt_((IMIC *icp, int preedit)); | |
213 static void fillCommonDefault _Pt_((IMIC *icp, unsigned long mask)); | |
214 static int getNaturalLineSpace _Pt_((IMIC *icp, int preedit)); | |
215 static void fillPSDefault _Pt_((IMIC *icp, int type, unsigned long mask)); | |
216 static int validateCommonAttr _Pt_((IMIC *icp, int checkonly)); | |
217 static int validatePSAttr _Pt_((IMIC *icp, int type, int checkonly)); | |
218 static void changeConversionAttributes _Pt_((IMIC *icp)); | |
219 static void computeAreaNeeded _Pt_((IMIC *icp)); | |
220 static void computeAreaForQuery _Pt_((IMIC *icp)); | |
221 | |
222 | |
223 /* | |
224 * Functions reading out numbers from byte buffer | |
225 */ | |
226 | |
227 static unsigned int | |
228 getC16(data, order) | |
229 char *data; | |
230 int order; | |
231 { | |
232 unsigned char *p = (unsigned char *)data; | |
233 unsigned int x; | |
234 | |
235 x = (order == ORDER_BIG) ? ((p[0] << 8) | p[1]) : (p[0] | p[1] << 8); | |
236 return x; | |
237 } | |
238 | |
239 static int | |
240 getI16(data, order) | |
241 char *data; | |
242 int order; | |
243 { | |
244 unsigned char *p = (unsigned char *)data; | |
245 long l; | |
246 | |
247 l = (order == ORDER_BIG) ? ((p[0] << 8) | p[1]) : (p[0] | p[1] << 8); | |
248 return (l < 32768) ? (int)l : (int)(l - 65536L); | |
249 } | |
250 | |
251 static unsigned long | |
252 getC32(data, order) | |
253 char *data; | |
254 int order; | |
255 { | |
256 unsigned char *p = (unsigned char *)data; | |
257 unsigned long x; | |
258 | |
259 if (order == ORDER_BIG) { | |
260 x = (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; | |
261 } else { | |
262 x = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); | |
263 } | |
264 return x; | |
265 } | |
266 | |
267 | |
268 /* | |
269 * Functions that check the validity of resources. | |
270 */ | |
271 | |
272 static int | |
273 validateClientWindow(icp) | |
274 IMIC *icp; | |
275 { | |
276 return IMValidateWindow(XtDisplay(icp->im->connection->proto_widget), | |
277 icp->common_attr.client, &icp->client_profile); | |
278 } | |
279 | |
280 static int | |
281 validateFocusWindow(icp) | |
282 IMIC *icp; | |
283 { | |
284 IMCommonAttributes *ap = &icp->common_attr; | |
285 | |
286 /* | |
287 * This function assumes that the client window has already | |
288 * been validated. | |
289 */ | |
290 if ((ap->set_mask & ATTR_MASK_CLIENT) && ap->focus == ap->client) { | |
291 icp->focus_profile = icp->client_profile; | |
292 return 1; | |
293 } else { | |
294 return IMValidateWindow(XtDisplay(icp->im->connection->proto_widget), | |
295 icp->common_attr.focus, &icp->focus_profile); | |
296 } | |
297 } | |
298 | |
299 | |
300 /* | |
301 * Functions submit errors | |
302 */ | |
303 | |
304 static void | |
305 badSizeError(icp, code) | |
306 IMIC *icp; | |
307 int code; | |
308 { | |
309 DPRINT(("bad size error for IC #%d\n", icp->id)); | |
310 IMSendError(icp->im->connection, code, icp->im->id, icp->id, | |
311 "invalid size of attribute value"); | |
312 } | |
313 | |
314 static void | |
315 unnestedError(icp) | |
316 IMIC *icp; | |
317 { | |
318 DPRINT(("unnested error for IC #%d\n", icp->id)); | |
319 IMSendError(icp->im->connection, IMBadSomething, icp->im->id, icp->id, | |
320 "either preedit or status specification required"); | |
321 } | |
322 | |
323 | |
324 /* | |
325 * Functions getting IM attributes | |
326 */ | |
327 | |
328 static IMPSAttributes * | |
329 getPSPtr(icp, type) | |
330 IMIC *icp; | |
331 int type; | |
332 { | |
333 switch (type) { | |
334 case NEST_PREEDIT: return &icp->preedit_attr; | |
335 case NEST_STATUS: return &icp->status_attr; | |
336 default: return NULL; | |
337 } | |
338 } | |
339 | |
340 static int | |
341 getIMValues(imp, data, len, offset) | |
342 IMIM *imp; | |
343 char *data; | |
344 int len; | |
345 int offset; /* request offset */ | |
346 { | |
347 unsigned int id; /* attribute ID */ | |
348 IMAttribute *attrp; | |
349 IMConnection *conn = imp->connection; | |
350 int byte_order = conn->byte_order; | |
351 | |
352 while (len >= 2) { | |
353 id = getC16(data, byte_order); | |
354 data += 2; | |
355 len -= 2; | |
356 | |
357 if (id > numImAttributes) { | |
358 /* invalid attribute ID */ | |
359 IMCancelRequest(conn, offset); | |
360 IMSendError(conn, IMBadSomething, imp->id, 0, | |
361 "invalid IM attribute ID"); | |
362 return -1; | |
363 } | |
364 | |
365 attrp = &imAttributes[id]; | |
366 if (!(attrp->valid_ops & OP_G)) { | |
367 IMCancelRequest(conn, offset); | |
368 IMSendError(conn, IMBadSomething, imp->id, 0, | |
369 "invalid operation (IMGetValues) for this attribute"); | |
370 return -1; | |
371 } | |
372 | |
373 if ((*attrp->get_proc)(imp, id, offset) < 0) return -1; | |
374 } | |
375 return 0; | |
376 } | |
377 | |
378 /* ARGSUSED */ | |
379 static int | |
380 getQueryInputStyle(imp, id, offset) | |
381 IMIM *imp; | |
382 unsigned int id; | |
383 int offset; | |
384 { | |
385 IMConnection *conn = imp->connection; | |
386 unsigned int num_styles, num_bytes; | |
387 InputStyle *stp; | |
388 | |
389 TRACE(("imlib:getQueryInputStyle()\n")); | |
390 | |
391 for (num_styles = 0, stp = styles; stp->xim_style != 0; stp++) { | |
392 num_styles++; | |
393 } | |
394 num_bytes = num_styles * 4 + 4; | |
395 IMPutC16(conn, id); | |
396 IMPutC16(conn, num_bytes); | |
397 IMPutC16(conn, num_styles); | |
398 IMPutC16(conn, 0); | |
399 for (stp = styles; stp->xim_style != 0; stp++) { | |
400 IMPutC32(conn, stp->xim_style); | |
401 } | |
402 return 0; | |
403 } | |
404 | |
405 | |
406 /* | |
407 * Functions setting IC attributes | |
408 */ | |
409 | |
410 static int | |
411 setICValues(icp, data, len, nest, op) | |
412 IMIC *icp; | |
413 char *data; | |
414 int len; | |
415 int nest; | |
416 int op; | |
417 { | |
418 IMConnection *conn = icp->im->connection; | |
419 unsigned int imid = icp->im->id; | |
420 unsigned int icid = icp->id; | |
421 unsigned int id; | |
422 unsigned int value_len; | |
423 unsigned int attr_len; | |
424 char *value; | |
425 ICAttribute *attrp; | |
426 int byte_order = icp->im->connection->byte_order; | |
427 | |
428 TRACE(("imlib:setICValues()\n")); | |
429 | |
430 while (len > 0) { | |
431 if (len < 4) { | |
432 DPRINT(("attribute data length < 4\n")); | |
433 IMSendError(conn, IMBadSomething, imid, icid, "Bad attribute data"); | |
434 return -1; | |
435 } | |
436 id = getC16(data, byte_order); | |
437 value_len = getC16(data + 2, byte_order); | |
438 attr_len = PAD4(4 + value_len); | |
439 | |
440 if (attr_len > len) { | |
441 DPRINT(("attribute data length > request length\n")); | |
442 IMSendError(conn, IMBadSomething, imid, icid, | |
443 "Bad attribute length"); | |
444 return -1; | |
445 } | |
446 value = data + 4; | |
447 | |
448 if (id > numIcAttributes) { | |
449 DPRINT(("invalid IC attribute ID %d\n", id)); | |
450 IMSendError(conn, IMBadSomething, imid, icid, | |
451 "invalid IC attribute ID"); | |
452 return -1; | |
453 } | |
454 attrp = &icAttributes[id]; | |
455 if (!(attrp->valid_ops & op)) { | |
456 DPRINT(("invalid operation (%s) for IC attr %d\n", | |
457 op == OP_C ? "create" : "set", id)); | |
458 IMSendError(conn, IMBadSomething, imid, icid, | |
459 "invalid operation for this attribute"); | |
460 return -1; | |
461 } | |
462 | |
463 /* | |
464 * Call attribute set procedure. | |
465 */ | |
466 if ((*attrp->set_proc)(icp, value, (int)value_len, byte_order, nest, op) < 0) { | |
467 /* | |
468 * Error has occured. The set procedure has already sent | |
469 * appropriate error message, so just return here. | |
470 */ | |
471 return -1; | |
472 } | |
473 | |
474 data += attr_len; | |
475 len -= attr_len; | |
476 } | |
477 return 0; | |
478 } | |
479 | |
480 /* ARGSUSED */ | |
481 static int | |
482 setInputStyle(icp, value, len, order, nest, op) | |
483 IMIC *icp; | |
484 char *value; | |
485 int len; | |
486 int order; | |
487 int nest; | |
488 int op; | |
489 { | |
490 TRACE(("imlib:setInputStyle()\n")); | |
491 | |
492 CHECK_ICATTR_SIZE(4, IMBadStyle); | |
493 | |
494 /* | |
495 * InputStyle must be set with CreateIC. | |
496 */ | |
497 if (op != OP_C) { | |
498 DPRINT(("trying to change input style through SetICValues\n")); | |
499 IMSendError(icp->im->connection, IMBadStyle, | |
500 icp->im->id, icp->id, | |
501 "InputStyle cannot be changed by SetICValues"); | |
502 return -1; | |
503 } | |
504 | |
505 icp->common_attr.input_style = (XIMStyle)getC32(value, order); | |
506 icp->common_attr.set_mask |= ATTR_MASK_INPUT_STYLE; | |
507 icp->common_attr.change_mask |= ATTR_MASK_INPUT_STYLE; | |
508 TRACE(("\tinput style: %ld\n", icp->common_attr.input_style)); | |
509 return 0; | |
510 } | |
511 | |
512 /* ARGSUSED */ | |
513 static int | |
514 setClientWindow(icp, value, len, order, nest, op) | |
515 IMIC *icp; | |
516 char *value; | |
517 int len; | |
518 int order; | |
519 int nest; | |
520 int op; | |
521 { | |
522 TRACE(("imlib:setClientWindow()\n")); | |
523 | |
524 CHECK_ICATTR_SIZE(4, IMBadClientWindow); | |
525 | |
526 /* | |
527 * ClientWindow cannot be changed. | |
528 */ | |
529 if (icp->common_attr.set_mask & ATTR_MASK_CLIENT) { | |
530 DPRINT(("client window already specified\n")); | |
531 IMSendError(icp->im->connection, IMBadClientWindow, | |
532 icp->im->id, icp->id, "ClientWindow already set"); | |
533 return -1; | |
534 } | |
535 | |
536 icp->common_attr.client = (Window)getC32(value, order); | |
537 TRACE(("\tclient window: %08lx\n", icp->common_attr.client)); | |
538 | |
539 icp->common_attr.set_mask |= ATTR_MASK_CLIENT; | |
540 icp->common_attr.change_mask |= ATTR_MASK_CLIENT; | |
541 | |
542 return 0; | |
543 } | |
544 | |
545 /* ARGSUSED */ | |
546 static int | |
547 setFocusWindow(icp, value, len, order, nest, op) | |
548 IMIC *icp; | |
549 char *value; | |
550 int len; | |
551 int order; | |
552 int nest; | |
553 int op; | |
554 { | |
555 Window focus; | |
556 | |
557 TRACE(("imlib:setFocusWindow()\n")); | |
558 | |
559 CHECK_ICATTR_SIZE(4, IMBadFocusWindow); | |
560 | |
561 focus = (Window)getC32(value, order); | |
562 TRACE(("\tfocus window: %08lx\n", focus)); | |
563 | |
564 if (!(icp->common_attr.set_mask & ATTR_MASK_FOCUS) || | |
565 focus != icp->common_attr.focus) { | |
566 icp->common_attr.change_mask |= ATTR_MASK_FOCUS; | |
567 } | |
568 icp->common_attr.focus = focus; | |
569 icp->common_attr.set_mask |= ATTR_MASK_FOCUS; | |
570 return 0; | |
571 } | |
572 | |
573 /* ARGSUSED */ | |
574 static int | |
575 setPreeditAttributes(icp, value, len, order, nest, op) | |
576 IMIC *icp; | |
577 char *value; | |
578 int len; | |
579 int order; | |
580 int nest; | |
581 int op; | |
582 { | |
583 TRACE(("imlib:setPreeditAttributes()\n")); | |
584 return setICValues(icp, value, len, NEST_PREEDIT, op); | |
585 } | |
586 | |
587 /* ARGSUSED */ | |
588 static int | |
589 setStatusAttributes(icp, value, len, order, nest, op) | |
590 IMIC *icp; | |
591 char *value; | |
592 int len; | |
593 int order; | |
594 int nest; | |
595 int op; | |
596 { | |
597 TRACE(("imlib:setStatusAttributes()\n")); | |
598 return setICValues(icp, value, len, NEST_STATUS, op); | |
599 } | |
600 | |
601 /* ARGSUSED */ | |
602 static int | |
603 setArea(icp, value, len, order, nest, op) | |
604 IMIC *icp; | |
605 char *value; | |
606 int len; | |
607 int order; | |
608 int nest; | |
609 int op; | |
610 { | |
611 IMPSAttributes *ap; | |
612 XRectangle area; | |
613 | |
614 TRACE(("imlib:setArea()\n")); | |
615 | |
616 CHECK_ICATTR_SIZE(8, IMBadArea); | |
617 | |
618 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
619 unnestedError(icp); | |
620 return -1; | |
621 } | |
622 | |
623 area.x = getI16(value, order); | |
624 area.y = getI16(value + 2, order); | |
625 area.width = getC16(value + 4, order); | |
626 area.height = getC16(value + 6, order); | |
627 TRACE(("\tarea: %d, %d, %d, %d\n", | |
628 area.x, area.y, area.width, area.height)); | |
629 | |
630 if (!(ap->set_mask & ATTR_MASK_AREA) || | |
631 area.x != ap->area.x || | |
632 area.y != ap->area.y || | |
633 area.width != ap->area.width || | |
634 area.height != ap->area.height) { | |
635 ap->change_mask |= ATTR_MASK_AREA; | |
636 } | |
637 | |
638 ap->area.x = area.x; | |
639 ap->area.y = area.y; | |
640 ap->area.width = area.width; | |
641 ap->area.height = area.height; | |
642 ap->set_mask |= ATTR_MASK_AREA; | |
643 | |
644 return 0; | |
645 } | |
646 | |
647 /* ARGSUSED */ | |
648 static int | |
649 setAreaNeeded(icp, value, len, order, nest, op) | |
650 IMIC *icp; | |
651 char *value; | |
652 int len; | |
653 int order; | |
654 int nest; | |
655 int op; | |
656 { | |
657 IMPSAttributes *ap; | |
658 XRectangle area; | |
659 | |
660 TRACE(("imlib:setAreaNeeded()\n")); | |
661 | |
662 CHECK_ICATTR_SIZE(8, IMBadArea); | |
663 | |
664 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
665 unnestedError(icp); | |
666 return -1; | |
667 } | |
668 | |
669 area.width = getC16(value + 4, order); | |
670 area.height = getC16(value + 6, order); | |
671 TRACE(("\tarea needed: %d, %d\n", area.width, area.height)); | |
672 | |
673 if (!(ap->set_mask & ATTR_MASK_AREA_NEEDED) || | |
674 area.width != ap->area_needed.width || | |
675 area.height != ap->area_needed.height) { | |
676 ap->change_mask |= ATTR_MASK_AREA_NEEDED; | |
677 } | |
678 | |
679 ap->area_needed.width = area.width; | |
680 ap->area_needed.height = area.height; | |
681 ap->set_mask |= ATTR_MASK_AREA_NEEDED; | |
682 | |
683 return 0; | |
684 } | |
685 | |
686 /* ARGSUSED */ | |
687 static int | |
688 setForeground(icp, value, len, order, nest, op) | |
689 IMIC *icp; | |
690 char *value; | |
691 int len; | |
692 int order; | |
693 int nest; | |
694 int op; | |
695 { | |
696 IMPSAttributes *ap; | |
697 Pixel fore; | |
698 | |
699 TRACE(("imlib:setForeground()\n")); | |
700 | |
701 CHECK_ICATTR_SIZE(4, IMBadForeground); | |
702 | |
703 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
704 unnestedError(icp); | |
705 return -1; | |
706 } | |
707 | |
708 fore = getC32(value, order); | |
709 TRACE(("\tforeground: %ld\n", fore)); | |
710 | |
711 if (!(ap->set_mask & ATTR_MASK_FOREGROUND) || fore != ap->foreground) { | |
712 ap->change_mask |= ATTR_MASK_FOREGROUND; | |
713 } | |
714 ap->foreground = fore; | |
715 ap->set_mask |= ATTR_MASK_FOREGROUND; | |
716 return 0; | |
717 } | |
718 | |
719 /* ARGSUSED */ | |
720 static int | |
721 setBackground(icp, value, len, order, nest, op) | |
722 IMIC *icp; | |
723 char *value; | |
724 int len; | |
725 int order; | |
726 int nest; | |
727 int op; | |
728 { | |
729 IMPSAttributes *ap; | |
730 Pixel back; | |
731 | |
732 TRACE(("imlib:setBackground()\n")); | |
733 | |
734 CHECK_ICATTR_SIZE(4, IMBadBackground); | |
735 | |
736 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
737 unnestedError(icp); | |
738 return -1; | |
739 } | |
740 | |
741 back = getC32(value, order); | |
742 TRACE(("\tbackground: %ld\n", back)); | |
743 | |
744 if (!(ap->set_mask & ATTR_MASK_BACKGROUND) || back != ap->background) { | |
745 ap->change_mask |= ATTR_MASK_BACKGROUND; | |
746 } | |
747 ap->background = back; | |
748 ap->set_mask |= ATTR_MASK_BACKGROUND; | |
749 return 0; | |
750 } | |
751 | |
752 /* ARGSUSED */ | |
753 static int | |
754 setColormap(icp, value, len, order, nest, op) | |
755 IMIC *icp; | |
756 char *value; | |
757 int len; | |
758 int order; | |
759 int nest; | |
760 int op; | |
761 { | |
762 IMPSAttributes *ap; | |
763 Colormap cmap; | |
764 | |
765 TRACE(("imlib:setColormap()\n")); | |
766 | |
767 CHECK_ICATTR_SIZE(4, IMBadColormap); | |
768 | |
769 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
770 unnestedError(icp); | |
771 return -1; | |
772 } | |
773 | |
774 cmap = getC32(value, order); | |
775 TRACE(("\tcolormap: %08lx\n", cmap)); | |
776 | |
777 if (!(ap->set_mask & ATTR_MASK_COLORMAP) || cmap != ap->colormap) { | |
778 ap->change_mask |= ATTR_MASK_COLORMAP; | |
779 } | |
780 ap->colormap = cmap; | |
781 ap->set_mask |= ATTR_MASK_COLORMAP; | |
782 return 0; | |
783 } | |
784 | |
785 /* ARGSUSED */ | |
786 static int | |
787 setBgPixmap(icp, value, len, order, nest, op) | |
788 IMIC *icp; | |
789 char *value; | |
790 int len; | |
791 int order; | |
792 int nest; | |
793 int op; | |
794 { | |
795 IMPSAttributes *ap; | |
796 Pixmap pixmap; | |
797 | |
798 TRACE(("imlib:setBgPixmap()\n")); | |
799 | |
800 CHECK_ICATTR_SIZE(4, IMBadPixmap); | |
801 | |
802 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
803 unnestedError(icp); | |
804 return -1; | |
805 } | |
806 | |
807 pixmap = getC32(value, order); | |
808 TRACE(("\tbackground pixmap: %08lx\n", pixmap)); | |
809 | |
810 if (!(ap->set_mask & ATTR_MASK_BG_PIXMAP) || pixmap != ap->bg_pixmap) { | |
811 ap->change_mask |= ATTR_MASK_BG_PIXMAP; | |
812 } | |
813 | |
814 ap->bg_pixmap = pixmap; | |
815 ap->set_mask |= ATTR_MASK_BG_PIXMAP; | |
816 | |
817 return 0; | |
818 } | |
819 | |
820 /* ARGSUSED */ | |
821 static int | |
822 setLineSpace(icp, value, len, order, nest, op) | |
823 IMIC *icp; | |
824 char *value; | |
825 int len; | |
826 int order; | |
827 int nest; | |
828 int op; | |
829 { | |
830 IMPSAttributes *ap; | |
831 int line_space; | |
832 | |
833 TRACE(("imlib:setLineSpace()\n")); | |
834 | |
835 CHECK_ICATTR_SIZE(2, IMBadSomething); | |
836 | |
837 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
838 unnestedError(icp); | |
839 return -1; | |
840 } | |
841 | |
842 line_space = getI16(value, order); /* ??? linespacing is 'int' */ | |
843 TRACE(("\tline space: %d\n", line_space)); | |
844 | |
845 if (!(ap->set_mask & ATTR_MASK_LINESPACE) || | |
846 line_space != ap->line_space) { | |
847 ap->change_mask |= ATTR_MASK_LINESPACE; | |
848 } | |
849 ap->line_space = line_space; | |
850 ap->set_mask |= ATTR_MASK_LINESPACE; | |
851 return 0; | |
852 } | |
853 | |
854 /* ARGSUSED */ | |
855 static int | |
856 setCursor(icp, value, len, order, nest, op) | |
857 IMIC *icp; | |
858 char *value; | |
859 int len; | |
860 int order; | |
861 int nest; | |
862 int op; | |
863 { | |
864 IMPSAttributes *ap; | |
865 Cursor cursor; | |
866 | |
867 TRACE(("imlib:setCursor()\n")); | |
868 | |
869 CHECK_ICATTR_SIZE(4, IMBadCursor); | |
870 | |
871 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
872 unnestedError(icp); | |
873 return -1; | |
874 } | |
875 | |
876 cursor = getC32(value, order); | |
877 TRACE(("\tcursor: %08lx\n", cursor)); | |
878 | |
879 if (!(ap->set_mask & ATTR_MASK_CURSOR) || cursor != ap->cursor) { | |
880 ap->change_mask |= ATTR_MASK_CURSOR; | |
881 } | |
882 ap->cursor = cursor; | |
883 ap->set_mask |= ATTR_MASK_CURSOR; | |
884 return 0; | |
885 } | |
886 | |
887 /* ARGSUSED */ | |
888 static int | |
889 setSpotLocation(icp, value, len, order, nest, op) | |
890 IMIC *icp; | |
891 char *value; | |
892 int len; | |
893 int order; | |
894 int nest; | |
895 int op; | |
896 { | |
897 IMPSAttributes *ap; | |
898 XPoint spot; | |
899 | |
900 TRACE(("imlib:setSpotLocation()\n")); | |
901 | |
902 CHECK_ICATTR_SIZE(4, IMBadSpotLocation); | |
903 | |
904 if (nest == NEST_STATUS) { | |
905 DPRINT(("spot location specified in a status attribute list\n")); | |
906 IMSendError(icp->im->connection, IMBadSpotLocation, | |
907 icp->im->id, icp->id, | |
908 "spot location isn't a status attribute"); | |
909 return -1; | |
910 } | |
911 | |
912 ap = &icp->preedit_attr; | |
913 | |
914 spot.x = getI16(value, order); | |
915 spot.y = getI16(value + 2, order); | |
916 TRACE(("\tspot location: %d, %d\n", spot.x, spot.y)); | |
917 | |
918 if (!(ap->set_mask & ATTR_MASK_SPOT_LOCATION) || | |
919 spot.x != ap->spot_location.x || spot.y != ap->spot_location.y) { | |
920 ap->change_mask |= ATTR_MASK_SPOT_LOCATION; | |
921 } | |
922 ap->spot_location.x = spot.x; | |
923 ap->spot_location.y = spot.y; | |
924 ap->set_mask |= ATTR_MASK_SPOT_LOCATION; | |
925 return 0; | |
926 } | |
927 | |
928 /* ARGSUSED */ | |
929 static int | |
930 setStdColormap(icp, value, len, order, nest, op) | |
931 IMIC *icp; | |
932 char *value; | |
933 int len; | |
934 int order; | |
935 int nest; | |
936 int op; | |
937 { | |
938 IMPSAttributes *ap; | |
939 Atom colormap_name; | |
940 XStandardColormap *stdcolormaps; | |
941 Widget w = icp->im->connection->proto_widget; | |
942 Display *dpy = XtDisplay(w); | |
943 int ncolormaps; | |
944 Window root; | |
945 XAEHandle h; | |
946 int status; | |
947 | |
948 TRACE(("imlib:setStdColormap()\n")); | |
949 | |
950 CHECK_ICATTR_SIZE(4, IMBadAtom); | |
951 | |
952 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
953 unnestedError(icp); | |
954 return -1; | |
955 } | |
956 | |
957 colormap_name = getC32(value, order); | |
958 if (icp->common_attr.set_mask & ATTR_MASK_CLIENT) { | |
959 root = icp->client_profile.root; | |
960 } else if (icp->common_attr.set_mask & ATTR_MASK_FOCUS) { | |
961 root = icp->focus_profile.root; | |
962 } else { | |
963 /* | |
964 * Client has not specified client window yet. | |
965 * Reading standard colormap property should been deffered | |
966 * until the window is set, but for now... | |
967 */ | |
968 DDPRINT(2, ("std colormap specified, leaving client window unspecified\n")); | |
969 root = RootWindowOfScreen(XtScreen(w)); | |
970 } | |
971 | |
972 h = XAESetIgnoreErrors(dpy); | |
973 status = XGetRGBColormaps(dpy, root, | |
974 &stdcolormaps, &ncolormaps, colormap_name); | |
975 XAEUnset(h); | |
976 if (!status || ncolormaps < 0) { | |
977 DPRINT(("can't get standard colormap (%ld)\n", colormap_name)); | |
978 IMSendError(icp->im->connection, IMBadName, icp->im->id, icp->id, | |
979 "invalid standard colormap name"); | |
980 return -1; | |
981 } | |
982 | |
983 if (!(ap->set_mask & ATTR_MASK_STD_COLORMAP) || | |
984 colormap_name != ap->std_colormap) { | |
985 ap->change_mask |= ATTR_MASK_STD_COLORMAP; | |
986 } | |
987 ap->std_colormap = colormap_name; | |
988 ap->colormap = stdcolormaps[0].colormap; | |
989 TRACE(("\tstandard colormap: %ld (colormap=%08lx)\n", | |
990 colormap_name, ap->colormap)); | |
991 | |
992 ap->set_mask |= ATTR_MASK_STD_COLORMAP | ATTR_MASK_COLORMAP; | |
993 XFree((char *)stdcolormaps); | |
994 return 0; | |
995 } | |
996 | |
997 /* ARGSUSED */ | |
998 static int | |
999 setFontSet(icp, value, len, order, nest, op) | |
1000 IMIC *icp; | |
1001 char *value; | |
1002 int len; | |
1003 int order; | |
1004 int nest; | |
1005 int op; | |
1006 { | |
1007 IMPSAttributes *ap; | |
1008 unsigned int name_list_len; | |
1009 char *name_list; | |
1010 | |
1011 TRACE(("imlib:setFontSet()\n")); | |
1012 | |
1013 if (len < 2) { | |
1014 badSizeError(icp, IMBadName); | |
1015 return -1; | |
1016 } | |
1017 name_list_len = getC16(value, order); | |
1018 if (2 + name_list_len > len) { | |
1019 badSizeError(icp, IMBadName); | |
1020 return -1; | |
1021 } | |
1022 | |
1023 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1024 unnestedError(icp); | |
1025 return -1; | |
1026 } | |
1027 | |
1028 name_list = XtMalloc(name_list_len + 1); | |
1029 bcopy(value + 2, name_list, name_list_len); | |
1030 name_list[name_list_len] = '\0'; | |
1031 TRACE(("\tfontset: %s\n", name_list)); | |
1032 | |
1033 if (ap->set_mask & ATTR_MASK_FONT_SET) { | |
1034 if (!strcmp(name_list, ap->font_set)) { | |
1035 XtFree(name_list); | |
1036 } else { | |
1037 ap->change_mask |= ATTR_MASK_FONT_SET; | |
1038 if (ap->font_set != IMDefaultFontSet(icp->im)) { | |
1039 XtFree(ap->font_set); | |
1040 } | |
1041 ap->font_set = name_list; | |
1042 } | |
1043 } else { | |
1044 ap->font_set = name_list; | |
1045 ap->set_mask |= ATTR_MASK_FONT_SET; | |
1046 ap->change_mask |= ATTR_MASK_FONT_SET; | |
1047 } | |
1048 return 0; | |
1049 } | |
1050 | |
1051 /* ARGSUSED */ | |
1052 static int | |
1053 setPreeditState(icp, value, len, order, nest, op) | |
1054 IMIC *icp; | |
1055 char *value; | |
1056 int len; | |
1057 int order; | |
1058 int nest; | |
1059 int op; | |
1060 { | |
1061 IMCommonAttributes *ap = &icp->common_attr; | |
1062 unsigned long preedit_state; | |
1063 | |
1064 TRACE(("imlib:setPreeditState()\n")); | |
1065 | |
1066 CHECK_ICATTR_SIZE(4, IMBadSomething); | |
1067 | |
1068 if (nest == NEST_STATUS) { | |
1069 DPRINT(("preedit state specified in a status attribute list\n")); | |
1070 IMSendError(icp->im->connection, IMBadSomething, | |
1071 icp->im->id, icp->id, | |
1072 "preedit state isn't a status attribute"); | |
1073 return -1; | |
1074 } | |
1075 | |
1076 preedit_state = getC32(value, order); | |
1077 | |
1078 ap->set_mask |= ATTR_MASK_PREEDIT_STATE; | |
1079 ap->change_mask |= ATTR_MASK_PREEDIT_STATE; | |
1080 ap->preedit_state = preedit_state; | |
1081 return 0; | |
1082 } | |
1083 | |
1084 /* ARGSUSED */ | |
1085 static int | |
1086 setResetState(icp, value, len, order, nest, op) | |
1087 IMIC *icp; | |
1088 char *value; | |
1089 int len; | |
1090 int order; | |
1091 int nest; | |
1092 int op; | |
1093 { | |
1094 IMCommonAttributes *ap = &icp->common_attr; | |
1095 unsigned long reset_state; | |
1096 | |
1097 TRACE(("imlib:setResetState()\n")); | |
1098 | |
1099 CHECK_ICATTR_SIZE(4, IMBadSomething); | |
1100 | |
1101 reset_state = getC32(value, order); | |
1102 | |
1103 ap->set_mask |= ATTR_MASK_RESET_STATE; | |
1104 ap->change_mask |= ATTR_MASK_RESET_STATE; | |
1105 ap->reset_state = reset_state; | |
1106 return 0; | |
1107 } | |
1108 | |
1109 | |
1110 /* | |
1111 * Functions getting IC attributes | |
1112 */ | |
1113 | |
1114 static int | |
1115 getICValues(icp, data, len, nest, offset, sepp) | |
1116 IMIC *icp; | |
1117 char *data; | |
1118 int len; | |
1119 int nest; /* NEST_NONE, NEST_PREEDIT or NEST_STATUS */ | |
1120 int offset; /* request offset */ | |
1121 int *sepp; /* Out: true if ended with a nested list separator */ | |
1122 { | |
1123 unsigned int id; /* attribute ID */ | |
1124 ICAttribute *attrp; | |
1125 IMConnection *conn = icp->im->connection; | |
1126 int byte_order = conn->byte_order; | |
1127 char *org_data = data; | |
1128 int r; | |
1129 | |
1130 TRACE(("imlib:getICValues()\n")); | |
1131 | |
1132 while (len >= 2) { | |
1133 id = getC16(data, byte_order); | |
1134 data += 2; | |
1135 len -= 2; | |
1136 | |
1137 if (id > numIcAttributes) { | |
1138 /* invalid attribute ID */ | |
1139 DPRINT(("invalid IC attribute ID (%d) specified\n", id)); | |
1140 IMCancelRequest(conn, offset); | |
1141 IMSendError(conn, IMBadSomething, icp->im->id, icp->id, | |
1142 "invalid IC attribute ID"); | |
1143 return -1; | |
1144 } | |
1145 | |
1146 attrp = &icAttributes[id]; | |
1147 if (attrp->type == TYPE_SEPARATOR) { | |
1148 /* nested list separator */ | |
1149 *sepp = 1; | |
1150 return data - org_data; | |
1151 } | |
1152 | |
1153 if (!(attrp->valid_ops & OP_G)) { | |
1154 DPRINT(("invalid operation (get) for IC attr %d\n", id)); | |
1155 IMCancelRequest(conn, offset); | |
1156 IMSendError(conn, IMBadSomething, icp->im->id, icp->id, | |
1157 "invalid operation (ICGetValues) for this attribute"); | |
1158 return -1; | |
1159 } | |
1160 | |
1161 r = (*attrp->get_proc)(icp, id, nest, offset, data, len); | |
1162 /* | |
1163 * The return value of get_proc is usually 0, indicating success. | |
1164 * If it is less than 0, there are some errors. | |
1165 * If it is greater than 0, | |
1166 */ | |
1167 if (r < 0) return -1; | |
1168 | |
1169 data += r; /* r is extra offset */ | |
1170 len -= r; | |
1171 } | |
1172 *sepp = 0; | |
1173 return data - org_data; | |
1174 } | |
1175 | |
1176 /* ARGSUSED */ | |
1177 static int | |
1178 getPSAttributes(icp, id, nest, offset, data, len) | |
1179 IMIC *icp; | |
1180 unsigned int id; | |
1181 int nest; | |
1182 int offset; | |
1183 char *data; | |
1184 int len; | |
1185 { | |
1186 IMConnection *conn = icp->im->connection; | |
1187 unsigned int length; | |
1188 int length_offset; | |
1189 int attr_offset; | |
1190 int nested_separator; | |
1191 int r; | |
1192 | |
1193 IMPutC16(conn, id); | |
1194 | |
1195 length_offset = IMWritePos(conn); | |
1196 IMPutC16(conn, 0); /* dummy -- overwritten afterwards */ | |
1197 | |
1198 attr_offset = IMWritePos(conn); | |
1199 | |
1200 r = getICValues(icp, data, len, nest, offset, &nested_separator); | |
1201 if (r < 0) return -1; | |
1202 if (!nested_separator) { | |
1203 /* there's no nested list separator */ | |
1204 DPRINT(("nested list doesn't end with separator\n")); | |
1205 /* | |
1206 * X11R6 Xlib sends nested attribute list which has no | |
1207 * separator at its end. In order to accommodate to it, | |
1208 * don't send error for that. | |
1209 */ | |
1210 #ifdef notdef | |
1211 IMCancelRequest(conn, offset); | |
1212 IMSendError(conn, IMBadSomething, icp->im->id, icp->id, | |
1213 "corrupted nested list"); | |
1214 return -1; | |
1215 #endif | |
1216 } | |
1217 | |
1218 /* | |
1219 * Nested list is written on the output buffer. | |
1220 * Calculate the length of the list. | |
1221 */ | |
1222 length = IMWritePos(conn) - attr_offset; | |
1223 | |
1224 /* rewrite attribute length field */ | |
1225 IMRewriteC16(conn, length_offset, length); | |
1226 IMPutPad(conn); | |
1227 | |
1228 return r; | |
1229 } | |
1230 | |
1231 /* ARGSUSED */ | |
1232 static int | |
1233 getPreeditAttributes(icp, id, nest, offset, data, len) | |
1234 IMIC *icp; | |
1235 unsigned int id; | |
1236 int nest; /* unused */ | |
1237 int offset; | |
1238 char *data; | |
1239 int len; | |
1240 { | |
1241 TRACE(("imlib:getPreeditAttributes()\n")); | |
1242 return getPSAttributes(icp, id, NEST_PREEDIT, offset, data, len); | |
1243 } | |
1244 | |
1245 /* ARGSUSED */ | |
1246 static int | |
1247 getStatusAttributes(icp, id, nest, offset, data, len) | |
1248 IMIC *icp; | |
1249 unsigned int id; | |
1250 int nest; /* unused */ | |
1251 int offset; | |
1252 char *data; | |
1253 int len; | |
1254 { | |
1255 TRACE(("imlib:getStatusAttributes()\n")); | |
1256 return getPSAttributes(icp, id, NEST_STATUS, offset, data, len); | |
1257 } | |
1258 | |
1259 /* ARGSUSED */ | |
1260 static int | |
1261 getInputStyle(icp, id, nest, offset, data, len) | |
1262 IMIC *icp; | |
1263 unsigned int id; | |
1264 int nest; | |
1265 int offset; | |
1266 char *data; | |
1267 int len; | |
1268 { | |
1269 IMConnection *conn = icp->im->connection; | |
1270 | |
1271 TRACE(("imlib:getInputStyle()\n")); | |
1272 | |
1273 /* | |
1274 * Input style must have been specified, (and validated) | |
1275 * at IC creation. No need for checking. | |
1276 */ | |
1277 IMPutC16(conn, id); /* attribute ID */ | |
1278 IMPutC16(conn, 4); /* value length */ | |
1279 IMPutC32(conn, icp->common_attr.input_style); | |
1280 return 0; | |
1281 } | |
1282 | |
1283 /* ARGSUSED */ | |
1284 static int | |
1285 getClientWindow(icp, id, nest, offset, data, len) | |
1286 IMIC *icp; | |
1287 unsigned int id; | |
1288 int nest; | |
1289 int offset; | |
1290 char *data; | |
1291 int len; | |
1292 { | |
1293 IMConnection *conn = icp->im->connection; | |
1294 | |
1295 TRACE(("imlib:getClientWindow()\n")); | |
1296 | |
1297 if (icp->common_attr.set_mask & ATTR_MASK_CLIENT) { | |
1298 IMPutC16(conn, id); /* attribute ID */ | |
1299 IMPutC16(conn, 4); /* value length */ | |
1300 IMPutC32(conn, icp->common_attr.client); | |
1301 return 0; | |
1302 } else { | |
1303 /* no default is available */ | |
1304 DPRINT(("getClientWindow without setting client window previously\n")); | |
1305 IMCancelRequest(conn, offset); | |
1306 IMSendError(conn, IMBadClientWindow, icp->im->id, icp->id, | |
1307 "client window not specified yet"); | |
1308 return -1; | |
1309 } | |
1310 } | |
1311 | |
1312 /* ARGSUSED */ | |
1313 static int | |
1314 getFocusWindow(icp, id, nest, offset, data, len) | |
1315 IMIC *icp; | |
1316 unsigned int id; | |
1317 int nest; | |
1318 int offset; | |
1319 char *data; | |
1320 int len; | |
1321 { | |
1322 IMConnection *conn = icp->im->connection; | |
1323 | |
1324 TRACE(("imlib:getFocusWindow()\n")); | |
1325 | |
1326 if (!(icp->common_attr.set_mask & ATTR_MASK_FOCUS)) { | |
1327 /* fill default value */ | |
1328 fillCommonDefault(icp, (unsigned long)ATTR_MASK_FOCUS); | |
1329 } | |
1330 | |
1331 if (icp->common_attr.set_mask & ATTR_MASK_FOCUS) { | |
1332 IMPutC16(conn, id); /* attribute ID */ | |
1333 IMPutC16(conn, 4); /* value length */ | |
1334 IMPutC32(conn, icp->common_attr.focus); | |
1335 return 0; | |
1336 } else { | |
1337 /* | |
1338 * Couldn't get the default value. That is, neither | |
1339 * focus window nor client window is specified yet. | |
1340 */ | |
1341 DPRINT(("getFocusWindow without setting focus/client window previously\n")); | |
1342 IMCancelRequest(conn, offset); | |
1343 IMSendError(conn, IMBadFocusWindow, icp->im->id, icp->id, | |
1344 "neither of client/focus window not specified yet"); | |
1345 return -1; | |
1346 } | |
1347 } | |
1348 | |
1349 /* ARGSUSED */ | |
1350 static int | |
1351 getFilterEvents(icp, id, nest, offset, data, len) | |
1352 IMIC *icp; | |
1353 unsigned int id; | |
1354 int nest; | |
1355 int offset; | |
1356 char *data; | |
1357 int len; | |
1358 { | |
1359 IMConnection *conn = icp->im->connection; | |
1360 | |
1361 TRACE(("imlib:getFilterEvents()\n")); | |
1362 | |
1363 /* We need only Key events */ | |
1364 IMPutC16(conn, id); /* attribute ID */ | |
1365 IMPutC16(conn, 4); /* value length */ | |
1366 IMPutC32(conn, KeyPressMask | KeyReleaseMask); | |
1367 return 0; | |
1368 } | |
1369 | |
1370 /* ARGSUSED */ | |
1371 static int | |
1372 getArea(icp, id, nest, offset, data, len) | |
1373 IMIC *icp; | |
1374 unsigned int id; | |
1375 int nest; | |
1376 int offset; | |
1377 char *data; | |
1378 int len; | |
1379 { | |
1380 IMConnection *conn = icp->im->connection; | |
1381 IMPSAttributes *ap; | |
1382 | |
1383 TRACE(("imlib:getArea()\n")); | |
1384 | |
1385 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1386 IMCancelRequest(conn, offset); | |
1387 unnestedError(icp); | |
1388 return -1; | |
1389 } | |
1390 | |
1391 if (!(ap->set_mask & ATTR_MASK_AREA)) { | |
1392 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_AREA); | |
1393 } | |
1394 | |
1395 IMPutC16(conn, id); /* attribute ID */ | |
1396 IMPutC16(conn, 8); /* value length */ | |
1397 IMPutI16(conn, ap->area.x); | |
1398 IMPutI16(conn, ap->area.y); | |
1399 IMPutC16(conn, ap->area.width); | |
1400 IMPutC16(conn, ap->area.height); | |
1401 return 0; | |
1402 } | |
1403 | |
1404 /* ARGSUSED */ | |
1405 static int | |
1406 getAreaNeeded(icp, id, nest, offset, data, len) | |
1407 IMIC *icp; | |
1408 unsigned int id; | |
1409 int nest; | |
1410 int offset; | |
1411 char *data; | |
1412 int len; | |
1413 { | |
1414 IMConnection *conn = icp->im->connection; | |
1415 IMPSAttributes *ap; | |
1416 | |
1417 TRACE(("imlib:getAreaNeeded()\n")); | |
1418 | |
1419 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1420 IMCancelRequest(conn, offset); | |
1421 unnestedError(icp); | |
1422 return -1; | |
1423 } | |
1424 | |
1425 /* | |
1426 * Always call fillPSDefault to get appropriate AreaNeeded value. | |
1427 */ | |
1428 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_AREA_NEEDED); | |
1429 | |
1430 TRACE(("\tarea needed: %d, %d, %d, %d\n", | |
1431 ap->area_needed.x, ap->area_needed.y, | |
1432 ap->area_needed.width, ap->area_needed.height)); | |
1433 | |
1434 IMPutC16(conn, id); /* attribute ID */ | |
1435 IMPutC16(conn, 8); /* value length */ | |
1436 IMPutI16(conn, ap->area_needed.x); | |
1437 IMPutI16(conn, ap->area_needed.y); | |
1438 IMPutC16(conn, ap->area_needed.width); | |
1439 IMPutC16(conn, ap->area_needed.height); | |
1440 return 0; | |
1441 } | |
1442 | |
1443 /* ARGSUSED */ | |
1444 static int | |
1445 getSpotLocation(icp, id, nest, offset, data, len) | |
1446 IMIC *icp; | |
1447 unsigned int id; | |
1448 int nest; | |
1449 int offset; | |
1450 char *data; | |
1451 int len; | |
1452 { | |
1453 IMConnection *conn = icp->im->connection; | |
1454 IMPSAttributes *ap = &icp->preedit_attr; | |
1455 | |
1456 TRACE(("imlib:getSpotLocation()\n")); | |
1457 | |
1458 if (nest == NEST_STATUS) { | |
1459 IMCancelRequest(conn, offset); | |
1460 IMSendError(conn, IMBadSomething, icp->im->id, icp->id, | |
1461 "spot location isn't a status attribute"); | |
1462 return -1; | |
1463 } | |
1464 | |
1465 if (!(ap->set_mask & ATTR_MASK_SPOT_LOCATION)) { | |
1466 fillPSDefault(icp, NEST_PREEDIT, | |
1467 (unsigned long)ATTR_MASK_SPOT_LOCATION); | |
1468 } | |
1469 | |
1470 IMPutC16(conn, id); /* attribute ID */ | |
1471 IMPutC16(conn, 4); /* value length */ | |
1472 IMPutI16(conn, ap->spot_location.x); | |
1473 IMPutI16(conn, ap->spot_location.y); | |
1474 return 0; | |
1475 } | |
1476 | |
1477 /* ARGSUSED */ | |
1478 static int | |
1479 getColormap(icp, id, nest, offset, data, len) | |
1480 IMIC *icp; | |
1481 unsigned int id; | |
1482 int nest; | |
1483 int offset; | |
1484 char *data; | |
1485 int len; | |
1486 { | |
1487 IMConnection *conn = icp->im->connection; | |
1488 IMPSAttributes *ap; | |
1489 | |
1490 TRACE(("imlib:getColormap()\n")); | |
1491 | |
1492 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1493 IMCancelRequest(conn, offset); | |
1494 unnestedError(icp); | |
1495 return -1; | |
1496 } | |
1497 | |
1498 if (!(ap->set_mask & ATTR_MASK_COLORMAP)) { | |
1499 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_COLORMAP); | |
1500 } | |
1501 | |
1502 IMPutC16(conn, id); /* attribute ID */ | |
1503 IMPutC16(conn, 4); /* value length */ | |
1504 IMPutC32(conn, ap->colormap); | |
1505 return 0; | |
1506 } | |
1507 | |
1508 /* ARGSUSED */ | |
1509 static int | |
1510 getStdColormap(icp, id, nest, offset, data, len) | |
1511 IMIC *icp; | |
1512 unsigned int id; | |
1513 int nest; | |
1514 int offset; | |
1515 char *data; | |
1516 int len; | |
1517 { | |
1518 IMConnection *conn = icp->im->connection; | |
1519 IMPSAttributes *ap; | |
1520 Atom colormap_name; | |
1521 | |
1522 TRACE(("imlib:getStdColormap()\n")); | |
1523 | |
1524 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1525 IMCancelRequest(conn, offset); | |
1526 unnestedError(icp); | |
1527 return -1; | |
1528 } | |
1529 | |
1530 if (ap->set_mask & ATTR_MASK_STD_COLORMAP) { | |
1531 colormap_name = ap->std_colormap; | |
1532 } else { | |
1533 /* what to do? */ | |
1534 colormap_name = None; | |
1535 DPRINT(("client asks standard colormap, but not specified\n")); | |
1536 } | |
1537 | |
1538 IMPutC16(conn, id); /* attribute ID */ | |
1539 IMPutC16(conn, 4); /* value length */ | |
1540 IMPutC32(conn, colormap_name); | |
1541 return 0; | |
1542 } | |
1543 | |
1544 /* ARGSUSED */ | |
1545 static int | |
1546 getForeground(icp, id, nest, offset, data, len) | |
1547 IMIC *icp; | |
1548 unsigned int id; | |
1549 int nest; | |
1550 int offset; | |
1551 char *data; | |
1552 int len; | |
1553 { | |
1554 IMConnection *conn = icp->im->connection; | |
1555 IMPSAttributes *ap; | |
1556 | |
1557 TRACE(("imlib:getForeground()\n")); | |
1558 | |
1559 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1560 IMCancelRequest(conn, offset); | |
1561 unnestedError(icp); | |
1562 return -1; | |
1563 } | |
1564 | |
1565 if (!(ap->set_mask & ATTR_MASK_FOREGROUND)) { | |
1566 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_FOREGROUND); | |
1567 } | |
1568 | |
1569 IMPutC16(conn, id); /* attribute ID */ | |
1570 IMPutC16(conn, 4); /* value length */ | |
1571 IMPutC32(conn, ap->foreground); | |
1572 return 0; | |
1573 } | |
1574 | |
1575 /* ARGSUSED */ | |
1576 static int | |
1577 getBackground(icp, id, nest, offset, data, len) | |
1578 IMIC *icp; | |
1579 unsigned int id; | |
1580 int nest; | |
1581 int offset; | |
1582 char *data; | |
1583 int len; | |
1584 { | |
1585 IMConnection *conn = icp->im->connection; | |
1586 IMPSAttributes *ap; | |
1587 | |
1588 TRACE(("imlib:getBackground()\n")); | |
1589 | |
1590 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1591 IMCancelRequest(conn, offset); | |
1592 unnestedError(icp); | |
1593 return -1; | |
1594 } | |
1595 | |
1596 if (!(ap->set_mask & ATTR_MASK_BACKGROUND)) { | |
1597 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_BACKGROUND); | |
1598 } | |
1599 | |
1600 IMPutC16(conn, id); /* attribute ID */ | |
1601 IMPutC16(conn, 4); /* value length */ | |
1602 IMPutC32(conn, ap->background); | |
1603 return 0; | |
1604 } | |
1605 | |
1606 /* ARGSUSED */ | |
1607 static int | |
1608 getBgPixmap(icp, id, nest, offset, data, len) | |
1609 IMIC *icp; | |
1610 unsigned int id; | |
1611 int nest; | |
1612 int offset; | |
1613 char *data; | |
1614 int len; | |
1615 { | |
1616 IMConnection *conn = icp->im->connection; | |
1617 IMPSAttributes *ap; | |
1618 | |
1619 TRACE(("imlib:getBgPixmap()\n")); | |
1620 | |
1621 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1622 IMCancelRequest(conn, offset); | |
1623 unnestedError(icp); | |
1624 return -1; | |
1625 } | |
1626 | |
1627 if (!(ap->set_mask & ATTR_MASK_BG_PIXMAP)) { | |
1628 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_BG_PIXMAP); | |
1629 } | |
1630 | |
1631 IMPutC16(conn, id); /* attribute ID */ | |
1632 IMPutC16(conn, 4); /* value length */ | |
1633 IMPutC32(conn, ap->bg_pixmap); | |
1634 return 0; | |
1635 } | |
1636 | |
1637 /* ARGSUSED */ | |
1638 static int | |
1639 getFontSet(icp, id, nest, offset, data, len) | |
1640 IMIC *icp; | |
1641 unsigned int id; | |
1642 int nest; | |
1643 int offset; | |
1644 char *data; | |
1645 int len; | |
1646 { | |
1647 IMConnection *conn = icp->im->connection; | |
1648 IMPSAttributes *ap; | |
1649 int name_len; | |
1650 | |
1651 TRACE(("imlib:getFontSet()\n")); | |
1652 | |
1653 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1654 IMCancelRequest(conn, offset); | |
1655 unnestedError(icp); | |
1656 return -1; | |
1657 } | |
1658 | |
1659 if (!(ap->set_mask & ATTR_MASK_FONT_SET)) { | |
1660 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_FONT_SET); | |
1661 } | |
1662 | |
1663 name_len = strlen(ap->font_set); | |
1664 | |
1665 IMPutC16(conn, id); /* attribute ID */ | |
1666 | |
1667 IMPutC16(conn, (unsigned int)name_len); /* value length */ | |
1668 IMPutString(conn, ap->font_set, name_len); | |
1669 IMPutPad(conn); | |
1670 return 0; | |
1671 } | |
1672 | |
1673 /* ARGSUSED */ | |
1674 static int | |
1675 getLineSpace(icp, id, nest, offset, data, len) | |
1676 IMIC *icp; | |
1677 unsigned int id; | |
1678 int nest; | |
1679 int offset; | |
1680 char *data; | |
1681 int len; | |
1682 { | |
1683 IMConnection *conn = icp->im->connection; | |
1684 IMPSAttributes *ap; | |
1685 | |
1686 TRACE(("imlib:getLineSpace()\n")); | |
1687 | |
1688 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1689 IMCancelRequest(conn, offset); | |
1690 unnestedError(icp); | |
1691 return -1; | |
1692 } | |
1693 | |
1694 if (!(ap->set_mask & ATTR_MASK_LINESPACE)) { | |
1695 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_LINESPACE); | |
1696 } | |
1697 | |
1698 IMPutC16(conn, id); /* attribute ID */ | |
1699 IMPutC16(conn, 4); /* value length */ | |
1700 IMPutC32(conn, (unsigned long)ap->line_space); | |
1701 return 0; | |
1702 } | |
1703 | |
1704 /* ARGSUSED */ | |
1705 static int | |
1706 getCursor(icp, id, nest, offset, data, len) | |
1707 IMIC *icp; | |
1708 unsigned int id; | |
1709 int nest; | |
1710 int offset; | |
1711 char *data; | |
1712 int len; | |
1713 { | |
1714 IMConnection *conn = icp->im->connection; | |
1715 IMPSAttributes *ap; | |
1716 | |
1717 TRACE(("imlib:getCursor()\n")); | |
1718 | |
1719 if ((ap = getPSPtr(icp, nest)) == NULL) { | |
1720 IMCancelRequest(conn, offset); | |
1721 unnestedError(icp); | |
1722 return -1; | |
1723 } | |
1724 | |
1725 if (!(ap->set_mask & ATTR_MASK_CURSOR)) { | |
1726 fillPSDefault(icp, nest, (unsigned long)ATTR_MASK_CURSOR); | |
1727 } | |
1728 | |
1729 IMPutC16(conn, id); /* attribute ID */ | |
1730 IMPutC16(conn, 4); /* value length */ | |
1731 IMPutC32(conn, ap->cursor); | |
1732 return 0; | |
1733 } | |
1734 | |
1735 /* ARGSUSED */ | |
1736 static int | |
1737 getPreeditState(icp, id, nest, offset, data, len) | |
1738 IMIC *icp; | |
1739 unsigned int id; | |
1740 int nest; | |
1741 int offset; | |
1742 char *data; | |
1743 int len; | |
1744 { | |
1745 IMConnection *conn = icp->im->connection; | |
1746 | |
1747 TRACE(("imlib:getPreeditState()\n")); | |
1748 | |
1749 if (nest == NEST_STATUS) { | |
1750 IMCancelRequest(conn, offset); | |
1751 IMSendError(conn, IMBadSomething, icp->im->id, icp->id, | |
1752 "preedit state isn't a status attribute"); | |
1753 return -1; | |
1754 } | |
1755 | |
1756 IMPutC16(conn, id); /* attribute ID */ | |
1757 IMPutC16(conn, 4); /* value length */ | |
1758 IMPutC32(conn, | |
1759 (icp->state & IC_CONVERTING) ? | |
1760 XIMPreeditEnable : XIMPreeditDisable); | |
1761 return 0; | |
1762 } | |
1763 | |
1764 /* ARGSUSED */ | |
1765 static int | |
1766 getResetState(icp, id, nest, offset, data, len) | |
1767 IMIC *icp; | |
1768 unsigned int id; | |
1769 int nest; | |
1770 int offset; | |
1771 char *data; | |
1772 int len; | |
1773 { | |
1774 IMConnection *conn = icp->im->connection; | |
1775 | |
1776 TRACE(("imlib:getResetState()\n")); | |
1777 | |
1778 IMPutC16(conn, id); /* attribute ID */ | |
1779 IMPutC16(conn, 4); /* value length */ | |
1780 IMPutC32(conn, icp->common_attr.reset_state); | |
1781 return 0; | |
1782 } | |
1783 | |
1784 static void | |
1785 changeFonts(icp, preedit) | |
1786 IMIC *icp; | |
1787 int preedit; | |
1788 { | |
1789 FontBank bank = IMFontBank(icp->im); | |
1790 String font_set; | |
1791 XFontStruct ***fontsp; | |
1792 int *num_fontsp; | |
1793 | |
1794 TRACE(("imlib:changeFonts()\n")); | |
1795 | |
1796 if (preedit) { | |
1797 font_set = icp->preedit_attr.font_set; | |
1798 fontsp = &icp->fonts; | |
1799 num_fontsp = &icp->num_fonts; | |
1800 } else { | |
1801 font_set = icp->status_attr.font_set; | |
1802 fontsp = &icp->status_fonts; | |
1803 num_fontsp = &icp->num_status_fonts; | |
1804 } | |
1805 | |
1806 /* | |
1807 * Unload previous fonts. | |
1808 */ | |
1809 if (*num_fontsp > 0) { | |
1810 FontBankFreeFonts(bank, *fontsp, *num_fontsp); | |
1811 } | |
1812 | |
1813 /* | |
1814 * Load new fonts and store them in the IC structure. | |
1815 */ | |
1816 *fontsp = FontBankGet(bank, font_set, num_fontsp); | |
1817 } | |
1818 | |
1819 | |
1820 /* | |
1821 * Functions computing default attribute values | |
1822 */ | |
1823 | |
1824 static void | |
1825 fillCommonDefault(icp, mask) | |
1826 IMIC *icp; | |
1827 unsigned long mask; | |
1828 { | |
1829 IMCommonAttributes *ap = &icp->common_attr; | |
1830 | |
1831 TRACE(("imlib:fillCommonDefault()\n")); | |
1832 | |
1833 /* | |
1834 * Don't bother with the attributes which have been set. | |
1835 */ | |
1836 mask &= ~ap->set_mask; | |
1837 | |
1838 /* | |
1839 * The attributes that have default value are FocusWindow, | |
1840 * PreeditState and ResetState. | |
1841 */ | |
1842 if (mask & ATTR_MASK_FOCUS) { | |
1843 /* if ClientWindow is not set... no way */ | |
1844 if (mask & ATTR_MASK_CLIENT) { | |
1845 ap->focus = ap->client; | |
1846 ap->set_mask |= ATTR_MASK_FOCUS; | |
1847 icp->focus_profile = icp->client_profile; | |
1848 TRACE(("\tdefault focus window: %08lx\n", ap->focus)); | |
1849 } | |
1850 } | |
1851 if (mask & ATTR_MASK_PREEDIT_STATE) { | |
1852 /* unless the client specified, we should start with disabled state. */ | |
1853 ap->set_mask |= ATTR_MASK_PREEDIT_STATE; | |
1854 ap->reset_state = XIMPreeditDisable; | |
1855 } | |
1856 if (mask & ATTR_MASK_RESET_STATE) { | |
1857 /* the default reset state must be the initial state. */ | |
1858 ap->set_mask |= ATTR_MASK_RESET_STATE; | |
1859 ap->reset_state = XIMInitialState; | |
1860 } | |
1861 } | |
1862 | |
1863 static int | |
1864 getNaturalLineSpace(icp, preedit) | |
1865 IMIC *icp; | |
1866 int preedit; | |
1867 { | |
1868 XFontStruct **fonts; | |
1869 int num_fonts; | |
1870 int max_ascent = 0, max_descent = 0; | |
1871 int i; | |
1872 | |
1873 changeFonts(icp, preedit); | |
1874 if (preedit) { | |
1875 fonts = icp->fonts; | |
1876 num_fonts = icp->num_fonts; | |
1877 } else { | |
1878 fonts = icp->status_fonts; | |
1879 num_fonts = icp->num_status_fonts; | |
1880 } | |
1881 | |
1882 for (i = 0; i < num_fonts; i++) { | |
1883 XFontStruct *font = fonts[i]; | |
1884 if (max_ascent < font->ascent) max_ascent = font->ascent; | |
1885 if (max_descent < font->descent) max_descent = font->descent; | |
1886 } | |
1887 | |
1888 if (max_ascent + max_descent < MIN_LINE_SPACING) { | |
1889 return MIN_LINE_SPACING; | |
1890 } else { | |
1891 return max_ascent + max_descent; | |
1892 } | |
1893 } | |
1894 | |
1895 static void | |
1896 fillPSDefault(icp, type, mask) | |
1897 IMIC *icp; | |
1898 int type; /* NEST_PREEDIT or NEST_STATUS */ | |
1899 unsigned long mask; | |
1900 { | |
1901 IMPSAttributes *ap; | |
1902 IMConnection *conn = icp->im->connection; | |
1903 Widget pw = conn->proto_widget; | |
1904 int preedit; | |
1905 #ifdef DEBUG | |
1906 char *typename = (type == NEST_PREEDIT) ? "preedit" : "status"; | |
1907 #endif | |
1908 | |
1909 TRACE(("imlib:fillPSDefault(%s)\n", typename)); | |
1910 | |
1911 preedit = (type == NEST_PREEDIT); | |
1912 ap = preedit ? &icp->preedit_attr : &icp->status_attr; | |
1913 | |
1914 /* | |
1915 * Don't bother with the attributes which have been set. | |
1916 * But area_needed needs to be computed each time (to get | |
1917 * correct X and Y coordinates). | |
1918 */ | |
1919 mask &= ~ap->set_mask | ATTR_MASK_AREA_NEEDED; | |
1920 | |
1921 if (mask & ATTR_MASK_AREA) { | |
1922 computeAreaForQuery(icp); | |
1923 ap->set_mask |= ATTR_MASK_AREA; | |
1924 DDPRINT(5, ("\tdefault %s area: %d,%d,%d,%d\n", typename, | |
1925 ap->area.x, ap->area.y, ap->area.width, ap->area.height)); | |
1926 } | |
1927 if (mask & ATTR_MASK_FOREGROUND) { | |
1928 ap->foreground = IMDefaultForeground(pw); | |
1929 ap->set_mask |= ATTR_MASK_FOREGROUND; | |
1930 DDPRINT(5, ("\tdefault %s foreground: %ld\n", | |
1931 typename, ap->foreground)); | |
1932 } | |
1933 if (mask & ATTR_MASK_BACKGROUND) { | |
1934 ap->background = IMDefaultBackground(pw); | |
1935 ap->set_mask |= ATTR_MASK_BACKGROUND; | |
1936 DDPRINT(5, ("\tdefault %s background: %ld\n", | |
1937 typename, ap->background)); | |
1938 } | |
1939 if (mask & ATTR_MASK_COLORMAP) { | |
1940 ap->colormap = pw->core.colormap; | |
1941 ap->set_mask |= ATTR_MASK_COLORMAP; | |
1942 DDPRINT(5, ("\tdefault %s colormap: %08lx\n", | |
1943 typename, ap->colormap)); | |
1944 } | |
1945 if (mask & ATTR_MASK_STD_COLORMAP) { | |
1946 /* you can't fill default. what to do? */ | |
1947 DDPRINT(5, ("\tdefault %s std colormap: N/A\n", typename)); | |
1948 } | |
1949 if (mask & ATTR_MASK_BG_PIXMAP) { | |
1950 ap->bg_pixmap = None; | |
1951 ap->set_mask |= ATTR_MASK_BG_PIXMAP; | |
1952 DDPRINT(5, ("\tdefault %s background pixmap: None\n", typename)); | |
1953 } | |
1954 if (mask & ATTR_MASK_LINESPACE) { | |
1955 if (!(ap->set_mask & ATTR_MASK_FONT_SET)) { | |
1956 fillPSDefault(icp, type, (unsigned long)ATTR_MASK_FONT_SET); | |
1957 } | |
1958 ap->line_space = getNaturalLineSpace(icp, type == NEST_PREEDIT); | |
1959 ap->set_mask |= ATTR_MASK_LINESPACE; | |
1960 DDPRINT(5, ("\tdefault line space: %d\n", ap->line_space)); | |
1961 } | |
1962 if (mask & ATTR_MASK_CURSOR) { | |
1963 ap->cursor = None; | |
1964 ap->set_mask |= ATTR_MASK_CURSOR; | |
1965 DDPRINT(5, ("\tdefault %s cursor: None\n", typename)); | |
1966 } | |
1967 if (mask & ATTR_MASK_AREA_NEEDED) { | |
1968 computeAreaNeeded(icp); | |
1969 DDPRINT(5, ("\t%s area_needed: %d,%d,%d,%d\n", typename, | |
1970 ap->area_needed.x, ap->area_needed.y, | |
1971 ap->area_needed.width, ap->area_needed.height)); | |
1972 } | |
1973 if (mask & ATTR_MASK_FONT_SET) { | |
1974 ap->font_set = IMDefaultFontSet(icp->im); | |
1975 ap->set_mask |= ATTR_MASK_FONT_SET; | |
1976 DDPRINT(5, ("\tdefault %s fontset: %s\n", typename, ap->font_set)); | |
1977 } | |
1978 if (mask & ATTR_MASK_SPOT_LOCATION) { | |
1979 ap->spot_location.x = ap->spot_location.y = 0; | |
1980 ap->set_mask |= ATTR_MASK_SPOT_LOCATION; | |
1981 DDPRINT(5, ("\tdefault spot location: %d, %d\n", | |
1982 ap->spot_location.x, ap->spot_location.y)); | |
1983 } | |
1984 } | |
1985 | |
1986 /* | |
1987 * Function validating attribute values | |
1988 */ | |
1989 | |
1990 static int | |
1991 validateCommonAttr(icp, checkonly) | |
1992 IMIC *icp; | |
1993 int checkonly; | |
1994 { | |
1995 IMCommonAttributes *ap = &icp->common_attr; | |
1996 IMConnection *conn = icp->im->connection; | |
1997 unsigned long mask = ap->change_mask; | |
1998 int ret = 0; | |
1999 | |
2000 TRACE(("imlib:validateCommonAttr()\n")); | |
2001 | |
2002 mask &= ap->set_mask; | |
2003 | |
2004 #define SENDERROR(code, msg) \ | |
2005 if (!checkonly && ret == 0) { \ | |
2006 IMSendError(conn, code, icp->im->id, icp->id, msg); ret = -1; \ | |
2007 } | |
2008 | |
2009 if (mask & ATTR_MASK_INPUT_STYLE) { | |
2010 XIMStyle xstyle = icp->common_attr.input_style; | |
2011 InputStyle *isp = styles; | |
2012 | |
2013 while (isp->xim_style != 0) { | |
2014 if (isp->xim_style == xstyle) break; | |
2015 isp++; | |
2016 } | |
2017 if (isp->xim_style == 0) { | |
2018 DPRINT(("unsupported input style\n")); | |
2019 ap->set_mask &= ~ATTR_MASK_INPUT_STYLE; | |
2020 SENDERROR(IMBadStyle, "unsupported input style"); | |
2021 } else { | |
2022 icp->style = isp->conversion_style; | |
2023 } | |
2024 } | |
2025 if (mask & ATTR_MASK_CLIENT) { | |
2026 if (!validateClientWindow(icp)) { | |
2027 DPRINT(("invalid client window ID\n")); | |
2028 ap->set_mask &= ~ATTR_MASK_CLIENT; | |
2029 SENDERROR(IMBadClientWindow, "invalid client window ID"); | |
2030 } | |
2031 } | |
2032 if (mask & ATTR_MASK_FOCUS) { | |
2033 if (!validateFocusWindow(icp)) { | |
2034 DPRINT(("invalid focus window ID\n")); | |
2035 ap->set_mask &= ~ATTR_MASK_FOCUS; | |
2036 SENDERROR(IMBadFocusWindow, "invalid focus window ID"); | |
2037 } | |
2038 } | |
2039 if (mask & ATTR_MASK_PREEDIT_STATE) { | |
2040 unsigned long preedit_state = ap->preedit_state; | |
2041 | |
2042 if (preedit_state != XIMPreeditEnable && | |
2043 preedit_state != XIMPreeditDisable) { | |
2044 DPRINT(("invalid preedit state\n")); | |
2045 ap->set_mask &= ~ATTR_MASK_PREEDIT_STATE; | |
2046 SENDERROR(IMBadSomething, "invalid preedit state"); | |
2047 } | |
2048 } | |
2049 if (mask & ATTR_MASK_RESET_STATE) { | |
2050 unsigned long reset_state = ap->reset_state; | |
2051 | |
2052 if (reset_state != XIMInitialState && | |
2053 reset_state != XIMPreserveState) { | |
2054 /* | |
2055 * Xlib document says invalid values should be interpreted as | |
2056 * XIMInitialState. | |
2057 */ | |
2058 DPRINT(("invalid reset state -- forcing initial state\n")); | |
2059 ap->reset_state = XIMInitialState; | |
2060 } | |
2061 } | |
2062 | |
2063 return ret; | |
2064 #undef SENDERROR | |
2065 } | |
2066 | |
2067 static int | |
2068 validatePSAttr(icp, type, checkonly) | |
2069 IMIC *icp; | |
2070 int type; | |
2071 int checkonly; | |
2072 { | |
2073 /* | |
2074 * Check validity of preedit/status attribute values. | |
2075 * 'type' is either NEST_PREEDIT or NEST_STATUS, indicating | |
2076 * whether preedit or status attributes are to be checked. | |
2077 * 'mask' is the attribute mask to be checked. | |
2078 * If all the attributes are valid, this function return 0. | |
2079 * Otherwise it issues an error message for the first invalid | |
2080 * value detected, and returns -1. | |
2081 */ | |
2082 IMPSAttributes *ap; | |
2083 IMConnection *conn = icp->im->connection; | |
2084 unsigned long mask; | |
2085 int preedit; | |
2086 int ret = 0; | |
2087 | |
2088 TRACE(("imlib:validatePSAttr()\n")); | |
2089 | |
2090 preedit = (type == NEST_PREEDIT); | |
2091 ap = preedit ? &icp->preedit_attr : &icp->status_attr; | |
2092 | |
2093 /* do not check unset attributes */ | |
2094 mask = ap->change_mask & ap->set_mask; | |
2095 | |
2096 #define SENDERROR(code, msg) \ | |
2097 if (!checkonly && ret == 0) { \ | |
2098 IMSendError(conn, code, icp->im->id, icp->id, msg); ret = -1; \ | |
2099 } | |
2100 | |
2101 if (mask & ATTR_MASK_AREA) { | |
2102 if (ap->area.width == 0 || ap->area.height == 0) { | |
2103 ap->set_mask &= ~ATTR_MASK_AREA; | |
2104 DPRINT(("zero area width/height\n")); | |
2105 SENDERROR(IMBadArea, "invalid area width/height"); | |
2106 } | |
2107 } | |
2108 | |
2109 #ifdef notdef | |
2110 if (mask & ATTR_MASK_COLORMAP) { | |
2111 } | |
2112 | |
2113 if (mask & ATTR_MASK_BG_PIXMAP) { | |
2114 } | |
2115 #endif | |
2116 | |
2117 if (mask & ATTR_MASK_LINESPACE) { | |
2118 if (ap->line_space < MIN_LINE_SPACING) { | |
2119 ap->set_mask &= ~ATTR_MASK_LINESPACE; | |
2120 /* | |
2121 * we don't send error message in this case, because | |
2122 * there exist some applications which send invalid line | |
2123 * spacing and we don't want to break them. | |
2124 */ | |
2125 DPRINT(("line space too small %d\n", ap->line_space)); | |
2126 } | |
2127 } | |
2128 | |
2129 #ifdef notdef | |
2130 if (mask & ATTR_MASK_CURSOR) { | |
2131 /* How should we check it? */ | |
2132 } | |
2133 #endif | |
2134 | |
2135 if (mask & ATTR_MASK_AREA_NEEDED) { | |
2136 } | |
2137 #ifdef notdef | |
2138 if (mask & ATTR_MASK_FONT_SET) { | |
2139 } | |
2140 if (mask & ATTR_MASK_SPOT_LOCATION) { | |
2141 } | |
2142 #endif | |
2143 | |
2144 return ret; | |
2145 #undef SENDERROR | |
2146 } | |
2147 | |
2148 | |
2149 /* | |
2150 * Functions to extract necessary attributes and make conversion argument | |
2151 */ | |
2152 | |
2153 static void | |
2154 changeConversionAttributes(icp) | |
2155 IMIC *icp; | |
2156 { | |
2157 unsigned long mask; | |
2158 ConversionAttributes attr; | |
2159 | |
2160 TRACE(("imlib:changeConversionAttributes()\n")); | |
2161 mask = IMMakeConvAttributes(icp, &attr); | |
2162 CControlChangeAttributes(icp->conversion, mask, &attr); | |
2163 } | |
2164 | |
2165 static void | |
2166 computeAreaNeeded(icp) | |
2167 IMIC *icp; | |
2168 { | |
2169 IMPSAttributes *pattr = &icp->preedit_attr; | |
2170 IMPSAttributes *sattr = &icp->status_attr; | |
2171 IMWindowProfile *cpr = &icp->client_profile; | |
2172 int width, height; | |
2173 int min_width, min_height; | |
2174 int default_status_width; | |
2175 int font_height; | |
2176 | |
2177 TRACE(("computeAreaNeeded()\n")); | |
2178 | |
2179 if (icp->style == IMSTYLE_SEPARATE) return; | |
2180 | |
2181 /* | |
2182 * Get the current dimension of the client window. | |
2183 */ | |
2184 (void)validateClientWindow(icp); | |
2185 | |
2186 /* | |
2187 * Compute the dimensions of the status region. | |
2188 */ | |
2189 fillPSDefault(icp, NEST_STATUS, (unsigned long)ATTR_MASK_LINESPACE); | |
2190 font_height = sattr->line_space + 2; | |
2191 width = height = 0; | |
2192 if (sattr->set_mask & ATTR_MASK_AREA_NEEDED) { | |
2193 width = sattr->area_needed.width; | |
2194 height = sattr->area_needed.height; | |
2195 TRACE(("\tstatus areaNeeded was: (%d,%d)\n", width, height)); | |
2196 } | |
2197 | |
2198 min_width = font_height * 3; | |
2199 min_height = font_height; | |
2200 if (min_width < MIN_AREA_WIDTH) min_width = MIN_AREA_WIDTH; | |
2201 if (min_height < MIN_AREA_HEIGHT) min_height = MIN_AREA_HEIGHT; | |
2202 | |
2203 if (width == 0) { | |
2204 default_status_width = | |
2205 IMStatusWidth(icp->im->connection->proto_widget); | |
2206 if (default_status_width > 0) { | |
2207 width = default_status_width; | |
2208 } else { | |
2209 width = cpr->width / 5; /* wild guess */ | |
2210 } | |
2211 } | |
2212 | |
2213 if (width < min_width) width = min_width; | |
2214 if (height < min_height) height = min_height; | |
2215 | |
2216 sattr->area_needed.x = 0; | |
2217 sattr->area_needed.y = cpr->height - height; | |
2218 sattr->area_needed.width = width; | |
2219 sattr->area_needed.height = height; | |
2220 TRACE(("\tstatus areaNeeded is now: (%d, %d, %d, %d)\n", | |
2221 sattr->area_needed.x, sattr->area_needed.y, width, height)); | |
2222 | |
2223 /* | |
2224 * Compute the dimensions of the pre-edit region. | |
2225 */ | |
2226 if (icp->style != IMSTYLE_OFF_THE_SPOT) return; | |
2227 | |
2228 fillPSDefault(icp, NEST_PREEDIT, (unsigned long)ATTR_MASK_LINESPACE); | |
2229 font_height = pattr->line_space + 2; | |
2230 width = height = 0; | |
2231 if (pattr->set_mask & ATTR_MASK_AREA_NEEDED) { | |
2232 width = pattr->area_needed.width; | |
2233 height = pattr->area_needed.height; | |
2234 TRACE(("\tpreedit areaNeeded was: (%d,%d)\n", | |
2235 width, height)); | |
2236 } | |
2237 | |
2238 min_width = (cpr->width - sattr->area_needed.width) / 2; | |
2239 min_height = font_height; | |
2240 if (min_width < MIN_AREA_WIDTH) min_width = MIN_AREA_WIDTH; | |
2241 if (min_height < MIN_AREA_HEIGHT) min_height = MIN_AREA_HEIGHT; | |
2242 | |
2243 if (width < min_width) width = min_width; | |
2244 if (height < min_height) height = min_height; | |
2245 | |
2246 pattr->area_needed.x = sattr->area_needed.width; | |
2247 pattr->area_needed.y = cpr->height - height; | |
2248 pattr->area_needed.width = width; | |
2249 pattr->area_needed.height = height; | |
2250 TRACE(("\tpreedit areaNeeded is now: (%d, %d, %d, %d)\n", | |
2251 pattr->area_needed.x, pattr->area_needed.y, width, height)); | |
2252 } | |
2253 | |
2254 static void | |
2255 computeAreaForQuery(icp) | |
2256 IMIC *icp; | |
2257 { | |
2258 IMPSAttributes *pattr = &icp->preedit_attr; | |
2259 IMPSAttributes *sattr = &icp->status_attr; | |
2260 | |
2261 TRACE(("computeAreaForQuery()\n")); | |
2262 | |
2263 if (icp->style == IMSTYLE_SEPARATE) return; | |
2264 | |
2265 computeAreaNeeded(icp); | |
2266 | |
2267 if (!(pattr->set_mask & ATTR_MASK_AREA)) { | |
2268 if (icp->style == IMSTYLE_OVER_THE_SPOT) { | |
2269 IMWindowProfile *fpr = &icp->focus_profile; | |
2270 | |
2271 pattr->area.x = 0; | |
2272 pattr->area.y = 0; | |
2273 pattr->area.width = fpr->width; | |
2274 pattr->area.height = fpr->height; | |
2275 } else { /* IMSTYLE_OFF_THE_SPOT */ | |
2276 pattr->area = pattr->area_needed; | |
2277 } | |
2278 } | |
2279 | |
2280 if (!(sattr->set_mask & ATTR_MASK_AREA)) { | |
2281 sattr->area = sattr->area_needed; | |
2282 } | |
2283 } | |
2284 | |
2285 | |
2286 /* | |
2287 * Public functions | |
2288 */ | |
2289 | |
2290 /*- IMPutIMAttrList: write list of supported IM attributes to output buffer -*/ | |
2291 void | |
2292 IMPutIMAttrList(imp) | |
2293 IMIM *imp; | |
2294 { | |
2295 IMConnection *conn = imp->connection; | |
2296 IMAttribute *iap; | |
2297 int offset, list_start, list_end; | |
2298 int n; | |
2299 | |
2300 TRACE(("IMPutIMAttrList()\n")); | |
2301 | |
2302 offset = IMWritePos(conn); | |
2303 IMPutC16(conn, 0); /* dummy. overwritten afterwards */ | |
2304 | |
2305 list_start = IMWritePos(conn); | |
2306 for (n = 0, iap = imAttributes; n < numImAttributes; n++, iap++) { | |
2307 int length; | |
2308 | |
2309 IMPutC16(conn, (unsigned int)n); | |
2310 IMPutC16(conn, (unsigned int)iap->type); | |
2311 length = strlen(iap->name); | |
2312 IMPutC16(conn, (unsigned int)length); | |
2313 IMPutString(conn, iap->name, length); | |
2314 IMPutPad(conn); | |
2315 } | |
2316 list_end = IMWritePos(conn); | |
2317 IMRewriteC16(conn, offset, (unsigned int)(list_end - list_start)); | |
2318 } | |
2319 | |
2320 /*- IMPutICAttrList: write list of supported IC attributes to output buffer -*/ | |
2321 void | |
2322 IMPutICAttrList(imp) | |
2323 IMIM *imp; | |
2324 { | |
2325 IMConnection *conn = imp->connection; | |
2326 ICAttribute *iap; | |
2327 int offset, list_start, list_end; | |
2328 int n; | |
2329 | |
2330 TRACE(("IMPutICAttrList()\n")); | |
2331 | |
2332 offset = IMWritePos(conn); | |
2333 IMPutC16(conn, 0); /* dummy. overwritten afterwards */ | |
2334 IMPutC16(conn, 0); /* unused */ | |
2335 | |
2336 list_start = IMWritePos(conn); | |
2337 for (n = 0, iap = icAttributes; n < numIcAttributes; n++, iap++) { | |
2338 int length; | |
2339 | |
2340 IMPutC16(conn, (unsigned int)n); | |
2341 IMPutC16(conn, (unsigned int)iap->type); | |
2342 length = strlen(iap->name); | |
2343 IMPutC16(conn, (unsigned int)length); | |
2344 IMPutString(conn, iap->name, length); | |
2345 IMPutPad(conn); | |
2346 } | |
2347 list_end = IMWritePos(conn); | |
2348 IMRewriteC16(conn, offset, (unsigned int)(list_end - list_start)); | |
2349 } | |
2350 | |
2351 /* ARGSUSED */ | |
2352 int | |
2353 IMSetIMValues(imp, data, len, major) | |
2354 IMIM *imp; | |
2355 char *data; | |
2356 int len; | |
2357 int major; | |
2358 { | |
2359 TRACE(("IMSetIMValues(): not supported yet\n")); | |
2360 /* not supported yet */ | |
2361 | |
2362 IMSendError(imp->connection, IMBadProtocol, imp->id, 0, | |
2363 "this protocol is not supported yet"); | |
2364 return -1; | |
2365 } | |
2366 | |
2367 int | |
2368 IMGetIMValues(imp, data, len, offset) | |
2369 IMIM *imp; | |
2370 char *data; | |
2371 int len; | |
2372 int offset; /* request offset */ | |
2373 { | |
2374 IMConnection *conn = imp->connection; | |
2375 int pos, list_start, list_end; | |
2376 | |
2377 TRACE(("IMGetIMValues()\n")); | |
2378 | |
2379 pos = IMWritePos(conn); | |
2380 IMPutC16(conn, 0); /* length of the list. to be overwritten. */ | |
2381 | |
2382 list_start = IMWritePos(conn); | |
2383 | |
2384 if (getIMValues(imp, data, len, offset) < 0) return -1; | |
2385 | |
2386 list_end = IMWritePos(conn); | |
2387 IMRewriteC16(conn, pos, (unsigned int)(list_end - list_start)); | |
2388 return 0; | |
2389 } | |
2390 | |
2391 int | |
2392 IMSetICValues(icp, data, len, major) | |
2393 IMIC *icp; | |
2394 char *data; | |
2395 int len; | |
2396 int major; | |
2397 { | |
2398 int r1, r2, r3; | |
2399 | |
2400 TRACE(("IMSetICValues()\n")); | |
2401 | |
2402 /* clear change mask */ | |
2403 icp->common_attr.change_mask = 0; | |
2404 icp->preedit_attr.change_mask = 0; | |
2405 icp->status_attr.change_mask = 0; | |
2406 | |
2407 /* read the specified data and set attributes */ | |
2408 r1 = setICValues(icp, data, len, 0, | |
2409 (major == XIM_CREATE_IC) ? OP_C : OP_S); | |
2410 | |
2411 /* validate attributes */ | |
2412 r2 = IMValidateICAttributes(icp, (r1 < 0)); | |
2413 | |
2414 /* | |
2415 * If the operation is CREATE_IC, input style attribute must be set. | |
2416 */ | |
2417 if (major == XIM_CREATE_IC && | |
2418 !(icp->common_attr.set_mask & ATTR_MASK_INPUT_STYLE) && | |
2419 r1 == 0 && r2 == 0) { | |
2420 DPRINT(("input style not specified by CreateIC\n")); | |
2421 IMSendError(icp->im->connection, IMBadSomething, icp->im->id, icp->id, | |
2422 "inputStyle resource must be set"); | |
2423 r3 = -1; | |
2424 } else { | |
2425 r3 = 0; | |
2426 } | |
2427 | |
2428 if (r1 == 0 && r2 == 0) { | |
2429 /* if conversion is taking place... */ | |
2430 if (icp->state & IC_CONVERTING) { | |
2431 changeConversionAttributes(icp); | |
2432 } | |
2433 | |
2434 /* if preedit state is specified... */ | |
2435 if (icp->common_attr.change_mask & ATTR_MASK_PREEDIT_STATE) { | |
2436 TRACE(("changing preedit state to %s\n", | |
2437 (icp->common_attr.preedit_state == XIMPreeditEnable) ? | |
2438 "enabled" : "disabled")); | |
2439 if (icp->common_attr.preedit_state == XIMPreeditEnable) { | |
2440 IMStartConversion(icp); | |
2441 } else { | |
2442 IMStopConversion(icp); | |
2443 } | |
2444 } | |
2445 } | |
2446 | |
2447 return (r1 < 0 || r2 < 0 || r3 < 0) ? -1 : 0; | |
2448 } | |
2449 | |
2450 int | |
2451 IMGetICValues(icp, data, len, offset) | |
2452 IMIC *icp; | |
2453 char *data; | |
2454 int len; | |
2455 int offset; /* request offset */ | |
2456 { | |
2457 int nested_separator; | |
2458 int r; | |
2459 IMConnection *conn = icp->im->connection; | |
2460 int pos, list_start, list_end; | |
2461 | |
2462 TRACE(("IMGetICValues()\n")); | |
2463 | |
2464 pos = IMWritePos(conn); | |
2465 IMPutC16(conn, 0); /* dummy. overwritten afterwards */ | |
2466 IMPutC16(conn, 0); /* unused */ | |
2467 | |
2468 list_start = IMWritePos(conn); | |
2469 | |
2470 r = getICValues(icp, data, len, NEST_NONE, offset, &nested_separator); | |
2471 if (r < 0) return -1; | |
2472 | |
2473 list_end = IMWritePos(conn); | |
2474 IMRewriteC16(conn, pos, (unsigned int)(list_end - list_start)); | |
2475 | |
2476 if (nested_separator) { | |
2477 /* | |
2478 * There must have been some unbalanced NestedListSeparator. | |
2479 */ | |
2480 DPRINT(("getICvalues: unmatched separator\n")); | |
2481 IMCancelRequest(icp->im->connection, offset); | |
2482 IMSendError(icp->im->connection, IMBadSomething, icp->im->id, icp->id, | |
2483 "corrupted nested list"); | |
2484 return -1; | |
2485 } | |
2486 return 0; | |
2487 } | |
2488 | |
2489 void | |
2490 IMFillDefault(icp, common_mask, preedit_mask, status_mask) | |
2491 IMIC *icp; | |
2492 unsigned long common_mask; | |
2493 unsigned long preedit_mask; | |
2494 unsigned long status_mask; | |
2495 { | |
2496 TRACE(("IMFillDefault()\n")); | |
2497 | |
2498 if (common_mask != 0) fillCommonDefault(icp, common_mask); | |
2499 if (preedit_mask != 0) fillPSDefault(icp, NEST_PREEDIT, preedit_mask); | |
2500 if (status_mask != 0) fillPSDefault(icp, NEST_STATUS, status_mask); | |
2501 } | |
2502 | |
2503 int | |
2504 IMValidateWindow(dpy, win, profilep) | |
2505 Display *dpy; | |
2506 Window win; | |
2507 IMWindowProfile *profilep; | |
2508 { | |
2509 Window root; | |
2510 int x, y; | |
2511 unsigned int width, height, border, depth; | |
2512 XAEHandle h; | |
2513 int s; | |
2514 | |
2515 TRACE(("IMValidateWindow(win: %08lx)\n", win)); | |
2516 | |
2517 h = XAESetIgnoreErrors(dpy); | |
2518 s = XGetGeometry(dpy, win, &root, &x, &y, | |
2519 &width, &height, &border, &depth); | |
2520 XAEUnset(h); | |
2521 | |
2522 if (profilep != NULL && s) { | |
2523 profilep->width = width; | |
2524 profilep->height = width; | |
2525 profilep->root = root; | |
2526 } | |
2527 return s; | |
2528 } | |
2529 | |
2530 int | |
2531 IMValidateICAttributes(icp, checkonly) | |
2532 IMIC *icp; | |
2533 int checkonly; | |
2534 { | |
2535 int error_occured; | |
2536 int r; | |
2537 | |
2538 TRACE(("IMValidateICAttributes()\n")); | |
2539 | |
2540 /* | |
2541 * Be careful not to send multiple error messages. | |
2542 */ | |
2543 | |
2544 error_occured = 0; | |
2545 | |
2546 r = validateCommonAttr(icp, checkonly); | |
2547 if (r < 0) error_occured = 1; | |
2548 | |
2549 r = validatePSAttr(icp, NEST_PREEDIT, (checkonly && error_occured)); | |
2550 if (r < 0) error_occured = 1; | |
2551 | |
2552 r = validatePSAttr(icp, NEST_STATUS, (checkonly && error_occured)); | |
2553 if (r < 0) error_occured = 1; | |
2554 | |
2555 return error_occured ? -1 : 0; | |
2556 } | |
2557 | |
2558 void | |
2559 IMFreeICAttributes(icp) | |
2560 IMIC *icp; | |
2561 { | |
2562 IMPSAttributes *pattr = &icp->preedit_attr; | |
2563 IMPSAttributes *sattr = &icp->status_attr; | |
2564 FontBank bank = IMFontBank(icp->im); | |
2565 | |
2566 TRACE(("IMFreeICAttributes()\n")); | |
2567 | |
2568 if (pattr->set_mask & ATTR_MASK_FONT_SET) XtFree(pattr->font_set); | |
2569 if (sattr->set_mask & ATTR_MASK_FONT_SET) XtFree(sattr->font_set); | |
2570 | |
2571 if (icp->num_fonts > 0) { | |
2572 FontBankFreeFonts(bank, icp->fonts, icp->num_fonts); | |
2573 } | |
2574 if (icp->num_status_fonts > 0) { | |
2575 FontBankFreeFonts(bank, icp->status_fonts, icp->num_status_fonts); | |
2576 } | |
2577 } | |
2578 | |
2579 unsigned long | |
2580 IMMakeConvAttributes(icp, attr) | |
2581 IMIC *icp; | |
2582 ConversionAttributes *attr; | |
2583 { | |
2584 IMCommonAttributes *cattr; | |
2585 IMPSAttributes *pattr, *sattr; | |
2586 unsigned long cmask; /* changed attributes */ | |
2587 unsigned long mask; /* attributes to be set */ | |
2588 | |
2589 TRACE(("IMMakeConvAttributes()\n")); | |
2590 mask = 0L; | |
2591 | |
2592 cattr = &icp->common_attr; | |
2593 pattr = &icp->preedit_attr; | |
2594 sattr = &icp->status_attr; | |
2595 | |
2596 /* | |
2597 * Check changes of common attributes. | |
2598 */ | |
2599 cmask = cattr->change_mask; | |
2600 | |
2601 /* focus window */ | |
2602 if (cmask & ATTR_MASK_FOCUS) { | |
2603 attr->focuswindow = cattr->focus; | |
2604 mask |= CAFocusWindow; | |
2605 } | |
2606 | |
2607 /* | |
2608 * Check changes of preedit attributes. | |
2609 */ | |
2610 cmask = pattr->change_mask; | |
2611 | |
2612 /* client area */ | |
2613 if (cmask & ATTR_MASK_AREA) { | |
2614 attr->clientarea.x = pattr->area.x; | |
2615 attr->clientarea.y = pattr->area.y; | |
2616 attr->clientarea.width = pattr->area.width; | |
2617 attr->clientarea.height = pattr->area.height; | |
2618 mask |= CAClientArea; | |
2619 } | |
2620 | |
2621 /* foreground/background */ | |
2622 if (cmask & ATTR_MASK_FOREGROUND) { | |
2623 attr->foreground = pattr->foreground; | |
2624 mask |= CAColor; | |
2625 } | |
2626 if (cmask & ATTR_MASK_BACKGROUND) { | |
2627 attr->background = pattr->background; | |
2628 mask |= CAColor; | |
2629 } | |
2630 | |
2631 /* colormap */ | |
2632 if (cmask & ATTR_MASK_COLORMAP) { | |
2633 attr->colormap = pattr->colormap; | |
2634 mask |= CAColormap; | |
2635 } | |
2636 | |
2637 /* background pixmap */ | |
2638 if (cmask & ATTR_MASK_BG_PIXMAP) { | |
2639 attr->background_pixmap = pattr->bg_pixmap; | |
2640 mask |= CABackgroundPixmap; | |
2641 } | |
2642 | |
2643 /* line spacing */ | |
2644 if (cmask & ATTR_MASK_LINESPACE) { | |
2645 attr->linespacing = pattr->line_space; | |
2646 mask |= CALineSpacing; | |
2647 } | |
2648 | |
2649 /* cursor */ | |
2650 if (cmask & ATTR_MASK_CURSOR) { | |
2651 attr->cursor = pattr->cursor; | |
2652 mask |= CACursor; | |
2653 } | |
2654 | |
2655 /* font */ | |
2656 if (cmask & ATTR_MASK_FONT_SET) { | |
2657 changeFonts(icp, 1); | |
2658 attr->fonts = icp->fonts; | |
2659 attr->num_fonts = icp->num_fonts; | |
2660 mask |= CAFonts; | |
2661 } | |
2662 | |
2663 /* spot location */ | |
2664 if ((cmask & ATTR_MASK_SPOT_LOCATION) && | |
2665 icp->style == IMSTYLE_OVER_THE_SPOT) { | |
2666 attr->spotx = pattr->spot_location.x; | |
2667 attr->spoty = pattr->spot_location.y; | |
2668 mask |= CASpotLocation; | |
2669 } | |
2670 | |
2671 /* | |
2672 * Check changes of status attributes. | |
2673 */ | |
2674 cmask = sattr->change_mask; | |
2675 | |
2676 /* status area */ | |
2677 if (cmask & ATTR_MASK_AREA) { | |
2678 attr->statusarea.x = sattr->area.x; | |
2679 attr->statusarea.y = sattr->area.y; | |
2680 attr->statusarea.width = sattr->area.width; | |
2681 attr->statusarea.height = sattr->area.height; | |
2682 mask |= CAStatusArea; | |
2683 } | |
2684 | |
2685 /* font */ | |
2686 if (cmask & ATTR_MASK_FONT_SET) { | |
2687 changeFonts(icp, 0); | |
2688 attr->status_fonts = icp->status_fonts; | |
2689 attr->num_status_fonts = icp->num_status_fonts; | |
2690 mask |= CAStatusFonts; | |
2691 } | |
2692 | |
2693 return mask; | |
2694 } | |
2695 | |
2696 void | |
2697 IMMoveLocation(icp, x, y) | |
2698 IMIC *icp; | |
2699 int x; | |
2700 int y; | |
2701 { | |
2702 TRACE(("IMMoveLocation()\n")); | |
2703 | |
2704 icp->preedit_attr.spot_location.x = x; | |
2705 icp->preedit_attr.spot_location.y = y; | |
2706 icp->preedit_attr.set_mask |= ATTR_MASK_SPOT_LOCATION; | |
2707 icp->preedit_attr.change_mask = ATTR_MASK_SPOT_LOCATION; | |
2708 if (icp->state & IC_CONVERTING) { | |
2709 changeConversionAttributes(icp); | |
2710 } | |
2711 } |