XDefaultOMIF.c revision 2d67cb4f
1/* 2Copyright 1985, 1986, 1987, 1991, 1998 The Open Group 3 4Permission is hereby granted, free of charge, to any person obtaining a 5copy of this software and associated documentation files (the 6"Software"), to deal in the Software without restriction, including 7without limitation the rights to use, copy, modify, merge, publish, 8distribute, sublicense, and/or sell copies of the Software, and to 9permit persons to whom the Software is furnished to do so, subject to 10the following conditions: The above copyright notice and this 11permission notice shall be included in all copies or substantial 12portions of the Software. 13 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE 21EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. 22 23 24Except as contained in this notice, the name of The Open Group shall not be 25used in advertising or otherwise to promote the sale, use or other dealings 26in this Software without prior written authorization from The Open Group. 27 28 29X Window System is a trademark of The Open Group 30 31OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF 32logo, LBX, X Window System, and Xinerama are trademarks of the Open 33Group. All other trademarks and registered trademarks mentioned herein 34are the property of their respective owners. No right, title or 35interest in or to any trademark, service mark, logo or trade name of 36Sun Microsystems, Inc. or its licensors is granted. 37 38*/ 39/* 40 * Copyright 2000 Oracle and/or its affiliates. All rights reserved. 41 * 42 * Permission is hereby granted, free of charge, to any person obtaining a 43 * copy of this software and associated documentation files (the "Software"), 44 * to deal in the Software without restriction, including without limitation 45 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 46 * and/or sell copies of the Software, and to permit persons to whom the 47 * Software is furnished to do so, subject to the following conditions: 48 * 49 * The above copyright notice and this permission notice (including the next 50 * paragraph) shall be included in all copies or substantial portions of the 51 * Software. 52 * 53 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 54 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 56 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 57 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 58 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 59 * DEALINGS IN THE SOFTWARE. 60 */ 61 62 63#ifdef HAVE_CONFIG_H 64#include <config.h> 65#endif 66#include "Xlibint.h" 67#include "Xlcint.h" 68#include "XlcPublic.h" 69#include <X11/Xos.h> 70#include <X11/Xatom.h> 71#include <stdio.h> 72 73#define MAXFONTS 100 74 75#define XOM_GENERIC(om) (&((XOMGeneric) om)->gen) 76#define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen) 77 78#define DefineLocalBuf char local_buf[BUFSIZ] 79#define AllocLocalBuf(length) (length > BUFSIZ ? Xmalloc(length) : local_buf) 80#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) 81 82typedef struct _FontDataRec { 83 char *name; 84} FontDataRec, *FontData; 85 86typedef struct _OMDataRec { 87 int font_data_count; 88 FontData font_data; 89} OMDataRec, *OMData; 90 91typedef struct _XOMGenericPart { 92 OMData data; 93} XOMGenericPart; 94 95typedef struct _XOMGenericRec { 96 XOMMethods methods; 97 XOMCoreRec core; 98 XOMGenericPart gen; 99} XOMGenericRec, *XOMGeneric; 100 101typedef struct _FontSetRec { 102 int id; 103 int font_data_count; 104 FontData font_data; 105 char *font_name; 106 XFontStruct *info; 107 XFontStruct *font; 108} FontSetRec, *FontSet; 109 110typedef struct _XOCGenericPart { 111 XlcConv wcs_to_cs; 112 FontSet font_set; 113} XOCGenericPart; 114 115typedef struct _XOCGenericRec { 116 XOCMethods methods; 117 XOCCoreRec core; 118 XOCGenericPart gen; 119} XOCGenericRec, *XOCGeneric; 120 121static Bool 122init_fontset( 123 XOC oc) 124{ 125 XOCGenericPart *gen; 126 FontSet font_set; 127 OMData data; 128 129 data = XOM_GENERIC(oc->core.om)->data; 130 131 font_set = Xcalloc(1, sizeof(FontSetRec)); 132 if (font_set == NULL) 133 return False; 134 135 gen = XOC_GENERIC(oc); 136 gen->font_set = font_set; 137 138 font_set->font_data_count = data->font_data_count; 139 font_set->font_data = data->font_data; 140 141 return True; 142} 143 144static char * 145get_prop_name( 146 Display *dpy, 147 XFontStruct *fs) 148{ 149 unsigned long fp; 150 151 if (XGetFontProperty(fs, XA_FONT, &fp)) 152 return XGetAtomName(dpy, fp); 153 154 return (char *) NULL; 155} 156 157static FontData 158check_charset( 159 FontSet font_set, 160 char *font_name) 161{ 162 FontData font_data; 163 char *last; 164 int count; 165 ssize_t length, name_len; 166 167 name_len = strlen(font_name); 168 last = font_name + name_len; 169 170 count = font_set->font_data_count; 171 font_data = font_set->font_data; 172 173 for ( ; count-- > 0; font_data++) { 174 length = strlen(font_data->name); 175 176 if (length > name_len) 177 return(NULL); 178 179 if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) 180 return font_data; 181 } 182 return (FontData) NULL; 183} 184 185static Bool 186load_font( 187 XOC oc) 188{ 189 Display *dpy = oc->core.om->core.display; 190 XOCGenericPart *gen = XOC_GENERIC(oc); 191 FontSet font_set = gen->font_set; 192 193 if (font_set->font_name == NULL) 194 return False; 195 196 if (font_set->font == NULL) { 197 font_set->font = XLoadQueryFont(dpy, font_set->font_name); 198 if (font_set->font == NULL) 199 return False; 200 } 201 return True; 202} 203 204static void 205set_fontset_extents( 206 XOC oc) 207{ 208 XRectangle *ink = &oc->core.font_set_extents.max_ink_extent; 209 XRectangle *logical = &oc->core.font_set_extents.max_logical_extent; 210 XFontStruct **font_list, *font; 211 XCharStruct overall; 212 int logical_ascent, logical_descent; 213 214 font_list = oc->core.font_info.font_struct_list; 215 font = *font_list++; 216 overall = font->max_bounds; 217 overall.lbearing = font->min_bounds.lbearing; 218 logical_ascent = font->ascent; 219 logical_descent = font->descent; 220 221 ink->x = overall.lbearing; 222 ink->y = -(overall.ascent); 223 ink->width = overall.rbearing - overall.lbearing; 224 ink->height = overall.ascent + overall.descent; 225 226 logical->x = 0; 227 logical->y = -(logical_ascent); 228 logical->width = overall.width; 229 logical->height = logical_ascent + logical_descent; 230} 231 232static Bool 233init_core_part( 234 XOC oc) 235{ 236 XOCGenericPart *gen = XOC_GENERIC(oc); 237 FontSet font_set; 238 XFontStruct **font_struct_list; 239 char **font_name_list, *font_name_buf; 240 241 font_set = gen->font_set; 242 243 if (font_set->font_name == NULL) 244 return False; 245 246 font_struct_list = Xmalloc(sizeof(XFontStruct *)); 247 if (font_struct_list == NULL) 248 return False; 249 250 font_name_list = Xmalloc(sizeof(char *)); 251 if (font_name_list == NULL) 252 goto err; 253 254 font_name_buf = strdup(font_set->font_name); 255 if (font_name_buf == NULL) 256 goto err; 257 258 oc->core.font_info.num_font = 1; 259 oc->core.font_info.font_name_list = font_name_list; 260 oc->core.font_info.font_struct_list = font_struct_list; 261 262 font_set->id = 1; 263 if (font_set->font) 264 *font_struct_list = font_set->font; 265 else 266 *font_struct_list = font_set->info; 267 Xfree(font_set->font_name); 268 *font_name_list = font_set->font_name = font_name_buf; 269 270 set_fontset_extents(oc); 271 272 return True; 273 274err: 275 276 Xfree(font_name_list); 277 Xfree(font_struct_list); 278 279 return False; 280} 281 282static char * 283get_font_name( 284 XOC oc, 285 char *pattern) 286{ 287 char **list, *name; 288 int count; 289 XFontStruct *fs; 290 Display *dpy = oc->core.om->core.display; 291 292 list = XListFonts(dpy, pattern, 1, &count); 293 if (list != NULL) { 294 name = strdup(*list); 295 296 XFreeFontNames(list); 297 } else { 298 fs = XLoadQueryFont(dpy, pattern); 299 if (fs == NULL) return NULL; 300 301 name = get_prop_name(dpy, fs); 302 XFreeFont(dpy, fs); 303 } 304 return name; 305} 306 307static int 308parse_fontname( 309 XOC oc) 310{ 311 XOCGenericPart *gen = XOC_GENERIC(oc); 312 FontSet font_set; 313 FontData font_data; 314 char *pattern, *last, buf[BUFSIZ]; 315 int font_data_count, found_num = 0; 316 ssize_t length; 317 int count, num_fields; 318 char *base_name, *font_name, **name_list, **cur_name_list; 319 char *charset_p = NULL; 320 Bool append_charset; 321 /* 322 append_charset flag should be set to True when the XLFD fontname 323 doesn't contain a chaset part. 324 */ 325 326 name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); 327 if (name_list == NULL) 328 return -1; 329 cur_name_list = name_list; 330 331 while (count-- > 0) { 332 pattern = *cur_name_list++; 333 if (pattern == NULL || *pattern == '\0') 334 continue; 335 336 append_charset = False; 337 338 if (strchr(pattern, '*') == NULL && 339 (font_name = get_font_name(oc, pattern))) { 340 341 font_set = gen->font_set; 342 343 font_data = check_charset(font_set, font_name); 344 if (font_data == NULL) { 345 Display *dpy = oc->core.om->core.display; 346 char **fn_list = NULL, *prop_fname = NULL; 347 int list_num; 348 XFontStruct *fs_list; 349 if ((fn_list = XListFontsWithInfo(dpy, font_name, 350 MAXFONTS, 351 &list_num, &fs_list)) 352 && (prop_fname = get_prop_name(dpy, fs_list)) 353 && (font_data = check_charset(font_set, prop_fname))) { 354 if (fn_list) { 355 XFreeFontInfo(fn_list, fs_list, list_num); 356 fn_list = NULL; 357 } 358 font_name = prop_fname; 359 } 360 } 361 if (font_data == NULL) 362 continue; 363 364 font_set->font_name = strdup(font_name); 365 Xfree(font_name); 366 if (font_set->font_name == NULL) { 367 goto err; 368 } 369 found_num++; 370 goto found; 371 } 372 373 strncpy(buf, pattern, BUFSIZ); 374 buf[BUFSIZ-1] = '\0'; 375 length = strlen(buf); 376 last = buf + length - 1; 377 378 for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) 379 if (*base_name == '-') num_fields++; 380 if (strchr(pattern, '*') == NULL) { 381 if (num_fields == 12) { 382 append_charset = True; 383 *++last = '-'; 384 last++; 385 } else 386 continue; 387 } else { 388 if (num_fields == 13 || num_fields == 14) { 389 /* 390 * There are 14 fields in an XLFD name -- make certain the 391 * charset (& encoding) is placed in the correct field. 392 */ 393 append_charset = True; 394 last = strrchr (buf, '-'); 395 if (num_fields == 14) { 396 *last = '\0'; 397 last = strrchr (buf, '-'); 398 } 399 last++; 400 } else if (*last == '*') { 401 append_charset = True; 402 if (length > 3 && *(last-3) == '-' && *(last-2) == '*' 403 && *(last-1) == '-') { 404 last -= 2; 405 } 406 *++last = '-'; 407 last++; 408 } else { 409 last = strrchr (buf, '-'); 410 charset_p = last; 411 charset_p = strrchr (buf, '-'); 412 while (*(--charset_p) != '-'); 413 charset_p++; 414 } 415 } 416 417 font_set = gen->font_set; 418 419 font_data = font_set->font_data; 420 font_data_count = font_set->font_data_count; 421 for ( ; font_data_count-- > 0; font_data++) { 422 if (append_charset) 423 { 424 strncpy(last, font_data->name, BUFSIZ - length); 425 buf[BUFSIZ-1] = '\0'; 426 } 427 else { 428 if (_XlcCompareISOLatin1(charset_p, 429 font_data->name)) { 430 continue; 431 } 432 } 433 if ((font_set->font_name = get_font_name(oc, buf))) 434 break; 435 } 436 if (font_set->font_name != NULL) { 437 found_num++; 438 goto found; 439 } 440 } 441 found: 442 base_name = strdup(oc->core.base_name_list); 443 if (base_name == NULL) 444 goto err; 445 446 oc->core.base_name_list = base_name; 447 448 XFreeStringList(name_list); 449 450 return found_num; 451err: 452 XFreeStringList(name_list); 453 454 return -1; 455} 456 457static Bool 458set_missing_list( 459 XOC oc) 460{ 461 XOCGenericPart *gen = XOC_GENERIC(oc); 462 FontSet font_set; 463 char **charset_list, *charset_buf; 464 465 font_set = gen->font_set; 466 467 if (font_set->info == NULL || font_set->font == NULL) 468 return True; 469 470 charset_list = Xmalloc(sizeof(char *)); 471 if (charset_list == NULL) 472 return False; 473 474 charset_buf = strdup(font_set->font_data->name); 475 if (charset_buf == NULL) { 476 Xfree(charset_list); 477 return False; 478 } 479 480 oc->core.missing_list.charset_list = charset_list; 481 482 *charset_list = charset_buf; 483 484 return True; 485} 486 487static Bool 488create_fontset( 489 XOC oc) 490{ 491 int found_num; 492 493 if (init_fontset(oc) == False) 494 return False; 495 496 found_num = parse_fontname(oc); 497 if (found_num <= 0) { 498 if (found_num == 0) 499 set_missing_list(oc); 500 return False; 501 } 502 503 if (load_font(oc) == False) 504 return False; 505 506 if (init_core_part(oc) == False) 507 return False; 508 509 if (set_missing_list(oc) == False) 510 return False; 511 512 return True; 513} 514 515static void 516destroy_oc( 517 XOC oc) 518{ 519 Display *dpy = oc->core.om->core.display; 520 XOCGenericPart *gen = XOC_GENERIC(oc); 521 XFontStruct **font_list, *font; 522 523 524 Xfree(gen->font_set); 525 Xfree(oc->core.base_name_list); 526 XFreeStringList(oc->core.font_info.font_name_list); 527 528 if ((font_list = oc->core.font_info.font_struct_list)) { 529 if ((font = *font_list)) { 530 if (font->fid) 531 XFreeFont(dpy, font); 532 else 533 XFreeFontInfo(NULL, font, 1); 534 } 535 Xfree(oc->core.font_info.font_struct_list); 536 } 537 538 539 XFreeStringList(oc->core.missing_list.charset_list); 540 541#ifdef notdef 542 Xfree(oc->core.res_name); 543 Xfree(oc->core.res_class); 544#endif 545 546 Xfree(oc); 547} 548 549static char * 550set_oc_values( 551 XOC oc, 552 XlcArgList args, 553 int num_args) 554{ 555 if (oc->core.resources == NULL) 556 return NULL; 557 558 return _XlcSetValues((XPointer) oc, oc->core.resources, 559 oc->core.num_resources, args, num_args, XlcSetMask); 560} 561 562static char * 563get_oc_values( 564 XOC oc, 565 XlcArgList args, 566 int num_args) 567{ 568 if (oc->core.resources == NULL) 569 return NULL; 570 571 return _XlcGetValues((XPointer) oc, oc->core.resources, 572 oc->core.num_resources, args, num_args, XlcGetMask); 573} 574 575static Bool 576wcs_to_mbs( 577 XOC oc, 578 char *to, 579 _Xconst wchar_t *from, 580 int length) 581{ 582 XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs; 583 XLCd lcd; 584 int ret, to_left = length; 585 586 if (conv == NULL) { 587 lcd = oc->core.om->core.lcd; 588 conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte); 589 if (conv == NULL) 590 return False; 591 XOC_GENERIC(oc)->wcs_to_cs = conv; 592 } else 593 _XlcResetConverter(conv); 594 595 ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to, 596 &to_left, NULL, 0); 597 if (ret != 0 || length > 0) 598 return False; 599 600 return True; 601} 602 603static int 604_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length) 605{ 606 return XTextWidth(*oc->core.font_info.font_struct_list, text, length); 607} 608 609static int 610_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length) 611{ 612 DefineLocalBuf; 613 char *buf = AllocLocalBuf(length); 614 int ret = 0; 615 616 if (buf == NULL) 617 return 0; 618 619 if (wcs_to_mbs(oc, buf, text, length) == False) 620 goto err; 621 622 ret = _XmbDefaultTextEscapement(oc, buf, length); 623 624err: 625 FreeLocalBuf(buf); 626 627 return ret; 628} 629 630static int 631_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length, 632 XRectangle *overall_ink, XRectangle *overall_logical) 633{ 634 int direction, logical_ascent, logical_descent; 635 XCharStruct overall; 636 637 XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction, 638 &logical_ascent, &logical_descent, &overall); 639 640 if (overall_ink) { 641 overall_ink->x = overall.lbearing; 642 overall_ink->y = -(overall.ascent); 643 overall_ink->width = overall.rbearing - overall.lbearing; 644 overall_ink->height = overall.ascent + overall.descent; 645 } 646 647 if (overall_logical) { 648 overall_logical->x = 0; 649 overall_logical->y = -(logical_ascent); 650 overall_logical->width = overall.width; 651 overall_logical->height = logical_ascent + logical_descent; 652 } 653 654 return overall.width; 655} 656 657static int 658_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length, 659 XRectangle *overall_ink, XRectangle *overall_logical) 660{ 661 DefineLocalBuf; 662 char *buf = AllocLocalBuf(length); 663 int ret = 0; 664 665 if (buf == NULL) 666 return 0; 667 668 if (wcs_to_mbs(oc, buf, text, length) == False) 669 goto err; 670 671 ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical); 672 673err: 674 FreeLocalBuf(buf); 675 676 return ret; 677} 678 679static Status 680_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length, 681 XRectangle *ink_buf, XRectangle *logical_buf, 682 int buf_size, int *num_chars, 683 XRectangle *overall_ink, 684 XRectangle *overall_logical) 685{ 686 XFontStruct *font = *oc->core.font_info.font_struct_list; 687 XCharStruct *def, *cs, overall; 688 Bool first = True; 689 690 if (buf_size < length) 691 return 0; 692 693 bzero((char *) &overall, sizeof(XCharStruct)); 694 *num_chars = 0; 695 696 CI_GET_DEFAULT_INFO_1D(font, def) 697 698 while (length-- > 0) { 699 CI_GET_CHAR_INFO_1D(font, *text, def, cs) 700 text++; 701 if (cs == NULL) 702 continue; 703 704 ink_buf->x = overall.width + cs->lbearing; 705 ink_buf->y = -(cs->ascent); 706 ink_buf->width = cs->rbearing - cs->lbearing; 707 ink_buf->height = cs->ascent + cs->descent; 708 ink_buf++; 709 710 logical_buf->x = overall.width; 711 logical_buf->y = -(font->ascent); 712 logical_buf->width = cs->width; 713 logical_buf->height = font->ascent + font->descent; 714 logical_buf++; 715 716 if (first) { 717 overall = *cs; 718 first = False; 719 } else { 720 overall.ascent = max(overall.ascent, cs->ascent); 721 overall.descent = max(overall.descent, cs->descent); 722 overall.lbearing = min(overall.lbearing, overall.width + 723 cs->lbearing); 724 overall.rbearing = max(overall.rbearing, overall.width + 725 cs->rbearing); 726 overall.width += cs->width; 727 } 728 (*num_chars)++; 729 } 730 731 if (overall_ink) { 732 overall_ink->x = overall.lbearing; 733 overall_ink->y = -(overall.ascent); 734 overall_ink->width = overall.rbearing - overall.lbearing; 735 overall_ink->height = overall.ascent + overall.descent; 736 } 737 738 if (overall_logical) { 739 overall_logical->x = 0; 740 overall_logical->y = -(font->ascent); 741 overall_logical->width = overall.width; 742 overall_logical->height = font->ascent + font->descent; 743 } 744 745 return 1; 746} 747 748static Status 749_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length, 750 XRectangle *ink_buf, XRectangle *logical_buf, 751 int buf_size, int *num_chars, 752 XRectangle *overall_ink, 753 XRectangle *overall_logical) 754{ 755 DefineLocalBuf; 756 char *buf = AllocLocalBuf(length); 757 Status ret = 0; 758 759 if (buf == NULL) 760 return 0; 761 762 if (wcs_to_mbs(oc, buf, text, length) == False) 763 goto err; 764 765 ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf, 766 buf_size, num_chars, overall_ink, 767 overall_logical); 768 769err: 770 FreeLocalBuf(buf); 771 772 return ret; 773} 774 775static int 776_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 777 _Xconst char *text, int length) 778{ 779 XFontStruct *font = *oc->core.font_info.font_struct_list; 780 781 XSetFont(dpy, gc, font->fid); 782 XDrawString(dpy, d, gc, x, y, text, length); 783 784 return XTextWidth(font, text, length); 785} 786 787static int 788_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, 789 _Xconst wchar_t *text, int length) 790{ 791 DefineLocalBuf; 792 char *buf = AllocLocalBuf(length); 793 int ret = 0; 794 795 if (buf == NULL) 796 return 0; 797 798 if (wcs_to_mbs(oc, buf, text, length) == False) 799 goto err; 800 801 ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length); 802 803err: 804 FreeLocalBuf(buf); 805 806 return ret; 807} 808 809static void 810_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, 811 int y, _Xconst char *text, int length) 812{ 813 XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid); 814 XDrawImageString(dpy, d, gc, x, y, text, length); 815} 816 817static void 818_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, 819 int y, _Xconst wchar_t *text, int length) 820{ 821 DefineLocalBuf; 822 char *buf = AllocLocalBuf(length); 823 824 if (buf == NULL) 825 return; 826 827 if (wcs_to_mbs(oc, buf, text, length) == False) 828 goto err; 829 830 _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length); 831 832err: 833 FreeLocalBuf(buf); 834} 835 836static _Xconst XOCMethodsRec oc_default_methods = { 837 destroy_oc, 838 set_oc_values, 839 get_oc_values, 840 _XmbDefaultTextEscapement, 841 _XmbDefaultTextExtents, 842 _XmbDefaultTextPerCharExtents, 843 _XmbDefaultDrawString, 844 _XmbDefaultDrawImageString, 845 _XwcDefaultTextEscapement, 846 _XwcDefaultTextExtents, 847 _XwcDefaultTextPerCharExtents, 848 _XwcDefaultDrawString, 849 _XwcDefaultDrawImageString 850}; 851 852static XlcResource oc_resources[] = { 853 { XNBaseFontName, NULLQUARK, sizeof(char *), 854 XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, 855 { XNOMAutomatic, NULLQUARK, sizeof(Bool), 856 XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, 857 { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), 858 XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, 859 { XNDefaultString, NULLQUARK, sizeof(char *), 860 XOffsetOf(XOCRec, core.default_string), XlcGetMask }, 861 { XNOrientation, NULLQUARK, sizeof(XOrientation), 862 XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask }, 863 { XNResourceName, NULLQUARK, sizeof(char *), 864 XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, 865 { XNResourceClass, NULLQUARK, sizeof(char *), 866 XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, 867 { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), 868 XOffsetOf(XOCRec, core.font_info), XlcGetMask } 869}; 870 871static XOC 872create_oc( 873 XOM om, 874 XlcArgList args, 875 int num_args) 876{ 877 XOC oc; 878 879 oc = Xcalloc(1, sizeof(XOCGenericRec)); 880 if (oc == NULL) 881 return (XOC) NULL; 882 883 oc->core.om = om; 884 885 if (oc_resources[0].xrm_name == NULLQUARK) 886 _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); 887 888 if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), 889 args, num_args, XlcCreateMask | XlcDefaultMask)) 890 goto err; 891 892 if (oc->core.base_name_list == NULL) 893 goto err; 894 895 oc->core.resources = oc_resources; 896 oc->core.num_resources = XlcNumber(oc_resources); 897 898 if (create_fontset(oc) == False) 899 goto err; 900 901 oc->methods = (XOCMethods)&oc_default_methods; 902 903 return oc; 904 905err: 906 destroy_oc(oc); 907 908 return (XOC) NULL; 909} 910 911static Status 912close_om( 913 XOM om) 914{ 915 XOMGenericPart *gen = XOM_GENERIC(om); 916 OMData data; 917 FontData font_data; 918 int count; 919 920 if ((data = gen->data)) { 921 if (data->font_data) { 922 for (font_data = data->font_data, count = data->font_data_count; 923 count-- > 0 ; font_data++) { 924 Xfree(font_data->name); 925 } 926 Xfree(data->font_data); 927 } 928 Xfree(gen->data); 929 } 930 931 932 Xfree(om->core.res_name); 933 Xfree(om->core.res_class); 934 935 if (om->core.required_charset.charset_list) 936 XFreeStringList(om->core.required_charset.charset_list); 937 else 938 Xfree((char*)om->core.required_charset.charset_list); 939 940 Xfree(om->core.orientation_list.orientation); 941 Xfree(om); 942 943 return 1; 944} 945 946static char * 947set_om_values( 948 XOM om, 949 XlcArgList args, 950 int num_args) 951{ 952 if (om->core.resources == NULL) 953 return NULL; 954 955 return _XlcSetValues((XPointer) om, om->core.resources, 956 om->core.num_resources, args, num_args, XlcSetMask); 957} 958 959static char * 960get_om_values( 961 XOM om, 962 XlcArgList args, 963 int num_args) 964{ 965 if (om->core.resources == NULL) 966 return NULL; 967 968 return _XlcGetValues((XPointer) om, om->core.resources, 969 om->core.num_resources, args, num_args, XlcGetMask); 970} 971 972static _Xconst XOMMethodsRec methods = { 973 close_om, 974 set_om_values, 975 get_om_values, 976 create_oc 977}; 978 979static XlcResource om_resources[] = { 980 { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), 981 XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, 982 { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), 983 XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, 984 { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), 985 XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, 986 { XNContextualDrawing, NULLQUARK, sizeof(Bool), 987 XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } 988}; 989 990static OMData 991add_data( 992 XOM om) 993{ 994 XOMGenericPart *gen = XOM_GENERIC(om); 995 OMData new; 996 997 new = Xcalloc(1, sizeof(OMDataRec)); 998 999 if (new == NULL) 1000 return NULL; 1001 1002 gen->data = new; 1003 1004 return new; 1005} 1006 1007static _Xconst char *supported_charset_list[] = { 1008 "ISO8859-1", 1009 "adobe-fontspecific", 1010 "SUNOLCURSOR-1", 1011 "SUNOLGLYPH-1" 1012}; 1013 1014static Bool 1015init_om( 1016 XOM om) 1017{ 1018 XOMGenericPart *gen = XOM_GENERIC(om); 1019 OMData data; 1020 FontData font_data; 1021 char **required_list; 1022 XOrientation *orientation; 1023 char *bufptr; 1024 int i, count; 1025 1026 count = XlcNumber(supported_charset_list); 1027 1028 data = add_data(om); 1029 if (data == NULL) 1030 return False; 1031 1032 font_data = Xcalloc(count, sizeof(FontDataRec)); 1033 if (font_data == NULL) 1034 return False; 1035 data->font_data = font_data; 1036 data->font_data_count = count; 1037 1038 for (i = 0; i < count; i++, font_data++) { 1039 font_data->name = strdup(supported_charset_list[i]); 1040 if (font_data->name == NULL) 1041 return False; 1042 } 1043 1044 /* required charset list */ 1045 required_list = Xmalloc(sizeof(char *)); 1046 if (required_list == NULL) 1047 return False; 1048 1049 bufptr = strdup(data->font_data->name); 1050 if (bufptr == NULL) { 1051 Xfree(required_list); 1052 return False; 1053 } 1054 1055 om->core.required_charset.charset_list = required_list; 1056 om->core.required_charset.charset_count = 1; /* always 1 */ 1057 1058 data = gen->data; 1059 1060 *required_list = bufptr; 1061 1062 /* orientation list */ 1063 orientation = Xmalloc(sizeof(XOrientation)); 1064 if (orientation == NULL) 1065 return False; 1066 1067 *orientation = XOMOrientation_LTR_TTB; 1068 om->core.orientation_list.orientation = orientation; 1069 om->core.orientation_list.num_orientation = 1; 1070 1071 /* directional dependent drawing */ 1072 om->core.directional_dependent = False; 1073 1074 /* contexual drawing */ 1075 om->core.contextual_drawing = False; 1076 1077 /* context dependent */ 1078 om->core.context_dependent = False; 1079 1080 return True; 1081} 1082 1083XOM 1084_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, 1085 _Xconst char *res_name, _Xconst char *res_class) 1086{ 1087 XOM om; 1088 1089 om = Xcalloc(1, sizeof(XOMGenericRec)); 1090 if (om == NULL) 1091 return (XOM) NULL; 1092 1093 om->methods = (XOMMethods)&methods; 1094 om->core.lcd = lcd; 1095 om->core.display = dpy; 1096 om->core.rdb = rdb; 1097 if (res_name) { 1098 om->core.res_name = strdup(res_name); 1099 if (om->core.res_name == NULL) 1100 goto err; 1101 } 1102 if (res_class) { 1103 om->core.res_class = strdup(res_class); 1104 if (om->core.res_class == NULL) 1105 goto err; 1106 } 1107 1108 if (om_resources[0].xrm_name == NULLQUARK) 1109 _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); 1110 1111 om->core.resources = om_resources; 1112 om->core.num_resources = XlcNumber(om_resources); 1113 1114 if (init_om(om) == False) 1115 goto err; 1116 1117 return om; 1118err: 1119 close_om(om); 1120 1121 return (XOM) NULL; 1122} 1123