1 /* 2 Copyright 1985, 1986, 1987, 1991, 1998 The Open Group 3 4 Permission is hereby granted, free of charge, to any person obtaining a 5 copy of this software and associated documentation files (the 6 "Software"), to deal in the Software without restriction, including 7 without limitation the rights to use, copy, modify, merge, publish, 8 distribute, sublicense, and/or sell copies of the Software, and to 9 permit persons to whom the Software is furnished to do so, subject to 10 the following conditions: The above copyright notice and this 11 permission notice shall be included in all copies or substantial 12 portions of the Software. 13 14 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE 21 EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. 22 23 24 Except as contained in this notice, the name of The Open Group shall not be 25 used in advertising or otherwise to promote the sale, use or other dealings 26 in this Software without prior written authorization from The Open Group. 27 28 29 X Window System is a trademark of The Open Group 30 31 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF 32 logo, LBX, X Window System, and Xinerama are trademarks of the Open 33 Group. All other trademarks and registered trademarks mentioned herein 34 are the property of their respective owners. No right, title or 35 interest in or to any trademark, service mark, logo or trade name of 36 Sun Microsystems, Inc. or its licensors is granted. 37 38 */ 39 /* 40 * Copyright (c) 2000, Oracle and/or its affiliates. 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 82 typedef struct _FontDataRec { 83 char *name; 84 } FontDataRec, *FontData; 85 86 typedef struct _OMDataRec { 87 int font_data_count; 88 FontData font_data; 89 } OMDataRec, *OMData; 90 91 typedef struct _XOMGenericPart { 92 OMData data; 93 } XOMGenericPart; 94 95 typedef struct _XOMGenericRec { 96 XOMMethods methods; 97 XOMCoreRec core; 98 XOMGenericPart gen; 99 } XOMGenericRec, *XOMGeneric; 100 101 typedef 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 110 typedef struct _XOCGenericPart { 111 XlcConv wcs_to_cs; 112 FontSet font_set; 113 } XOCGenericPart; 114 115 typedef struct _XOCGenericRec { 116 XOCMethods methods; 117 XOCCoreRec core; 118 XOCGenericPart gen; 119 } XOCGenericRec, *XOCGeneric; 120 121 static Bool 122 init_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 144 static char * 145 get_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 157 static FontData 158 check_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 = (ssize_t) 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 = (ssize_t) 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 185 static Bool 186 load_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 204 static void 205 set_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 232 static Bool 233 init_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 274 err: 275 276 Xfree(font_name_list); 277 Xfree(font_struct_list); 278 279 return False; 280 } 281 282 static char * 283 get_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 307 static int 308 parse_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 = (ssize_t) 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, (size_t) (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; 451 err: 452 XFreeStringList(name_list); 453 454 return -1; 455 } 456 457 static Bool 458 set_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 487 static Bool 488 create_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 515 static void 516 destroy_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 549 static char * 550 set_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 562 static char * 563 get_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 575 static Bool 576 wcs_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 603 static 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 609 static 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 624 err: 625 FreeLocalBuf(buf); 626 627 return ret; 628 } 629 630 static 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 657 static 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 673 err: 674 FreeLocalBuf(buf); 675 676 return ret; 677 } 678 679 static 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 748 static 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 769 err: 770 FreeLocalBuf(buf); 771 772 return ret; 773 } 774 775 static 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 787 static 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 803 err: 804 FreeLocalBuf(buf); 805 806 return ret; 807 } 808 809 static 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 817 static 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 832 err: 833 FreeLocalBuf(buf); 834 } 835 836 static _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 852 static 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 871 static XOC 872 create_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 905 err: 906 destroy_oc(oc); 907 908 return (XOC) NULL; 909 } 910 911 static Status 912 close_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 946 static char * 947 set_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 959 static char * 960 get_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 972 static _Xconst XOMMethodsRec methods = { 973 close_om, 974 set_om_values, 975 get_om_values, 976 create_oc 977 }; 978 979 static 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 990 static OMData 991 add_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 1007 static _Xconst char *supported_charset_list[] = { 1008 "ISO8859-1", 1009 "adobe-fontspecific", 1010 "SUNOLCURSOR-1", 1011 "SUNOLGLYPH-1" 1012 }; 1013 1014 static Bool 1015 init_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 /* contextual drawing */ 1075 om->core.contextual_drawing = False; 1076 1077 /* context dependent */ 1078 om->core.context_dependent = False; 1079 1080 return True; 1081 } 1082 1083 XOM 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; 1118 err: 1119 close_om(om); 1120 1121 return (XOM) NULL; 1122 } 1123