1/* 2 3Copyright 1989, 1994, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27/* 28 * Author: Chris Peterson, MIT X Consortium. 29 * 30 * Much code taken from X11R3 AsciiSink. 31 */ 32 33/* 34 * TextSink.c - TextSink object. (For use with the text widget). 35 * 36 */ 37 38#ifdef HAVE_CONFIG_H 39#include <config.h> 40#endif 41#include <stdio.h> 42#include <stdlib.h> 43#include <ctype.h> 44#include <X11/IntrinsicP.h> 45#include <X11/StringDefs.h> 46#include <X11/Xaw/TextP.h> 47#include <X11/Xaw/TextSinkP.h> 48#include <X11/Xaw/XawInit.h> 49#include "Private.h" 50 51/* 52 * Prototypes 53 */ 54static void XawTextSinkClassPartInitialize(WidgetClass); 55static void XawTextSinkInitialize(Widget, Widget, ArgList, Cardinal*); 56static void XawTextSinkDestroy(Widget); 57static Boolean XawTextSinkSetValues(Widget, Widget, Widget, 58 ArgList, Cardinal*); 59 60static int MaxLines(Widget, unsigned int); 61static int MaxHeight(Widget, int); 62static void DisplayText(Widget, int, int, XawTextPosition, XawTextPosition, 63 Bool); 64static void InsertCursor(Widget, int, int, XawTextInsertState); 65static void ClearToBackground(Widget, int, int, unsigned int, unsigned int); 66static void FindPosition(Widget, XawTextPosition, int, int, Bool, 67 XawTextPosition*, int*, int*); 68static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*, 69 XawTextPosition*, int*); 70static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*); 71static void SetTabs(Widget, int, short*); 72static void GetCursorBounds(Widget, XRectangle*); 73 74#ifndef OLDXAW 75static Boolean CvtStringToPropertyList(Display*, XrmValue*, Cardinal*, 76 XrmValue*, XrmValue*, XtPointer*); 77static Boolean CvtPropertyListToString(Display*, XrmValue*, Cardinal*, 78 XrmValue*, XrmValue*, XtPointer*); 79static Bool BeginPaint(Widget); 80static Bool EndPaint(Widget); 81static void SetXlfdDefaults(Display*, XawTextProperty*); 82#endif 83 84/* 85 * External 86 */ 87void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned); 88void _XawTextSinkDisplayText(Widget, int, int, XawTextPosition, XawTextPosition, 89 Bool); 90 91/* 92 * Initialization 93 */ 94#define offset(field) XtOffsetOf(TextSinkRec, text_sink.field) 95static XtResource resources[] = { 96 { 97 XtNforeground, 98 XtCForeground, 99 XtRPixel, 100 sizeof(Pixel), 101 offset(foreground), 102 XtRString, 103 (XtPointer)XtDefaultForeground 104 }, 105 { 106 XtNbackground, 107 XtCBackground, 108 XtRPixel, 109 sizeof(Pixel), 110 offset(background), 111 XtRString, 112 (XtPointer)XtDefaultBackground 113 }, 114#ifndef OLDXAW 115 { 116 XtNcursorColor, 117 XtCColor, 118 XtRPixel, 119 sizeof(Pixel), 120 offset(cursor_color), 121 XtRString, 122 (XtPointer)XtDefaultForeground 123 }, 124 { 125 XawNtextProperties, 126 XawCTextProperties, 127 XawRTextProperties, 128 sizeof(XawTextPropertyList*), 129 offset(properties), 130 XtRImmediate, 131 NULL 132 }, 133#endif 134}; 135#undef offset 136 137#ifndef OLDXAW 138static TextSinkExtRec extension_rec = { 139 NULL, /* next_extension */ 140 NULLQUARK, /* record_type */ 141 1, /* version */ 142 sizeof(TextSinkExtRec), /* record_size */ 143 BeginPaint, 144 NULL, 145 NULL, 146 EndPaint 147}; 148 149static XrmQuark Qdefault; 150#endif 151 152#define Superclass (&objectClassRec) 153TextSinkClassRec textSinkClassRec = { 154 /* object */ 155 { 156 (WidgetClass)Superclass, /* superclass */ 157 "TextSink", /* class_name */ 158 sizeof(TextSinkRec), /* widget_size */ 159 XawInitializeWidgetSet, /* class_initialize */ 160 XawTextSinkClassPartInitialize, /* class_part_initialize */ 161 False, /* class_inited */ 162 XawTextSinkInitialize, /* initialize */ 163 NULL, /* initialize_hook */ 164 NULL, /* obj1 */ 165 NULL, /* obj2 */ 166 0, /* obj3 */ 167 resources, /* resources */ 168 XtNumber(resources), /* num_resources */ 169 NULLQUARK, /* xrm_class */ 170 False, /* obj4 */ 171 False, /* obj5 */ 172 False, /* obj6 */ 173 False, /* obj7 */ 174 XawTextSinkDestroy, /* destroy */ 175 NULL, /* obj8 */ 176 NULL, /* obj9 */ 177 XawTextSinkSetValues, /* set_values */ 178 NULL, /* set_values_hook */ 179 NULL, /* obj10 */ 180 NULL, /* get_values_hook */ 181 NULL, /* obj11 */ 182 XtVersion, /* version */ 183 NULL, /* callback_private */ 184 NULL, /* obj12 */ 185 NULL, /* obj13 */ 186 NULL, /* obj14 */ 187 NULL, /* extension */ 188 }, 189 /* text_sink */ 190 { 191 DisplayText, /* DisplayText */ 192 InsertCursor, /* InsertCursor */ 193 ClearToBackground, /* ClearToBackground */ 194 FindPosition, /* FindPosition */ 195 FindDistance, /* FindDistance */ 196 Resolve, /* Resolve */ 197 MaxLines, /* MaxLines */ 198 MaxHeight, /* MaxHeight */ 199 SetTabs, /* SetTabs */ 200 GetCursorBounds, /* GetCursorBounds */ 201#ifndef OLDXAW 202 NULL, 203#endif 204 }, 205}; 206 207WidgetClass textSinkObjectClass = (WidgetClass)&textSinkClassRec; 208 209/* 210 * Implementation 211 */ 212static void 213XawTextSinkClassPartInitialize(WidgetClass wc) 214{ 215 TextSinkObjectClass t_src, superC; 216#ifndef OLDXAW 217 static XtConvertArgRec CvtArgs[] = { 218 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.self), 219 sizeof(Widget)}, 220 }; 221#endif 222 223 t_src = (TextSinkObjectClass) wc; 224 superC = (TextSinkObjectClass) t_src->object_class.superclass; 225 226#ifndef OLDXAW 227 extension_rec.record_type = XrmPermStringToQuark("TextSink"); 228 extension_rec.next_extension = (XtPointer)t_src->text_sink_class.extension; 229 t_src->text_sink_class.extension = &extension_rec; 230 231 Qdefault = XrmPermStringToQuark("default"); 232#endif 233 234 /* 235 * We don't need to check for null super since we'll get to TextSink 236 * eventually. 237 */ 238 if (t_src->text_sink_class.DisplayText == XtInheritDisplayText) 239 t_src->text_sink_class.DisplayText = 240 superC->text_sink_class.DisplayText; 241 242 if (t_src->text_sink_class.InsertCursor == XtInheritInsertCursor) 243 t_src->text_sink_class.InsertCursor = 244 superC->text_sink_class.InsertCursor; 245 246 if (t_src->text_sink_class.ClearToBackground== XtInheritClearToBackground) 247 t_src->text_sink_class.ClearToBackground = 248 superC->text_sink_class.ClearToBackground; 249 250 if (t_src->text_sink_class.FindPosition == XtInheritFindPosition) 251 t_src->text_sink_class.FindPosition = 252 superC->text_sink_class.FindPosition; 253 254 if (t_src->text_sink_class.FindDistance == XtInheritFindDistance) 255 t_src->text_sink_class.FindDistance = 256 superC->text_sink_class.FindDistance; 257 258 if (t_src->text_sink_class.Resolve == XtInheritResolve) 259 t_src->text_sink_class.Resolve = 260 superC->text_sink_class.Resolve; 261 262 if (t_src->text_sink_class.MaxLines == XtInheritMaxLines) 263 t_src->text_sink_class.MaxLines = 264 superC->text_sink_class.MaxLines; 265 266 if (t_src->text_sink_class.MaxHeight == XtInheritMaxHeight) 267 t_src->text_sink_class.MaxHeight = 268 superC->text_sink_class.MaxHeight; 269 270 if (t_src->text_sink_class.SetTabs == XtInheritSetTabs) 271 t_src->text_sink_class.SetTabs = 272 superC->text_sink_class.SetTabs; 273 274 if (t_src->text_sink_class.GetCursorBounds == XtInheritGetCursorBounds) 275 t_src->text_sink_class.GetCursorBounds = 276 superC->text_sink_class.GetCursorBounds; 277 278#ifndef OLDXAW 279 XtSetTypeConverter(XtRString, XawRTextProperties, CvtStringToPropertyList, 280 &CvtArgs[0], XtNumber(CvtArgs), XtCacheNone, NULL); 281 XtSetTypeConverter(XawRTextProperties, XtRString, CvtPropertyListToString, 282 NULL, 0, XtCacheNone, NULL); 283#endif 284} 285 286/* 287 * Function: 288 * XawTextSinkInitialize 289 * 290 * Parameters: 291 * request - requested and new values for the object instance 292 * cnew - "" 293 * 294 * Description: 295 * Initializes the TextSink Object. 296 */ 297/*ARGSUSED*/ 298static void 299XawTextSinkInitialize(Widget request _X_UNUSED, Widget cnew, 300 ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 301{ 302 TextSinkObject sink = (TextSinkObject)cnew; 303 304 sink->text_sink.tab_count = 0; /* Initialize the tab stops. */ 305 sink->text_sink.tabs = NULL; 306 sink->text_sink.char_tabs = NULL; 307#ifndef OLDXAW 308 sink->text_sink.paint = NULL; 309#endif 310} 311 312/* 313 * Function: 314 * XawTextSinkDestroy 315 * 316 * Parameters: 317 * w - TextSink Object 318 * 319 * Description: 320 * This function cleans up when the object is destroyed. 321 */ 322static void 323XawTextSinkDestroy(Widget w) 324{ 325 TextSinkObject sink = (TextSinkObject) w; 326 327 XtFree((char *)sink->text_sink.tabs); 328 XtFree((char *)sink->text_sink.char_tabs); 329} 330 331/* 332 * Function: 333 * XawTextSinkSetValues 334 * 335 * Parameters: 336 * current - current state of the object 337 * request - what was requested 338 * cnew - what the object will become 339 * 340 * Description: 341 * Sets the values for the TextSink. 342 * 343 * Returns: 344 * True if redisplay is needed 345 */ 346/*ARGSUSED*/ 347static Boolean 348XawTextSinkSetValues(Widget current, Widget request _X_UNUSED, Widget cnew, 349 ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED) 350{ 351 TextSinkObject w = (TextSinkObject)cnew; 352 TextSinkObject old_w = (TextSinkObject)current; 353 354 if (w->text_sink.foreground != old_w->text_sink.foreground) 355 ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; 356 357 return (False); 358} 359 360/* 361 * Function: 362 * DisplayText 363 * 364 * Parameters: 365 * w - TextSink Object 366 * x - location to start drawing text 367 * y - "" 368 * pos1 - location of starting and ending points in the text buffer 369 * pos2 - "" 370 * highlight - highlight this text? 371 * 372 * Description: 373 * Stub function that in subclasses will display text. 374 */ 375/*ARGSUSED*/ 376static void 377DisplayText(Widget w _X_UNUSED, int x _X_UNUSED, int y _X_UNUSED, 378 XawTextPosition pos1 _X_UNUSED, XawTextPosition pos2 _X_UNUSED, Bool highlight _X_UNUSED) 379{ 380 return; 381} 382 383/* 384 * Function: 385 * InsertCursor 386 * 387 * Parameters: 388 * w - TextSink Object 389 * x - location for the cursor 390 * y - "" 391 * state - whether to turn the cursor on, or off 392 * 393 * Description: 394 * Places the InsertCursor. 395 */ 396/*ARGSUSED*/ 397static void 398InsertCursor(Widget w _X_UNUSED, int x _X_UNUSED, int y _X_UNUSED, XawTextInsertState state _X_UNUSED) 399{ 400 return; 401} 402 403/* 404 * Function: 405 * ClearToBackground 406 * 407 * Parameters: 408 * w - TextSink Object 409 * x - location of area to clear 410 * y - "" 411 * width - size of area to clear 412 * height - "" 413 * 414 * Description: 415 * Clears a region of the sink to the background color. 416 */ 417/*ARGSUSED*/ 418static void 419ClearToBackground(Widget w, int x, int y, 420 unsigned int width, unsigned int height) 421{ 422 /* 423 * Don't clear in height or width are zero 424 * XClearArea() has special semantic for these values 425 */ 426 TextWidget xaw = (TextWidget)XtParent(w); 427 Position x1, y1, x2, y2; 428 429 x1 = (Position) (XawMax(x, xaw->text.r_margin.left)); 430 y1 = (Position) (XawMax(y, xaw->text.r_margin.top)); 431 x2 = (Position) (XawMin(x + (int)width, (int)XtWidth(xaw) - xaw->text.r_margin.right)); 432 y2 = (Position) (XawMin(y + (int)height, (int)XtHeight(xaw) - xaw->text.r_margin.bottom)); 433 434 x = (int)x1; 435 y = (int)y1; 436 width = (unsigned)(XawMax(0, x2 - x1)); 437 height = (unsigned)(XawMax(0, y2 - y1)); 438 439 if (height != 0 && width != 0) 440 XClearArea(XtDisplayOfObject(w), XtWindowOfObject(w), 441 x, y, width, height, False); 442} 443 444/* 445 * Function: 446 * FindPosition 447 * 448 * Parameters: 449 * w - TextSink Object 450 * fromPos - reference position 451 * fromX - reference location 452 * width - width of section to paint text 453 * stopAtWordBreak - returned position is a word break? 454 * resPos - position found (return) 455 * resWidth - Width actually used (return) 456 * resHeight - Height actually used (return) 457 * 458 * Description: 459 * Finds a position in the text. 460 */ 461/*ARGSUSED*/ 462static void 463FindPosition(Widget w _X_UNUSED, XawTextPosition fromPos _X_UNUSED, int fromx _X_UNUSED, int width _X_UNUSED, 464 Bool stopAtWordBreak _X_UNUSED, XawTextPosition *resPos, 465 int *resWidth, int *resHeight) 466{ 467 *resPos = fromPos; 468 *resHeight = *resWidth = 0; 469} 470 471/* 472 * Function: 473 * FindDistance 474 * 475 * Parameters: 476 * w - TextSink Object 477 * fromPos - starting Position 478 * fromX - x location of starting Position 479 * toPos - end Position 480 * resWidth - Distance between fromPos and toPos 481 * resPos - Actual toPos used 482 * resHeight - Height required by this text 483 * 484 * Description: 485 * Find the Pixel Distance between two text Positions. 486 */ 487/*ARGSUSED*/ 488static void 489FindDistance(Widget w _X_UNUSED, XawTextPosition fromPos, int fromx _X_UNUSED, 490 XawTextPosition toPos _X_UNUSED, int *resWidth, 491 XawTextPosition *resPos, int *resHeight) 492{ 493 *resWidth = *resHeight = 0; 494 *resPos = fromPos; 495} 496 497/* 498 * Function: 499 * Resolve 500 * 501 * Parameters: 502 * w - TextSink Object 503 * pos - reference Position 504 * fromx - reference Location 505 * width - width to move 506 * resPos - resulting position 507 * 508 * Description: 509 * Resolves a location to a position. 510 */ 511/*ARGSUSED*/ 512static void 513Resolve(Widget w _X_UNUSED, XawTextPosition pos _X_UNUSED, int fromx _X_UNUSED, int width _X_UNUSED, 514 XawTextPosition *resPos) 515{ 516 *resPos = pos; 517} 518 519/* 520 * Function: 521 * MaxLines 522 * 523 * Parameters: 524 * w - TextSink Object 525 * height - height to fit lines into 526 * 527 * Description: 528 * Finds the Maximum number of lines that will fit in a given height. 529 * 530 * Returns: 531 * Number of lines that will fit 532 */ 533/*ARGSUSED*/ 534static int 535MaxLines(Widget w _X_UNUSED, unsigned int height _X_UNUSED) 536{ 537 /* 538 * The fontset has gone down to descent Sink Widget, so 539 * the functions such MaxLines, SetTabs... are bound to the descent. 540 * 541 * by Li Yuhong, Jan. 15, 1991 542 */ 543 return (0); 544} 545 546/* 547 * Function: 548 * MaxHeight 549 * 550 * Parameters: 551 * w - TextSink Object 552 * lines - number of lines 553 * 554 * Description: 555 * Finds the Minimum height that will contain a given number lines. 556 * 557 * Returns: 558 * the height 559 */ 560/*ARGSUSED*/ 561static int 562MaxHeight(Widget w _X_UNUSED, int lines _X_UNUSED) 563{ 564 return (0); 565} 566 567/* 568 * Function: 569 * SetTabs 570 * 571 * Parameters: 572 * w - TextSink Object 573 * tab_count - the number of tabs in the list 574 * tabs - text positions of the tabs 575 * Description: 576 * Sets the Tab stops. 577 */ 578/*ARGSUSED*/ 579static void 580SetTabs(Widget w _X_UNUSED, int tab_count _X_UNUSED, short *tabs _X_UNUSED) 581{ 582 return; 583} 584 585/* 586 * Function: 587 * GetCursorBounds 588 * 589 * Parameters: 590 * w - TextSinkObject. 591 * rect - X rectangle containing the cursor bounds 592 * 593 * Description: 594 * Finds the bounding box for the insert cursor (caret) 595 */ 596/*ARGSUSED*/ 597static void 598GetCursorBounds(Widget w _X_UNUSED, XRectangle *rect) 599{ 600 rect->x = rect->y = (short)(rect->width = rect->height = 0); 601} 602 603/* 604 * Public Functions 605 */ 606/* 607 * Function: 608 * XawTextSinkDisplayText 609 * 610 * Parameters: 611 * w - TextSink Object 612 * x - location to start drawing text 613 * y - "" 614 * pos1 - location of starting and ending points in the text buffer 615 * pos2 - "" 616 * highlight - highlight this text? 617 */ 618/*ARGSUSED*/ 619void 620XawTextSinkDisplayText(Widget w, 621#if NeedWidePrototypes 622 int x, int y, 623#else 624 Position x, Position y, 625#endif 626 XawTextPosition pos1, XawTextPosition pos2, 627#if NeedWidePrototypes 628 int highlight 629#else 630 Boolean highlight 631#endif 632) 633{ 634 _XawTextSinkDisplayText(w, x, y, pos1, pos2, highlight); 635} 636 637void 638_XawTextSinkDisplayText(Widget w, int x, int y, 639 XawTextPosition pos1, XawTextPosition pos2, 640 Bool highlight) 641{ 642 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 643 644 (*cclass->text_sink_class.DisplayText)(w, x, y, pos1, pos2, highlight); 645} 646 647/* 648 * Function: 649 * XawTextSinkInsertCursor 650 * 651 * Parameters: 652 * w - TextSink Object 653 * x - location for the cursor 654 * y - "" 655 * state - whether to turn the cursor on, or off 656 * 657 * Description: 658 * Places the InsertCursor. 659 */ 660/*ARGSUSED*/ 661void 662#if NeedWidePrototypes 663XawTextSinkInsertCursor(Widget w, int x, int y, int state) 664#else 665XawTextSinkInsertCursor(Widget w, Position x, Position y, XawTextInsertState state) 666#endif 667{ 668 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 669 670 (*cclass->text_sink_class.InsertCursor)(w, x, y, state); 671} 672 673/* 674 * Function: 675 * XawTextSinkClearToBackground 676 * 677 * Parameters: 678 * w - TextSink Object 679 * x - location of area to clear 680 * y - "" 681 * width - size of area to clear 682 * height - "" 683 * 684 * Description: 685 * Clears a region of the sink to the background color. 686 */ 687/*ARGSUSED*/ 688void 689XawTextSinkClearToBackground(Widget w, 690#if NeedWidePrototypes 691 int x, int y, 692 unsigned int width, unsigned int height 693#else 694 Position x, Position y, 695 Dimension width, Dimension height 696#endif 697) 698{ 699 _XawTextSinkClearToBackground(w, x, y, width, height); 700} 701 702void 703_XawTextSinkClearToBackground(Widget w, 704 int x, int y, 705 unsigned int width, unsigned int height) 706{ 707 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 708 709 (*cclass->text_sink_class.ClearToBackground)(w, x, y, width, height); 710} 711 712/* 713 * Function: 714 * XawTextSinkFindPosition 715 * 716 * Parameters: 717 * w - TextSink Object 718 * fromPos - reference position 719 * fromX - reference location 720 * width - width of section to paint text 721 * stopAtWordBreak - returned position is a word break? 722 * resPos - position found (return) 723 * resWidth - Width actually used (return) 724 * resHeight - Height actually used (return) 725 * 726 * Description: 727 * Finds a position in the text. 728 */ 729/*ARGSUSED*/ 730void 731XawTextSinkFindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, 732#if NeedWidePrototypes 733 int stopAtWordBreak, 734#else 735 Boolean stopAtWordBreak, 736#endif 737 XawTextPosition *resPos, int *resWidth, int *resHeight) 738{ 739 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 740 741 (*cclass->text_sink_class.FindPosition)(w, fromPos, fromx, width, 742 stopAtWordBreak, 743 resPos, resWidth, resHeight); 744} 745 746/* 747 * Function: 748 * XawTextSinkFindDistance 749 * 750 * Parameters: 751 * w - TextSink Object 752 * fromPos - starting Position 753 * fromX - x location of starting Position 754 * toPos - end Position 755 * resWidth - Distance between fromPos and toPos 756 * resPos - Actual toPos used 757 * resHeight - Height required by this text 758 * 759 * Description: 760 * Find the Pixel Distance between two text Positions. 761 */ 762/*ARGSUSED*/ 763void 764XawTextSinkFindDistance(Widget w, XawTextPosition fromPos, int fromx, 765 XawTextPosition toPos, int *resWidth, 766 XawTextPosition *resPos, int *resHeight) 767{ 768 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 769 770 (*cclass->text_sink_class.FindDistance)(w, fromPos, fromx, toPos, 771 resWidth, resPos, resHeight); 772} 773 774/* 775 * Function: 776 * XawTextSinkResolve 777 * 778 * Parameters: 779 * w - TextSink Object 780 * pos - reference Position 781 * fromx - reference Location 782 * width - width to move 783 * resPos - resulting position 784 * 785 * Description: 786 * Resolves a location to a position. 787 */ 788/*ARGSUSED*/ 789void 790XawTextSinkResolve(Widget w, XawTextPosition pos, int fromx, int width, 791 XawTextPosition *resPos) 792{ 793 TextSinkObjectClass cclass = (TextSinkObjectClass) w->core.widget_class; 794 795 (*cclass->text_sink_class.Resolve)(w, pos, fromx, width, resPos); 796} 797 798/* 799 * Function: 800 * XawTextSinkMaxLines 801 * 802 * Parameters: 803 * w - TextSink Object 804 * height - height to fit lines into 805 * 806 * Description: 807 * Finds the Maximum number of lines that will fit in a given height. 808 * 809 * Returns: 810 * Number of lines that will fit 811 */ 812/*ARGSUSED*/ 813int 814#if NeedWidePrototypes 815XawTextSinkMaxLines(Widget w, unsigned int height) 816#else 817XawTextSinkMaxLines(Widget w, Dimension height) 818#endif 819{ 820 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 821 822 return((*cclass->text_sink_class.MaxLines)(w, height)); 823} 824 825/* 826 * Function: 827 * XawTextSinkMaxHeight 828 * 829 * Parameters: 830 * w - TextSink Object 831 * lines - number of lines 832 * 833 * Description: 834 * Finds the Minimum height that will contain a given number lines. 835 * 836 * Returns: 837 * the height 838 */ 839/*ARGSUSED*/ 840int 841XawTextSinkMaxHeight(Widget w, int lines) 842{ 843 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 844 845 return((*cclass->text_sink_class.MaxHeight)(w, lines)); 846} 847 848/* 849 * Function: 850 * XawTextSinkSetTabs 851 * 852 * Parameters: 853 * w - TextSink Object 854 * tab_count - the number of tabs in the list 855 * tabs - text positions of the tabs 856 * Description: 857 * Sets the Tab stops. 858 */ 859void 860XawTextSinkSetTabs(Widget w, int tab_count, int *tabs) 861{ 862 if (tab_count > 0) { 863 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 864 short *char_tabs = (short*)XtMalloc((Cardinal)((unsigned)tab_count * sizeof(short))); 865 short *tab, len = 0; 866 int i; 867 868 for (i = tab_count, tab = char_tabs; i; i--) { 869 if ((short)*tabs > len) 870 *tab++ = (len = (short)*tabs++); 871 else { 872 tabs++; 873 --tab_count; 874 } 875 } 876 877 if (tab_count > 0) 878 (*cclass->text_sink_class.SetTabs)(w, tab_count, char_tabs); 879 XtFree((char *)char_tabs); 880 } 881} 882 883/* 884 * Function: 885 * XawTextSinkGetCursorBounds 886 * 887 * Parameters: 888 * w - TextSinkObject 889 * rect - X rectance containing the cursor bounds 890 * 891 * Description: 892 * Finds the bounding box for the insert cursor (caret). 893 */ 894/*ARGSUSED*/ 895void 896XawTextSinkGetCursorBounds(Widget w, XRectangle *rect) 897{ 898 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 899 900 (*cclass->text_sink_class.GetCursorBounds)(w, rect); 901} 902 903#ifndef OLDXAW 904Bool 905XawTextSinkBeginPaint(Widget w) 906{ 907 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 908 909 if (cclass->text_sink_class.extension->BeginPaint == NULL || 910 cclass->text_sink_class.extension->PreparePaint == NULL || 911 cclass->text_sink_class.extension->DoPaint == NULL || 912 cclass->text_sink_class.extension->EndPaint == NULL) 913 return (False); 914 915 return ((*cclass->text_sink_class.extension->BeginPaint)(w)); 916} 917 918static Bool 919BeginPaint(Widget w) 920{ 921 TextSinkObject sink = (TextSinkObject)w; 922 923 if (sink->text_sink.paint != NULL) 924 return (False); 925 926 sink->text_sink.paint = XtNew(XawTextPaintList); 927 sink->text_sink.paint->clip = XmuCreateArea(); 928 sink->text_sink.paint->hightabs = NULL; 929 sink->text_sink.paint->paint = NULL; 930 sink->text_sink.paint->bearings = NULL; 931 932 return (True); 933} 934 935void 936XawTextSinkPreparePaint(Widget w, int y, int line, XawTextPosition from, 937 XawTextPosition to, Bool highlight) 938{ 939 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 940 941 (*cclass->text_sink_class.extension->PreparePaint) 942 (w, y, line, from, to, highlight); 943} 944 945void 946XawTextSinkDoPaint(Widget w) 947{ 948 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 949 950 (*cclass->text_sink_class.extension->DoPaint)(w); 951} 952 953Bool 954XawTextSinkEndPaint(Widget w) 955{ 956 TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class; 957 958 return ((*cclass->text_sink_class.extension->EndPaint)(w)); 959} 960 961static Bool 962EndPaint(Widget w) 963{ 964 TextSinkObject sink = (TextSinkObject)w; 965 XawTextPaintStruct *paint, *next; 966 967 if (sink->text_sink.paint == NULL) 968 return (False); 969 970 XmuDestroyArea(sink->text_sink.paint->clip); 971 if (sink->text_sink.paint->hightabs) 972 XmuDestroyArea(sink->text_sink.paint->hightabs); 973 paint = sink->text_sink.paint->paint; 974 while (paint) { 975 next = paint->next; 976 if (paint->text) 977 XtFree((XtPointer)paint->text); 978 if (paint->backtabs) 979 XmuDestroyArea(paint->backtabs); 980 XtFree((XtPointer)paint); 981 paint = next; 982 } 983 984 paint = sink->text_sink.paint->bearings; 985 while (paint) { 986 next = paint->next; 987 if (paint->text) 988 XtFree((XtPointer)paint->text); 989 XtFree((XtPointer)paint); 990 paint = next; 991 } 992 993 XtFree((XtPointer)sink->text_sink.paint); 994 sink->text_sink.paint = NULL; 995 return (True); 996} 997 998static XawTextPropertyList **prop_lists; 999static Cardinal num_prop_lists; 1000 1001static int 1002bcmp_qident(_Xconst void *left, _Xconst void *right) 1003{ 1004 return (int)((long)left - (*(XawTextProperty**)right)->identifier); 1005} 1006 1007static int 1008qcmp_qident(_Xconst void *left, _Xconst void *right) 1009{ 1010 return ((*(XawTextProperty**)left)->identifier - 1011 (*(XawTextProperty**)right)->identifier); 1012} 1013 1014static void 1015SetXlfdDefaults(Display *display, XawTextProperty *property) 1016{ 1017 Atom atom = XInternAtom(display, "FONT", True); 1018 unsigned long value; 1019 char *str; 1020 1021 if (XGetFontProperty(property->font, atom, &value)) { 1022 char *xlfd = XGetAtomName(display, value); 1023 1024 if (xlfd) { 1025 char *sep = xlfd + 1; 1026 char *name = sep; 1027 1028 property->xlfd = XrmStringToQuark(xlfd); 1029 1030 sep = strchr(sep, '-'); *sep++ = '\0'; 1031 property->foundry = XrmStringToQuark(name); 1032 name = sep; 1033 1034 sep = strchr(sep, '-'); *sep++ = '\0'; 1035 property->family = XrmStringToQuark(name); 1036 name = sep; 1037 1038 sep = strchr(sep, '-'); *sep++ = '\0'; 1039 property->weight = XrmStringToQuark(name); 1040 name = sep; 1041 1042 sep = strchr(sep, '-'); *sep++ = '\0'; 1043 property->slant = XrmStringToQuark(name); 1044 name = sep; 1045 1046 sep = strchr(sep, '-'); *sep++ = '\0'; 1047 property->setwidth = XrmStringToQuark(name); 1048 name = sep; 1049 1050 sep = strchr(sep, '-'); *sep++ = '\0'; 1051 property->addstyle = XrmStringToQuark(name); 1052 name = sep; 1053 1054 sep = strchr(sep, '-'); *sep++ = '\0'; 1055 property->pixel_size = XrmStringToQuark(name); 1056 name = sep; 1057 1058 sep = strchr(sep, '-'); *sep++ = '\0'; 1059 property->point_size = XrmStringToQuark(name); 1060 name = sep; 1061 1062 sep = strchr(sep, '-'); *sep++ = '\0'; 1063 property->res_x = XrmStringToQuark(name); 1064 name = sep; 1065 1066 sep = strchr(sep, '-'); *sep++ = '\0'; 1067 property->res_y = XrmStringToQuark(name); 1068 name = sep; 1069 1070 sep = strchr(sep, '-'); *sep++ = '\0'; 1071 property->spacing = XrmStringToQuark(name); 1072 name = sep; 1073 1074 sep = strchr(sep, '-'); *sep++ = '\0'; 1075 property->avgwidth = XrmStringToQuark(name); 1076 name = sep; 1077 1078 sep = strchr(sep, '-'); *sep++ = '\0'; 1079 property->registry = XrmStringToQuark(name); 1080 name = sep; 1081 1082 property->encoding = XrmStringToQuark(name); 1083 1084 XFree(xlfd); 1085 } 1086 } 1087 1088 atom = XInternAtom(display, "UNDERLINE_THICKNESS", True); 1089 if (XGetFontProperty(property->font, atom, &value) && 1090 (str = XGetAtomName(display, value)) != NULL) { 1091 property->underline_thickness = (short)(atoi(str)); 1092 XFree(str); 1093 } 1094 else { 1095 /* XLFD says: 1096 * CapStemWidth = average width of the stems of capitals 1097 * if (UNDERLINE_THICKNESS undefined) then 1098 * UNDERLINE_THICKNESS = CapStemWidth 1099 * 1100 * How do I know the value of CapStemWidth?? 1101 */ 1102 if (property->pixel_size != NULLQUARK) { 1103 property->underline_thickness = 1104 (short)(atoi(XrmQuarkToString(property->pixel_size)) / 10); 1105 property->underline_thickness = 1106 (XawMax(1, property->underline_thickness)); 1107 } 1108 else 1109 property->underline_thickness = 1; 1110 } 1111 1112 atom = XInternAtom(display, "UNDERLINE_POSITION", True); 1113 if (XGetFontProperty(property->font, atom, &value) && 1114 (str = XGetAtomName(display, value)) != NULL) { 1115 property->underline_position = (short)(atoi(str)); 1116 XFree(str); 1117 } 1118 else 1119 /* XLFD says: 1120 * if (UNDERLINE_POSITION undefined) then 1121 * UNDERLINE_POSITION = ROUND((maximum_descent) / 2) 1122 */ 1123 property->underline_position = 1124 property->font->max_bounds.descent >> 1; 1125 1126 /* I am assuming xlfd does not consider that lines are 1127 * centered in the path */ 1128 property->underline_position = (short)(property->underline_position 1129 + (property->underline_thickness >> 1)); 1130} 1131 1132static void 1133DestroyTextPropertyList(XawTextPropertyList *list) 1134{ 1135 int i; 1136 1137 for (i = 0; (Cardinal)i < list->num_properties; i++) { 1138 if (list->properties[i]->font) 1139 XFreeFont(DisplayOfScreen(list->screen), list->properties[i]->font); 1140 XtFree((char*)list->properties[i]); 1141 } 1142 if (list->properties) 1143 XtFree((char*)list->properties); 1144 XtFree((char*)list); 1145} 1146 1147static XawTextProperty * 1148_XawTextSinkGetProperty(XawTextPropertyList *list, XrmQuark property) 1149{ 1150 if (property != NULLQUARK && list && list->properties) { 1151 XawTextProperty **ptr = (XawTextProperty**) 1152 bsearch((void*)(long)property, 1153 list->properties, list->num_properties, 1154 sizeof(XawTextProperty*), bcmp_qident); 1155 1156 if (ptr) 1157 return (*ptr); 1158 } 1159 1160 return (NULL); 1161} 1162 1163XawTextProperty * 1164XawTextSinkGetProperty(Widget w, XrmQuark property) 1165{ 1166 TextSinkObject sink = (TextSinkObject)w; 1167 XawTextPropertyList *list = sink->text_sink.properties; 1168 1169 return (_XawTextSinkGetProperty(list, property)); 1170} 1171 1172XawTextProperty * 1173XawTextSinkCopyProperty(Widget w, XrmQuark property) 1174{ 1175 XawTextProperty *cur, *ret; 1176 1177 if ((cur = XawTextSinkGetProperty(w, property)) == NULL) 1178 cur = XawTextSinkGetProperty(w, Qdefault); 1179 ret = (XawTextProperty*)XtCalloc(1, sizeof(XawTextProperty)); 1180 if (cur) 1181 memcpy(ret, cur, sizeof(XawTextProperty)); 1182 ret->identifier = NULLQUARK; 1183 ret->mask &= (unsigned long)(~XAW_TPROP_FONT); 1184 1185 return (ret); 1186} 1187 1188static XawTextProperty * 1189_XawTextSinkAddProperty(XawTextPropertyList *list, XawTextProperty *property, 1190 Bool replace) 1191{ 1192 XawTextProperty *result; 1193 XColor color; 1194 char identifier[1024]; 1195 char foreground[16]; 1196 char background[16]; 1197 const char *foundry, *family, *weight, *slant, *setwidth, *addstyle, *pixel_size, 1198 *point_size, *res_x, *res_y, *spacing, *avgwidth, *registry, *encoding; 1199 const char *xlfd; 1200 static const char *asterisk = "*"; 1201 static const char *null = ""; 1202 XrmQuark quark; 1203 1204 if (list == NULL || property == NULL) 1205 return (NULL); 1206 1207 if (property->mask & XAW_TPROP_FOREGROUND) { 1208 color.pixel = property->foreground; 1209 XQueryColor(DisplayOfScreen(list->screen), list->colormap, &color); 1210 snprintf(foreground, sizeof(foreground), "%04x%04x%04x", 1211 color.red, color.green, color.blue); 1212 } 1213 else 1214 strcpy(foreground, asterisk); 1215 if (property->mask & XAW_TPROP_BACKGROUND) { 1216 color.pixel = property->background; 1217 XQueryColor(DisplayOfScreen(list->screen), list->colormap, &color); 1218 snprintf(background, sizeof(background), "%04x%04x%04x", 1219 color.red, color.green, color.blue); 1220 } 1221 else 1222 strcpy(background, asterisk); 1223 1224 if (property->xlfd_mask & XAW_TPROP_FOUNDRY) 1225 foundry = XrmQuarkToString(property->foundry); 1226 else 1227 foundry = asterisk; 1228 1229 /* use default, or what was requested */ 1230 if (property->family != NULLQUARK) 1231 family = XrmQuarkToString(property->family); 1232 else 1233 family = asterisk; 1234 if (property->weight != NULLQUARK) 1235 weight = XrmQuarkToString(property->weight); 1236 else 1237 weight = asterisk; 1238 if (property->slant != NULLQUARK) { 1239 slant = XrmQuarkToString(property->slant); 1240 if (toupper((unsigned char)*slant) != 'R') 1241 slant = asterisk; /* X defaults to italics, so, don't 1242 care in resolving between `I' and `O' */ 1243 } 1244 else 1245 slant = asterisk; 1246 1247 if (property->xlfd_mask & XAW_TPROP_SETWIDTH) 1248 setwidth = XrmQuarkToString(property->setwidth); 1249 else 1250 setwidth = asterisk; 1251 if (property->xlfd_mask & XAW_TPROP_ADDSTYLE) 1252 addstyle = XrmQuarkToString(property->addstyle); 1253 else 1254 addstyle = null; 1255 1256 /* use default, or what was requested */ 1257 if (!(property->mask & XAW_TPROP_POINTSIZE) && 1258 property->pixel_size != NULLQUARK) 1259 pixel_size = XrmQuarkToString(property->pixel_size); 1260 else 1261 pixel_size = asterisk; 1262 1263 if (property->xlfd_mask & XAW_TPROP_POINTSIZE) 1264 point_size = XrmQuarkToString(property->point_size); 1265 else 1266 point_size = asterisk; 1267 if (property->xlfd_mask & XAW_TPROP_RESX) 1268 res_x = XrmQuarkToString(property->res_x); 1269 else 1270 res_x = asterisk; 1271 if (property->xlfd_mask & XAW_TPROP_RESY) 1272 res_y = XrmQuarkToString(property->res_y); 1273 else 1274 res_y = asterisk; 1275 if (property->xlfd_mask & XAW_TPROP_SPACING) 1276 spacing = XrmQuarkToString(property->spacing); 1277 else 1278 spacing = asterisk; 1279 if (property->xlfd_mask & XAW_TPROP_AVGWIDTH) 1280 avgwidth = XrmQuarkToString(property->avgwidth); 1281 else 1282 avgwidth = asterisk; 1283 1284 /* use default, or what that was requested */ 1285 if (property->registry != NULLQUARK) 1286 registry = XrmQuarkToString(property->registry); 1287 else 1288 registry = asterisk; 1289 if (property->encoding != NULLQUARK) 1290 encoding = XrmQuarkToString(property->encoding); 1291 else 1292 encoding = asterisk; 1293 1294 if (replace) { 1295 result = XtNew(XawTextProperty); 1296 memcpy(result, property, sizeof(XawTextProperty)); 1297 } 1298 else 1299 result = property; 1300 1301 /* XXX should do the best to load a suitable font here */ 1302 if (!(result->mask & XAW_TPROP_FONT)) { 1303 snprintf(identifier, sizeof(identifier), 1304 "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", 1305 foundry, family, weight, slant, setwidth, addstyle, 1306 pixel_size, point_size, res_x, res_y, spacing, avgwidth, 1307 registry, encoding); 1308 if ((result->font = XLoadQueryFont(DisplayOfScreen(list->screen), 1309 identifier)) != NULL) { 1310 result->mask |= XAW_TPROP_FONT; 1311 SetXlfdDefaults(DisplayOfScreen(list->screen), result); 1312 } 1313 else 1314 result->mask &= (unsigned long)(~XAW_TPROP_FONT); 1315 } 1316 1317 if (result->font) 1318 xlfd = XrmQuarkToString(result->xlfd); 1319 else 1320 xlfd = null; 1321 1322 snprintf(identifier, sizeof(identifier), "%08lx%08lx%s%s%d%d%d%d%s", 1323 property->mask, property->xlfd_mask, 1324 foreground, background, 1325 (result->mask & XAW_TPROP_UNDERLINE) != 0, 1326 (result->mask & XAW_TPROP_OVERSTRIKE) != 0, 1327 (result->mask & XAW_TPROP_SUBSCRIPT) != 0, 1328 (result->mask & XAW_TPROP_SUPERSCRIPT) != 0, 1329 xlfd); 1330 1331 quark = XrmStringToQuark(identifier); 1332 if (result->identifier == NULLQUARK) 1333 result->identifier = quark; 1334 result->code = quark; 1335 1336 if ((property = _XawTextSinkGetProperty(list, result->identifier)) != NULL) { 1337 if (result->font) 1338 XFreeFont(DisplayOfScreen(list->screen), result->font); 1339 if (replace) 1340 XtFree((XtPointer)result); 1341 1342 return (property); 1343 } 1344 1345 list->properties = (XawTextProperty**) 1346 XtRealloc((XtPointer)list->properties, 1347 (Cardinal)(sizeof(XawTextProperty*) * 1348 (list->num_properties + 1))); 1349 list->properties[list->num_properties++] = result; 1350 qsort((void*)list->properties, list->num_properties, 1351 sizeof(XawTextProperty*), qcmp_qident); 1352 1353 return (result); 1354} 1355 1356XawTextProperty * 1357XawTextSinkAddProperty(Widget w, XawTextProperty *property) 1358{ 1359 TextSinkObject sink = (TextSinkObject)w; 1360 XawTextPropertyList *list = sink->text_sink.properties; 1361 1362 return (_XawTextSinkAddProperty(list, property, True)); 1363} 1364 1365XawTextProperty * 1366XawTextSinkCombineProperty(Widget w _X_UNUSED, 1367 XawTextProperty *property, XawTextProperty *combine, 1368 Bool override) 1369{ 1370 if (property == NULL || combine == NULL) 1371 return (property); 1372 1373 if ((override || !(property->mask & XAW_TPROP_FOREGROUND)) && 1374 (combine->mask & XAW_TPROP_FOREGROUND)) { 1375 property->mask |= XAW_TPROP_FOREGROUND; 1376 property->foreground = combine->foreground; 1377 } 1378 if ((override || !(property->mask & XAW_TPROP_BACKGROUND)) && 1379 (combine->mask & XAW_TPROP_BACKGROUND)) { 1380 property->mask |= XAW_TPROP_BACKGROUND; 1381 property->background = combine->background; 1382 } 1383 if ((override || !(property->mask & XAW_TPROP_FPIXMAP)) && 1384 (combine->mask & XAW_TPROP_FPIXMAP)) { 1385 property->mask |= XAW_TPROP_FPIXMAP; 1386 property->foreground_pixmap = combine->foreground_pixmap; 1387 } 1388 if ((override || !(property->mask & XAW_TPROP_BPIXMAP)) && 1389 (combine->mask & XAW_TPROP_BPIXMAP)) { 1390 property->mask |= XAW_TPROP_BPIXMAP; 1391 property->background_pixmap = combine->background_pixmap; 1392 } 1393 if (combine->mask & XAW_TPROP_UNDERLINE) 1394 property->mask |= XAW_TPROP_UNDERLINE; 1395 if (combine->mask & XAW_TPROP_OVERSTRIKE) 1396 property->mask |= XAW_TPROP_OVERSTRIKE; 1397 if ((override || !(property->mask & XAW_TPROP_SUPERSCRIPT)) && 1398 (combine->mask & XAW_TPROP_SUBSCRIPT)) 1399 property->mask |= XAW_TPROP_SUBSCRIPT; 1400 if ((property->mask & XAW_TPROP_SUBSCRIPT) && 1401 (combine->mask & XAW_TPROP_SUPERSCRIPT)) 1402 property->mask |= XAW_TPROP_SUPERSCRIPT; 1403 if ((override || !(property->xlfd_mask & XAW_TPROP_FOUNDRY)) && 1404 (combine->xlfd_mask & XAW_TPROP_FOUNDRY)) { 1405 property->xlfd_mask |= XAW_TPROP_FOUNDRY; 1406 property->foundry = combine->foundry; 1407 } 1408 if ((override || !(property->xlfd_mask & XAW_TPROP_FAMILY)) && 1409 (combine->xlfd_mask & XAW_TPROP_FAMILY)) { 1410 property->xlfd_mask |= XAW_TPROP_FAMILY; 1411 property->family = combine->family; 1412 } 1413 if ((override || !(property->xlfd_mask & XAW_TPROP_WEIGHT)) && 1414 (combine->xlfd_mask & XAW_TPROP_WEIGHT)) { 1415 property->xlfd_mask |= XAW_TPROP_WEIGHT; 1416 property->weight = combine->weight; 1417 } 1418 if ((override || !(property->xlfd_mask & XAW_TPROP_SLANT)) && 1419 (combine->xlfd_mask & XAW_TPROP_SLANT)) { 1420 property->xlfd_mask |= XAW_TPROP_SLANT; 1421 property->slant = combine->slant; 1422 } 1423 if ((override || !(property->xlfd_mask & XAW_TPROP_SETWIDTH)) && 1424 (combine->xlfd_mask & XAW_TPROP_SETWIDTH)) { 1425 property->xlfd_mask |= XAW_TPROP_SETWIDTH; 1426 property->setwidth = combine->setwidth; 1427 } 1428 if ((override || !(property->xlfd_mask & XAW_TPROP_ADDSTYLE)) && 1429 (combine->xlfd_mask & XAW_TPROP_ADDSTYLE)) { 1430 property->xlfd_mask |= XAW_TPROP_ADDSTYLE; 1431 property->addstyle = combine->addstyle; 1432 } 1433 if ((override || !(property->xlfd_mask & XAW_TPROP_PIXELSIZE)) && 1434 (combine->xlfd_mask & XAW_TPROP_PIXELSIZE)) { 1435 property->xlfd_mask |= XAW_TPROP_PIXELSIZE; 1436 property->pixel_size = combine->pixel_size; 1437 } 1438 if ((override || !(property->xlfd_mask & XAW_TPROP_POINTSIZE)) && 1439 (combine->xlfd_mask & XAW_TPROP_POINTSIZE)) { 1440 property->xlfd_mask |= XAW_TPROP_POINTSIZE; 1441 property->point_size = combine->point_size; 1442 } 1443 if ((override || !(property->xlfd_mask & XAW_TPROP_RESX)) && 1444 (combine->xlfd_mask & XAW_TPROP_RESX)) { 1445 property->xlfd_mask |= XAW_TPROP_RESX; 1446 property->res_x = combine->res_x; 1447 } 1448 if ((override || !(property->xlfd_mask & XAW_TPROP_RESY)) && 1449 (combine->xlfd_mask & XAW_TPROP_RESY)) { 1450 property->xlfd_mask |= XAW_TPROP_RESY; 1451 property->res_y = combine->res_y; 1452 } 1453 if ((override || !(property->xlfd_mask & XAW_TPROP_SPACING)) && 1454 (combine->xlfd_mask & XAW_TPROP_SPACING)) { 1455 property->xlfd_mask |= XAW_TPROP_SPACING; 1456 property->spacing = combine->spacing; 1457 } 1458 if ((override || !(property->xlfd_mask & XAW_TPROP_AVGWIDTH)) && 1459 (combine->xlfd_mask & XAW_TPROP_AVGWIDTH)) { 1460 property->xlfd_mask |= XAW_TPROP_AVGWIDTH; 1461 property->avgwidth = combine->avgwidth; 1462 } 1463 if ((override || !(property->xlfd_mask & XAW_TPROP_REGISTRY)) && 1464 (combine->xlfd_mask & XAW_TPROP_REGISTRY)) { 1465 property->xlfd_mask |= XAW_TPROP_REGISTRY; 1466 property->registry = combine->registry; 1467 } 1468 if ((override || !(property->xlfd_mask & XAW_TPROP_ENCODING)) && 1469 (combine->xlfd_mask & XAW_TPROP_ENCODING)) { 1470 property->xlfd_mask |= XAW_TPROP_ENCODING; 1471 property->encoding = combine->encoding; 1472 } 1473 1474 return (property); 1475} 1476 1477/* 1478 * The default property must be defined first, if the code is willing to 1479 * combine properties. 1480 */ 1481XawTextPropertyList * 1482XawTextSinkConvertPropertyList(String name, String spec, Screen *screen, 1483 Colormap colormap, int depth) 1484{ 1485 XrmQuark qname = XrmStringToQuark(name); 1486 XawTextPropertyList **ptr = NULL; 1487 XawTextPropertyList *propl, *prev = NULL; 1488 XawTextProperty *def_prop = NULL; 1489 char * str; 1490 String tok; 1491 char *tmp; 1492 char buffer[BUFSIZ]; 1493 1494 if (prop_lists) ptr = (XawTextPropertyList**) 1495 bsearch((void*)(long)qname, prop_lists, num_prop_lists, 1496 sizeof(XawTextPropertyList*), bcmp_qident); 1497 if (ptr) { 1498 propl = *ptr; 1499 while (propl) { 1500 prev = propl; 1501 if (propl->screen == screen && 1502 propl->colormap == colormap && 1503 propl->depth == depth) 1504 return (propl); 1505 propl = propl->next; 1506 } 1507 } 1508 1509 propl = XtNew(XawTextPropertyList); 1510 propl->identifier = qname; 1511 propl->screen = screen; 1512 propl->colormap = colormap; 1513 propl->depth = depth; 1514 propl->next = NULL; 1515 1516 if (prev) 1517 prev->next = propl; 1518 1519 propl->properties = NULL; 1520 propl->num_properties = 0; 1521 1522 str = XtNewString(spec); 1523 for (tok = str; tok; tok = tmp) { 1524 XawTextProperty *prop; 1525 XawParams *params; 1526 XrmQuark ident; 1527 XawArgVal *argval; 1528 XColor color, exact; 1529 1530 if (def_prop == NULL && propl->num_properties) 1531 def_prop = _XawTextSinkGetProperty(propl, Qdefault); 1532 tmp = strchr(tok, ','); 1533 if (tmp) { 1534 *tmp = '\0'; 1535 if (*++tmp == '\0') 1536 tmp = NULL; 1537 } 1538 params = XawParseParamsString(tok); 1539 ident = XrmStringToQuark(params->name); 1540 if (ident == NULLQUARK) { 1541 snprintf(buffer, sizeof(buffer), "Bad text property name \"%s\".", 1542 params->name); 1543 XtAppWarning(XtDisplayToApplicationContext 1544 (DisplayOfScreen(screen)), buffer); 1545 DestroyTextPropertyList(propl); 1546 if (prev) 1547 prev->next = NULL; 1548 XawFreeParamsStruct(params); 1549 return (NULL); 1550 } 1551 else if (_XawTextSinkGetProperty(propl, ident) != NULL) { 1552 XawFreeParamsStruct(params); 1553 continue; 1554 } 1555 1556 prop = (XawTextProperty*)XtCalloc(1, sizeof(XawTextProperty)); 1557 prop->identifier = ident; 1558 1559 if ((argval = XawFindArgVal(params, "font")) != NULL && 1560 argval->value) { 1561 1562 if ((prop->font = XLoadQueryFont(DisplayOfScreen(screen), 1563 argval->value)) == NULL) { 1564 snprintf(buffer, sizeof(buffer), "Cannot load font \"%s\".", 1565 argval->value); 1566 XtAppWarning(XtDisplayToApplicationContext 1567 (DisplayOfScreen(screen)), buffer); 1568 DestroyTextPropertyList(propl); 1569 if (prev) 1570 prev->next = NULL; 1571 XawFreeParamsStruct(params); 1572 XtFree((char *)prop); 1573 return (NULL); 1574 } 1575 prop->mask |= XAW_TPROP_FONT; 1576 SetXlfdDefaults(DisplayOfScreen(screen), prop); 1577 } 1578 /* fontset processing here */ 1579 1580 if ((argval = XawFindArgVal(params, "foreground")) != NULL && 1581 argval->value) { 1582 if (!XAllocNamedColor(DisplayOfScreen(screen), colormap, 1583 argval->value, &color, &exact)) { 1584 snprintf(buffer, sizeof(buffer), 1585 "Cannot allocate color \"%s\".", argval->value); 1586 XtAppWarning(XtDisplayToApplicationContext 1587 (DisplayOfScreen(screen)), buffer); 1588 DestroyTextPropertyList(propl); 1589 if (prev) 1590 prev->next = NULL; 1591 XawFreeParamsStruct(params); 1592 XtFree((char *)prop); 1593 return (NULL); 1594 } 1595 prop->foreground = color.pixel; 1596 prop->mask |= XAW_TPROP_FOREGROUND; 1597 } 1598 if ((argval = XawFindArgVal(params, "background")) != NULL && 1599 argval->value) { 1600 if (!XAllocNamedColor(DisplayOfScreen(screen), colormap, 1601 argval->value, &color, &exact)) { 1602 snprintf(buffer, sizeof(buffer), 1603 "Cannot allocate color \"%s\".", argval->value); 1604 XtAppWarning(XtDisplayToApplicationContext 1605 (DisplayOfScreen(screen)), buffer); 1606 DestroyTextPropertyList(propl); 1607 if (prev) 1608 prev->next = NULL; 1609 XawFreeParamsStruct(params); 1610 XtFree((char *)prop); 1611 return (NULL); 1612 } 1613 prop->background = color.pixel; 1614 prop->mask |= XAW_TPROP_BACKGROUND; 1615 } 1616 /* foreground_pixmap and background_pixmap processing here */ 1617 1618 if (XawFindArgVal(params, "underline")) 1619 prop->mask |= XAW_TPROP_UNDERLINE; 1620 if (XawFindArgVal(params, "overstrike")) 1621 prop->mask |= XAW_TPROP_OVERSTRIKE; 1622 1623 if (XawFindArgVal(params, "subscript")) 1624 prop->mask |= XAW_TPROP_SUBSCRIPT; 1625 else if (XawFindArgVal(params, "superscript")) 1626 prop->mask |= XAW_TPROP_SUPERSCRIPT; 1627 1628 /* xlfd */ 1629 if ((argval = XawFindArgVal(params, "foundry")) != NULL && 1630 argval->value) { 1631 prop->xlfd_mask |= XAW_TPROP_FOUNDRY; 1632 prop->foundry = XrmStringToQuark(argval->value); 1633 } 1634 if ((argval = XawFindArgVal(params, "family")) != NULL && 1635 argval->value) { 1636 prop->xlfd_mask |= XAW_TPROP_FAMILY; 1637 prop->family = XrmStringToQuark(argval->value); 1638 } 1639 if ((argval = XawFindArgVal(params, "weight")) != NULL && 1640 argval->value) { 1641 prop->xlfd_mask |= XAW_TPROP_WEIGHT; 1642 prop->weight = XrmStringToQuark(argval->value); 1643 } 1644 if ((argval = XawFindArgVal(params, "slant")) != NULL && 1645 argval->value) { 1646 prop->xlfd_mask |= XAW_TPROP_SLANT; 1647 prop->slant = XrmStringToQuark(argval->value); 1648 } 1649 if ((argval = XawFindArgVal(params, "setwidth")) != NULL && 1650 argval->value) { 1651 prop->xlfd_mask |= XAW_TPROP_SETWIDTH; 1652 prop->setwidth = XrmStringToQuark(argval->value); 1653 } 1654 if ((argval = XawFindArgVal(params, "addstyle")) != NULL && 1655 argval->value) { 1656 prop->xlfd_mask |= XAW_TPROP_ADDSTYLE; 1657 prop->addstyle = XrmStringToQuark(argval->value); 1658 } 1659 if ((argval = XawFindArgVal(params, "pixelsize")) != NULL && 1660 argval->value) { 1661 prop->xlfd_mask |= XAW_TPROP_PIXELSIZE; 1662 prop->pixel_size = XrmStringToQuark(argval->value); 1663 } 1664 if ((argval = XawFindArgVal(params, "pointsize")) != NULL && 1665 argval->value) { 1666 prop->xlfd_mask |= XAW_TPROP_POINTSIZE; 1667 prop->point_size = XrmStringToQuark(argval->value); 1668 } 1669 if ((argval = XawFindArgVal(params, "resx")) != NULL && 1670 argval->value) { 1671 prop->xlfd_mask |= XAW_TPROP_RESX; 1672 prop->res_x = XrmStringToQuark(argval->value); 1673 } 1674 if ((argval = XawFindArgVal(params, "resy")) != NULL && 1675 argval->value) { 1676 prop->xlfd_mask |= XAW_TPROP_RESY; 1677 prop->res_y = XrmStringToQuark(argval->value); 1678 } 1679 if ((argval = XawFindArgVal(params, "spacing")) != NULL && 1680 argval->value) { 1681 prop->xlfd_mask |= XAW_TPROP_SPACING; 1682 prop->spacing = XrmStringToQuark(argval->value); 1683 } 1684 if ((argval = XawFindArgVal(params, "avgwidth")) != NULL && 1685 argval->value) { 1686 prop->xlfd_mask |= XAW_TPROP_AVGWIDTH; 1687 prop->avgwidth = XrmStringToQuark(argval->value); 1688 } 1689 if ((argval = XawFindArgVal(params, "registry")) != NULL && 1690 argval->value) { 1691 prop->xlfd_mask |= XAW_TPROP_REGISTRY; 1692 prop->registry = XrmStringToQuark(argval->value); 1693 } 1694 if ((argval = XawFindArgVal(params, "encoding")) != NULL && 1695 argval->value) { 1696 prop->xlfd_mask |= XAW_TPROP_ENCODING; 1697 prop->encoding = XrmStringToQuark(argval->value); 1698 } 1699 1700 if (def_prop) 1701 (void)XawTextSinkCombineProperty(NULL, prop, def_prop, False); 1702 (void)_XawTextSinkAddProperty(propl, prop, False); 1703 1704 XawFreeParamsStruct(params); 1705 } 1706 1707 prop_lists = (XawTextPropertyList**) 1708 XtRealloc((XtPointer)prop_lists, 1709 (Cardinal)(sizeof(XawTextPropertyList*) * 1710 (num_prop_lists + 1))); 1711 prop_lists[num_prop_lists++] = propl; 1712 qsort((void*)prop_lists, num_prop_lists, sizeof(XawTextPropertyList*), 1713 qcmp_qident); 1714 1715 XtFree(str); 1716 1717 return (propl); 1718} 1719 1720/*ARGSUSED*/ 1721static Boolean 1722CvtStringToPropertyList(Display *dpy, XrmValue *args, Cardinal *num_args, 1723 XrmValue *fromVal, XrmValue *toVal, 1724 XtPointer *converter_data _X_UNUSED) 1725{ 1726 XawTextPropertyList *propl = NULL; 1727 String name; 1728 Widget w; 1729 1730 if (*num_args != 1) { 1731 XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 1732 "wrongParameters", "cvtStringToTextProperties", 1733 "ToolkitError", 1734 "String to textProperties conversion needs widget argument", 1735 NULL, NULL); 1736 return (False); 1737 } 1738 1739 w = *(Widget*)args[0].addr; 1740 while (w && !XtIsWidget(w)) 1741 w = XtParent(w); 1742 1743 name = (String)(fromVal[0].addr); 1744 1745 if (w) { 1746 XawTextPropertyList **ptr = NULL; 1747 if (prop_lists) ptr = (XawTextPropertyList**) 1748 bsearch((void*)(long)XrmStringToQuark(name), 1749 prop_lists, num_prop_lists, 1750 sizeof(XawTextPropertyList*), bcmp_qident); 1751 1752 if (ptr) { 1753 Screen *screen = w->core.screen; 1754 Colormap colormap = w->core.colormap; 1755 int depth = (int)w->core.depth; 1756 1757 propl = *ptr; 1758 while (propl) { 1759 if (propl->screen == screen && 1760 propl->colormap == colormap && 1761 propl->depth == depth) 1762 break; 1763 propl = propl->next; 1764 } 1765 } 1766 } 1767 1768 if (!propl) { 1769 XtDisplayStringConversionWarning(dpy, (String)fromVal->addr, 1770 XawRTextProperties); 1771 toVal->addr = NULL; 1772 toVal->size = sizeof(XawTextPropertyList*); 1773 return (False); 1774 } 1775 1776 if (toVal->addr != NULL) { 1777 if (toVal->size < sizeof(XawTextPropertyList*)) { 1778 toVal->size = sizeof(XawTextPropertyList*); 1779 return (False); 1780 } 1781 *(XawTextPropertyList**)(toVal->addr) = propl; 1782 } 1783 else { 1784 static XawTextPropertyList *static_val; 1785 1786 static_val = propl; 1787 toVal->addr = (XPointer)&static_val; 1788 } 1789 toVal->size = sizeof(XawTextProperty*); 1790 1791 return (True); 1792} 1793 1794/*ARGSUSED*/ 1795static Boolean 1796CvtPropertyListToString(Display *dpy, XrmValue *args _X_UNUSED, Cardinal *num_args _X_UNUSED, 1797 XrmValue *fromVal, XrmValue *toVal, 1798 XtPointer *converter_data _X_UNUSED) 1799{ 1800 static char *buffer; 1801 Cardinal size; 1802 XawTextPropertyList *propl; 1803 1804 propl = *(XawTextPropertyList**)fromVal[0].addr; 1805 if (propl == NULL) { 1806 XtAppWarningMsg(XtDisplayToApplicationContext(dpy), 1807 "wrongParameters", "cvtPropertyListToString", 1808 "ToolkitError", 1809 "textProperties to String conversion needs property list argument", 1810 NULL, NULL); 1811 return (False); 1812 } 1813 1814 buffer = XrmQuarkToString(propl->identifier); 1815 size = (Cardinal)(strlen(buffer) + 1); 1816 1817 if (toVal->addr != NULL) { 1818 if (toVal->size < size) { 1819 toVal->size = size; 1820 return (False); 1821 } 1822 strcpy((char *)toVal->addr, buffer); 1823 } 1824 else 1825 toVal->addr = buffer; 1826 toVal->size = size; 1827 1828 return (True); 1829} 1830#endif 1831