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