imDefIc.c revision eb411b4b
1/* 2 * Copyright 1991, 1992 Oracle and/or its affiliates. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23/****************************************************************** 24 25 Copyright 1992, 1993, 1994 by FUJITSU LIMITED 26 27Permission to use, copy, modify, distribute, and sell this software 28and its documentation for any purpose is hereby granted without fee, 29provided that the above copyright notice appear in all copies and 30that both that copyright notice and this permission notice appear 31in supporting documentation, and that the name of FUJITSU LIMITED 32not be used in advertising or publicity pertaining to distribution 33of the software without specific, written prior permission. 34FUJITSU LIMITED makes no representations about the suitability of 35this software for any purpose. 36It is provided "as is" without express or implied warranty. 37 38FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 39INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 40EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR 41CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 42USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 43OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 44PERFORMANCE OF THIS SOFTWARE. 45 46 Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. 47 Takashi Fujiwara FUJITSU LIMITED 48 fujiwara@a80.tech.yk.fujitsu.co.jp 49 50******************************************************************/ 51 52#ifdef HAVE_CONFIG_H 53#include <config.h> 54#endif 55#include "Xlibint.h" 56#include "Xlcint.h" 57#include "Ximint.h" 58 59static Bool 60_XimCreateICCheck( 61 Xim im, 62 INT16 len, 63 XPointer data, 64 XPointer arg) 65{ 66 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 67 CARD8 major_opcode = *((CARD8 *)data); 68 CARD8 minor_opcode = *((CARD8 *)data + 1); 69 XIMID imid = buf_s[0]; 70 71 if ((major_opcode == XIM_CREATE_IC_REPLY) 72 && (minor_opcode == 0) 73 && (imid == im->private.proto.imid)) 74 return True; 75 if ((major_opcode == XIM_ERROR) 76 && (minor_opcode == 0) 77 && (buf_s[2] & XIM_IMID_VALID) 78 && (imid == im->private.proto.imid)) 79 return True; 80 return False; 81} 82 83#ifdef XIM_CONNECTABLE 84Bool 85_XimReCreateIC(ic) 86 Xic ic; 87{ 88 Xim im = (Xim)ic->core.im; 89 Xic save_ic; 90 XIMResourceList res; 91 unsigned int num; 92 XIMStyle input_style = ic->core.input_style; 93 XimDefICValues ic_values; 94 INT16 len; 95 CARD16 *buf_s; 96 char *tmp; 97 CARD32 tmp_buf32[BUFSIZE/4]; 98 char *tmp_buf = (char *)tmp_buf32; 99 char *buf; 100 int buf_size; 101 char *data; 102 int data_len; 103 int ret_len; 104 int total; 105 int idx; 106 CARD32 reply32[BUFSIZE/4]; 107 char *reply = (char *)reply32; 108 XPointer preply; 109 int ret_code; 110 111 if (!(save_ic = (Xic)Xmalloc(sizeof(XicRec)))) 112 return False; 113 memcpy((char *)save_ic, (char *)ic, sizeof(XicRec)); 114 115 ic->core.filter_events = im->private.proto.forward_event_mask; 116 ic->private.proto.forward_event_mask = 117 im->private.proto.forward_event_mask; 118 ic->private.proto.synchronous_event_mask = 119 im->private.proto.synchronous_event_mask; 120 121 num = im->core.ic_num_resources; 122 buf_size = sizeof(XIMResource) * num; 123 if (!(res = (XIMResourceList)Xmalloc(buf_size))) 124 goto ErrorOnReCreateIC; 125 (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size); 126 ic->private.proto.ic_resources = res; 127 ic->private.proto.ic_num_resources = num; 128 129 num = im->private.proto.ic_num_inner_resources; 130 buf_size = sizeof(XIMResource) * num; 131 if (!(res = (XIMResourceList)Xmalloc(buf_size))) 132 goto ErrorOnReCreateIC; 133 (void)memcpy((char *)res, 134 (char *)im->private.proto.ic_inner_resources, buf_size); 135 ic->private.proto.ic_inner_resources = res; 136 ic->private.proto.ic_num_inner_resources = num; 137 138 _XimSetICMode(ic->private.proto.ic_resources, 139 ic->private.proto.ic_num_resources, input_style); 140 141 _XimSetICMode(ic->private.proto.ic_inner_resources, 142 ic->private.proto.ic_num_inner_resources, input_style); 143 144 _XimGetCurrentICValues(ic, &ic_values); 145 buf = tmp_buf; 146 buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); 147 data_len = BUFSIZE - buf_size; 148 total = 0; 149 idx = 0; 150 for (;;) { 151 data = &buf[buf_size]; 152 if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources, 153 ic->private.proto.ic_num_resources, &idx, data, data_len, 154 &ret_len, (XPointer)&ic_values, XIM_CREATEIC)) { 155 if (buf != tmp_buf) 156 Xfree(buf); 157 goto ErrorOnReCreateIC; 158 } 159 160 total += ret_len; 161 if (idx == -1) { 162 break; 163 } 164 165 buf_size += ret_len; 166 if (buf == tmp_buf) { 167 if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { 168 goto ErrorOnReCreateIC; 169 } 170 memcpy(tmp, buf, buf_size); 171 buf = tmp; 172 } else { 173 if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { 174 Xfree(buf); 175 goto ErrorOnReCreateIC; 176 } 177 buf = tmp; 178 } 179 } 180 181 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 182 buf_s[0] = im->private.proto.imid; 183 buf_s[1] = (INT16)total; 184 185 len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); 186 _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len); 187 if (!(_XimWrite(im, len, (XPointer)buf))) { 188 if (buf != tmp_buf) 189 Xfree(buf); 190 goto ErrorOnReCreateIC; 191 } 192 _XimFlush(im); 193 if (buf != tmp_buf) 194 Xfree(buf); 195 ic->private.proto.waitCallback = True; 196 buf_size = BUFSIZE; 197 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 198 _XimCreateICCheck, 0); 199 if (ret_code == XIM_TRUE) { 200 preply = reply; 201 } else if (ret_code == XIM_OVERFLOW) { 202 if (len <= 0) { 203 preply = reply; 204 } else { 205 buf_size = (int)len; 206 preply = (XPointer)Xmalloc(buf_size); 207 ret_code = _XimRead(im, &len, preply, buf_size, 208 _XimCreateICCheck, 0); 209 if (ret_code != XIM_TRUE) { 210 Xfree(preply); 211 ic->private.proto.waitCallback = False; 212 goto ErrorOnReCreateIC; 213 } 214 } 215 } else { 216 ic->private.proto.waitCallback = False; 217 goto ErrorOnReCreateIC; 218 } 219 ic->private.proto.waitCallback = False; 220 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 221 if (*((CARD8 *)preply) == XIM_ERROR) { 222 _XimProcError(im, 0, (XPointer)&buf_s[3]); 223 if (reply != preply) 224 Xfree(preply); 225 goto ErrorOnReCreateIC; 226 } 227 228 ic->private.proto.icid = buf_s[1]; /* icid */ 229 if (reply != preply) 230 Xfree(preply); 231 232 _XimRegisterFilter(ic); 233 MARK_IC_CONNECTED(ic); 234 if (save_ic->private.proto.ic_resources) 235 Xfree(save_ic->private.proto.ic_resources); 236 if (save_ic->private.proto.ic_inner_resources) 237 Xfree(save_ic->private.proto.ic_inner_resources); 238 Xfree(save_ic); 239 return True; 240 241ErrorOnReCreateIC: 242 memcpy((char *)ic, (char *)save_ic, sizeof(XicRec)); 243 Xfree(save_ic); 244 return False; 245} 246 247static char * 248_XimDelayModeGetICValues(ic, arg) 249 Xic ic; 250 XIMArg *arg; 251{ 252 XimDefICValues ic_values; 253 254 _XimGetCurrentICValues(ic, &ic_values); 255 return _XimGetICValueData(ic, (XPointer)&ic_values, 256 ic->private.proto.ic_resources, 257 ic->private.proto.ic_num_resources, 258 arg, XIM_GETICVALUES); 259} 260#endif /* XIM_CONNECTABLE */ 261 262static Bool 263_XimGetICValuesCheck( 264 Xim im, 265 INT16 len, 266 XPointer data, 267 XPointer arg) 268{ 269 Xic ic = (Xic)arg; 270 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 271 CARD8 major_opcode = *((CARD8 *)data); 272 CARD8 minor_opcode = *((CARD8 *)data + 1); 273 XIMID imid = buf_s[0]; 274 XICID icid = buf_s[1]; 275 276 if ((major_opcode == XIM_GET_IC_VALUES_REPLY) 277 && (minor_opcode == 0) 278 && (imid == im->private.proto.imid) 279 && (icid == ic->private.proto.icid)) 280 return True; 281 if ((major_opcode == XIM_ERROR) 282 && (minor_opcode == 0) 283 && (buf_s[2] & XIM_IMID_VALID) 284 && (imid == im->private.proto.imid) 285 && (buf_s[2] & XIM_ICID_VALID) 286 && (icid == ic->private.proto.icid)) 287 return True; 288 return False; 289} 290 291static char * 292_XimProtoGetICValues( 293 XIC xic, 294 XIMArg *arg) 295{ 296 Xic ic = (Xic)xic; 297 Xim im = (Xim)ic->core.im; 298 register XIMArg *p; 299 register XIMArg *pp; 300 register int n; 301 CARD8 *buf; 302 CARD16 *buf_s; 303 INT16 len; 304 CARD32 reply32[BUFSIZE/4]; 305 char *reply = (char *)reply32; 306 XPointer preply = NULL; 307 int buf_size; 308 int ret_code; 309 char *makeid_name; 310 char *decode_name; 311 CARD16 *data = NULL; 312 INT16 data_len = 0; 313 314#ifndef XIM_CONNECTABLE 315 if (!IS_IC_CONNECTED(ic)) 316 return arg->name; 317#else 318 if (!IS_IC_CONNECTED(ic)) { 319 if (IS_CONNECTABLE(im)) { 320 if (_XimConnectServer(im)) { 321 if (!_XimReCreateIC(ic)) { 322 _XimDelayModeSetAttr(im); 323 return _XimDelayModeGetICValues(ic, arg); 324 } 325 } else { 326 return _XimDelayModeGetICValues(ic, arg); 327 } 328 } else { 329 return arg->name; 330 } 331 } 332#endif /* XIM_CONNECTABLE */ 333 334 for (n = 0, p = arg; p && p->name; p++) { 335 n++; 336 if ((strcmp(p->name, XNPreeditAttributes) == 0) 337 || (strcmp(p->name, XNStatusAttributes) == 0)) { 338 n++; 339 for (pp = (XIMArg *)p->value; pp && pp->name; pp++) 340 n++; 341 } 342 } 343 344 if (!n) 345 return (char *)NULL; 346 347 buf_size = sizeof(CARD16) * n; 348 buf_size += XIM_HEADER_SIZE 349 + sizeof(CARD16) 350 + sizeof(CARD16) 351 + sizeof(INT16) 352 + XIM_PAD(2 + buf_size); 353 354 if (!(buf = (CARD8 *)Xmalloc(buf_size))) 355 return arg->name; 356 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 357 358 makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources, 359 ic->private.proto.ic_num_resources, arg, 360 &buf_s[3], &len, XIM_GETICVALUES); 361 362 if (len > 0) { 363 buf_s[0] = im->private.proto.imid; /* imid */ 364 buf_s[1] = ic->private.proto.icid; /* icid */ 365 buf_s[2] = len; /* length of ic-attr-id */ 366 len += sizeof(INT16); /* sizeof length of attr */ 367 XIM_SET_PAD(&buf_s[2], len); /* pad */ 368 len += sizeof(CARD16) /* sizeof imid */ 369 + sizeof(CARD16); /* sizeof icid */ 370 371 _XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len); 372 if (!(_XimWrite(im, len, (XPointer)buf))) { 373 Xfree(buf); 374 return arg->name; 375 } 376 _XimFlush(im); 377 Xfree(buf); 378 buf_size = BUFSIZE; 379 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 380 _XimGetICValuesCheck, (XPointer)ic); 381 if (ret_code == XIM_TRUE) { 382 preply = reply; 383 } else if (ret_code == XIM_OVERFLOW) { 384 if (len <= 0) { 385 preply = reply; 386 } else { 387 buf_size = (int)len; 388 preply = (XPointer)Xmalloc(len); 389 ret_code = _XimRead(im, &len, preply, buf_size, 390 _XimGetICValuesCheck, (XPointer)ic); 391 if (ret_code != XIM_TRUE) { 392 if (preply != reply) 393 Xfree(preply); 394 return arg->name; 395 } 396 } 397 } else { 398 return arg->name; 399 } 400 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 401 if (*((CARD8 *)preply) == XIM_ERROR) { 402 _XimProcError(im, 0, (XPointer)&buf_s[3]); 403 if (reply != preply) 404 Xfree(preply); 405 return arg->name; 406 } 407 data = &buf_s[4]; 408 data_len = buf_s[2]; 409 } 410 else if (len < 0) { 411 return arg->name; 412 } 413 414 decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources, 415 ic->private.proto.ic_num_resources, data, data_len, 416 arg, XIM_GETICVALUES); 417 if (reply != preply) 418 Xfree(preply); 419 420 if (decode_name) 421 return decode_name; 422 else 423 return makeid_name; 424} 425 426#ifdef XIM_CONNECTABLE 427static Bool 428_XimCheckNestQuarkList(quark_list, num_quark, quark, separator) 429 XrmQuark *quark_list; 430 int num_quark; 431 XrmQuark quark; 432 XrmQuark separator; 433{ 434 register int i; 435 436 for (i = 0; i < num_quark; i++) { 437 if (quark_list[i] == separator) { 438 break; 439 } 440 if (quark_list[i] == quark) { 441 return True; 442 } 443 } 444 return False; 445} 446 447static Bool 448_XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator) 449 XrmQuark **quark_list; 450 int idx; 451 int *num_quark; 452 XIMArg *arg; 453 XrmQuark separator; 454{ 455 XrmQuark *q_list = *quark_list; 456 int n_quark = *num_quark; 457 register XIMArg *p; 458 XrmQuark quark; 459 XrmQuark *tmp; 460 register int i; 461 462 for (p = arg; p && p->name; p++) { 463 quark = XrmStringToQuark(p->name); 464 if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx, 465 quark, separator)) { 466 continue; 467 } 468 if (!(tmp = (XrmQuark *)Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) { 469 *quark_list = q_list; 470 *num_quark = n_quark; 471 return False; 472 } 473 n_quark++; 474 for (i = 0; i < idx; i++) { 475 tmp[i] = q_list[i]; 476 } 477 tmp[i] = quark; 478 for (i = idx + 1; i < n_quark; i++) { 479 tmp[i] = q_list[i - 1]; 480 } 481 q_list = tmp; 482 } 483 *quark_list = q_list; 484 *num_quark = n_quark; 485 return True; 486} 487 488static Bool 489_XimCheckICQuarkList(quark_list, num_quark, quark, idx) 490 XrmQuark *quark_list; 491 int num_quark; 492 XrmQuark quark; 493 int *idx; 494{ 495 register int i; 496 497 for (i = 0; i < num_quark; i++) { 498 if (quark_list[i] == quark) { 499 *idx = i; 500 return True; 501 } 502 } 503 return False; 504} 505 506static Bool 507_XimSaveICValues(ic, arg) 508 Xic ic; 509 XIMArg *arg; 510{ 511 register XIMArg *p; 512 register int n; 513 XrmQuark *quark_list; 514 XrmQuark *tmp; 515 XrmQuark quark; 516 int num_quark; 517 XrmQuark pre_quark; 518 XrmQuark sts_quark; 519 XrmQuark separator; 520 int idx; 521 522 pre_quark = XrmStringToQuark(XNPreeditAttributes); 523 sts_quark = XrmStringToQuark(XNStatusAttributes); 524 separator = XrmStringToQuark(XNSeparatorofNestedList); 525 526 if (quark_list = ic->private.proto.saved_icvalues) { 527 num_quark = ic->private.proto.num_saved_icvalues; 528 for (p = arg; p && p->name; p++) { 529 quark = XrmStringToQuark(p->name); 530 if ((quark == pre_quark) || (quark == sts_quark)) { 531 if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { 532 register XIMArg *pp; 533 int nn; 534 XrmQuark *q_list; 535 536 for (pp = (XIMArg *)p->value, nn = 0; 537 pp && pp->name; pp++, nn++); 538 if (!(tmp = (XrmQuark *)Xrealloc(quark_list, 539 (sizeof(XrmQuark) * (num_quark + nn + 2))))) { 540 ic->private.proto.saved_icvalues = quark_list; 541 ic->private.proto.num_saved_icvalues = num_quark; 542 return False; 543 } 544 quark_list = tmp; 545 q_list = &quark_list[num_quark]; 546 num_quark += nn + 2; 547 *q_list++ = quark; 548 for (pp = (XIMArg *)p->value; 549 pp && pp->name; pp++, quark_list++) { 550 *q_list = XrmStringToQuark(pp->name); 551 } 552 *q_list = separator; 553 } else { 554 if (!_XimCheckNestedQuarkList(&quark_list, idx + 1, 555 &num_quark, (XIMArg *)p->value, separator)) { 556 ic->private.proto.saved_icvalues = quark_list; 557 ic->private.proto.num_saved_icvalues = num_quark; 558 return False; 559 } 560 } 561 } else { 562 if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { 563 continue; 564 } 565 if (!(tmp = (XrmQuark *)Xrealloc(quark_list, 566 (sizeof(XrmQuark) * (num_quark + 1))))) { 567 ic->private.proto.saved_icvalues = quark_list; 568 ic->private.proto.num_saved_icvalues = num_quark; 569 return False; 570 } 571 quark_list = tmp; 572 quark_list[num_quark] = quark; 573 num_quark++; 574 } 575 } 576 ic->private.proto.saved_icvalues = quark_list; 577 ic->private.proto.num_saved_icvalues = num_quark; 578 return True; 579 } 580 581 for (p = arg, n = 0; p && p->name; p++, n++) { 582 if ((!strcmp(p->name, XNPreeditAttributes)) 583 || (!strcmp(p->name, XNStatusAttributes))) { 584 register XIMArg *pp; 585 int nn; 586 587 for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++); 588 n += nn + 1; 589 } 590 } 591 592 if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) { 593 return False; 594 } 595 596 ic->private.proto.saved_icvalues = quark_list; 597 ic->private.proto.num_saved_icvalues = n; 598 for (p = arg; p && p->name; p++, quark_list++) { 599 *quark_list = XrmStringToQuark(p->name); 600 if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) { 601 register XIMArg *pp; 602 603 quark_list++; 604 for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) { 605 *quark_list = XrmStringToQuark(pp->name); 606 } 607 *quark_list = separator; 608 } 609 } 610 return True; 611} 612 613static char * 614_XimDelayModeSetICValues(ic, arg) 615 Xic ic; 616 XIMArg *arg; 617{ 618 XimDefICValues ic_values; 619 char *name; 620 621 _XimGetCurrentICValues(ic, &ic_values); 622 name = _XimSetICValueData(ic, (XPointer)&ic_values, 623 ic->private.proto.ic_resources, 624 ic->private.proto.ic_num_resources, 625 arg, XIM_SETICVALUES, False); 626 _XimSetCurrentICValues(ic, &ic_values); 627 return name; 628} 629#endif /* XIM_CONNECTABLE */ 630 631static Bool 632_XimSetICValuesCheck( 633 Xim im, 634 INT16 len, 635 XPointer data, 636 XPointer arg) 637{ 638 Xic ic = (Xic)arg; 639 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 640 CARD8 major_opcode = *((CARD8 *)data); 641 CARD8 minor_opcode = *((CARD8 *)data + 1); 642 XIMID imid = buf_s[0]; 643 XICID icid = buf_s[1]; 644 645 if ((major_opcode == XIM_SET_IC_VALUES_REPLY) 646 && (minor_opcode == 0) 647 && (imid == im->private.proto.imid) 648 && (icid == ic->private.proto.icid)) 649 return True; 650 if ((major_opcode == XIM_ERROR) 651 && (minor_opcode == 0) 652 && (buf_s[2] & XIM_IMID_VALID) 653 && (imid == im->private.proto.imid) 654 && (buf_s[2] & XIM_ICID_VALID) 655 && (icid == ic->private.proto.icid)) 656 return True; 657 return False; 658} 659 660static char * 661_XimProtoSetICValues( 662 XIC xic, 663 XIMArg *arg) 664{ 665 Xic ic = (Xic)xic; 666 Xim im = (Xim)ic->core.im; 667 XimDefICValues ic_values; 668 INT16 len; 669 CARD16 *buf_s; 670 char *tmp; 671 CARD32 tmp_buf32[BUFSIZE/4]; 672 char *tmp_buf = (char *)tmp_buf32; 673 char *buf; 674 int buf_size; 675 char *data; 676 int data_len; 677 int ret_len; 678 int total; 679 XIMArg *arg_ret; 680 CARD32 reply32[BUFSIZE/4]; 681 char *reply = (char *)reply32; 682 XPointer preply = NULL; 683 int ret_code; 684 BITMASK32 flag = 0L; 685 char *name; 686 char *tmp_name = (arg) ? arg->name : NULL; 687 688#ifndef XIM_CONNECTABLE 689 if (!IS_IC_CONNECTED(ic)) 690 return tmp_name; 691#else 692 if (!_XimSaveICValues(ic, arg)) 693 return NULL; 694 695 if (!IS_IC_CONNECTED(ic)) { 696 if (IS_CONNECTABLE(im)) { 697 if (_XimConnectServer(im)) { 698 if (!_XimReCreateIC(ic)) { 699 _XimDelayModeSetAttr(im); 700 return _XimDelayModeSetICValues(ic, arg); 701 } 702 } else { 703 return _XimDelayModeSetICValues(ic, arg); 704 } 705 } else { 706 return tmp_name; 707 } 708 } 709#endif /* XIM_CONNECTABLE */ 710 711 _XimGetCurrentICValues(ic, &ic_values); 712 buf = tmp_buf; 713 buf_size = XIM_HEADER_SIZE 714 + sizeof(CARD16) + sizeof(CARD16) + sizeof(INT16) + sizeof(CARD16); 715 data_len = BUFSIZE - buf_size; 716 total = 0; 717 arg_ret = arg; 718 for (;;) { 719 data = &buf[buf_size]; 720 if ((name = _XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources, 721 ic->private.proto.ic_num_resources, arg, &arg_ret, 722 data, data_len, &ret_len, (XPointer)&ic_values, 723 &flag, XIM_SETICVALUES))) { 724 break; 725 } 726 727 total += ret_len; 728 if (!(arg = arg_ret)) { 729 break; 730 } 731 732 buf_size += ret_len; 733 if (buf == tmp_buf) { 734 if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { 735 return tmp_name; 736 } 737 memcpy(tmp, buf, buf_size); 738 buf = tmp; 739 } else { 740 if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { 741 Xfree(buf); 742 return tmp_name; 743 } 744 buf = tmp; 745 } 746 } 747 _XimSetCurrentICValues(ic, &ic_values); 748 749 if (!total) { 750 return tmp_name; 751 } 752 753 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 754 755#ifdef EXT_MOVE 756 if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total)) 757 return name; 758#endif 759 760 buf_s[0] = im->private.proto.imid; 761 buf_s[1] = ic->private.proto.icid; 762 buf_s[2] = (INT16)total; 763 buf_s[3] = 0; 764 len = (INT16)(sizeof(CARD16) + sizeof(CARD16) 765 + sizeof(INT16) + sizeof(CARD16) + total); 766 767 _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len); 768 if (!(_XimWrite(im, len, (XPointer)buf))) { 769 if (buf != tmp_buf) 770 Xfree(buf); 771 return tmp_name; 772 } 773 _XimFlush(im); 774 if (buf != tmp_buf) 775 Xfree(buf); 776 ic->private.proto.waitCallback = True; 777 buf_size = BUFSIZE; 778 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 779 _XimSetICValuesCheck, (XPointer)ic); 780 if (ret_code == XIM_TRUE) { 781 preply = reply; 782 } else if (ret_code == XIM_OVERFLOW) { 783 buf_size = (int)len; 784 preply = (XPointer)Xmalloc(buf_size); 785 ret_code = _XimRead(im, &len, preply, buf_size, 786 _XimSetICValuesCheck, (XPointer)ic); 787 if (ret_code != XIM_TRUE) { 788 Xfree(preply); 789 ic->private.proto.waitCallback = False; 790 return tmp_name; 791 } 792 } else { 793 ic->private.proto.waitCallback = False; 794 return tmp_name; 795 } 796 ic->private.proto.waitCallback = False; 797 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 798 if (*((CARD8 *)preply) == XIM_ERROR) { 799 _XimProcError(im, 0, (XPointer)&buf_s[3]); 800 if (reply != preply) 801 Xfree(preply); 802 return tmp_name; 803 } 804 if (reply != preply) 805 Xfree(preply); 806 807 return name; 808} 809 810static Bool 811_XimDestroyICCheck( 812 Xim im, 813 INT16 len, 814 XPointer data, 815 XPointer arg) 816{ 817 Xic ic = (Xic)arg; 818 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 819 CARD8 major_opcode = *((CARD8 *)data); 820 CARD8 minor_opcode = *((CARD8 *)data + 1); 821 XIMID imid = buf_s[0]; 822 XICID icid = buf_s[1]; 823 Bool ret = False; 824 825 if ((major_opcode == XIM_DESTROY_IC_REPLY) 826 && (minor_opcode == 0) 827 && (imid == im->private.proto.imid) 828 && (icid == ic->private.proto.icid)) 829 ret = True; 830 if ((major_opcode == XIM_ERROR) 831 && (minor_opcode == 0) 832 && (buf_s[2] & XIM_IMID_VALID) 833 && (imid == im->private.proto.imid) 834 && (buf_s[2] & XIM_ICID_VALID) 835 && (icid == ic->private.proto.icid)) 836 ret = False; 837 return ret; 838} 839 840static void 841_XimProtoICFree( 842 Xic ic) 843{ 844#ifdef XIM_CONNECTABLE 845 Xim im = (Xim)ic->core.im; 846#endif 847 848 if (ic->private.proto.preedit_font) { 849 Xfree(ic->private.proto.preedit_font); 850 ic->private.proto.preedit_font = NULL; 851 } 852 if (ic->private.proto.status_font) { 853 Xfree(ic->private.proto.status_font); 854 ic->private.proto.status_font = NULL; 855 } 856 if (ic->private.proto.commit_info) { 857 _XimFreeCommitInfo(ic); 858 ic->private.proto.commit_info = NULL; 859 } 860 if (ic->private.proto.ic_inner_resources) { 861 Xfree(ic->private.proto.ic_inner_resources); 862 ic->private.proto.ic_inner_resources = NULL; 863 } 864 865#ifdef XIM_CONNECTABLE 866 if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { 867 return; 868 } 869#endif /* XIM_CONNECTABLE */ 870 871 if (ic->private.proto.saved_icvalues) { 872 Xfree(ic->private.proto.saved_icvalues); 873 ic->private.proto.saved_icvalues = NULL; 874 } 875 if (ic->private.proto.ic_resources) { 876 Xfree(ic->private.proto.ic_resources); 877 ic->private.proto.ic_resources = NULL; 878 } 879 if (ic->core.hotkey) { 880 Xfree(ic->core.hotkey); 881 ic->core.hotkey = NULL; 882 } 883 884 return; 885} 886 887static void 888_XimProtoDestroyIC( 889 XIC xic) 890{ 891 Xic ic = (Xic)xic; 892 Xim im = (Xim)ic->core.im; 893 CARD32 buf32[BUFSIZE/4]; 894 CARD8 *buf = (CARD8 *)buf32; 895 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 896 INT16 len; 897 CARD32 reply32[BUFSIZE/4]; 898 char *reply = (char *)reply32; 899 XPointer preply; 900 int buf_size; 901 int ret_code; 902 903 if (IS_SERVER_CONNECTED(im)) { 904 buf_s[0] = im->private.proto.imid; /* imid */ 905 buf_s[1] = ic->private.proto.icid; /* icid */ 906 907 len = sizeof(CARD16) /* sizeof imid */ 908 + sizeof(CARD16); /* sizeof icid */ 909 910 _XimSetHeader((XPointer)buf, XIM_DESTROY_IC, 0, &len); 911 (void)_XimWrite(im, len, (XPointer)buf); 912 _XimFlush(im); 913 buf_size = BUFSIZE; 914 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 915 _XimDestroyICCheck, (XPointer)ic); 916 if (ret_code == XIM_OVERFLOW) { 917 buf_size = len; 918 preply = (XPointer)Xmalloc(buf_size); 919 (void)_XimRead(im, &len, preply, buf_size, 920 _XimDestroyICCheck, (XPointer)ic); 921 Xfree(preply); 922 } 923 } 924 UNMARK_IC_CONNECTED(ic); 925 _XimUnregisterFilter(ic); 926 _XimProtoICFree(ic); 927 return; 928} 929 930static void 931_XimProtoSetFocus( 932 XIC xic) 933{ 934 Xic ic = (Xic)xic; 935 Xim im = (Xim)ic->core.im; 936 CARD32 buf32[BUFSIZE/4]; 937 CARD8 *buf = (CARD8 *)buf32; 938 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 939 INT16 len; 940 941#ifndef XIM_CONNECTABLE 942 if (!IS_IC_CONNECTED(ic)) 943 return; 944#else 945 if (!IS_IC_CONNECTED(ic)) { 946 if (IS_CONNECTABLE(im)) { 947 if (_XimConnectServer(im)) { 948 if (!_XimReCreateIC(ic)) { 949 _XimDelayModeSetAttr(im); 950 return; 951 } 952 } else { 953 return; 954 } 955 } else { 956 return; 957 } 958 } 959#endif /* XIM_CONNECTABLE */ 960 961 buf_s[0] = im->private.proto.imid; /* imid */ 962 buf_s[1] = ic->private.proto.icid; /* icid */ 963 964 len = sizeof(CARD16) /* sizeof imid */ 965 + sizeof(CARD16); /* sizeof icid */ 966 967 _XimSetHeader((XPointer)buf, XIM_SET_IC_FOCUS, 0, &len); 968 (void)_XimWrite(im, len, (XPointer)buf); 969 _XimFlush(im); 970 971 _XimRegisterFilter(ic); 972 return; 973} 974 975static void 976_XimProtoUnsetFocus( 977 XIC xic) 978{ 979 Xic ic = (Xic)xic; 980 Xim im = (Xim)ic->core.im; 981 CARD32 buf32[BUFSIZE/4]; 982 CARD8 *buf = (CARD8 *)buf32; 983 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 984 INT16 len; 985 986#ifndef XIM_CONNECTABLE 987 if (!IS_IC_CONNECTED(ic)) 988 return; 989#else 990 if (!IS_IC_CONNECTED(ic)) { 991 if (IS_CONNECTABLE(im)) { 992 if (_XimConnectServer(im)) { 993 if (!_XimReCreateIC(ic)) { 994 _XimDelayModeSetAttr(im); 995 return; 996 } 997 } else { 998 return; 999 } 1000 } else { 1001 return; 1002 } 1003 } 1004#endif /* XIM_CONNECTABLE */ 1005 1006 buf_s[0] = im->private.proto.imid; /* imid */ 1007 buf_s[1] = ic->private.proto.icid; /* icid */ 1008 1009 len = sizeof(CARD16) /* sizeof imid */ 1010 + sizeof(CARD16); /* sizeof icid */ 1011 1012 _XimSetHeader((XPointer)buf, XIM_UNSET_IC_FOCUS, 0, &len); 1013 (void)_XimWrite(im, len, (XPointer)buf); 1014 _XimFlush(im); 1015 1016 _XimUnregisterFilter(ic); 1017 return; 1018} 1019 1020static Bool 1021_XimResetICCheck( 1022 Xim im, 1023 INT16 len, 1024 XPointer data, 1025 XPointer arg) 1026{ 1027 Xic ic = (Xic)arg; 1028 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 1029 CARD8 major_opcode = *((CARD8 *)data); 1030 CARD8 minor_opcode = *((CARD8 *)data + 1); 1031 XIMID imid = buf_s[0]; 1032 XICID icid = buf_s[1]; 1033 1034 if ((major_opcode == XIM_RESET_IC_REPLY) 1035 && (minor_opcode == 0) 1036 && (imid == im->private.proto.imid) 1037 && (icid == ic->private.proto.icid)) 1038 return True; 1039 if ((major_opcode == XIM_ERROR) 1040 && (minor_opcode == 0) 1041 && (buf_s[2] & XIM_IMID_VALID) 1042 && (imid == im->private.proto.imid) 1043 && (buf_s[2] & XIM_ICID_VALID) 1044 && (icid == ic->private.proto.icid)) 1045 return True; 1046 return False; 1047} 1048 1049static char * 1050_XimProtoReset( 1051 XIC xic, 1052 char * (*retfunc) (Xim im, Xic ic, XPointer buf) ) 1053{ 1054 Xic ic = (Xic)xic; 1055 Xim im = (Xim)ic->core.im; 1056 CARD32 buf32[BUFSIZE/4]; 1057 CARD8 *buf = (CARD8 *)buf32; 1058 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1059 INT16 len; 1060 CARD32 reply32[BUFSIZE/4]; 1061 char *reply = (char *)reply32; 1062 XPointer preply; 1063 int buf_size; 1064 int ret_code; 1065 char *commit; 1066 1067 if (!IS_IC_CONNECTED(ic)) 1068 return (char *)NULL; 1069 1070 buf_s[0] = im->private.proto.imid; /* imid */ 1071 buf_s[1] = ic->private.proto.icid; /* icid */ 1072 1073 len = sizeof(CARD16) /* sizeof imid */ 1074 + sizeof(CARD16); /* sizeof icid */ 1075 1076 _XimSetHeader((XPointer)buf, XIM_RESET_IC, 0, &len); 1077 if (!(_XimWrite(im, len, (XPointer)buf))) 1078 return NULL; 1079 _XimFlush(im); 1080 ic->private.proto.waitCallback = True; 1081 buf_size = BUFSIZE; 1082 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1083 _XimResetICCheck, (XPointer)ic); 1084 if (ret_code == XIM_TRUE) { 1085 preply = reply; 1086 } else if (ret_code == XIM_OVERFLOW) { 1087 if (len < 0) { 1088 preply = reply; 1089 } else { 1090 buf_size = len; 1091 preply = (XPointer)Xmalloc(buf_size); 1092 ret_code = _XimRead(im, &len, preply, buf_size, 1093 _XimResetICCheck, (XPointer)ic); 1094 if (ret_code != XIM_TRUE) { 1095 Xfree(preply); 1096 ic->private.proto.waitCallback = False; 1097 return NULL; 1098 } 1099 } 1100 } else { 1101 ic->private.proto.waitCallback = False; 1102 return NULL; 1103 } 1104 ic->private.proto.waitCallback = False; 1105 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1106 if (*((CARD8 *)preply) == XIM_ERROR) { 1107 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1108 if (reply != preply) 1109 free(preply); 1110 return NULL; 1111 } 1112 1113 commit = retfunc(im, ic, (XPointer)&buf_s[2]); 1114 1115 if (reply != preply) 1116 Xfree(preply); 1117 return commit; 1118} 1119 1120static char * 1121_XimCommitedMbString( 1122 Xim im, 1123 Xic ic, 1124 XPointer buf) 1125{ 1126 CARD16 *buf_s = (CARD16 *)buf; 1127 XimCommitInfo info; 1128 int len; 1129 int new_len; 1130 char *commit; 1131 char *new_commit = NULL; 1132 char *str; 1133 Status status; 1134 1135 len = 0; 1136 for (info = ic->private.proto.commit_info; info; info = info->next) 1137 len += info->string_len; 1138 len += buf_s[0]; 1139 if ( len == 0 ) 1140 return( NULL ); 1141 1142 if (!(commit = (char *)Xmalloc(len + 1))) 1143 goto Error_On_Reset; 1144 1145 str = commit; 1146 for (info = ic->private.proto.commit_info; info; info = info->next) { 1147 (void)memcpy(str, info->string, info->string_len); 1148 str += info->string_len; 1149 } 1150 (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); 1151 commit[len] = '\0'; 1152 1153 new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status); 1154 if (status != XLookupNone) { 1155 if (!(new_commit = Xmalloc(new_len + 1))) { 1156 Xfree(commit); 1157 goto Error_On_Reset; 1158 } 1159 (void)im->methods->ctstombs((XIM)im, commit, len, 1160 new_commit, new_len, NULL); 1161 new_commit[new_len] = '\0'; 1162 } 1163 Xfree(commit); 1164 1165Error_On_Reset: 1166 _XimFreeCommitInfo( ic ); 1167 return new_commit; 1168} 1169 1170static char * 1171_XimProtoMbReset( 1172 XIC xic) 1173{ 1174 return _XimProtoReset(xic, _XimCommitedMbString); 1175} 1176 1177static wchar_t * 1178_XimCommitedWcString( 1179 Xim im, 1180 Xic ic, 1181 XPointer buf) 1182{ 1183 CARD16 *buf_s = (CARD16 *)buf; 1184 XimCommitInfo info; 1185 int len; 1186 int new_len; 1187 char *commit; 1188 wchar_t *new_commit = (wchar_t *)NULL; 1189 char *str; 1190 Status status; 1191 1192 len = 0; 1193 for (info = ic->private.proto.commit_info; info; info = info->next) 1194 len += info->string_len; 1195 len += buf_s[0]; 1196 if ( len == 0 ) 1197 return( (wchar_t *)NULL ); 1198 1199 if (!(commit = (char *)Xmalloc(len + 1))) 1200 goto Error_On_Reset; 1201 1202 str = commit; 1203 for (info = ic->private.proto.commit_info; info; info = info->next) { 1204 (void)memcpy(str, info->string, info->string_len); 1205 str += info->string_len; 1206 } 1207 (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); 1208 commit[len] = '\0'; 1209 1210 new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status); 1211 if (status != XLookupNone) { 1212 if (!(new_commit = 1213 (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) { 1214 Xfree(commit); 1215 goto Error_On_Reset; 1216 } 1217 (void)im->methods->ctstowcs((XIM)im, commit, len, 1218 new_commit, new_len, NULL); 1219 new_commit[new_len] = (wchar_t)'\0'; 1220 } 1221 Xfree(commit); 1222 1223Error_On_Reset: 1224 _XimFreeCommitInfo( ic ); 1225 return new_commit; 1226} 1227 1228static wchar_t * 1229_XimProtoWcReset( 1230 XIC xic) 1231{ 1232 return (wchar_t *) _XimProtoReset(xic, 1233 (char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString); 1234} 1235 1236static char * 1237_XimCommitedUtf8String( 1238 Xim im, 1239 Xic ic, 1240 XPointer buf) 1241{ 1242 CARD16 *buf_s = (CARD16 *)buf; 1243 XimCommitInfo info; 1244 int len; 1245 int new_len; 1246 char *commit; 1247 char *new_commit = NULL; 1248 char *str; 1249 Status status; 1250 1251 len = 0; 1252 for (info = ic->private.proto.commit_info; info; info = info->next) 1253 len += info->string_len; 1254 len += buf_s[0]; 1255 if ( len == 0 ) 1256 return( NULL ); 1257 1258 if (!(commit = (char *)Xmalloc(len + 1))) 1259 goto Error_On_Reset; 1260 1261 str = commit; 1262 for (info = ic->private.proto.commit_info; info; info = info->next) { 1263 (void)memcpy(str, info->string, info->string_len); 1264 str += info->string_len; 1265 } 1266 (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); 1267 commit[len] = '\0'; 1268 1269 new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status); 1270 if (status != XLookupNone) { 1271 if (!(new_commit = Xmalloc(new_len + 1))) { 1272 Xfree(commit); 1273 goto Error_On_Reset; 1274 } 1275 (void)im->methods->ctstoutf8((XIM)im, commit, len, 1276 new_commit, new_len, NULL); 1277 new_commit[new_len] = '\0'; 1278 } 1279 Xfree(commit); 1280 1281Error_On_Reset: 1282 _XimFreeCommitInfo( ic ); 1283 return new_commit; 1284} 1285 1286static char * 1287_XimProtoUtf8Reset( 1288 XIC xic) 1289{ 1290 return _XimProtoReset(xic, _XimCommitedUtf8String); 1291} 1292 1293static XICMethodsRec ic_methods = { 1294 _XimProtoDestroyIC, /* destroy */ 1295 _XimProtoSetFocus, /* set_focus */ 1296 _XimProtoUnsetFocus, /* unset_focus */ 1297 _XimProtoSetICValues, /* set_values */ 1298 _XimProtoGetICValues, /* get_values */ 1299 _XimProtoMbReset, /* mb_reset */ 1300 _XimProtoWcReset, /* wc_reset */ 1301 _XimProtoUtf8Reset, /* utf8_reset */ 1302 _XimProtoMbLookupString, /* mb_lookup_string */ 1303 _XimProtoWcLookupString, /* wc_lookup_string */ 1304 _XimProtoUtf8LookupString /* utf8_lookup_string */ 1305}; 1306 1307static Bool 1308_XimGetInputStyle( 1309 XIMArg *arg, 1310 XIMStyle *input_style) 1311{ 1312 register XIMArg *p; 1313 1314 for (p = arg; p && p->name; p++) { 1315 if (!(strcmp(p->name, XNInputStyle))) { 1316 *input_style = (XIMStyle)p->value; 1317 return True; 1318 } 1319 } 1320 return False; 1321} 1322 1323#ifdef XIM_CONNECTABLE 1324static Bool 1325_XimDelayModeCreateIC( 1326 Xic ic, 1327 XIMArg *values, 1328 XIMResourceList res, 1329 unsigned int num) 1330{ 1331 Xim im = (Xim)ic->core.im; 1332 XimDefICValues ic_values; 1333 int len; 1334 XIMStyle input_style; 1335 1336 bzero((char *)&ic_values, sizeof(XimDefICValues)); 1337 _XimGetCurrentICValues(ic, &ic_values); 1338 if (!(_XimGetInputStyle(values, &input_style))) 1339 return False; 1340 1341 _XimSetICMode(res, num, input_style); 1342 1343 if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num, 1344 values, XIM_CREATEIC, False)) { 1345 return False; 1346 } 1347 _XimSetCurrentICValues(ic, &ic_values); 1348 if (!_XimSetICDefaults(ic, (XPointer)&ic_values, 1349 XIM_SETICDEFAULTS, res, num)) { 1350 return False; 1351 } 1352 ic_values.filter_events = KeyPressMask; 1353 _XimSetCurrentICValues(ic, &ic_values); 1354 _XimRegisterFilter(ic); 1355 1356 return True; 1357} 1358 1359Bool 1360_XimReconnectModeCreateIC(ic) 1361 Xic ic; 1362{ 1363 Xim im = (Xim)ic->core.im; 1364 int len; 1365 XIMStyle input_style = ic->core.input_style; 1366 XIMResourceList res; 1367 unsigned int num; 1368 1369 num = im->core.ic_num_resources; 1370 len = sizeof(XIMResource) * num; 1371 if (!(res = (XIMResourceList)Xmalloc(len))) 1372 return False; 1373 (void)memcpy((char *)res, (char *)im->core.ic_resources, len); 1374 ic->private.proto.ic_resources = res; 1375 ic->private.proto.ic_num_resources = num; 1376 1377 _XimSetICMode(res, num, input_style); 1378 1379 ic->core.filter_events = KeyPressMask; 1380 1381 return True; 1382} 1383#endif /* XIM_CONNECTABLE */ 1384 1385XIC 1386_XimProtoCreateIC( 1387 XIM xim, 1388 XIMArg *arg) 1389{ 1390 Xim im = (Xim)xim; 1391 Xic ic; 1392 XimDefICValues ic_values; 1393 XIMResourceList res; 1394 unsigned int num; 1395 XIMStyle input_style; 1396 INT16 len; 1397 CARD16 *buf_s; 1398 char *tmp; 1399 CARD32 tmp_buf32[BUFSIZE/4]; 1400 char *tmp_buf = (char *)tmp_buf32; 1401 char *buf; 1402 int buf_size; 1403 char *data; 1404 int data_len; 1405 int ret_len; 1406 int total; 1407 XIMArg *arg_ret; 1408 CARD32 reply32[BUFSIZE/4]; 1409 char *reply = (char *)reply32; 1410 XPointer preply; 1411 int ret_code; 1412 1413#ifdef XIM_CONNECTABLE 1414 if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im)) 1415 return (XIC)NULL; 1416#else 1417 if (!IS_SERVER_CONNECTED(im)) 1418 return (XIC)NULL; 1419#endif /* XIM_CONNECTABLE */ 1420 1421 if (!(_XimGetInputStyle(arg, &input_style))) 1422 return (XIC)NULL; 1423 1424 if ((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL) 1425 return (XIC)NULL; 1426 1427 ic->methods = &ic_methods; 1428 ic->core.im = (XIM)im; 1429 ic->core.input_style = input_style; 1430 1431 num = im->core.ic_num_resources; 1432 len = sizeof(XIMResource) * num; 1433 if (!(res = (XIMResourceList)Xmalloc(len))) 1434 goto ErrorOnCreatingIC; 1435 (void)memcpy((char *)res, (char *)im->core.ic_resources, len); 1436 ic->private.proto.ic_resources = res; 1437 ic->private.proto.ic_num_resources = num; 1438 1439#ifdef XIM_CONNECTABLE 1440 if (!_XimSaveICValues(ic, arg)) 1441 return False; 1442 1443 if (!IS_SERVER_CONNECTED(im)) { 1444 if (!_XimConnectServer(im)) { 1445 if (_XimDelayModeCreateIC(ic, arg, res, num)) { 1446 return (XIC)ic; 1447 } 1448 goto ErrorOnCreatingIC; 1449 } 1450 } 1451#endif /* XIM_CONNECTABLE */ 1452 1453 ic->core.filter_events = im->private.proto.forward_event_mask; 1454 ic->private.proto.forward_event_mask = 1455 im->private.proto.forward_event_mask; 1456 ic->private.proto.synchronous_event_mask = 1457 im->private.proto.synchronous_event_mask; 1458 1459 num = im->private.proto.ic_num_inner_resources; 1460 len = sizeof(XIMResource) * num; 1461 if (!(res = (XIMResourceList)Xmalloc(len))) 1462 goto ErrorOnCreatingIC; 1463 (void)memcpy((char *)res, 1464 (char *)im->private.proto.ic_inner_resources, len); 1465 ic->private.proto.ic_inner_resources = res; 1466 ic->private.proto.ic_num_inner_resources = num; 1467 1468 _XimSetICMode(ic->private.proto.ic_resources, 1469 ic->private.proto.ic_num_resources, input_style); 1470 1471 _XimSetICMode(ic->private.proto.ic_inner_resources, 1472 ic->private.proto.ic_num_inner_resources, input_style); 1473 1474 _XimGetCurrentICValues(ic, &ic_values); 1475 buf = tmp_buf; 1476 buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); 1477 data_len = BUFSIZE - buf_size; 1478 total = 0; 1479 arg_ret = arg; 1480 for (;;) { 1481 data = &buf[buf_size]; 1482 if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources, 1483 ic->private.proto.ic_num_resources, arg, &arg_ret, data, 1484 data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) { 1485 goto ErrorOnCreatingIC; 1486 } 1487 1488 total += ret_len; 1489 if (!(arg = arg_ret)) { 1490 break; 1491 } 1492 1493 buf_size += ret_len; 1494 if (buf == tmp_buf) { 1495 if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { 1496 goto ErrorOnCreatingIC; 1497 } 1498 memcpy(tmp, buf, buf_size); 1499 buf = tmp; 1500 } else { 1501 if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { 1502 Xfree(buf); 1503 goto ErrorOnCreatingIC; 1504 } 1505 buf = tmp; 1506 } 1507 } 1508 _XimSetCurrentICValues(ic, &ic_values); 1509 1510 if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources, 1511 ic->private.proto.ic_num_resources))) 1512 goto ErrorOnCreatingIC; 1513 1514 _XimRegisterFilter(ic); 1515 1516 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1517 buf_s[0] = im->private.proto.imid; 1518 buf_s[1] = (INT16)total; 1519 1520 len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); 1521 _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len); 1522 if (!(_XimWrite(im, len, (XPointer)buf))) { 1523 if (buf != tmp_buf) 1524 Xfree(buf); 1525 goto ErrorOnCreatingIC; 1526 } 1527 _XimFlush(im); 1528 if (buf != tmp_buf) 1529 Xfree(buf); 1530 ic->private.proto.waitCallback = True; 1531 buf_size = BUFSIZE; 1532 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1533 _XimCreateICCheck, 0); 1534 if (ret_code == XIM_TRUE) { 1535 preply = reply; 1536 } else if (ret_code == XIM_OVERFLOW) { 1537 if (len <= 0) { 1538 preply = reply; 1539 } else { 1540 buf_size = (int)len; 1541 preply = (XPointer)Xmalloc(buf_size); 1542 ret_code = _XimRead(im, &len, preply, buf_size, 1543 _XimCreateICCheck, 0); 1544 if (ret_code != XIM_TRUE) { 1545 Xfree(preply); 1546 ic->private.proto.waitCallback = False; 1547 goto ErrorOnCreatingIC; 1548 } 1549 } 1550 } else { 1551 ic->private.proto.waitCallback = False; 1552 goto ErrorOnCreatingIC; 1553 } 1554 ic->private.proto.waitCallback = False; 1555 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1556 if (*((CARD8 *)preply) == XIM_ERROR) { 1557 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1558 if (reply != preply) 1559 Xfree(preply); 1560 goto ErrorOnCreatingIC; 1561 } 1562 1563 ic->private.proto.icid = buf_s[1]; /* icid */ 1564 if (reply != preply) 1565 Xfree(preply); 1566 MARK_IC_CONNECTED(ic); 1567 return (XIC)ic; 1568 1569ErrorOnCreatingIC: 1570 _XimUnregisterFilter(ic); 1571 if (ic->private.proto.ic_resources) 1572 Xfree(ic->private.proto.ic_resources); 1573 if (ic->private.proto.ic_inner_resources) 1574 Xfree(ic->private.proto.ic_inner_resources); 1575 Xfree(ic); 1576 return (XIC)NULL; 1577} 1578