imRmAttr.c revision 6e467124
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 len = 0; 1119 buf_s = (CARD16 *)buf; 1120 if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) { 1121 if (_XimSetInnerICAttributes(ic, top, p, mode)) 1122 continue; 1123 return p->name; 1124 } 1125 1126 check = _XimCheckICMode(res, mode); 1127 if (check == XIM_CHECK_INVALID) 1128 continue; 1129 else if (check == XIM_CHECK_ERROR) 1130 return p->name; 1131 1132 if (mode & XIM_PREEDIT_ATTR) { 1133 if (!(_XimEncodePreeditValue(ic, res, p))) 1134 return p->name; 1135 } else if (mode & XIM_STATUS_ATTR) { 1136 if (!(_XimEncodeStatusValue(ic, res, p))) 1137 return p->name; 1138 } else { 1139 if (!(_XimEncodeTopValue(ic, res, p))) 1140 return p->name; 1141 } 1142 1143 if (res->resource_size == XimType_NEST) { 1144 XimDefICValues *ic_attr = (XimDefICValues *)top; 1145 1146 if (res->xrm_name == pre_quark) { 1147 XIMArg *arg_rt; 1148 if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num, 1149 (XIMArg *)p->value, &arg_rt, 1150 (char *)&buf_s[2], (size - min_len), 1151 &len, (XPointer)&ic_attr->preedit_attr, flag, 1152 (mode | XIM_PREEDIT_ATTR)))) { 1153 return name; 1154 } 1155 1156 } else if (res->xrm_name == sts_quark) { 1157 XIMArg *arg_rt; 1158 if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num, 1159 (XIMArg *)p->value, &arg_rt, 1160 (char *)&buf_s[2], (size - min_len), 1161 &len, (XPointer)&ic_attr->status_attr, flag, 1162 (mode | XIM_STATUS_ATTR)))) { 1163 return name; 1164 } 1165 } 1166 } else { 1167#ifdef EXT_MOVE 1168 if (flag) 1169 *flag |= _XimExtenArgCheck(p); 1170#endif 1171 if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode))) 1172 return p->name; 1173 1174 if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], 1175 (size - min_len), p->value, 1176 &len, mode, (XPointer)ic))) 1177 return p->name; 1178 } 1179 1180 if (len == 0) { 1181 continue; 1182 } else if (len < 0) { 1183 *arg_ret = p; 1184 return (char *)NULL; 1185 } 1186 1187 buf_s[0] = res->id; /* attribute ID */ 1188 buf_s[1] = len; /* value length */ 1189 XIM_SET_PAD(&buf_s[2], len); /* pad */ 1190 len += min_len; 1191 1192 buf += len; 1193 *ret_len += len; 1194 size -= len; 1195 } 1196 *arg_ret = (XIMArg *)NULL; 1197 return (char *)NULL; 1198} 1199 1200#ifdef XIM_CONNECTABLE 1201static Bool 1202_XimEncodeSavedPreeditValue( 1203 Xic ic, 1204 XIMResourceList res, 1205 XPointer value) 1206{ 1207 int list_ret; 1208 XFontStruct **struct_list; 1209 char **name_list; 1210 char *tmp; 1211 int len; 1212 register int i; 1213 1214 if (res->xrm_name == XrmStringToQuark(XNFontSet)) { 1215 if (!value) 1216 return False; 1217 1218 if (ic->private.proto.preedit_font) 1219 Xfree(ic->private.proto.preedit_font); 1220 1221 list_ret = XFontsOfFontSet((XFontSet)value, 1222 &struct_list, &name_list); 1223 for(i = 0, len = 0; i < list_ret; i++) { 1224 len += (strlen(name_list[i]) + sizeof(char)); 1225 } 1226 if(!(tmp = Xmalloc(len + 1))) { 1227 ic->private.proto.preedit_font = NULL; 1228 return False; 1229 } 1230 1231 tmp[0] = '\0'; 1232 for(i = 0; i < list_ret; i++) { 1233 strcat(tmp, name_list[i]); 1234 strcat(tmp, ","); 1235 } 1236 tmp[len - 1] = 0; 1237 ic->private.proto.preedit_font = tmp; 1238 ic->private.proto.preedit_font_length = len - 1; 1239 } 1240 return True; 1241} 1242 1243static Bool 1244_XimEncodeSavedStatusValue( 1245 Xic ic, 1246 XIMResourceList res, 1247 XPointer value) 1248{ 1249 int list_ret; 1250 XFontStruct **struct_list; 1251 char **name_list; 1252 char *tmp; 1253 int len; 1254 register int i; 1255 1256 if (res->xrm_name == XrmStringToQuark(XNFontSet)) { 1257 if (!value) 1258 return False; 1259 1260 Xfree(ic->private.proto.status_font); 1261 1262 list_ret = XFontsOfFontSet((XFontSet)value, 1263 &struct_list, &name_list); 1264 for(i = 0, len = 0; i < list_ret; i++) { 1265 len += (strlen(name_list[i]) + sizeof(char)); 1266 } 1267 if(!(tmp = Xmalloc(len + 1))) { 1268 ic->private.proto.status_font = NULL; 1269 return False; 1270 } 1271 1272 tmp[0] = '\0'; 1273 for(i = 0; i < list_ret; i++) { 1274 strcat(tmp, name_list[i]); 1275 strcat(tmp, ","); 1276 } 1277 tmp[len - 1] = 0; 1278 ic->private.proto.status_font = tmp; 1279 ic->private.proto.status_font_length = len - 1; 1280 } 1281 return True; 1282} 1283 1284Bool 1285_XimEncodeSavedICATTRIBUTE( 1286 Xic ic, 1287 XIMResourceList res_list, 1288 unsigned int res_num, 1289 int *idx, 1290 char *buf, 1291 int size, 1292 int *ret_len, 1293 XPointer top, 1294 unsigned long mode) 1295{ 1296 int i; 1297 int num = ic->private.proto.num_saved_icvalues; 1298 XrmQuark *quark_list = ic->private.proto.saved_icvalues; 1299 XIMResourceList res; 1300 XPointer value; 1301 CARD16 *buf_s; 1302 int len; 1303 int min_len = sizeof(CARD16) /* sizeof attribute ID */ 1304 + sizeof(INT16); /* sizeof value length */ 1305 XrmQuark pre_quark; 1306 XrmQuark sts_quark; 1307 XrmQuark separator; 1308 1309 if (!ic->private.proto.saved_icvalues) { 1310 *idx = -1; 1311 *ret_len = 0; 1312 return True; 1313 } 1314 1315 pre_quark = XrmStringToQuark(XNPreeditAttributes); 1316 sts_quark = XrmStringToQuark(XNStatusAttributes); 1317 separator = XrmStringToQuark(XNSeparatorofNestedList); 1318 1319 *ret_len = 0; 1320 for (i = *idx; i < num; i++) { 1321 if (quark_list[i] == separator) { 1322 *idx = i; 1323 return True; 1324 } 1325 1326 if (!(res = _XimGetResourceListRecByQuark(res_list, 1327 res_num, quark_list[i]))) 1328 continue; 1329 1330 if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode)) 1331 return False; 1332 1333 if (mode & XIM_PREEDIT_ATTR) { 1334 if (!(_XimEncodeSavedPreeditValue(ic, res, value))) { 1335 return False; 1336 } 1337 } else if (mode & XIM_STATUS_ATTR) { 1338 if (!(_XimEncodeSavedStatusValue(ic, res, value))) { 1339 return False; 1340 } 1341 } 1342 1343 buf_s = (CARD16 *)buf; 1344 if (res->resource_size == XimType_NEST) { 1345 XimDefICValues *ic_attr = (XimDefICValues *)top; 1346 1347 i++; 1348 if (res->xrm_name == pre_quark) { 1349 if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num, 1350 &i, (char *)&buf_s[2], (size - min_len), 1351 &len, (XPointer)&ic_attr->preedit_attr, 1352 (mode | XIM_PREEDIT_ATTR))) { 1353 return False; 1354 } 1355 1356 } else if (res->xrm_name == sts_quark) { 1357 if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num, 1358 &i, (char *)&buf_s[2], (size - min_len), 1359 &len, (XPointer)&ic_attr->status_attr, 1360 (mode | XIM_STATUS_ATTR))) { 1361 return False; 1362 } 1363 } 1364 } else { 1365 if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], 1366 (size - min_len), value, 1367 &len, mode, (XPointer)ic))) { 1368 return False; 1369 } 1370 } 1371 1372 if (len == 0) { 1373 continue; 1374 } else if (len < 0) { 1375 if (quark_list[i] == separator) 1376 i++; 1377 *idx = i; 1378 return True; 1379 } 1380 1381 buf_s[0] = res->id; /* attribute ID */ 1382 buf_s[1] = len; /* value length */ 1383 XIM_SET_PAD(&buf_s[2], len); /* pad */ 1384 len += min_len; 1385 1386 buf += len; 1387 *ret_len += len; 1388 size -= len; 1389 } 1390 *idx = -1; 1391 return True; 1392} 1393#endif /* XIM_CONNECTABLE */ 1394 1395static unsigned int 1396_XimCountNumberOfAttr( 1397 CARD16 total, 1398 CARD16 *attr, 1399 unsigned int *names_len) 1400{ 1401 unsigned int n; 1402 CARD16 len; 1403 CARD16 min_len = sizeof(CARD16) /* sizeof attribute ID */ 1404 + sizeof(CARD16) /* sizeof type of value */ 1405 + sizeof(INT16); /* sizeof length of attribute */ 1406 1407 n = 0; 1408 *names_len = 0; 1409 while (total > min_len) { 1410 len = attr[2]; 1411 if (len > (total - min_len)) { 1412 return 0; 1413 } 1414 *names_len += (len + 1); 1415 len += (min_len + XIM_PAD(len + 2)); 1416 total -= len; 1417 attr = (CARD16 *)((char *)attr + len); 1418 n++; 1419 } 1420 return n; 1421} 1422 1423Bool 1424_XimGetAttributeID( 1425 Xim im, 1426 CARD16 *buf) 1427{ 1428 unsigned int n, names_len, values_len; 1429 XIMResourceList res; 1430 char *names; 1431 XPointer tmp; 1432 XIMValuesList *values_list; 1433 char **values; 1434 register int i; 1435 CARD16 len; 1436 CARD16 min_len = sizeof(CARD16) /* sizeof attribute ID */ 1437 + sizeof(CARD16) /* sizeof type of value */ 1438 + sizeof(INT16); /* sizeof length of attr */ 1439 /* 1440 * IM attribute ID 1441 */ 1442 1443 if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len))) 1444 return False; 1445 1446 if (!(res = Xcalloc(n, sizeof(XIMResource)))) 1447 return False; 1448 1449 values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len; 1450 if (!(tmp = Xcalloc(1, values_len))) { 1451 Xfree(res); 1452 return False; 1453 } 1454 1455 values_list = (XIMValuesList *)tmp; 1456 values = (char **)((char *)tmp + sizeof(XIMValuesList)); 1457 names = (char *)((char *)values + (sizeof(char **) * n)); 1458 1459 values_list->count_values = n; 1460 values_list->supported_values = values; 1461 1462 buf++; 1463 for (i = 0; i < n; i++) { 1464 len = buf[2]; 1465 (void)memcpy(names, (char *)&buf[3], len); 1466 values[i] = names; 1467 names[len] = '\0'; 1468 res[i].resource_name = names; 1469 res[i].resource_size = buf[1]; 1470 res[i].id = buf[0]; 1471 names += (len + 1); 1472 len += (min_len + XIM_PAD(len + 2)); 1473 buf = (CARD16 *)((char *)buf + len); 1474 } 1475 _XIMCompileResourceList(res, n); 1476 1477 Xfree(im->core.im_resources); 1478 Xfree(im->core.im_values_list); 1479 1480 im->core.im_resources = res; 1481 im->core.im_num_resources = n; 1482 im->core.im_values_list = values_list; 1483 1484 /* 1485 * IC attribute ID 1486 */ 1487 1488 if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len))) 1489 return False; 1490 1491 if (!(res = Xcalloc(n, sizeof(XIMResource)))) 1492 return False; 1493 1494 values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len; 1495 if (!(tmp = Xcalloc(1, values_len))) { 1496 Xfree(res); 1497 return False; 1498 } 1499 1500 values_list = (XIMValuesList *)tmp; 1501 values = (char **)((char *)tmp + sizeof(XIMValuesList)); 1502 names = (char *)((char *)values + (sizeof(char **) * n)); 1503 1504 values_list->count_values = n; 1505 values_list->supported_values = values; 1506 1507 buf += 2; 1508 for (i = 0; i < n; i++) { 1509 len = buf[2]; 1510 (void)memcpy(names, (char *)&buf[3], len); 1511 values[i] = names; 1512 names[len] = '\0'; 1513 res[i].resource_name = names; 1514 res[i].resource_size = buf[1]; 1515 res[i].id = buf[0]; 1516 names += (len + 1); 1517 len += (min_len + XIM_PAD(len + 2)); 1518 buf = (CARD16 *)((char *)buf + len); 1519 } 1520 _XIMCompileResourceList(res, n); 1521 1522 1523 Xfree(im->core.ic_resources); 1524 Xfree(im->core.ic_values_list); 1525 1526 im->core.ic_resources = res; 1527 im->core.ic_num_resources = n; 1528 im->core.ic_values_list = values_list; 1529 1530 return True; 1531} 1532