1/* 2 * Copyright (c) 1991, 1992, Oracle and/or its affiliates. 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 = 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 = 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 = 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 = Xmalloc(buf_size + data_len))) { 168 goto ErrorOnReCreateIC; 169 } 170 memcpy(tmp, buf, buf_size); 171 buf = tmp; 172 } else { 173 if (!(tmp = 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 = 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 235 Xfree(save_ic->private.proto.ic_resources); 236 Xfree(save_ic->private.proto.ic_inner_resources); 237 Xfree(save_ic); 238 return True; 239 240ErrorOnReCreateIC: 241 memcpy((char *)ic, (char *)save_ic, sizeof(XicRec)); 242 Xfree(save_ic); 243 return False; 244} 245 246static char * 247_XimDelayModeGetICValues(ic, arg) 248 Xic ic; 249 XIMArg *arg; 250{ 251 XimDefICValues ic_values; 252 253 _XimGetCurrentICValues(ic, &ic_values); 254 return _XimGetICValueData(ic, (XPointer)&ic_values, 255 ic->private.proto.ic_resources, 256 ic->private.proto.ic_num_resources, 257 arg, XIM_GETICVALUES); 258} 259#endif /* XIM_CONNECTABLE */ 260 261static Bool 262_XimGetICValuesCheck( 263 Xim im, 264 INT16 len, 265 XPointer data, 266 XPointer arg) 267{ 268 Xic ic = (Xic)arg; 269 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 270 CARD8 major_opcode = *((CARD8 *)data); 271 CARD8 minor_opcode = *((CARD8 *)data + 1); 272 XIMID imid = buf_s[0]; 273 XICID icid = buf_s[1]; 274 275 if ((major_opcode == XIM_GET_IC_VALUES_REPLY) 276 && (minor_opcode == 0) 277 && (imid == im->private.proto.imid) 278 && (icid == ic->private.proto.icid)) 279 return True; 280 if ((major_opcode == XIM_ERROR) 281 && (minor_opcode == 0) 282 && (buf_s[2] & XIM_IMID_VALID) 283 && (imid == im->private.proto.imid) 284 && (buf_s[2] & XIM_ICID_VALID) 285 && (icid == ic->private.proto.icid)) 286 return True; 287 return False; 288} 289 290static char * 291_XimProtoGetICValues( 292 XIC xic, 293 XIMArg *arg) 294{ 295 Xic ic = (Xic)xic; 296 Xim im = (Xim)ic->core.im; 297 register XIMArg *p; 298 register XIMArg *pp; 299 register int n; 300 CARD8 *buf; 301 CARD16 *buf_s; 302 INT16 len; 303 CARD32 reply32[BUFSIZE/4]; 304 char *reply = (char *)reply32; 305 XPointer preply = NULL; 306 int buf_size; 307 int ret_code; 308 char *makeid_name; 309 char *decode_name; 310 CARD16 *data = NULL; 311 INT16 data_len = 0; 312 313#ifndef XIM_CONNECTABLE 314 if (!IS_IC_CONNECTED(ic)) 315 return arg->name; 316#else 317 if (!IS_IC_CONNECTED(ic)) { 318 if (IS_CONNECTABLE(im)) { 319 if (_XimConnectServer(im)) { 320 if (!_XimReCreateIC(ic)) { 321 _XimDelayModeSetAttr(im); 322 return _XimDelayModeGetICValues(ic, arg); 323 } 324 } else { 325 return _XimDelayModeGetICValues(ic, arg); 326 } 327 } else { 328 return arg->name; 329 } 330 } 331#endif /* XIM_CONNECTABLE */ 332 333 for (n = 0, p = arg; p && p->name; p++) { 334 n++; 335 if ((strcmp(p->name, XNPreeditAttributes) == 0) 336 || (strcmp(p->name, XNStatusAttributes) == 0)) { 337 n++; 338 for (pp = (XIMArg *)p->value; pp && pp->name; pp++) 339 n++; 340 } 341 } 342 343 if (!n) 344 return (char *)NULL; 345 346 buf_size = sizeof(CARD16) * n; 347 buf_size += XIM_HEADER_SIZE 348 + sizeof(CARD16) 349 + sizeof(CARD16) 350 + sizeof(INT16) 351 + XIM_PAD(2 + buf_size); 352 353 if (!(buf = Xcalloc(buf_size, 1))) 354 return arg->name; 355 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 356 357 makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources, 358 ic->private.proto.ic_num_resources, arg, 359 &buf_s[3], &len, XIM_GETICVALUES); 360 361 if (len > 0) { 362 buf_s[0] = im->private.proto.imid; /* imid */ 363 buf_s[1] = ic->private.proto.icid; /* icid */ 364 buf_s[2] = len; /* length of ic-attr-id */ 365 len += sizeof(INT16); /* sizeof length of attr */ 366 XIM_SET_PAD(&buf_s[2], len); /* pad */ 367 len += sizeof(CARD16) /* sizeof imid */ 368 + sizeof(CARD16); /* sizeof icid */ 369 370 _XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len); 371 if (!(_XimWrite(im, len, (XPointer)buf))) { 372 Xfree(buf); 373 return arg->name; 374 } 375 _XimFlush(im); 376 Xfree(buf); 377 buf_size = BUFSIZE; 378 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 379 _XimGetICValuesCheck, (XPointer)ic); 380 if (ret_code == XIM_TRUE) { 381 preply = reply; 382 } else if (ret_code == XIM_OVERFLOW) { 383 if (len <= 0) { 384 preply = reply; 385 } else { 386 buf_size = (int)len; 387 preply = Xmalloc(len); 388 ret_code = _XimRead(im, &len, preply, buf_size, 389 _XimGetICValuesCheck, (XPointer)ic); 390 if (ret_code != XIM_TRUE) { 391 if (preply != reply) 392 Xfree(preply); 393 return arg->name; 394 } 395 } 396 } else { 397 return arg->name; 398 } 399 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 400 if (*((CARD8 *)preply) == XIM_ERROR) { 401 _XimProcError(im, 0, (XPointer)&buf_s[3]); 402 if (reply != preply) 403 Xfree(preply); 404 return arg->name; 405 } 406 data = &buf_s[4]; 407 data_len = buf_s[2]; 408 } 409 else if (len < 0) { 410 return arg->name; 411 } 412 413 decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources, 414 ic->private.proto.ic_num_resources, data, data_len, 415 arg, XIM_GETICVALUES); 416 if (reply != preply) 417 Xfree(preply); 418 419 if (decode_name) 420 return decode_name; 421 else 422 return makeid_name; 423} 424 425#ifdef XIM_CONNECTABLE 426static Bool 427_XimCheckNestQuarkList(quark_list, num_quark, quark, separator) 428 XrmQuark *quark_list; 429 int num_quark; 430 XrmQuark quark; 431 XrmQuark separator; 432{ 433 register int i; 434 435 for (i = 0; i < num_quark; i++) { 436 if (quark_list[i] == separator) { 437 break; 438 } 439 if (quark_list[i] == quark) { 440 return True; 441 } 442 } 443 return False; 444} 445 446static Bool 447_XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator) 448 XrmQuark **quark_list; 449 int idx; 450 int *num_quark; 451 XIMArg *arg; 452 XrmQuark separator; 453{ 454 XrmQuark *q_list = *quark_list; 455 int n_quark = *num_quark; 456 register XIMArg *p; 457 XrmQuark quark; 458 XrmQuark *tmp; 459 register int i; 460 461 for (p = arg; p && p->name; p++) { 462 quark = XrmStringToQuark(p->name); 463 if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx, 464 quark, separator)) { 465 continue; 466 } 467 if (!(tmp = Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) { 468 *quark_list = q_list; 469 *num_quark = n_quark; 470 return False; 471 } 472 n_quark++; 473 for (i = 0; i < idx; i++) { 474 tmp[i] = q_list[i]; 475 } 476 tmp[i] = quark; 477 for (i = idx + 1; i < n_quark; i++) { 478 tmp[i] = q_list[i - 1]; 479 } 480 q_list = tmp; 481 } 482 *quark_list = q_list; 483 *num_quark = n_quark; 484 return True; 485} 486 487static Bool 488_XimCheckICQuarkList(quark_list, num_quark, quark, idx) 489 XrmQuark *quark_list; 490 int num_quark; 491 XrmQuark quark; 492 int *idx; 493{ 494 register int i; 495 496 for (i = 0; i < num_quark; i++) { 497 if (quark_list[i] == quark) { 498 *idx = i; 499 return True; 500 } 501 } 502 return False; 503} 504 505static Bool 506_XimSaveICValues(ic, arg) 507 Xic ic; 508 XIMArg *arg; 509{ 510 register XIMArg *p; 511 register int n; 512 XrmQuark *quark_list; 513 XrmQuark *tmp; 514 XrmQuark quark; 515 int num_quark; 516 XrmQuark pre_quark; 517 XrmQuark sts_quark; 518 XrmQuark separator; 519 int idx; 520 521 pre_quark = XrmStringToQuark(XNPreeditAttributes); 522 sts_quark = XrmStringToQuark(XNStatusAttributes); 523 separator = XrmStringToQuark(XNSeparatorofNestedList); 524 525 if (quark_list = ic->private.proto.saved_icvalues) { 526 num_quark = ic->private.proto.num_saved_icvalues; 527 for (p = arg; p && p->name; p++) { 528 quark = XrmStringToQuark(p->name); 529 if ((quark == pre_quark) || (quark == sts_quark)) { 530 if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { 531 register XIMArg *pp; 532 int nn; 533 XrmQuark *q_list; 534 535 for (pp = (XIMArg *)p->value, nn = 0; 536 pp && pp->name; pp++, nn++); 537 if (!(tmp = Xrealloc(quark_list, 538 (sizeof(XrmQuark) * (num_quark + nn + 2))))) { 539 ic->private.proto.saved_icvalues = quark_list; 540 ic->private.proto.num_saved_icvalues = num_quark; 541 return False; 542 } 543 quark_list = tmp; 544 q_list = &quark_list[num_quark]; 545 num_quark += nn + 2; 546 *q_list++ = quark; 547 for (pp = (XIMArg *)p->value; 548 pp && pp->name; pp++, quark_list++) { 549 *q_list = XrmStringToQuark(pp->name); 550 } 551 *q_list = separator; 552 } else { 553 if (!_XimCheckNestedQuarkList(&quark_list, idx + 1, 554 &num_quark, (XIMArg *)p->value, separator)) { 555 ic->private.proto.saved_icvalues = quark_list; 556 ic->private.proto.num_saved_icvalues = num_quark; 557 return False; 558 } 559 } 560 } else { 561 if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { 562 continue; 563 } 564 if (!(tmp = Xrealloc(quark_list, 565 (sizeof(XrmQuark) * (num_quark + 1))))) { 566 ic->private.proto.saved_icvalues = quark_list; 567 ic->private.proto.num_saved_icvalues = num_quark; 568 return False; 569 } 570 quark_list = tmp; 571 quark_list[num_quark] = quark; 572 num_quark++; 573 } 574 } 575 ic->private.proto.saved_icvalues = quark_list; 576 ic->private.proto.num_saved_icvalues = num_quark; 577 return True; 578 } 579 580 for (p = arg, n = 0; p && p->name; p++, n++) { 581 if ((!strcmp(p->name, XNPreeditAttributes)) 582 || (!strcmp(p->name, XNStatusAttributes))) { 583 register XIMArg *pp; 584 int nn; 585 586 for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++); 587 n += nn + 1; 588 } 589 } 590 591 if (!(quark_list = Xmalloc(sizeof(XrmQuark) * n))) { 592 return False; 593 } 594 595 ic->private.proto.saved_icvalues = quark_list; 596 ic->private.proto.num_saved_icvalues = n; 597 for (p = arg; p && p->name; p++, quark_list++) { 598 *quark_list = XrmStringToQuark(p->name); 599 if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) { 600 register XIMArg *pp; 601 602 quark_list++; 603 for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) { 604 *quark_list = XrmStringToQuark(pp->name); 605 } 606 *quark_list = separator; 607 } 608 } 609 return True; 610} 611 612static char * 613_XimDelayModeSetICValues(ic, arg) 614 Xic ic; 615 XIMArg *arg; 616{ 617 XimDefICValues ic_values; 618 char *name; 619 620 _XimGetCurrentICValues(ic, &ic_values); 621 name = _XimSetICValueData(ic, (XPointer)&ic_values, 622 ic->private.proto.ic_resources, 623 ic->private.proto.ic_num_resources, 624 arg, XIM_SETICVALUES, False); 625 _XimSetCurrentICValues(ic, &ic_values); 626 return name; 627} 628#endif /* XIM_CONNECTABLE */ 629 630static Bool 631_XimSetICValuesCheck( 632 Xim im, 633 INT16 len, 634 XPointer data, 635 XPointer arg) 636{ 637 Xic ic = (Xic)arg; 638 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 639 CARD8 major_opcode = *((CARD8 *)data); 640 CARD8 minor_opcode = *((CARD8 *)data + 1); 641 XIMID imid = buf_s[0]; 642 XICID icid = buf_s[1]; 643 644 if ((major_opcode == XIM_SET_IC_VALUES_REPLY) 645 && (minor_opcode == 0) 646 && (imid == im->private.proto.imid) 647 && (icid == ic->private.proto.icid)) 648 return True; 649 if ((major_opcode == XIM_ERROR) 650 && (minor_opcode == 0) 651 && (buf_s[2] & XIM_IMID_VALID) 652 && (imid == im->private.proto.imid) 653 && (buf_s[2] & XIM_ICID_VALID) 654 && (icid == ic->private.proto.icid)) 655 return True; 656 return False; 657} 658 659static char * 660_XimProtoSetICValues( 661 XIC xic, 662 XIMArg *arg) 663{ 664 Xic ic = (Xic)xic; 665 Xim im = (Xim)ic->core.im; 666 XimDefICValues ic_values; 667 INT16 len; 668 CARD16 *buf_s; 669 char *tmp; 670 CARD32 tmp_buf32[BUFSIZE/4]; 671 char *tmp_buf = (char *)tmp_buf32; 672 char *buf; 673 int buf_size; 674 char *data; 675 int data_len; 676 int ret_len; 677 int total; 678 XIMArg *arg_ret; 679 CARD32 reply32[BUFSIZE/4]; 680 char *reply = (char *)reply32; 681 XPointer preply = NULL; 682 int ret_code; 683 BITMASK32 flag = 0L; 684 char *name; 685 char *tmp_name = (arg) ? arg->name : NULL; 686 687#ifndef XIM_CONNECTABLE 688 if (!IS_IC_CONNECTED(ic)) 689 return tmp_name; 690#else 691 if (!_XimSaveICValues(ic, arg)) 692 return NULL; 693 694 if (!IS_IC_CONNECTED(ic)) { 695 if (IS_CONNECTABLE(im)) { 696 if (_XimConnectServer(im)) { 697 if (!_XimReCreateIC(ic)) { 698 _XimDelayModeSetAttr(im); 699 return _XimDelayModeSetICValues(ic, arg); 700 } 701 } else { 702 return _XimDelayModeSetICValues(ic, arg); 703 } 704 } else { 705 return tmp_name; 706 } 707 } 708#endif /* XIM_CONNECTABLE */ 709 710 _XimGetCurrentICValues(ic, &ic_values); 711 memset(tmp_buf, 0, sizeof(tmp_buf32)); 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 = Xcalloc(buf_size + data_len, 1))) { 735 return tmp_name; 736 } 737 memcpy(tmp, buf, buf_size); 738 buf = tmp; 739 } else { 740 if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) { 741 Xfree(buf); 742 return tmp_name; 743 } 744 memset(&tmp[buf_size], 0, data_len); 745 buf = tmp; 746 } 747 } 748 _XimSetCurrentICValues(ic, &ic_values); 749 750 if (!total) { 751 return tmp_name; 752 } 753 754 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 755 756#ifdef EXT_MOVE 757 if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total)) 758 return name; 759#endif 760 761 buf_s[0] = im->private.proto.imid; 762 buf_s[1] = ic->private.proto.icid; 763 buf_s[2] = (INT16)total; 764 buf_s[3] = 0; 765 len = (INT16)(sizeof(CARD16) + sizeof(CARD16) 766 + sizeof(INT16) + sizeof(CARD16) + total); 767 768 _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len); 769 if (!(_XimWrite(im, len, (XPointer)buf))) { 770 if (buf != tmp_buf) 771 Xfree(buf); 772 return tmp_name; 773 } 774 _XimFlush(im); 775 if (buf != tmp_buf) 776 Xfree(buf); 777 ic->private.proto.waitCallback = True; 778 buf_size = BUFSIZE; 779 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 780 _XimSetICValuesCheck, (XPointer)ic); 781 if (ret_code == XIM_TRUE) { 782 preply = reply; 783 } else if (ret_code == XIM_OVERFLOW) { 784 buf_size = (int)len; 785 preply = Xmalloc(buf_size); 786 ret_code = _XimRead(im, &len, preply, buf_size, 787 _XimSetICValuesCheck, (XPointer)ic); 788 if (ret_code != XIM_TRUE) { 789 Xfree(preply); 790 ic->private.proto.waitCallback = False; 791 return tmp_name; 792 } 793 } else { 794 ic->private.proto.waitCallback = False; 795 return tmp_name; 796 } 797 ic->private.proto.waitCallback = False; 798 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 799 if (*((CARD8 *)preply) == XIM_ERROR) { 800 _XimProcError(im, 0, (XPointer)&buf_s[3]); 801 if (reply != preply) 802 Xfree(preply); 803 return tmp_name; 804 } 805 if (reply != preply) 806 Xfree(preply); 807 808 return name; 809} 810 811static Bool 812_XimDestroyICCheck( 813 Xim im, 814 INT16 len, 815 XPointer data, 816 XPointer arg) 817{ 818 Xic ic = (Xic)arg; 819 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 820 CARD8 major_opcode = *((CARD8 *)data); 821 CARD8 minor_opcode = *((CARD8 *)data + 1); 822 XIMID imid = buf_s[0]; 823 XICID icid = buf_s[1]; 824 Bool ret = False; 825 826 if ((major_opcode == XIM_DESTROY_IC_REPLY) 827 && (minor_opcode == 0) 828 && (imid == im->private.proto.imid) 829 && (icid == ic->private.proto.icid)) 830 ret = True; 831 if ((major_opcode == XIM_ERROR) 832 && (minor_opcode == 0) 833 && (buf_s[2] & XIM_IMID_VALID) 834 && (imid == im->private.proto.imid) 835 && (buf_s[2] & XIM_ICID_VALID) 836 && (icid == ic->private.proto.icid)) 837 ret = False; 838 return ret; 839} 840 841static void 842_XimProtoICFree( 843 Xic ic) 844{ 845#ifdef XIM_CONNECTABLE 846 Xim im = (Xim)ic->core.im; 847#endif 848 849 850 Xfree(ic->private.proto.preedit_font); 851 ic->private.proto.preedit_font = NULL; 852 853 854 Xfree(ic->private.proto.status_font); 855 ic->private.proto.status_font = NULL; 856 857 if (ic->private.proto.commit_info) { 858 _XimFreeCommitInfo(ic); 859 ic->private.proto.commit_info = NULL; 860 } 861 862 Xfree(ic->private.proto.ic_inner_resources); 863 ic->private.proto.ic_inner_resources = NULL; 864 865 866#ifdef XIM_CONNECTABLE 867 if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { 868 return; 869 } 870#endif /* XIM_CONNECTABLE */ 871 872 873 Xfree(ic->private.proto.saved_icvalues); 874 ic->private.proto.saved_icvalues = NULL; 875 876 877 Xfree(ic->private.proto.ic_resources); 878 ic->private.proto.ic_resources = NULL; 879 880 881 Xfree(ic->core.hotkey); 882 ic->core.hotkey = NULL; 883 884 885 return; 886} 887 888static void 889_XimProtoDestroyIC( 890 XIC xic) 891{ 892 Xic ic = (Xic)xic; 893 Xim im = (Xim)ic->core.im; 894 CARD32 buf32[BUFSIZE/4]; 895 CARD8 *buf = (CARD8 *)buf32; 896 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 897 INT16 len; 898 CARD32 reply32[BUFSIZE/4]; 899 char *reply = (char *)reply32; 900 XPointer preply; 901 int buf_size; 902 int ret_code; 903 904 if (IS_SERVER_CONNECTED(im)) { 905 buf_s[0] = im->private.proto.imid; /* imid */ 906 buf_s[1] = ic->private.proto.icid; /* icid */ 907 908 len = sizeof(CARD16) /* sizeof imid */ 909 + sizeof(CARD16); /* sizeof icid */ 910 911 _XimSetHeader((XPointer)buf, XIM_DESTROY_IC, 0, &len); 912 (void)_XimWrite(im, len, (XPointer)buf); 913 _XimFlush(im); 914 buf_size = BUFSIZE; 915 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 916 _XimDestroyICCheck, (XPointer)ic); 917 if (ret_code == XIM_OVERFLOW) { 918 buf_size = len; 919 preply = Xmalloc(buf_size); 920 (void)_XimRead(im, &len, preply, buf_size, 921 _XimDestroyICCheck, (XPointer)ic); 922 Xfree(preply); 923 } 924 } 925 UNMARK_IC_CONNECTED(ic); 926 _XimUnregisterFilter(ic); 927 _XimProtoICFree(ic); 928 return; 929} 930 931/* 932 * Some functions require the request queue from the server to be flushed 933 * so that the ordering of client initiated status changes and those requested 934 * by the server is well defined. 935 * _XimSync() would be the function of choice here as it should get a 936 * XIM_SYNC_REPLY back from the server. 937 * This however isn't implemented in the piece of junk that is used by most 938 * input servers as the server side protocol if to XIM. 939 * Since this code is not shipped as a library together with the client side 940 * XIM code but is duplicated by every input server around the world there 941 * is no easy fix to this but this ugly hack below. 942 * Obtaining an IC value from the server sends a request and empties out the 943 * event/server request queue until the answer to this request is found. 944 * Thus it is guaranteed that any pending server side request gets processed. 945 * This is what the hack below is doing. 946 */ 947 948static void 949BrokenSyncWithServer(XIC xic) 950{ 951 CARD32 dummy; 952 XGetICValues(xic, XNFilterEvents, &dummy, NULL); 953} 954 955static void 956_XimProtoSetFocus( 957 XIC xic) 958{ 959 Xic ic = (Xic)xic; 960 Xim im = (Xim)ic->core.im; 961 CARD32 buf32[BUFSIZE/4]; 962 CARD8 *buf = (CARD8 *)buf32; 963 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 964 INT16 len; 965 966#ifndef XIM_CONNECTABLE 967 if (!IS_IC_CONNECTED(ic)) 968 return; 969#else 970 if (!IS_IC_CONNECTED(ic)) { 971 if (IS_CONNECTABLE(im)) { 972 if (_XimConnectServer(im)) { 973 if (!_XimReCreateIC(ic)) { 974 _XimDelayModeSetAttr(im); 975 return; 976 } 977 } else { 978 return; 979 } 980 } else { 981 return; 982 } 983 } 984#endif /* XIM_CONNECTABLE */ 985 BrokenSyncWithServer(xic); 986 987 buf_s[0] = im->private.proto.imid; /* imid */ 988 buf_s[1] = ic->private.proto.icid; /* icid */ 989 990 len = sizeof(CARD16) /* sizeof imid */ 991 + sizeof(CARD16); /* sizeof icid */ 992 993 _XimSetHeader((XPointer)buf, XIM_SET_IC_FOCUS, 0, &len); 994 (void)_XimWrite(im, len, (XPointer)buf); 995 _XimFlush(im); 996 997 _XimRegisterFilter(ic); 998 return; 999} 1000 1001static void 1002_XimProtoUnsetFocus( 1003 XIC xic) 1004{ 1005 Xic ic = (Xic)xic; 1006 Xim im = (Xim)ic->core.im; 1007 CARD32 buf32[BUFSIZE/4]; 1008 CARD8 *buf = (CARD8 *)buf32; 1009 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1010 INT16 len; 1011 1012#ifndef XIM_CONNECTABLE 1013 if (!IS_IC_CONNECTED(ic)) 1014 return; 1015#else 1016 if (!IS_IC_CONNECTED(ic)) { 1017 if (IS_CONNECTABLE(im)) { 1018 if (_XimConnectServer(im)) { 1019 if (!_XimReCreateIC(ic)) { 1020 _XimDelayModeSetAttr(im); 1021 return; 1022 } 1023 } else { 1024 return; 1025 } 1026 } else { 1027 return; 1028 } 1029 } 1030#endif /* XIM_CONNECTABLE */ 1031 1032 BrokenSyncWithServer(xic); 1033 1034 buf_s[0] = im->private.proto.imid; /* imid */ 1035 buf_s[1] = ic->private.proto.icid; /* icid */ 1036 1037 len = sizeof(CARD16) /* sizeof imid */ 1038 + sizeof(CARD16); /* sizeof icid */ 1039 1040 _XimSetHeader((XPointer)buf, XIM_UNSET_IC_FOCUS, 0, &len); 1041 (void)_XimWrite(im, len, (XPointer)buf); 1042 _XimFlush(im); 1043 1044 _XimUnregisterFilter(ic); 1045 return; 1046} 1047 1048static Bool 1049_XimResetICCheck( 1050 Xim im, 1051 INT16 len, 1052 XPointer data, 1053 XPointer arg) 1054{ 1055 Xic ic = (Xic)arg; 1056 CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); 1057 CARD8 major_opcode = *((CARD8 *)data); 1058 CARD8 minor_opcode = *((CARD8 *)data + 1); 1059 XIMID imid = buf_s[0]; 1060 XICID icid = buf_s[1]; 1061 1062 if ((major_opcode == XIM_RESET_IC_REPLY) 1063 && (minor_opcode == 0) 1064 && (imid == im->private.proto.imid) 1065 && (icid == ic->private.proto.icid)) 1066 return True; 1067 if ((major_opcode == XIM_ERROR) 1068 && (minor_opcode == 0) 1069 && (buf_s[2] & XIM_IMID_VALID) 1070 && (imid == im->private.proto.imid) 1071 && (buf_s[2] & XIM_ICID_VALID) 1072 && (icid == ic->private.proto.icid)) 1073 return True; 1074 return False; 1075} 1076 1077static char * 1078_XimProtoReset( 1079 XIC xic, 1080 char * (*retfunc) (Xim im, Xic ic, XPointer buf) ) 1081{ 1082 Xic ic = (Xic)xic; 1083 Xim im = (Xim)ic->core.im; 1084 CARD32 buf32[BUFSIZE/4]; 1085 CARD8 *buf = (CARD8 *)buf32; 1086 CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1087 INT16 len; 1088 CARD32 reply32[BUFSIZE/4]; 1089 char *reply = (char *)reply32; 1090 XPointer preply; 1091 int buf_size; 1092 int ret_code; 1093 char *commit; 1094 1095 if (!IS_IC_CONNECTED(ic)) 1096 return (char *)NULL; 1097 1098 buf_s[0] = im->private.proto.imid; /* imid */ 1099 buf_s[1] = ic->private.proto.icid; /* icid */ 1100 1101 len = sizeof(CARD16) /* sizeof imid */ 1102 + sizeof(CARD16); /* sizeof icid */ 1103 1104 _XimSetHeader((XPointer)buf, XIM_RESET_IC, 0, &len); 1105 if (!(_XimWrite(im, len, (XPointer)buf))) 1106 return NULL; 1107 _XimFlush(im); 1108 ic->private.proto.waitCallback = True; 1109 buf_size = BUFSIZE; 1110 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1111 _XimResetICCheck, (XPointer)ic); 1112 if (ret_code == XIM_TRUE) { 1113 preply = reply; 1114 } else if (ret_code == XIM_OVERFLOW) { 1115 if (len < 0) { 1116 preply = reply; 1117 } else { 1118 buf_size = len; 1119 preply = Xmalloc(buf_size); 1120 ret_code = _XimRead(im, &len, preply, buf_size, 1121 _XimResetICCheck, (XPointer)ic); 1122 if (ret_code != XIM_TRUE) { 1123 Xfree(preply); 1124 ic->private.proto.waitCallback = False; 1125 return NULL; 1126 } 1127 } 1128 } else { 1129 ic->private.proto.waitCallback = False; 1130 return NULL; 1131 } 1132 ic->private.proto.waitCallback = False; 1133 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1134 if (*((CARD8 *)preply) == XIM_ERROR) { 1135 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1136 if (reply != preply) 1137 free(preply); 1138 return NULL; 1139 } 1140 1141 commit = retfunc(im, ic, (XPointer)&buf_s[2]); 1142 1143 if (reply != preply) 1144 Xfree(preply); 1145 return commit; 1146} 1147 1148static char * 1149_XimCommitedMbString( 1150 Xim im, 1151 Xic ic, 1152 XPointer buf) 1153{ 1154 CARD16 *buf_s = (CARD16 *)buf; 1155 XimCommitInfo info; 1156 int len; 1157 int new_len; 1158 char *commit; 1159 char *new_commit = NULL; 1160 char *str; 1161 Status status; 1162 1163 len = 0; 1164 for (info = ic->private.proto.commit_info; info; info = info->next) 1165 len += info->string_len; 1166 len += buf_s[0]; 1167 if ( len == 0 ) 1168 return( NULL ); 1169 1170 if (!(commit = Xmalloc(len + 1))) 1171 goto Error_On_Reset; 1172 1173 str = commit; 1174 for (info = ic->private.proto.commit_info; info; info = info->next) { 1175 (void)memcpy(str, info->string, info->string_len); 1176 str += info->string_len; 1177 } 1178 (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); 1179 commit[len] = '\0'; 1180 1181 new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status); 1182 if (status != XLookupNone) { 1183 if (!(new_commit = Xmalloc(new_len + 1))) { 1184 Xfree(commit); 1185 goto Error_On_Reset; 1186 } 1187 (void)im->methods->ctstombs((XIM)im, commit, len, 1188 new_commit, new_len, NULL); 1189 new_commit[new_len] = '\0'; 1190 } 1191 Xfree(commit); 1192 1193Error_On_Reset: 1194 _XimFreeCommitInfo( ic ); 1195 return new_commit; 1196} 1197 1198static char * 1199_XimProtoMbReset( 1200 XIC xic) 1201{ 1202 return _XimProtoReset(xic, _XimCommitedMbString); 1203} 1204 1205static wchar_t * 1206_XimCommitedWcString( 1207 Xim im, 1208 Xic ic, 1209 XPointer buf) 1210{ 1211 CARD16 *buf_s = (CARD16 *)buf; 1212 XimCommitInfo info; 1213 int len; 1214 int new_len; 1215 char *commit; 1216 wchar_t *new_commit = (wchar_t *)NULL; 1217 char *str; 1218 Status status; 1219 1220 len = 0; 1221 for (info = ic->private.proto.commit_info; info; info = info->next) 1222 len += info->string_len; 1223 len += buf_s[0]; 1224 if ( len == 0 ) 1225 return( (wchar_t *)NULL ); 1226 1227 if (!(commit = Xmalloc(len + 1))) 1228 goto Error_On_Reset; 1229 1230 str = commit; 1231 for (info = ic->private.proto.commit_info; info; info = info->next) { 1232 (void)memcpy(str, info->string, info->string_len); 1233 str += info->string_len; 1234 } 1235 (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); 1236 commit[len] = '\0'; 1237 1238 new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status); 1239 if (status != XLookupNone) { 1240 if (!(new_commit = 1241 (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) { 1242 Xfree(commit); 1243 goto Error_On_Reset; 1244 } 1245 (void)im->methods->ctstowcs((XIM)im, commit, len, 1246 new_commit, new_len, NULL); 1247 new_commit[new_len] = (wchar_t)'\0'; 1248 } 1249 Xfree(commit); 1250 1251Error_On_Reset: 1252 _XimFreeCommitInfo( ic ); 1253 return new_commit; 1254} 1255 1256static wchar_t * 1257_XimProtoWcReset( 1258 XIC xic) 1259{ 1260 return (wchar_t *) _XimProtoReset(xic, 1261 (char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString); 1262} 1263 1264static char * 1265_XimCommitedUtf8String( 1266 Xim im, 1267 Xic ic, 1268 XPointer buf) 1269{ 1270 CARD16 *buf_s = (CARD16 *)buf; 1271 XimCommitInfo info; 1272 int len; 1273 int new_len; 1274 char *commit; 1275 char *new_commit = NULL; 1276 char *str; 1277 Status status; 1278 1279 len = 0; 1280 for (info = ic->private.proto.commit_info; info; info = info->next) 1281 len += info->string_len; 1282 len += buf_s[0]; 1283 if ( len == 0 ) 1284 return( NULL ); 1285 1286 if (!(commit = Xmalloc(len + 1))) 1287 goto Error_On_Reset; 1288 1289 str = commit; 1290 for (info = ic->private.proto.commit_info; info; info = info->next) { 1291 (void)memcpy(str, info->string, info->string_len); 1292 str += info->string_len; 1293 } 1294 (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); 1295 commit[len] = '\0'; 1296 1297 new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status); 1298 if (status != XLookupNone) { 1299 if (!(new_commit = Xmalloc(new_len + 1))) { 1300 Xfree(commit); 1301 goto Error_On_Reset; 1302 } 1303 (void)im->methods->ctstoutf8((XIM)im, commit, len, 1304 new_commit, new_len, NULL); 1305 new_commit[new_len] = '\0'; 1306 } 1307 Xfree(commit); 1308 1309Error_On_Reset: 1310 _XimFreeCommitInfo( ic ); 1311 return new_commit; 1312} 1313 1314static char * 1315_XimProtoUtf8Reset( 1316 XIC xic) 1317{ 1318 return _XimProtoReset(xic, _XimCommitedUtf8String); 1319} 1320 1321static XICMethodsRec ic_methods = { 1322 _XimProtoDestroyIC, /* destroy */ 1323 _XimProtoSetFocus, /* set_focus */ 1324 _XimProtoUnsetFocus, /* unset_focus */ 1325 _XimProtoSetICValues, /* set_values */ 1326 _XimProtoGetICValues, /* get_values */ 1327 _XimProtoMbReset, /* mb_reset */ 1328 _XimProtoWcReset, /* wc_reset */ 1329 _XimProtoUtf8Reset, /* utf8_reset */ 1330 _XimProtoMbLookupString, /* mb_lookup_string */ 1331 _XimProtoWcLookupString, /* wc_lookup_string */ 1332 _XimProtoUtf8LookupString /* utf8_lookup_string */ 1333}; 1334 1335static Bool 1336_XimGetInputStyle( 1337 XIMArg *arg, 1338 XIMStyle *input_style) 1339{ 1340 register XIMArg *p; 1341 1342 for (p = arg; p && p->name; p++) { 1343 if (!(strcmp(p->name, XNInputStyle))) { 1344 *input_style = (XIMStyle)p->value; 1345 return True; 1346 } 1347 } 1348 return False; 1349} 1350 1351#ifdef XIM_CONNECTABLE 1352static Bool 1353_XimDelayModeCreateIC( 1354 Xic ic, 1355 XIMArg *values, 1356 XIMResourceList res, 1357 unsigned int num) 1358{ 1359 Xim im = (Xim)ic->core.im; 1360 XimDefICValues ic_values; 1361 int len; 1362 XIMStyle input_style; 1363 1364 bzero((char *)&ic_values, sizeof(XimDefICValues)); 1365 _XimGetCurrentICValues(ic, &ic_values); 1366 if (!(_XimGetInputStyle(values, &input_style))) 1367 return False; 1368 1369 _XimSetICMode(res, num, input_style); 1370 1371 if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num, 1372 values, XIM_CREATEIC, False)) { 1373 return False; 1374 } 1375 _XimSetCurrentICValues(ic, &ic_values); 1376 if (!_XimSetICDefaults(ic, (XPointer)&ic_values, 1377 XIM_SETICDEFAULTS, res, num)) { 1378 return False; 1379 } 1380 ic_values.filter_events = KeyPressMask; 1381 _XimSetCurrentICValues(ic, &ic_values); 1382 _XimRegisterFilter(ic); 1383 1384 return True; 1385} 1386 1387Bool 1388_XimReconnectModeCreateIC(ic) 1389 Xic ic; 1390{ 1391 Xim im = (Xim)ic->core.im; 1392 int len; 1393 XIMStyle input_style = ic->core.input_style; 1394 XIMResourceList res; 1395 unsigned int num; 1396 1397 num = im->core.ic_num_resources; 1398 len = sizeof(XIMResource) * num; 1399 if (!(res = Xmalloc(len))) 1400 return False; 1401 (void)memcpy((char *)res, (char *)im->core.ic_resources, len); 1402 ic->private.proto.ic_resources = res; 1403 ic->private.proto.ic_num_resources = num; 1404 1405 _XimSetICMode(res, num, input_style); 1406 1407 ic->core.filter_events = KeyPressMask; 1408 1409 return True; 1410} 1411#endif /* XIM_CONNECTABLE */ 1412 1413XIC 1414_XimProtoCreateIC( 1415 XIM xim, 1416 XIMArg *arg) 1417{ 1418 Xim im = (Xim)xim; 1419 Xic ic; 1420 XimDefICValues ic_values; 1421 XIMResourceList res; 1422 unsigned int num; 1423 XIMStyle input_style; 1424 INT16 len; 1425 CARD16 *buf_s; 1426 char *tmp; 1427 CARD32 tmp_buf32[BUFSIZE/4]; 1428 char *tmp_buf = (char *)tmp_buf32; 1429 char *buf; 1430 int buf_size; 1431 char *data; 1432 int data_len; 1433 int ret_len; 1434 int total; 1435 XIMArg *arg_ret; 1436 CARD32 reply32[BUFSIZE/4]; 1437 char *reply = (char *)reply32; 1438 XPointer preply; 1439 int ret_code; 1440 1441#ifdef XIM_CONNECTABLE 1442 if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im)) 1443 return (XIC)NULL; 1444#else 1445 if (!IS_SERVER_CONNECTED(im)) 1446 return (XIC)NULL; 1447#endif /* XIM_CONNECTABLE */ 1448 1449 if (!(_XimGetInputStyle(arg, &input_style))) 1450 return (XIC)NULL; 1451 1452 if ((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL) 1453 return (XIC)NULL; 1454 1455 ic->methods = &ic_methods; 1456 ic->core.im = (XIM)im; 1457 ic->core.input_style = input_style; 1458 1459 num = im->core.ic_num_resources; 1460 len = sizeof(XIMResource) * num; 1461 if (!(res = Xmalloc(len))) 1462 goto ErrorOnCreatingIC; 1463 (void)memcpy((char *)res, (char *)im->core.ic_resources, len); 1464 ic->private.proto.ic_resources = res; 1465 ic->private.proto.ic_num_resources = num; 1466 1467#ifdef XIM_CONNECTABLE 1468 if (!_XimSaveICValues(ic, arg)) 1469 return False; 1470 1471 if (!IS_SERVER_CONNECTED(im)) { 1472 if (!_XimConnectServer(im)) { 1473 if (_XimDelayModeCreateIC(ic, arg, res, num)) { 1474 return (XIC)ic; 1475 } 1476 goto ErrorOnCreatingIC; 1477 } 1478 } 1479#endif /* XIM_CONNECTABLE */ 1480 1481 ic->core.filter_events = im->private.proto.forward_event_mask; 1482 ic->private.proto.forward_event_mask = 1483 im->private.proto.forward_event_mask; 1484 ic->private.proto.synchronous_event_mask = 1485 im->private.proto.synchronous_event_mask; 1486 1487 num = im->private.proto.ic_num_inner_resources; 1488 len = sizeof(XIMResource) * num; 1489 if (!(res = Xmalloc(len))) 1490 goto ErrorOnCreatingIC; 1491 (void)memcpy((char *)res, 1492 (char *)im->private.proto.ic_inner_resources, len); 1493 ic->private.proto.ic_inner_resources = res; 1494 ic->private.proto.ic_num_inner_resources = num; 1495 1496 _XimSetICMode(ic->private.proto.ic_resources, 1497 ic->private.proto.ic_num_resources, input_style); 1498 1499 _XimSetICMode(ic->private.proto.ic_inner_resources, 1500 ic->private.proto.ic_num_inner_resources, input_style); 1501 1502 _XimGetCurrentICValues(ic, &ic_values); 1503 buf = tmp_buf; 1504 buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); 1505 data_len = BUFSIZE - buf_size; 1506 total = 0; 1507 arg_ret = arg; 1508 for (;;) { 1509 data = &buf[buf_size]; 1510 if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources, 1511 ic->private.proto.ic_num_resources, arg, &arg_ret, data, 1512 data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) { 1513 goto ErrorOnCreatingIC; 1514 } 1515 1516 total += ret_len; 1517 if (!(arg = arg_ret)) { 1518 break; 1519 } 1520 1521 buf_size += ret_len; 1522 if (buf == tmp_buf) { 1523 if (!(tmp = Xmalloc(buf_size + data_len))) { 1524 goto ErrorOnCreatingIC; 1525 } 1526 memcpy(tmp, buf, buf_size); 1527 buf = tmp; 1528 } else { 1529 if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) { 1530 Xfree(buf); 1531 goto ErrorOnCreatingIC; 1532 } 1533 buf = tmp; 1534 } 1535 } 1536 _XimSetCurrentICValues(ic, &ic_values); 1537 1538 if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources, 1539 ic->private.proto.ic_num_resources))) 1540 goto ErrorOnCreatingIC; 1541 1542 _XimRegisterFilter(ic); 1543 1544 buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; 1545 buf_s[0] = im->private.proto.imid; 1546 buf_s[1] = (INT16)total; 1547 1548 len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); 1549 _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len); 1550 if (!(_XimWrite(im, len, (XPointer)buf))) { 1551 if (buf != tmp_buf) 1552 Xfree(buf); 1553 goto ErrorOnCreatingIC; 1554 } 1555 _XimFlush(im); 1556 if (buf != tmp_buf) 1557 Xfree(buf); 1558 ic->private.proto.waitCallback = True; 1559 buf_size = BUFSIZE; 1560 ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, 1561 _XimCreateICCheck, 0); 1562 if (ret_code == XIM_TRUE) { 1563 preply = reply; 1564 } else if (ret_code == XIM_OVERFLOW) { 1565 if (len <= 0) { 1566 preply = reply; 1567 } else { 1568 buf_size = (int)len; 1569 preply = Xmalloc(buf_size); 1570 ret_code = _XimRead(im, &len, preply, buf_size, 1571 _XimCreateICCheck, 0); 1572 if (ret_code != XIM_TRUE) { 1573 Xfree(preply); 1574 ic->private.proto.waitCallback = False; 1575 goto ErrorOnCreatingIC; 1576 } 1577 } 1578 } else { 1579 ic->private.proto.waitCallback = False; 1580 goto ErrorOnCreatingIC; 1581 } 1582 ic->private.proto.waitCallback = False; 1583 buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); 1584 if (*((CARD8 *)preply) == XIM_ERROR) { 1585 _XimProcError(im, 0, (XPointer)&buf_s[3]); 1586 if (reply != preply) 1587 Xfree(preply); 1588 goto ErrorOnCreatingIC; 1589 } 1590 1591 ic->private.proto.icid = buf_s[1]; /* icid */ 1592 if (reply != preply) 1593 Xfree(preply); 1594 MARK_IC_CONNECTED(ic); 1595 return (XIC)ic; 1596 1597ErrorOnCreatingIC: 1598 _XimUnregisterFilter(ic); 1599 1600 Xfree(ic->private.proto.ic_resources); 1601 Xfree(ic->private.proto.ic_inner_resources); 1602 Xfree(ic); 1603 return (XIC)NULL; 1604} 1605