1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 /*
24 * HISTORY
25 */
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #define FIX_1152
31
32 #ifdef REV_INFO
33 #ifndef lint
34 static char rcsid[] = "$TOG: XmRenderT.c /main/14 1998/10/26 20:14:42 samborn $"
35 #endif
36 #endif
37
38 #ifndef X_NOT_STDC_ENV
39 #include <stdlib.h>
40 #endif
41 #include <string.h>
42 #include <ctype.h>
43 #include <math.h>
44
45 #ifdef __cplusplus
46 extern "C" { /* some 'locale.h' do not have prototypes (sun) */
47 #endif
48 #include <X11/Xlocale.h>
49 #ifdef __cplusplus
50 } /* Close scope of 'extern "C"' declaration */
51 #endif /* __cplusplus */
52
53 #include <Xm/XmosP.h> /* For ALLOCATE/DEALLOCATE_LOCAL */
54 #include <X11/IntrinsicP.h>
55 #include <X11/ShellP.h>
56 #include <X11/Xresource.h>
57 #include <Xm/Display.h> /* For XmGetXmDisplay */
58 #include <Xm/DisplayP.h> /* For direct access to callback fields */
59 #include "MessagesI.h"
60 #include "XmI.h"
61 #include "XmRenderTI.h"
62 #include "XmStringI.h"
63 #include "XmTabListI.h"
64 #ifdef USE_XFT
65 #include <X11/Xft/Xft.h>
66 #endif
67
68 /* Warning Messages */
69 #define NO_NULL_TAG_MSG _XmMMsgXmRenderT_0000
70 #define NULL_DISPLAY_MSG _XmMMsgXmRenderT_0001
71 #define INVALID_TYPE_MSG _XmMMsgXmRenderT_0002
72 #define CONVERSION_FAILED_MSG _XmMMsgXmRenderT_0003
73 #define NULL_FONT_TYPE_MSG _XmMMsgXmRenderT_0004
74 #define NULL_LOAD_IMMEDIATE_MSG _XmMMsgXmRenderT_0005
75
76 /* local macros */
77 #define GetHandle(type) (type *)XtMalloc(sizeof(type))
78 #define FreeHandle(handle) XtFree((char *)handle)
79 #define SetPtr(handle, ptr) *(handle) = ptr
80 #define GetPtr(handle) *(handle)
81 #define NameIsString(fontname) \
82 (((fontname) != NULL) && ((fontname) != (String)XmAS_IS))
83 #define ListIsList(tablist) \
84 (((tablist) != NULL) && \
85 ((unsigned int)(unsigned long)(tablist) != XmAS_IS))
86
87 #define FIX_1414
88 #define FIX_1449
89 #define FIX_1444
90 #define FIX_1451
91 #define FIX_1536
92 /**********************************************************************
93 * IMPORTANT NOTE: IMPLEMENTATION OF SHARING
94 *
95 * Instances of XmRenderTable and XmRendition are shared via a
96 * reference counting mechanism. This comment provides a general
97 * overview of how this is done.
98 *
99 * First, both rendertable and renditions are indirectly
100 * referenced via a handle mechanism. See the GetHandle,
101 * FreeHandle, SetPtr and GetPtr macros above. This allows
102 * either the handle to change without the underlying data
103 * structure changing, or the underlying data structure to change
104 * without the handle changing. I will indicate below where this
105 * happens.
106 *
107 * Second, the real data structure for rendertable and rendition
108 * contain a reference count. This count is incremented on copy
109 * and decremented on free. If a decrement produces a zero
110 * refcount, the actual memory is freed. If an increment
111 * produces a zero refcount, then the refcount has overflowed. The
112 * refcount is decremented, and new memory is allocated for a new
113 * copy.
114 *
115 * Finally, I have defined a terminology for the different types
116 * of "copying" that can done based on allocating a new handle or
117 * not and allocating a new data structure or not. This probably
118 * conflicts with some other existing terminology, probably in
119 * object oriented programming. Sorry about that.
120 *
121 * Function: Clone Copy Renew Duplicate
122 * (Mutate) (Update)
123 *
124 * handle new new old old
125 * structure new inc new inc
126 * (changed) (changed)
127 *
128 * (changed) indicates that the data in the new structure has
129 * been changed from the data in the old structure.
130 *
131 * I will use these terms as a short hand in describing the
132 * functions below.
133 **********************************************************************/
134
135
136 /******** Static Function Declarations ********/
137
138 static void CopyInto(XmRendition toRend,
139 XmRendition fromRend);
140 static void MergeInto(XmRendition toRend,
141 XmRendition fromRend);
142 static XmRendition CloneRendition(XmRendition rend);
143 static XmRendition CopyRendition(XmRendition rend);
144 static XmRendition RenewRendition(XmRendition rend);
145 static XmRendition DuplicateRendition(XmRendition rend);
146 static Boolean FreeRendition(XmRendition rend);
147 static void RenditionWarning(char *tag, char *type,
148 char *message, Display *dpy);
149 static void CleanupResources(XmRendition rend, Boolean copy);
150 static void ValidateTag(XmRendition rend,
151 XmStringTag dflt);
152 static void ValidateAndLoadFont(XmRendition rend, Display *display);
153 static void SetRend(XmRendition to,
154 XmRendition from);
155 static Boolean RendComplete(XmRendition rend);
156 static void CopyFromArg(XtArgVal src,
157 char *dst,
158 unsigned int size);
159 static void CopyToArg(char *src,
160 XtArgVal *dst,
161 unsigned int size);
162 static Cardinal GetNamesAndClasses(Widget w,
163 XrmNameList names,
164 XrmClassList classes);
165 static XrmResourceList CompileResourceTable(XtResourceList resources,
166 Cardinal num_resources);
167 static Boolean GetResources(XmRendition rend,
168 Display *dsp,
169 Widget wid,
170 String resname,
171 String resclass,
172 XmStringTag tag,
173 ArgList arglist,
174 Cardinal argcount);
175 static void SetDefault(XmRendition rend);
176 #ifdef USE_XFT
177 #ifdef FIX_1536
178 static XftColor GetCachedXftColor(Display *display, Pixel color);
179 #endif
180 #endif
181
182 /******** End Static Function Declarations ********/
183
184 /* Resource List. */
185
186 /************************************************************************/
187 /* N.B.: The SetDefault procedure has a hardcoded list of all the */
188 /* common resources. Be sure to update it when adding resources. */
189 /************************************************************************/
190
191 #define DEFAULT_loadModel XmAS_IS
192 #define DEFAULT_tag XmS
193 #define DEFAULT_fontName (String)XmAS_IS
194 #define DEFAULT_fontType (XmFontType)XmAS_IS
195 #define DEFAULT_font (XtPointer)XmAS_IS
196 #define DEFAULT_tabs (XmTabList)XmAS_IS
197 #define DEFAULT_background XmUNSPECIFIED_PIXEL
198 #define DEFAULT_foreground XmUNSPECIFIED_PIXEL
199 #define DEFAULT_underlineType XmAS_IS
200 #define DEFAULT_strikethruType XmAS_IS
201 #define DEFAULT_backgroundState XmAS_IS
202 #define DEFAULT_foregroundState XmAS_IS
203 #ifdef USE_XFT
204 #define DEFAULT_xftFont (XtPointer)XmAS_IS
205 #define DEFAULT_fontStyle (String)NULL
206 #define DEFAULT_fontFoundry (String)NULL
207 #define DEFAULT_fontEncoding (String)NULL
208 #define DEFAULT_fontSize 0
209 #endif
210
211 static XtResource _XmRenditionResources[] = {
212 {
213 XmNtag, XmCTag, XmRString,
214 sizeof(XmStringTag), XtOffsetOf(_XmRenditionRec, tag),
215 XmRImmediate, (XtPointer) DEFAULT_tag
216 },
217 {
218 XmNfontName, XmCFontName, XmRString,
219 sizeof(String), XtOffsetOf(_XmRenditionRec, fontName),
220 XmRImmediate, (XtPointer) DEFAULT_fontName
221 },
222 {
223 XmNfontType, XmCFontType, XmRFontType,
224 sizeof(XmFontType), XtOffsetOf(_XmRenditionRec, fontType),
225 XmRImmediate, (XtPointer) DEFAULT_fontType
226 },
227 {
228 XmNfont, XmCFont, XmRFontStruct,
229 sizeof(XtPointer), XtOffsetOf(_XmRenditionRec, font),
230 XmRImmediate, (XtPointer) DEFAULT_font
231 },
232 {
233 XmNloadModel, XmCLoadModel, XmRLoadModel,
234 sizeof(unsigned char), XtOffsetOf(_XmRenditionRec, loadModel),
235 XmRImmediate, (XtPointer) DEFAULT_loadModel
236 },
237 {
238 XmNtabList, XmCTabList, XmRTabList,
239 sizeof(XmTabList), XtOffsetOf(_XmRenditionRec, tabs),
240 XmRImmediate, (XtPointer) DEFAULT_tabs
241 },
242 #if USE_XFT
243 {
244 XmNxftFont, XmCXftFont, XmRPointer,
245 sizeof (XtPointer), XtOffsetOf (_XmRenditionRec, xftFont),
246 XmRImmediate, (XtPointer) DEFAULT_xftFont
247 },
248 {
249 XmNrenditionBackground, XmCRenditionBackground, XmRRenditionPixel,
250 sizeof (Pixel), XtOffsetOf (_XmRenditionRec, xftBackground.pixel),
251 XmRImmediate, (XtPointer) DEFAULT_background
252 },
253 {
254 XmNrenditionForeground, XmCRenditionForeground, XmRRenditionPixel,
255 sizeof (Pixel), XtOffsetOf (_XmRenditionRec, xftForeground.pixel),
256 XmRImmediate, (XtPointer) DEFAULT_foreground
257 },
258 {
259 XmNfontStyle, XmCFontStyle, XmRString,
260 sizeof(String), XtOffsetOf (_XmRenditionRec, fontStyle),
261 XmRImmediate, (XtPointer) DEFAULT_fontStyle
262 },
263 {
264 XmNfontFoundry, XmCFontFoundry, XmRString,
265 sizeof(String), XtOffsetOf (_XmRenditionRec, fontFoundry),
266 XmRImmediate, (XtPointer) DEFAULT_fontFoundry
267 },
268 {
269 XmNfontEncoding, XmCFontEncoding, XmRString,
270 sizeof(String), XtOffsetOf (_XmRenditionRec, fontEncoding),
271 XmRImmediate, (XtPointer) DEFAULT_fontEncoding
272 },
273 {
274 XmNfontSize, XmCFontSize, XmRInt,
275 sizeof(int), XtOffsetOf (_XmRenditionRec, fontSize),
276 XmRImmediate, (XtPointer) DEFAULT_fontSize
277 },
278 #else
279 {
280 XmNrenditionBackground, XmCRenditionBackground, XmRRenditionPixel,
281 sizeof (Pixel), XtOffsetOf (_XmRenditionRec, background),
282 XmRImmediate, (XtPointer) DEFAULT_background
283 },
284 {
285 XmNrenditionForeground, XmCRenditionForeground, XmRRenditionPixel,
286 sizeof (Pixel), XtOffsetOf (_XmRenditionRec, foreground),
287 XmRImmediate, (XtPointer) DEFAULT_foreground
288 },
289 #endif
290 {
291 XmNunderlineType, XmCUnderlineType, XmRLineType,
292 sizeof(unsigned char), XtOffsetOf(_XmRenditionRec, underlineType),
293 XmRImmediate, (XtPointer) DEFAULT_underlineType
294 },
295 {
296 XmNstrikethruType, XmCStrikethruType, XmRLineType,
297 sizeof(unsigned char), XtOffsetOf(_XmRenditionRec, strikethruType),
298 XmRImmediate, (XtPointer) DEFAULT_strikethruType
299 },
300 {
301 XmNforegroundState, XmCGroundState, XmRGroundState,
302 sizeof(unsigned char), XtOffsetOf(_XmRenditionRec, foregroundState),
303 XmRImmediate, (XtPointer) DEFAULT_foregroundState
304 },
305 {
306 XmNbackgroundState, XmCGroundState, XmRGroundState,
307 sizeof(unsigned char), XtOffsetOf(_XmRenditionRec, backgroundState),
308 XmRImmediate, (XtPointer) DEFAULT_backgroundState
309 },
310 };
311
312 static XmConst Cardinal _XmNumRenditionResources =
313 XtNumber(_XmRenditionResources);
314
315 /* Searches up widget hierarchy, quarkifying ancestor names and */
316 /* classes. */
317 static Cardinal
GetNamesAndClasses(Widget w,XrmNameList names,XrmClassList classes)318 GetNamesAndClasses(Widget w, XrmNameList names, XrmClassList classes)
319 {
320 Cardinal length, j;
321 XrmQuark t;
322 WidgetClass wc;
323
324 /* Return null-terminated quark arrays, with length the number of
325 quarks (not including NULL) */
326
327 for (length = 0; w != NULL; w = (Widget)w->core.parent)
328 {
329 names[length] = w->core.xrm_name;
330 wc = XtClass(w);
331 /* KLUDGE KLUDGE KLUDGE KLUDGE */
332 if (w->core.parent == NULL && XtIsApplicationShell(w)) {
333 classes[length] =
334 ((ApplicationShellWidget) w)->application.xrm_class;
335 } else classes[length] = wc->core_class.xrm_class;
336 length++;
337 }
338 /* They're in backwards order, flop them around */
339 for (j = 0; j < length/2; j++)
340 {
341 t = names[j];
342 names[j] = names[length-j-1];
343 names[length-j-1] = t;
344 t = classes[j];
345 classes[j] = classes[length-j-1];
346 classes[length-j-1] = t;
347 }
348 names[length] = NULLQUARK;
349 classes[length] = NULLQUARK;
350 return length;
351 } /* GetNamesAndClasses */
352
353 /* Converts resource list to quarkified list. */
354 static XrmResourceList
CompileResourceTable(XtResourceList resources,Cardinal num_resources)355 CompileResourceTable(XtResourceList resources,
356 Cardinal num_resources)
357 {
358 Cardinal count;
359 XrmResourceList table, tPtr;
360 XtResourceList rPtr;
361
362 tPtr = table = (XrmResourceList)XtMalloc(num_resources * sizeof(XrmResource));
363 rPtr = resources;
364
365 for (count = 0; count < num_resources; count++, tPtr++, rPtr++)
366 {
367 tPtr->xrm_name = XrmPermStringToQuark(rPtr->resource_name);
368 tPtr->xrm_class = XrmPermStringToQuark(rPtr->resource_class);
369 tPtr->xrm_type = XrmPermStringToQuark(rPtr->resource_type);
370 tPtr->xrm_size = rPtr->resource_size;
371 tPtr->xrm_offset = rPtr->resource_offset;
372 tPtr->xrm_default_type = XrmPermStringToQuark(rPtr->default_type);
373 tPtr->xrm_default_addr = rPtr->default_addr;
374 }
375 return(table);
376 }
377
378 /* Does resource database lookup for arglist, filling in defaults from */
379 /* resource list as necessary. */
380 static Boolean
GetResources(XmRendition rend,Display * dsp,Widget wid,String resname,String resclass,XmStringTag tag,ArgList arglist,Cardinal argcount)381 GetResources(XmRendition rend,
382 Display *dsp,
383 Widget wid,
384 String resname,
385 String resclass,
386 XmStringTag tag,
387 ArgList arglist,
388 Cardinal argcount)
389 {
390 XrmName names[100];
391 XrmClass classes[100];
392 Cardinal length = 0;
393 static XrmQuarkList quarks = NULL;
394 static Cardinal num_quarks = 0;
395 static Boolean *found = NULL;
396 int i, j;
397 static XrmResourceList table = NULL;
398 static XrmQuark QString;
399 static XrmQuark Qfont;
400 Arg *arg;
401 XrmName argName;
402 XrmResource *res;
403 XrmDatabase db = NULL;
404 XrmHashTable stackSearchList[100];
405 XrmHashTable *searchList = stackSearchList;
406 unsigned int searchListSize = 100;
407 Boolean got_one = False;
408 XrmValue value;
409 XrmQuark rawType;
410 XrmValue convValue;
411 Boolean have_value, copied;
412 #ifdef XTHREADS
413 XtAppContext app=NULL;
414
415 if (wid)
416 app = XtWidgetToApplicationContext(wid);
417 else if (dsp)
418 app = XtDisplayToApplicationContext(dsp);
419 if (app) {
420 _XmAppLock(app);
421 }
422 _XmProcessLock();
423 #endif
424 /* Initialize quark cache */
425 if (quarks == NULL)
426 {
427 quarks = (XrmQuark *)XtMalloc(_XmNumRenditionResources *
428 sizeof(XrmQuark));
429 num_quarks = _XmNumRenditionResources;
430 }
431
432 /* Initialize found */
433 if (found == NULL)
434 found = (Boolean *)XtMalloc(_XmNumRenditionResources * sizeof(Boolean));
435 bzero(found, _XmNumRenditionResources * sizeof(Boolean));
436
437 /* Compile names and classes. */
438 if (wid != NULL)
439 length = GetNamesAndClasses(wid, names, classes);
440
441 names[length] = XrmStringToQuark(resname);
442 classes[length] = XrmStringToQuark(resclass);
443 length++;
444
445 if (tag != NULL)
446 {
447 names[length] = XrmStringToQuark(tag);
448 classes[length] = XrmPermStringToQuark(XmCRendition);
449 length++;
450 }
451
452 names[length] = NULLQUARK;
453 classes[length] = NULLQUARK;
454
455 /* Cache arglist */
456 if (num_quarks < argcount)
457 {
458 quarks = (XrmQuark *)XtRealloc((char *)quarks,
459 argcount * sizeof(XrmQuark));
460 num_quarks = argcount;
461 }
462 for (i = 0; i < argcount; i++)
463 quarks[i] = XrmStringToQuark(arglist[i].name);
464
465 /* Compile resource description into XrmResourceList if not already done. */
466 if (table == NULL)
467 {
468 table = CompileResourceTable(_XmRenditionResources,
469 _XmNumRenditionResources);
470 QString = XrmPermStringToQuark(XtCString);
471 Qfont = XrmPermStringToQuark(XmNfont);
472 }
473
474 /* Set resources from arglist. */
475 for (arg = arglist, i = 0; i < argcount; arg++, i++)
476 {
477 argName = quarks[i];
478
479 for (j = 0, res = table; j < _XmNumRenditionResources; j++, res++)
480 {
481 if (res->xrm_name == argName)
482 {
483 CopyFromArg((arg->value),
484 ((char *)GetPtr(rend) + res->xrm_offset),
485 res->xrm_size);
486 found[j] = TRUE;
487 break;
488 }
489 }
490 }
491
492 /* DB query */
493 /* Get database */
494 if ((wid != NULL) || (dsp != NULL))
495 {
496 if (wid != NULL)
497 db = XtScreenDatabase(XtScreenOfObject(wid));
498 else db = XtScreenDatabase(DefaultScreenOfDisplay(dsp));
499
500 /* Get searchlist */
501 while (!XrmQGetSearchList(db, names, classes,
502 searchList, searchListSize))
503 {
504 if (searchList == stackSearchList)
505 searchList = NULL;
506 searchList = (XrmHashTable *)XtRealloc((char*)searchList,
507 sizeof(XrmHashTable) *
508 (searchListSize *= 2));
509 }
510 }
511
512 /* Loop over table */
513 for (j = 0, res = table; j < _XmNumRenditionResources; j++, res++)
514 {
515 if (!found[j])
516 {
517 copied = False;
518 have_value = False;
519
520 if ((db != NULL) &&
521 (XrmQGetSearchResource(searchList, res->xrm_name,
522 res->xrm_class, &rawType, &value)))
523 {
524 /* convert if necessary */
525 if (rawType != res->xrm_type)
526 {
527 if (wid != NULL)
528 {
529 convValue.size = res->xrm_size;
530 convValue.addr = (char *)GetPtr(rend) + res->xrm_offset;
531 /*
532 * Check for special font case.
533 * Depending upon the fontType resource, try to convert
534 * to a FontSet, else to a FontStruct.
535 */
536 if ((res->xrm_name == Qfont) &&
537 (_XmRendFontType(rend) == XmFONT_IS_FONTSET))
538 copied = have_value =
539 XtConvertAndStore(wid,
540 XrmQuarkToString(rawType),
541 &value,
542 "FontSet",
543 &convValue);
544 else
545 copied = have_value =
546 XtConvertAndStore(wid,
547 XrmQuarkToString(rawType),
548 &value,
549 XrmQuarkToString(res->xrm_type),
550 &convValue);
551 }
552 else have_value = False;
553 }
554 else have_value = True;
555
556 /* Check for special font case */
557 if (have_value)
558 {
559 if (res->xrm_name == Qfont)
560 {
561 _XmRendFontName(rend) = value.addr;
562 copied = True;
563 }
564 }
565 }
566
567 if (!got_one && have_value) got_one = True;
568
569 /* Set defaults */
570 if (!have_value)
571 {
572 CopyFromArg((XtArgVal)(res->xrm_default_addr),
573 ((char *)GetPtr(rend) + res->xrm_offset),
574 res->xrm_size);
575 copied = True;
576 }
577
578 /* Copy if needed */
579 if (!copied)
580 {
581 if (res->xrm_type == QString)
582 *((String *)((char *)GetPtr(rend) + res->xrm_offset)) =
583 value.addr;
584 else if (value.addr != NULL)
585 memcpy(((char *)GetPtr(rend) + res->xrm_offset),
586 value.addr, res->xrm_size);
587 else
588 bzero(((char *)GetPtr(rend) + res->xrm_offset), res->xrm_size);
589 }
590
591 }
592 }
593 if (searchList != stackSearchList) XtFree((char *)searchList);
594
595 #ifdef XTHREADS
596 _XmProcessUnlock();
597 if (app) {
598 _XmAppUnlock(app);
599 }
600 #endif
601 return(got_one);
602 }
603
604 /* Sets all resources to defaults from resource list. */
605 static void
SetDefault(XmRendition rend)606 SetDefault(XmRendition rend)
607 {
608 /* A more robust implementation of this routine would to to loop
609 * over _XmRenditionResources and use CopyFromArg to reset values
610 * in rend, but to improve performance we use direct assignments.
611 */
612
613 if (rend == NULL) return;
614
615 #ifdef USE_XFT
616 memset (&(_XmRendXftFG(rend)), 0, sizeof (XftColor));
617 memset (&(_XmRendXftBG(rend)), 0, sizeof (XftColor));
618 #endif
619
620 /* Leave _XmRendFontOnly unchanged. */
621 /* Leave _XmRendRefcount unchanged. */
622 _XmRendLoadModel(rend) = DEFAULT_loadModel;
623 _XmRendTag(rend) = DEFAULT_tag;
624 _XmRendFontName(rend) = DEFAULT_fontName;
625 _XmRendFontType(rend) = DEFAULT_fontType;
626 _XmRendFont(rend) = DEFAULT_font;
627 /* Leave _XmRendDisplay unchanged. */
628 /* Leave _XmRendGC unchanged. */
629 /* Leave _XmRendTags unchanged. */
630 /* Leave _XmRendCount unchanged. */
631 /* Leave _XmRendHadEnds unchanged. */
632 _XmRendTabs(rend) = DEFAULT_tabs;
633 _XmRendBG(rend) = DEFAULT_background;
634 _XmRendFG(rend) = DEFAULT_foreground;
635 _XmRendUnderlineType(rend) = DEFAULT_underlineType;
636 _XmRendStrikethruType(rend) = DEFAULT_strikethruType;
637 _XmRendBGState(rend) = DEFAULT_backgroundState;
638 _XmRendFGState(rend) = DEFAULT_foregroundState;
639
640 #ifdef USE_XFT
641 _XmRendXftFG (rend).color.alpha = 0xFFFF; /*TODO: it is really needed? (yura)*/
642 _XmRendXftBG (rend).color.alpha = 0xFFFF; /*TODO: it is really needed? (yura)*/
643 _XmRendXftFont(rend) = DEFAULT_xftFont;
644 _XmRendPattern(rend) = NULL;
645 _XmRendFontStyle(rend) = DEFAULT_fontStyle;
646 _XmRendFontFoundry(rend) = DEFAULT_fontFoundry;
647 _XmRendFontEncoding(rend) = DEFAULT_fontEncoding;
648 _XmRendFontSize(rend) = DEFAULT_fontSize;
649 _XmRendPixelSize(rend) = 0;
650 _XmRendFontSlant(rend) = 0;
651 _XmRendFontSpacing(rend) = 0;
652 _XmRendFontWeight(rend) = 0;
653 #endif
654 }
655
656 /* Extern function to pick out display from rendertable. */
657 Display *
_XmRenderTableDisplay(XmRenderTable table)658 _XmRenderTableDisplay(XmRenderTable table)
659 {
660 return(_XmRTDisplay(table));
661 }
662
663 /* Find a rendition in table with matching tag. Call callback if not */
664 /* found and callback available. Fail if need_font is true and */
665 /* rendition found does not provide font. */
666 XmRendition
_XmRenderTableFindRendition(XmRenderTable table,XmStringTag tag,int cached_tag,int need_font,int call,short * index)667 _XmRenderTableFindRendition(XmRenderTable table,
668 XmStringTag tag,
669 #if NeedWidePrototypes
670 int cached_tag,
671 int need_font,
672 int call,
673 #else
674 Boolean cached_tag,
675 Boolean need_font,
676 Boolean call,
677 #endif /* NeedWidePrototypes */
678 short *index)
679 {
680 int i, j;
681 XmRendition rend;
682 Boolean hit = FALSE;
683 XmDisplayCallbackStruct cb;
684 XmDisplay dsp;
685 XmRenderTable copy;
686
687 if ((table == NULL) || (tag == NULL)) return(NULL);
688
689
690 for (;;) /* May have to try twice */
691 {
692 for (i = 0; i < _XmRTCount(table); i++)
693 {
694 rend = _XmRTRenditions(table)[i];
695
696 if ((cached_tag) ?
697 (_XmRendTag(rend) == tag) :
698 (strcmp(_XmRendTag(rend), tag) == 0))
699 {
700 hit = TRUE;
701
702 if ((_XmRendFont(rend) == NULL) && (_XmRendXftFont (rend) == NULL) &&
703 NameIsString(_XmRendFontName(rend)))
704 {
705 if (_XmRendLoadModel(rend) == XmLOAD_DEFERRED)
706 _XmRendLoadModel(rend) = XmLOAD_IMMEDIATE;
707
708 ValidateAndLoadFont(rend, _XmRendDisplay(rend));
709
710 if (need_font && (_XmRendFont(rend) == NULL &&
711 _XmRendXftFont(rend) == NULL))
712 break;
713 }
714
715 if (index != NULL) *index = i;
716 return(rend);
717 }
718 }
719
720 /* Are we done? */
721 if (hit || !call) break;
722
723 call = FALSE;
724
725 /* Call callback */
726 if (_XmRTDisplay(table) != NULL)
727 {
728 dsp = (XmDisplay) XmGetXmDisplay(_XmRTDisplay(table));
729
730 /* CR 7964: XtHasCallbacks is surprisingly expensive, */
731 /* so we use a conservative approximation here. */
732 if (dsp && dsp->display.noRenditionCallback)
733 {
734 copy = XmRenderTableCopy(table, NULL, 0);
735
736 cb.reason = XmCR_NO_RENDITION;
737 cb.event = NULL;
738 cb.render_table = copy;
739 cb.tag = tag;
740
741 XtCallCallbackList((Widget)dsp,
742 dsp->display.noRenditionCallback,
743 &cb);
744
745 if (cb.render_table != copy)
746 {
747 /* Callback mutated table. Update table with */
748 /* substitution and search again. */
749
750 for (j = 0; j < _XmRTCount(table); j++)
751 if (FreeRendition(_XmRTRenditions(table)[j]))
752 FreeHandle(_XmRTRenditions(table)[j]);
753
754 if (_XmRTRefcountDec(table) == 0)
755 XtFree((char *)GetPtr(table));
756
757 SetPtr(table, GetPtr(cb.render_table));
758 FreeHandle(cb.render_table);
759 }
760 else break;
761 }
762 else break;
763 }
764 else break;
765 }
766
767 /* Didn't find it. */
768 if (index != NULL) *index = -1;
769 return(NULL);
770 }
771
772 /* If to has resource unset and from has it set, set in to. */
773 static void
SetRend(XmRendition to,XmRendition from)774 SetRend(XmRendition to,
775 XmRendition from)
776 {
777 if (NameIsString(_XmRendFontName(from)) &&
778 !NameIsString(_XmRendFontName(to)))
779 _XmRendFontName(to) = _XmRendFontName(from);
780 if ((_XmRendFontType(from) != XmAS_IS) &&
781 (_XmRendFontType(to) == XmAS_IS))
782 _XmRendFontType(to) = _XmRendFontType(from);
783 if ((_XmRendLoadModel(from) != XmAS_IS) &&
784 (_XmRendLoadModel(to) == XmAS_IS))
785 _XmRendLoadModel(to) = _XmRendLoadModel(from);
786 if ((_XmRendFont(from) != NULL) &&
787 ((unsigned int)(unsigned long)_XmRendFont(to) == XmAS_IS))
788 _XmRendFont(to) = _XmRendFont(from);
789 if (ListIsList(_XmRendTabs(from)) &&
790 !ListIsList(_XmRendTabs(to)))
791 _XmRendTabs(to) = _XmRendTabs(from);
792 #if USE_XFT
793 if ((_XmRendFG(from) != XmUNSPECIFIED_PIXEL) &&
794 (_XmRendFG(to) == XmUNSPECIFIED_PIXEL))
795 {
796 #ifdef FIX_1536
797 _XmRendFG(to) = _XmRendFG(from);
798 _XmRendXftFG(to) = GetCachedXftColor(_XmRendDisplay(to), _XmRendFG(to));
799 #else
800 XColor xcolor;
801 _XmRendFG(to) = _XmRendFG(from);
802 xcolor.pixel = _XmRendFG(to);
803 XQueryColor(_XmRendDisplay(to), DefaultColormapOfScreen(
804 DefaultScreenOfDisplay(_XmRendDisplay(to))), &xcolor);
805 /* doesn't needed (_XmRendXftFG (to)).pixel = xcolor.pixel; */
806 (_XmRendXftFG(to)).color.red = xcolor.red;
807 (_XmRendXftFG(to)).color.green = xcolor.green;
808 (_XmRendXftFG(to)).color.blue = xcolor.blue;
809 (_XmRendXftFG(to)).color.alpha = 0xFFFF;
810 #endif
811 }
812 if ((_XmRendBG(from) != XmUNSPECIFIED_PIXEL) &&
813 (_XmRendBG(to) == XmUNSPECIFIED_PIXEL))
814 {
815 #ifdef FIX_1536
816 _XmRendBG(to) = _XmRendBG (from);
817 _XmRendXftBG(to) = GetCachedXftColor(_XmRendDisplay(to), _XmRendBG(to));
818 #else
819 XColor xcolor;
820 _XmRendBG(to) = _XmRendBG (from);
821 xcolor.pixel = _XmRendBG (to);
822 XQueryColor(_XmRendDisplay(to), DefaultColormapOfScreen(
823 DefaultScreenOfDisplay(_XmRendDisplay(to))), &xcolor);
824 /* doesn't needed (_XmRendXftBG (to)).pixel = xcolor.pixel; */
825 (_XmRendXftBG(to)).color.red = xcolor.red;
826 (_XmRendXftBG(to)).color.green = xcolor.green;
827 (_XmRendXftBG(to)).color.blue = xcolor.blue;
828 (_XmRendXftBG(to)).color.alpha = 0xFFFF;
829 #endif
830 }
831 if ((_XmRendXftFont (from) != NULL) &&
832 ((unsigned int) (unsigned long) _XmRendXftFont (to) == XmAS_IS))
833 _XmRendXftFont (to) = _XmRendXftFont (from);
834 if ((_XmRendFontStyle (from) != NULL) && _XmRendFontStyle (to) == NULL)
835 _XmRendFontStyle (to) = _XmRendFontStyle (from);
836 if ((_XmRendFontFoundry (from) != NULL) && _XmRendFontFoundry (to) == NULL)
837 _XmRendFontFoundry (to) = _XmRendFontFoundry (from);
838 if ((_XmRendFontEncoding (from) != NULL) && _XmRendFontEncoding (to) == NULL)
839 _XmRendFontEncoding (to) = _XmRendFontEncoding (from);
840 if (_XmRendFontSize (to) == 0)
841 _XmRendFontSize (to) = _XmRendFontSize (from);
842 #else
843 if ((_XmRendFG(from) != XmUNSPECIFIED_PIXEL) &&
844 (_XmRendFG(to) == XmUNSPECIFIED_PIXEL))
845 _XmRendFG(to) = _XmRendFG (from);
846 if ((_XmRendBG(from) != XmUNSPECIFIED_PIXEL) &&
847 (_XmRendBG(to) == XmUNSPECIFIED_PIXEL))
848 _XmRendBG(to) = _XmRendBG (from);
849 #endif
850 if ((_XmRendUnderlineType(from) != XmAS_IS) &&
851 (_XmRendUnderlineType(to) == XmAS_IS))
852 _XmRendUnderlineType(to) = _XmRendUnderlineType(from);
853 if ((_XmRendStrikethruType(from) != XmAS_IS) &&
854 (_XmRendStrikethruType(to) == XmAS_IS))
855 _XmRendStrikethruType(to) = _XmRendStrikethruType(from);
856 }
857
858 /* Check that all resources are not default values. */
859 static Boolean
RendComplete(XmRendition rend)860 RendComplete(XmRendition rend)
861 {
862 return(((unsigned int)(unsigned long)_XmRendFontName(rend) != XmAS_IS) &&
863 (_XmRendFontType(rend) != XmAS_IS) &&
864 (_XmRendLoadModel(rend) != XmAS_IS) &&
865 (
866 ((unsigned int) (unsigned long) _XmRendFont (rend) != XmAS_IS)
867 #ifdef USE_XFT
868 || ((unsigned int) (unsigned long) _XmRendXftFont (rend) != XmAS_IS)
869 #endif
870 ) &&
871 ((unsigned int)(unsigned long)_XmRendTabs(rend) != XmAS_IS) &&
872 (_XmRendFG(rend) != XmUNSPECIFIED_PIXEL) &&
873 (_XmRendBG(rend) != XmUNSPECIFIED_PIXEL) &&
874 (_XmRendUnderlineType(rend) != XmAS_IS) &&
875 (_XmRendStrikethruType(rend) != XmAS_IS));
876 }
877
878 /* Search rt for all renditions matching tags, successively merging */
879 /* resource values in scr rendition. */
880 /*ARGSUSED*/
881 XmRendition
_XmRenditionMerge(Display * d,XmRendition * scr,XmRendition base_rend,XmRenderTable rt,XmStringTag base_tag,XmStringTag * tags,unsigned int tag_count,unsigned int copy)882 _XmRenditionMerge(Display *d, /* unused */
883 XmRendition *scr,
884 XmRendition base_rend,
885 XmRenderTable rt,
886 XmStringTag base_tag,
887 XmStringTag *tags,
888 #if NeedWidePrototypes
889 unsigned int tag_count,
890 unsigned int copy
891 #else
892 unsigned short tag_count,
893 Boolean copy
894 #endif /* NeedWidePrototypes */
895 )
896 {
897 XmRendition rend, tmp;
898 int i;
899
900 if (scr == NULL)
901 {
902 rend = XmRenditionCreate(NULL, XmS, NULL, 0); /* Create new */
903 }
904 else
905 {
906 rend = *scr;
907 if (copy)
908 {
909 if (NameIsString(_XmRendFontName(rend)))
910 XtFree(_XmRendFontName(rend));
911 if (ListIsList(_XmRendTabs(rend)))
912 XmTabListFree(_XmRendTabs(rend));
913 }
914 SetDefault(rend); /* Reset state */
915 }
916
917 for (i = (tag_count - 1); i >= 0; i--)
918 {
919 tmp = _XmRenderTableFindRendition(rt, tags[i], TRUE, FALSE, TRUE, NULL);
920 if (tmp == NULL) continue;
921
922 SetRend(rend, tmp);
923 if (RendComplete(rend)) break;
924 }
925
926 if (!RendComplete(rend))
927 {
928 short index;
929
930 _XmRenderTableFindFallback(rt, base_tag, TRUE, &index, &tmp);
931 if (tmp != NULL) SetRend(rend, tmp);
932 }
933
934 if (base_rend != NULL)
935 {
936 SetRend(rend, base_rend);
937
938 if (_XmRendFGState(base_rend) == XmFORCE_COLOR)
939 #if USE_XFT
940 _XmRendXftFG(rend) = _XmRendXftFG(base_rend);
941 #else
942 _XmRendFG(rend) = _XmRendFG(base_rend);
943 #endif
944
945 if (_XmRendBGState(base_rend) == XmFORCE_COLOR)
946 _XmRendBG(rend) = _XmRendBG(base_rend);
947 }
948
949 CleanupResources(rend, copy);
950
951 return(rend);
952 }
953
954
955 /****************
956 * If the cached_tag flag is true, _XmRenderTableFindFallback assumes that the
957 * tag pointer is a pointer out of the (local) tag cache.
958 * Since XmRenditionCreate also uses tag pointers out of this cache,
959 * a string compare is avoided by simply comparing pointer values.
960 ****************/
961 extern Boolean
_XmRenderTableFindFallback(XmRenderTable rendertable,XmStringTag tag,int cached_tag,short * indx,XmRendition * rend_ptr)962 _XmRenderTableFindFallback(
963 XmRenderTable rendertable,
964 XmStringTag tag,
965 #if NeedWidePrototypes
966 int cached_tag,
967 #else
968 Boolean cached_tag,
969 #endif /* NeedWidePrototypes */
970 short *indx,
971 XmRendition *rend_ptr )
972 {
973 XmStringTag search_cset = NULL;
974
975 *indx = -1 ;
976
977 if ((rendertable != NULL) && (_XmRTCount(rendertable) == 0))
978 {
979 *rend_ptr = NULL;
980 return(FALSE);
981 }
982
983 if (rendertable != NULL)
984 {
985 if (tag != NULL)
986 {
987 if (cached_tag) /* No XmSTRING_DEFAULT_CHARSET */
988 {
989 *rend_ptr = (XmRendition)
990 _XmRenderTableFindRendition(rendertable, tag, TRUE, TRUE, FALSE,
991 indx);
992 if (*rend_ptr != NULL) return(TRUE);
993 }
994 else
995 {
996 XmStringTag curtag;
997
998 if ((strcmp(tag, XmSTRING_DEFAULT_CHARSET) == 0))
999 curtag = _XmStringGetCurrentCharset();
1000 else curtag = tag;
1001
1002 *rend_ptr = (XmRendition)
1003 _XmRenderTableFindRendition(rendertable, curtag, FALSE, TRUE, FALSE,
1004 indx);
1005
1006 if (*rend_ptr != NULL) return(TRUE);
1007 }
1008
1009 /* Didn't find a match. See if tag is one of the defaults
1010 and search for the other. */
1011 if (_XmStringIsCurrentCharset(tag))
1012 {
1013 search_cset = XmFONTLIST_DEFAULT_TAG;
1014
1015 *rend_ptr = (XmRendition)
1016 _XmRenderTableFindRendition(rendertable, search_cset, TRUE,
1017 TRUE, FALSE, indx);
1018
1019 if (*rend_ptr != NULL) return(TRUE);
1020 }
1021 else if ((tag == XmFONTLIST_DEFAULT_TAG) ||
1022 (strcmp(tag, XmFONTLIST_DEFAULT_TAG) == 0))
1023 {
1024 search_cset = _XmStringGetCurrentCharset();
1025
1026 *rend_ptr = (XmRendition)
1027 _XmRenderTableFindRendition(rendertable, search_cset, FALSE,
1028 TRUE, FALSE, indx);
1029
1030 if (*rend_ptr != NULL) return(TRUE);
1031 }
1032 }
1033
1034 /* Otherwise pick up first font(set) if tag a default value. */
1035 if ((tag == NULL) ||
1036 (tag == XmFONTLIST_DEFAULT_TAG) ||
1037 (strcmp(tag, XmFONTLIST_DEFAULT_TAG) == 0) ||
1038 _XmStringIsCurrentCharset(tag))
1039 return(_XmRenderTableFindFirstFont(rendertable, indx, rend_ptr));
1040 }
1041 *rend_ptr = NULL;
1042 *indx = -1;
1043 return(FALSE);
1044 }
1045
1046 extern Boolean
_XmRenderTableFindFirstFont(XmRenderTable rendertable,short * indx,XmRendition * rend_ptr)1047 _XmRenderTableFindFirstFont(XmRenderTable rendertable,
1048 short *indx,
1049 XmRendition *rend_ptr)
1050 {
1051 int i, f_idx = -1, fs_idx = -1;
1052 #ifdef USE_XFT
1053 int xft_idx = -1;
1054 #endif
1055
1056 for (i = _XmRTCount(rendertable) - 1; i >= 0; i--)
1057 {
1058 *rend_ptr = _XmRTRenditions(rendertable)[i];
1059
1060 if (_XmRendFont(*rend_ptr) != NULL)
1061 {
1062 if (_XmRendFontType(*rend_ptr) == XmFONT_IS_FONT) f_idx = i;
1063 else if (_XmRendFontType(*rend_ptr) == XmFONT_IS_FONTSET) fs_idx = i;
1064 #ifdef USE_XFT
1065 } else if (_XmRendXftFont(*rend_ptr) != NULL) {
1066 if (_XmRendFontType(*rend_ptr) == XmFONT_IS_XFT) xft_idx = i;
1067 #endif
1068 }
1069 }
1070 #ifdef USE_XFT
1071 if (xft_idx >= 0)
1072 {
1073 *rend_ptr = _XmRTRenditions (rendertable)[xft_idx];
1074 *indx = xft_idx;
1075 }
1076 else
1077 #endif
1078 if (fs_idx >= 0)
1079 {
1080 *rend_ptr = _XmRTRenditions(rendertable)[fs_idx];
1081 *indx = fs_idx;
1082 }
1083 else if (f_idx >= 0)
1084 {
1085 *rend_ptr = _XmRTRenditions(rendertable)[f_idx];
1086 *indx = f_idx;
1087 }
1088 else
1089 {
1090 *rend_ptr = NULL;
1091 *indx = -1;
1092 return(FALSE);
1093 }
1094
1095 return(TRUE);
1096 }
1097
1098 /* Put value of every resource in fromRend into toRend, copying where */
1099 /* necessary. */
1100 static void
CopyInto(XmRendition toRend,XmRendition fromRend)1101 CopyInto(XmRendition toRend,
1102 XmRendition fromRend)
1103 {
1104 _XmRendTag(toRend) = _XmStringCacheTag(_XmRendTag(fromRend),
1105 XmSTRING_TAG_STRLEN);
1106 /* CR 7890 - the fontName might be XmAS_IS here - if so, we
1107 ** obviously don't want to do an XtNewString (implicit strcpy)
1108 */
1109 if (!NameIsString(_XmRendFontName(fromRend)))
1110 _XmRendFontName(toRend) = NULL;
1111 else
1112 _XmRendFontName(toRend) = XtNewString(_XmRendFontName(fromRend));
1113 _XmRendFontType(toRend) = _XmRendFontType(fromRend);
1114 _XmRendLoadModel(toRend) = _XmRendLoadModel(fromRend);
1115 _XmRendFont(toRend) = _XmRendFont(fromRend);
1116 _XmRendDisplay(toRend) = _XmRendDisplay(fromRend);
1117
1118 if (!ListIsList(_XmRendTabs(fromRend)))
1119 _XmRendTabs(toRend) = NULL;
1120 else
1121 _XmRendTabs(toRend) = XmTabListCopy(_XmRendTabs(fromRend), 0, 0);
1122 #if USE_XFT
1123 _XmRendXftFont (toRend) = _XmRendXftFont (fromRend);
1124 _XmRendXftBG (toRend) = _XmRendXftBG (fromRend);
1125 _XmRendXftFG (toRend) = _XmRendXftFG (fromRend);
1126 _XmRendFontStyle (toRend) = _XmRendFontStyle (fromRend);
1127 _XmRendFontFoundry (toRend) = _XmRendFontFoundry (fromRend);
1128 _XmRendFontEncoding (toRend) = _XmRendFontEncoding (fromRend);
1129 _XmRendFontSize (toRend) = _XmRendFontSize (fromRend);
1130 #else
1131 _XmRendBG (toRend) = _XmRendBG (fromRend);
1132 _XmRendFG (toRend) = _XmRendFG (fromRend);
1133 #endif
1134 _XmRendUnderlineType(toRend) = _XmRendUnderlineType(fromRend);
1135 _XmRendStrikethruType(toRend) = _XmRendStrikethruType(fromRend);
1136 }
1137
1138 /* As above, except only change resources in toRend that are default. */
1139 static void
MergeInto(XmRendition toRend,XmRendition fromRend)1140 MergeInto(XmRendition toRend,
1141 XmRendition fromRend)
1142 {
1143 _XmRendTag(toRend) = _XmStringCacheTag(_XmRendTag(fromRend),
1144 XmSTRING_TAG_STRLEN);
1145 if ((_XmRendFontName(toRend) == NULL) &&
1146 NameIsString(_XmRendFontName(fromRend)))
1147 _XmRendFontName(toRend) = XtNewString(_XmRendFontName(fromRend));
1148 if (_XmRendFontType(toRend) == XmAS_IS)
1149 _XmRendFontType(toRend) = _XmRendFontType(fromRend);
1150 if (_XmRendLoadModel(toRend) == XmAS_IS)
1151 _XmRendLoadModel(toRend) = _XmRendLoadModel(fromRend);
1152 if (_XmRendFont(toRend) == NULL)
1153 _XmRendFont(toRend) = _XmRendFont(fromRend);
1154
1155 if (!ListIsList(_XmRendTabs(toRend)) &&
1156 ListIsList(_XmRendTabs(fromRend)))
1157 _XmRendTabs(toRend) = XmTabListCopy(_XmRendTabs(fromRend), 0, 0);
1158 #if USE_XFT
1159 if (_XmRendXftFont(toRend) == NULL)
1160 _XmRendXftFont(toRend) = _XmRendXftFont(fromRend);
1161 if (_XmRendBG(toRend) == XmUNSPECIFIED_PIXEL)
1162 _XmRendXftBG(toRend) = _XmRendXftBG(fromRend);
1163 if (_XmRendFG(toRend) == XmUNSPECIFIED_PIXEL)
1164 _XmRendXftFG(toRend) = _XmRendXftFG(fromRend);
1165 if (_XmRendFontStyle(toRend) == NULL)
1166 _XmRendFontStyle(toRend) = _XmRendFontStyle(fromRend);
1167 if (_XmRendFontFoundry(toRend) == NULL)
1168 _XmRendFontFoundry(toRend) = _XmRendFontFoundry(fromRend);
1169 if (_XmRendFontEncoding(toRend) == NULL)
1170 _XmRendFontEncoding(toRend) = _XmRendFontEncoding(fromRend);
1171 if (_XmRendFontSize(toRend) == 0)
1172 _XmRendFontSize(toRend) = _XmRendFontSize(fromRend);
1173 #else
1174 if (_XmRendBG(toRend) == XmUNSPECIFIED_PIXEL)
1175 _XmRendBG(toRend) = _XmRendBG (fromRend);
1176 if (_XmRendFG(toRend) == XmUNSPECIFIED_PIXEL)
1177 _XmRendFG(toRend) = _XmRendFG (fromRend);
1178 #endif
1179 if (_XmRendUnderlineType(toRend) == XmAS_IS)
1180 _XmRendUnderlineType(toRend) = _XmRendUnderlineType(fromRend);
1181 if (_XmRendUnderlineType(toRend) == XmAS_IS)
1182 _XmRendStrikethruType(toRend) = _XmRendStrikethruType(fromRend);
1183 }
1184
1185 /* Make a Clone--new handle and new data structure--of a rendition. */
1186 static XmRendition
CloneRendition(XmRendition rend)1187 CloneRendition(XmRendition rend)
1188 {
1189 _XmRendition copy;
1190 XmRendition copy_handle;
1191
1192 if (rend == NULL) return(NULL);
1193
1194 copy = (_XmRendition)XtMalloc(sizeof(_XmRenditionRec));
1195 bzero((char*)copy, sizeof(_XmRenditionRec));
1196 copy_handle = GetHandle(_XmRendition);
1197 SetPtr(copy_handle, copy);
1198
1199 _XmRendFontOnly(copy_handle) = FALSE;
1200 _XmRendRefcount(copy_handle) = 1;
1201
1202 CopyInto(copy_handle, rend);
1203 return(copy_handle);
1204 }
1205
1206 /* Set the old handle to point to a new data structure. */
1207 static XmRendition
RenewRendition(XmRendition rend)1208 RenewRendition(XmRendition rend)
1209 {
1210 _XmRendition copy;
1211
1212 if (rend == NULL) return(NULL);
1213
1214 copy = (_XmRendition)XtMalloc(sizeof(_XmRenditionRec));
1215 memcpy((char *)copy, (char *)GetPtr(rend), sizeof(_XmRenditionRec));
1216 SetPtr(rend, copy);
1217
1218 _XmRendFontOnly(rend) = FALSE;
1219 _XmRendRefcount(rend) = 1;
1220
1221 return(rend);
1222 }
1223
1224 /* Allocate a new handle which points to the old data structure with */
1225 /* an incremented refcount. */
1226 static XmRendition
CopyRendition(XmRendition rend)1227 CopyRendition(XmRendition rend)
1228 {
1229 XmRendition copy;
1230
1231 if (rend == NULL) return(NULL);
1232
1233 if (_XmRendRefcountInc(rend) == 0)
1234 {
1235 _XmRendRefcountDec(rend);
1236 return(CloneRendition(rend));
1237 }
1238 else
1239 {
1240 copy = GetHandle(_XmRendition);
1241 SetPtr(copy, GetPtr(rend));
1242 return(copy);
1243 }
1244 }
1245
1246 /* Increment the refcount. Clone if overflow. */
1247 static XmRendition
DuplicateRendition(XmRendition rend)1248 DuplicateRendition(XmRendition rend)
1249 {
1250 if (rend == NULL) return(NULL);
1251
1252 if (_XmRendRefcountInc(rend) == 0)
1253 {
1254 _XmRendRefcountDec(rend);
1255 return(CloneRendition(rend));
1256 }
1257 else
1258 {
1259 return(rend);
1260 }
1261 }
1262
1263 /* Make a copy of a rendition, *including* the "scratch" info (tags,
1264 * GC, hadEnds).
1265 * Shared indicates whether or not this is a shared copy.
1266 */
1267 XmRendition
_XmRenditionCopy(XmRendition rend,Boolean shared)1268 _XmRenditionCopy(XmRendition rend,
1269 Boolean shared)
1270 {
1271 XmRendition toRend;
1272 int i;
1273
1274 if (rend == NULL) return(NULL);
1275
1276 if (shared) toRend = CopyRendition(rend);
1277 else toRend = CloneRendition(rend);
1278
1279 /* If we had to clone, copy the 'scratch' info. */
1280 if (*toRend != *rend)
1281 {
1282 _XmRendGC(toRend) = _XmRendGC(rend);
1283 _XmRendTagCount(toRend) = _XmRendTagCount(rend);
1284 _XmRendHadEnds(toRend) = _XmRendHadEnds(rend);
1285 _XmRendTags(toRend) =
1286 (XmStringTag *)XtMalloc(sizeof(XmStringTag) * _XmRendTagCount(rend));
1287 for (i = 0; i < _XmRendTagCount(rend); i++)
1288 _XmRendTags(toRend)[i] = _XmRendTags(rend)[i];
1289 }
1290
1291 return(toRend);
1292 }
1293
1294 /* Creates new rendertable, adding any new renditions. */
1295 /* Mutate rendertable. Copy renditions. */
1296 XmRenderTable
XmRenderTableAddRenditions(XmRenderTable oldtable,XmRendition * renditions,Cardinal rendition_count,XmMergeMode merge_mode)1297 XmRenderTableAddRenditions(XmRenderTable oldtable,
1298 XmRendition *renditions,
1299 Cardinal rendition_count,
1300 XmMergeMode merge_mode)
1301 {
1302 int i, next;
1303 int count = rendition_count;
1304 XmRendition rend, match;
1305 _XmRenderTable table;
1306 XmRenderTable newtable, tmptable = NULL;
1307 Boolean *matches;
1308 short idx;
1309 XtAppContext app=NULL;
1310
1311 if ((renditions == NULL) || (rendition_count == 0))
1312 return(oldtable);
1313
1314 #ifdef XTHREADS
1315 if (_XmRendDisplay(renditions[0]))
1316 app = XtDisplayToApplicationContext(_XmRendDisplay(renditions[0]));
1317 if (app) {
1318 _XmAppLock(app);
1319 }
1320 else {
1321 _XmProcessLock();
1322 }
1323 #endif
1324 if (oldtable == NULL)
1325 {
1326 /* Malloc new table */
1327 table =
1328 (_XmRenderTable)XtMalloc(sizeof(_XmRenderTableRec) +
1329 (sizeof(XmRendition) *
1330 (rendition_count -
1331 RENDITIONS_IN_STRUCT)));
1332 oldtable = GetHandle(_XmRenderTable);
1333 SetPtr(oldtable, table);
1334
1335 _XmRTCount(oldtable) = rendition_count;
1336 _XmRTDisplay(oldtable) = NULL;
1337 _XmRTRefcount(oldtable) = 1;
1338
1339 /* Copy renditions */
1340 for (i = 0; i < rendition_count; i++)
1341 {
1342 _XmRTRenditions(oldtable)[i] = CopyRendition(renditions[i]);
1343 if (_XmRTDisplay(oldtable) == NULL)
1344 _XmRTDisplay(oldtable) = _XmRendDisplay(renditions[i]);
1345 }
1346 }
1347 else
1348 {
1349 matches =
1350 (Boolean *)ALLOCATE_LOCAL(rendition_count * sizeof(Boolean));
1351 bzero(matches, rendition_count * sizeof(Boolean));
1352
1353 /* May have to copy table if shared. */
1354 if (_XmRTRefcount(oldtable) > 1)
1355 {
1356 /* Allocate new table */
1357 table = (_XmRenderTable)
1358 XtMalloc(sizeof(_XmRenderTableRec) +
1359 (sizeof(XmRendition) *
1360 (_XmRTCount(oldtable) - RENDITIONS_IN_STRUCT)));
1361
1362 newtable = GetHandle(_XmRenderTable);
1363 SetPtr(newtable, table);
1364
1365 _XmRTDisplay(newtable) = _XmRTDisplay(oldtable);
1366 _XmRTRefcount(newtable) = 1;
1367
1368 /* Move old Renditions. */
1369 for (i = 0; i < _XmRTCount(oldtable); i++)
1370 _XmRTRenditions(newtable)[i] = _XmRTRenditions(oldtable)[i];
1371
1372 _XmRTCount(newtable) = _XmRTCount(oldtable);
1373 _XmRTRefcountDec(oldtable);
1374
1375 /* Free at end so we don't get same memory from malloc. */
1376 tmptable = oldtable;
1377 oldtable = newtable;
1378 }
1379
1380 /* Merge matching renditions */
1381 for (i = 0; i < rendition_count; i++)
1382 {
1383 rend = renditions[i];
1384
1385 match =
1386 _XmRenderTableFindRendition(oldtable, _XmRendTag(rend),
1387 TRUE, FALSE, FALSE, &idx);
1388 if ((match != NULL) && (merge_mode != XmDUPLICATE))
1389 {
1390 /* Merge renditions. */
1391 switch (merge_mode)
1392 {
1393 case XmMERGE_REPLACE:
1394 if (FreeRendition(match)) FreeHandle(match);
1395 _XmRTRenditions(oldtable)[idx] =
1396 CopyRendition(rend);
1397 break;
1398
1399 case XmSKIP:
1400 break;
1401
1402 case XmMERGE_OLD:
1403 if (_XmRendRefcount(match) > 1)
1404 {
1405 match = CloneRendition(match);
1406 _XmRTRenditions(oldtable)[idx] = match;
1407 }
1408 MergeInto(match, rend);
1409 break;
1410
1411 case XmMERGE_NEW:
1412 rend = CloneRendition(rend);
1413 MergeInto(rend, match);
1414 _XmRTRenditions(oldtable)[idx] = rend;
1415 if (FreeRendition(match)) FreeHandle(match);
1416 break;
1417
1418 default:
1419 printf("NYI");
1420 break;
1421 }
1422
1423 matches[i] = TRUE;
1424 --count;
1425 }
1426 }
1427
1428 if (count > 0) /* Allocate new table */
1429 {
1430 table = (_XmRenderTable)
1431 XtMalloc(sizeof(_XmRenderTableRec) +
1432 (sizeof(XmRendition) *
1433 (_XmRTCount(oldtable) + count - RENDITIONS_IN_STRUCT)));
1434 newtable = GetHandle(_XmRenderTable);
1435 SetPtr(newtable, table);
1436
1437 _XmRTDisplay(newtable) = _XmRTDisplay(oldtable);
1438 _XmRTRefcount(newtable) = 1;
1439
1440 /* Move old Renditions. */
1441 for (i = 0; i < _XmRTCount(oldtable); i++)
1442 _XmRTRenditions(newtable)[i] = _XmRTRenditions(oldtable)[i];
1443
1444 /* Copy new renditions. */
1445 next = _XmRTCount(oldtable);
1446
1447 for (i = 0; i < rendition_count; i++)
1448 {
1449 if (!matches[i])
1450 {
1451 _XmRTRenditions(newtable)[next] =
1452 CopyRendition(renditions[i]);
1453 if (_XmRTDisplay(newtable) == NULL)
1454 _XmRTDisplay(newtable) = _XmRTDisplay(oldtable);
1455 ++next;
1456 }
1457 }
1458
1459 _XmRTCount(newtable) = _XmRTCount(oldtable) + count;
1460
1461 /* Deallocate oldtable */
1462 XtFree((char *)GetPtr(oldtable));
1463 FreeHandle(oldtable);
1464 }
1465 /* Otherwise just return newhandle to oldtable */
1466 else
1467 {
1468 table = GetPtr(oldtable);
1469 newtable = GetHandle(_XmRenderTable);
1470 SetPtr(newtable, table);
1471 FreeHandle(oldtable);
1472 }
1473
1474 DEALLOCATE_LOCAL((char *)matches);
1475
1476 oldtable = newtable;
1477 }
1478
1479 if (tmptable != NULL) FreeHandle(tmptable);
1480 #ifdef XTHREADS
1481 if (app) {
1482 _XmAppUnlock(app);
1483 }
1484 else {
1485 _XmProcessUnlock();
1486 }
1487 #endif
1488 return(oldtable);
1489 }
1490
1491 /* Remove matching renditions. */
1492 /* Mutates oldtable, decrements removed renditions. */
1493 XmRenderTable
XmRenderTableRemoveRenditions(XmRenderTable oldtable,XmStringTag * tags,int tag_count)1494 XmRenderTableRemoveRenditions(XmRenderTable oldtable,
1495 XmStringTag *tags,
1496 int tag_count)
1497 {
1498 XmRenderTable ret_val;
1499 #ifdef XTHREADS
1500 XtAppContext app=NULL;
1501
1502 if (_XmRTDisplay(oldtable))
1503 app = XtDisplayToApplicationContext(_XmRTDisplay(oldtable));
1504 if (app) {
1505 _XmAppLock(app);
1506 }
1507 else {
1508 _XmProcessLock();
1509 }
1510 #endif
1511 ret_val = _XmRenderTableRemoveRenditions(oldtable, tags,tag_count,
1512 FALSE, XmFONT_IS_FONT, NULL);
1513 #ifdef XTHREADS
1514 if (app) {
1515 _XmAppUnlock(app);
1516 }
1517 else {
1518 _XmProcessUnlock();
1519 }
1520 #endif
1521 return ret_val;
1522 }
1523
1524 /* Remove matching renditions. */
1525 /* Mutates oldtable, decrements removed renditions. */
1526 /* If chk_font TRUE, checks that font and type also match. */
1527 XmRenderTable
_XmRenderTableRemoveRenditions(XmRenderTable oldtable,XmStringTag * tags,int tag_count,int chk_font,XmFontType type,XtPointer font)1528 _XmRenderTableRemoveRenditions(XmRenderTable oldtable,
1529 XmStringTag *tags,
1530 int tag_count,
1531 #if NeedWidePrototypes
1532 int chk_font,
1533 #else
1534 Boolean chk_font,
1535 #endif /* NeedWidePrototypes */
1536 XmFontType type,
1537 XtPointer font)
1538 {
1539 int i, j;
1540 int count;
1541 _XmRenderTable table;
1542 XmRenderTable newtable = NULL;
1543
1544 if ((oldtable == NULL) || (tags == NULL) || (tag_count == 0))
1545 return(oldtable);
1546
1547 count = 0;
1548
1549 if (_XmRTRefcount(oldtable) > 1)
1550 {
1551 /* Allocate new table */
1552 table = (_XmRenderTable)
1553 XtMalloc(sizeof(_XmRenderTableRec) +
1554 (sizeof(XmRendition) *
1555 (_XmRTCount(oldtable) - RENDITIONS_IN_STRUCT)));
1556
1557 newtable = GetHandle(_XmRenderTable);
1558 SetPtr(newtable, table);
1559
1560 _XmRTDisplay(newtable) = _XmRTDisplay(oldtable);
1561 _XmRTRefcount(newtable) = 1;
1562
1563 /* Move old Renditions. */
1564 for (i = 0; i < _XmRTCount(oldtable); i++)
1565 _XmRTRenditions(newtable)[i] = _XmRTRenditions(oldtable)[i];
1566 _XmRTCount(newtable) = _XmRTCount(oldtable);
1567
1568 if (_XmRTRefcountDec(oldtable) == 0)
1569 XtFree((char *)GetPtr(oldtable));
1570 FreeHandle(oldtable);
1571
1572 oldtable = newtable;
1573 }
1574 /* Iterate over renditions */
1575 for (i = 0; i < _XmRTCount(oldtable); i++)
1576 {
1577 /* Match against tags */
1578 for (j = 0; j < tag_count; j++)
1579 {
1580 if ((strcmp(_XmRendTag(_XmRTRenditions(oldtable)[i]),
1581 tags[j]) == 0) &&
1582 (!chk_font ||
1583 ((font == _XmRendFont(_XmRTRenditions(oldtable)[i])) &&
1584 (type == _XmRendFontType(_XmRTRenditions(oldtable)[i])))))
1585 {
1586 if (FreeRendition(_XmRTRenditions(oldtable)[i]))
1587 FreeHandle(_XmRTRenditions(oldtable)[i]);
1588 _XmRTRenditions(oldtable)[i] = NULL;
1589 break;
1590 }
1591 }
1592 if (_XmRTRenditions(oldtable)[i] != NULL)
1593 {
1594 if (count != i)
1595 _XmRTRenditions(oldtable)[count] = _XmRTRenditions(oldtable)[i];
1596
1597 count++;
1598 }
1599 }
1600 if (count == 0)
1601 /* No renditions left. Return NULL. */
1602 {
1603 XmRenderTableFree(oldtable);
1604 return(NULL);
1605 }
1606 else if (count < _XmRTCount(oldtable))
1607 {
1608 /* Realloc table */
1609 table = (_XmRenderTable)XtRealloc((char *)*oldtable,
1610 sizeof(_XmRenderTableRec) +
1611 (sizeof(XmRendition) *
1612 (count - RENDITIONS_IN_STRUCT)));
1613 if (newtable == NULL)
1614 {
1615 newtable = GetHandle(_XmRenderTable);
1616 FreeHandle(oldtable);
1617 }
1618 SetPtr(newtable, table);
1619
1620 _XmRTCount(newtable) = count;
1621
1622 return(newtable);
1623 }
1624 return(oldtable);
1625 }
1626
1627 static void
CopyFromArg(XtArgVal src,char * dst,unsigned int size)1628 CopyFromArg(XtArgVal src, char *dst, unsigned int size)
1629 {
1630 if (size > sizeof(XtArgVal))
1631 memcpy((char *)dst, (char *)src, (size_t)size);
1632 else {
1633 union {
1634 long longval;
1635 #ifdef FIX_1152
1636 int intval;
1637 #endif
1638 short shortval;
1639 char charval;
1640 char* charptr;
1641 XtPointer ptr;
1642 } u;
1643 char *p = (char*)&u;
1644 if (size == sizeof(long)) u.longval = (long)src;
1645 #ifdef FIX_1152
1646 else if (size == sizeof(int)) u.intval = (int) src;
1647 #endif
1648 else if (size == sizeof(short)) u.shortval = (short)src;
1649 else if (size == sizeof(char)) u.charval = (char)src;
1650 else if (size == sizeof(XtPointer)) u.ptr = (XtPointer)src;
1651 else if (size == sizeof(char*)) u.charptr = (char*)src;
1652 else p = (char*)&src;
1653
1654 memcpy((char *)dst, p, (size_t)size);
1655 }
1656 } /* CopyFromArg */
1657
1658 static void
CopyToArg(char * src,XtArgVal * dst,unsigned int size)1659 CopyToArg(char *src, XtArgVal *dst, unsigned int size)
1660 {
1661 if ((void *)(*dst) == NULL) {
1662 /* old GetValues semantics (storing directly into arglists) are bad,
1663 * but preserve for compatibility as long as arglist contains NULL.
1664 */
1665 if (size == sizeof(long)) *dst = (XtArgVal)*(long*)src;
1666 #ifdef FIX_1152
1667 else if (size == sizeof(int)) *dst = (XtArgVal)*(int*)src;
1668 #endif
1669 else if (size == sizeof(short)) *dst = (XtArgVal)*(short*)src;
1670 else if (size == sizeof(char)) *dst = (XtArgVal)*(char*)src;
1671 else if (size == sizeof(XtPointer)) *dst = (XtArgVal)*(XtPointer*)src;
1672 else if (size == sizeof(char*)) *dst = (XtArgVal)*(char**)src;
1673 else if (size == sizeof(XtArgVal)) *dst = *(XtArgVal*)src;
1674 else memcpy((char*)dst, (char*)src, (size_t)size);
1675 }
1676 else {
1677 /* proper GetValues semantics: argval is pointer to destination */
1678 if (size == sizeof(long)) *((long*)*dst) = *(long*)src;
1679 #ifdef FIX_1152
1680 else if (size == sizeof(int)) *((int*)*dst) = *(int*)src;
1681 #endif
1682 else if (size == sizeof(short)) *((short*)*dst) = *(short*)src;
1683 else if (size == sizeof(char)) *((char*)*dst) = *(char*)src;
1684 else if (size == sizeof(XtPointer)) *((XtPointer*)*dst) = *(XtPointer*)src;
1685 else if (size == sizeof(char*)) *((char**)*dst) = *(char**)src;
1686 else if (size == sizeof(XtArgVal)) *((XtArgVal*)*dst)= *(XtArgVal*)src;
1687 else memcpy((char *)*dst, (char *)src, (size_t)size);
1688 }
1689 } /* CopyToArg */
1690
1691 /* Copies renditions matching tags to a new table. */
1692 /* If all renditions copied then duplicate rendertable, duplicate */
1693 /* renditions. Otherwise, mutate rendertable, duplicate renditions. */
1694 XmRenderTable
XmRenderTableCopy(XmRenderTable table,XmStringTag * tags,int tag_count)1695 XmRenderTableCopy(XmRenderTable table,
1696 XmStringTag *tags,
1697 int tag_count)
1698 {
1699 XmRenderTable rt = NULL;
1700 _XmRenderTable t = NULL;
1701 int i, j, count;
1702 int size;
1703 XmRendition rend = NULL;
1704 XtAppContext app = NULL;
1705
1706 if (table == NULL) return((XmRenderTable)NULL);
1707
1708 #ifdef XTHREADS
1709 if (_XmRTDisplay(table))
1710 app = XtDisplayToApplicationContext(_XmRTDisplay(table));
1711 if (app) {
1712 _XmAppLock(app);
1713 }
1714 else {
1715 _XmProcessLock();
1716 }
1717 #endif
1718 count = 0;
1719
1720 if ((_XmRTRefcountInc(table) == 0) || (tags != NULL))
1721 {
1722 /* Malloc new table */
1723 _XmRTRefcountDec(table);
1724
1725 if (tag_count > 0)
1726 size = (sizeof(_XmRendition) * (tag_count - RENDITIONS_IN_STRUCT));
1727 else
1728 size = (sizeof(_XmRendition) *
1729 (_XmRTCount(table) - RENDITIONS_IN_STRUCT));
1730
1731 size = (size < 0) ? 0 : size;
1732
1733 t = (_XmRenderTable)XtMalloc(sizeof(_XmRenderTableRec) + size);
1734 rt = GetHandle(_XmRenderTable);
1735 SetPtr(rt, t);
1736 _XmRTRefcount(rt) = 1;
1737 }
1738
1739 if (tags == NULL)
1740 {
1741 /* Increment renditions. */
1742 for (i = 0; i < _XmRTCount(table); i++)
1743 {
1744 rend = DuplicateRendition(_XmRTRenditions(table)[i]);
1745 /* Check for overflow. */
1746 if (rend != _XmRTRenditions(table)[i]) break;
1747 }
1748
1749 if (i < _XmRTCount(table)) /* Overflow! */
1750 {
1751 /* Malloc new table. */
1752 t = (_XmRenderTable)XtMalloc(sizeof(_XmRenderTableRec) +
1753 (sizeof(_XmRendition) *
1754 (_XmRTCount(table) - RENDITIONS_IN_STRUCT)));
1755 rt = GetHandle(_XmRenderTable);
1756 SetPtr(rt, t);
1757 _XmRTRefcount(rt) = 1;
1758
1759 _XmRTCount(rt) = _XmRTCount(table);
1760
1761 /* Move renditions done already. */
1762 for (j = 0; j < i; j++)
1763 _XmRTRenditions(rt)[j] = _XmRTRenditions(table)[j];
1764 _XmRTRenditions(rt)[i] = rend;
1765 /* Copy rest */
1766 for (j = i + 1; j < _XmRTCount(rt); j++)
1767 _XmRTRenditions(rt)[j] = DuplicateRendition(_XmRTRenditions(table)[j]);
1768 }
1769 else
1770 {
1771 rt = GetHandle(_XmRenderTable);
1772 SetPtr(rt, GetPtr(table));
1773 }
1774 }
1775 else
1776 {
1777 /* Copy matching renditions. */
1778 for (i = 0; i < tag_count; i++)
1779 {
1780 XmRendition match;
1781
1782 match = XmRenderTableGetRendition(table, tags[i]);
1783
1784 if (match != NULL)
1785 {
1786 _XmRTRenditions(rt)[i] = match;
1787 ++count;
1788 }
1789 }
1790
1791 /* Realloc table */
1792 t = (_XmRenderTable)XtRealloc((char *)t,
1793 sizeof(_XmRenderTableRec) +
1794 (sizeof(XmRendition) *
1795 (count - RENDITIONS_IN_STRUCT)));
1796 SetPtr(rt, t);
1797 _XmRTCount(rt) = count;
1798 }
1799
1800 _XmRTDisplay(rt) = _XmRTDisplay(table);
1801
1802 #ifdef XTHREADS
1803 if (app) {
1804 _XmAppUnlock(app);
1805 }
1806 else {
1807 _XmProcessUnlock();
1808 }
1809 #endif
1810 return(rt);
1811 }
1812
1813 /* Decrement rendertable, free if refcount is zero. XmRenditionFree */
1814 /* renditions. */
1815 void
XmRenderTableFree(XmRenderTable table)1816 XmRenderTableFree(XmRenderTable table)
1817 {
1818 int i;
1819
1820 _XmProcessLock();
1821 for (i = 0; i < _XmRTCount(table); i++)
1822 if (FreeRendition(_XmRTRenditions(table)[i]))
1823 FreeHandle(_XmRTRenditions(table)[i]);
1824
1825 if (_XmRTRefcountDec(table) == 0)
1826 XtFree((char *)GetPtr(table));
1827
1828 FreeHandle(table);
1829 _XmProcessUnlock();
1830 }
1831
1832 /* Get list of tags of all renditions in table. */
1833 int
XmRenderTableGetTags(XmRenderTable table,XmStringTag ** tag_list)1834 XmRenderTableGetTags(XmRenderTable table,
1835 XmStringTag **tag_list)
1836 {
1837 int i, ret_val;
1838 XtAppContext app = NULL;
1839
1840 if (table == NULL)
1841 {
1842 *tag_list = NULL;
1843 return(0);
1844 }
1845
1846 app = XtDisplayToApplicationContext(_XmRTDisplay(table));
1847 _XmAppLock(app);
1848 *tag_list =
1849 (XmStringTag *)XtMalloc(sizeof(XmStringTag) * _XmRTCount(table));
1850
1851 for (i = 0; i < _XmRTCount(table); i++)
1852 (*tag_list)[i] =
1853 XtNewString(_XmRendTag(_XmRTRenditions(table)[i]));
1854
1855 ret_val = _XmRTCount(table);
1856 _XmAppUnlock(app);
1857 return ret_val;
1858 }
1859
1860 /* Returns copy of matching rendition. */
1861 XmRendition
XmRenderTableGetRendition(XmRenderTable table,XmStringTag tag)1862 XmRenderTableGetRendition(XmRenderTable table,
1863 XmStringTag tag)
1864 {
1865 XmRendition ret_val;
1866 _XmDisplayToAppContext(_XmRTDisplay(table));
1867
1868 _XmAppLock(app);
1869 ret_val = CopyRendition(_XmRenderTableFindRendition(table, tag,
1870 FALSE, FALSE, FALSE, NULL));
1871 _XmAppUnlock(app);
1872 return ret_val;
1873 }
1874
1875 /* Returns array of copies of matching renditions. */
1876 XmRendition *
XmRenderTableGetRenditions(XmRenderTable table,char ** tags,Cardinal tag_count)1877 XmRenderTableGetRenditions(XmRenderTable table,
1878 char **tags,
1879 Cardinal tag_count)
1880 {
1881 XmRendition rend, *rends;
1882 int i, count;
1883 XtAppContext app = NULL;
1884
1885 if ((table == NULL) || (tags == NULL) || (tag_count == 0))
1886 return(NULL);
1887
1888 #ifdef XTHREADS
1889 if (_XmRTDisplay(table))
1890 {
1891 app = XtDisplayToApplicationContext(_XmRTDisplay(table));
1892 _XmAppLock(app);
1893 }
1894 #endif
1895 rends = (XmRendition *)XtMalloc(tag_count * sizeof(XmRendition));
1896
1897 count = 0;
1898 for (i = 0; i < tag_count; i++)
1899 {
1900 rend = _XmRenderTableFindRendition(table, tags[i],
1901 FALSE, FALSE, FALSE, NULL);
1902 if (rend != NULL)
1903 {
1904 rends[count] = CopyRendition(rend);
1905 count++;
1906 }
1907 }
1908
1909 if (count < tag_count)
1910 rends = (XmRendition *)XtRealloc((char *)rends, count * sizeof(XmRendition));
1911
1912 #ifdef XTHREADS
1913 if (app) {
1914 _XmAppUnlock(app);
1915 }
1916 #endif
1917 return(rends);
1918 }
1919
1920 /* Wrapper for calling XtWarning functions. */
1921 static void
RenditionWarning(char * tag,char * type,char * message,Display * dpy)1922 RenditionWarning(char *tag,
1923 char *type,
1924 char *message,
1925 Display *dpy)
1926 {
1927 char *params[1];
1928 Cardinal num_params = 1 ;
1929 Display *d;
1930
1931 /* the MotifWarningHandler installed in VendorS.c knows about
1932 this convention */
1933 params[0] = XME_WARNING;
1934
1935 if (dpy)
1936 d = dpy;
1937 else
1938 d = _XmGetDefaultDisplay();
1939 if (d)
1940 XtAppWarningMsg (XtDisplayToApplicationContext(d),
1941 tag, type, "XmRendition",
1942 message, params, &num_params);
1943 else XtWarning(message);
1944 }
1945
1946 /* Replace XmAS_IS and copy as necessary. */
1947 static void
CleanupResources(XmRendition rend,Boolean copy)1948 CleanupResources(XmRendition rend,
1949 Boolean copy)
1950 {
1951 if ((unsigned int)(unsigned long)_XmRendFont(rend) == XmAS_IS)
1952 _XmRendFont(rend) = NULL;
1953 else if (_XmRendFontType(rend) == XmAS_IS)
1954 _XmRendFontType(rend) = XmFONT_IS_FONT;
1955
1956 #ifdef USE_XFT
1957 if ((unsigned int)(unsigned long)_XmRendXftFont (rend) == XmAS_IS)
1958 _XmRendXftFont (rend) = NULL;
1959 #endif
1960
1961 if (((unsigned int)(unsigned long)_XmRendFontName(rend) == XmAS_IS) ||
1962 (strcmp(_XmRendFontName(rend), XmSXmAS_IS) == 0))
1963 _XmRendFontName(rend) = NULL;
1964 else if (copy)
1965 _XmRendFontName(rend) = XtNewString(_XmRendFontName(rend));
1966
1967 if ((unsigned int)(unsigned long)_XmRendTabs(rend) == XmAS_IS)
1968 _XmRendTabs(rend) = NULL;
1969 else if (copy)
1970 _XmRendTabs(rend) = XmTabListCopy(_XmRendTabs(rend), 0, 0);
1971 }
1972
1973
1974 /* Emit warning and set default if tag is NULL. */
1975 static void
ValidateTag(XmRendition rend,XmStringTag dflt)1976 ValidateTag(XmRendition rend,
1977 XmStringTag dflt)
1978 {
1979 if (_XmRendTag(rend) == NULL)
1980 {
1981 RenditionWarning(_XmRendTag(rend), "NO_NULL_TAG",
1982 NO_NULL_TAG_MSG, _XmRendDisplay(rend));
1983 _XmRendTag(rend) = _XmStringCacheTag(dflt, XmSTRING_TAG_STRLEN);
1984 }
1985 }
1986
1987 #ifdef FIX_1414
1988 #ifdef USE_XFT
1989 static int
GetSameRenditions(XmRendition * rend_cache,XmRendition rend,int count_rend)1990 GetSameRenditions(XmRendition *rend_cache, XmRendition rend, int count_rend)
1991 {
1992 int i;
1993 for (i=0; i<count_rend; i++){
1994
1995 if ( rend_cache && (rend_cache[i])
1996 && ((((_XmRendFontName(rend) && _XmRendFontName(rend_cache[i]) ) && !strcmp(_XmRendFontName(rend_cache[i]), _XmRendFontName(rend)))
1997 || (!_XmRendFontName(rend) && !_XmRendFontName(rend_cache[i])))
1998 && (((_XmRendFontFoundry(rend) && _XmRendFontFoundry(rend_cache[i])) && !strcmp(_XmRendFontFoundry(rend_cache[i]), _XmRendFontFoundry(rend)))
1999 || (!_XmRendFontFoundry(rend) && !_XmRendFontFoundry(rend_cache[i])))
2000 && (((_XmRendFontEncoding(rend) && _XmRendFontEncoding(rend_cache[i])) && !strcmp(_XmRendFontEncoding(rend_cache[i]), _XmRendFontEncoding(rend)))
2001 || (!_XmRendFontEncoding(rend) && !_XmRendFontEncoding(rend_cache[i])))
2002 && (((_XmRendFontStyle(rend) && _XmRendFontStyle(rend_cache[i])) && !strcmp(_XmRendFontStyle(rend_cache[i]), _XmRendFontStyle(rend)))
2003 || (!_XmRendFontStyle(rend) && !_XmRendFontStyle(rend_cache[i])) )
2004 && _XmRendFontSize(rend) == _XmRendFontSize(rend_cache[i])
2005 && _XmRendPixelSize(rend) == _XmRendPixelSize(rend_cache[i])
2006 && _XmRendFontSlant(rend) == _XmRendFontSlant(rend_cache[i])
2007 && _XmRendFontWeight(rend) == _XmRendFontWeight(rend_cache[i])
2008 && _XmRendFontSpacing(rend) == _XmRendFontSpacing(rend_cache[i]))
2009 )
2010 {
2011 return i;
2012 }
2013
2014 }
2015 return -1;
2016
2017 }
2018 #endif
2019 #endif
2020
2021 /* Make sure all the font related resources make sense together and */
2022 /* then load the font specified by fontName if necessary. */
2023 static void
ValidateAndLoadFont(XmRendition rend,Display * display)2024 ValidateAndLoadFont(XmRendition rend, Display *display)
2025 {
2026 XrmString locale;
2027 XtPointer font;
2028 XrmValue args[2];
2029 Cardinal num_args = 0;
2030 XrmValue fromVal;
2031 XrmValue toVal;
2032 Boolean result = False;
2033
2034 _XmRendDisplay(rend) = display;
2035
2036 if (_XmRendLoadModel(rend) != XmLOAD_DEFERRED)
2037 {
2038 XmDisplay dsp = NULL;
2039 XmDisplayCallbackStruct cb;
2040
2041 if ((_XmRendFont(rend) == NULL) &&
2042 #ifdef USE_XFT
2043 (_XmRendXftFont (rend) == NULL) &&
2044 #endif
2045 (_XmRendFontName(rend) != NULL))
2046 {
2047 if (_XmRendFontType(rend) != XmAS_IS)
2048 {
2049 if (display == NULL)
2050 {
2051 RenditionWarning(_XmRendTag(rend), "NULL_DISPLAY",
2052 NULL_DISPLAY_MSG, NULL);
2053 return;
2054 }
2055
2056 args[0].addr = (XPointer) &display;
2057 args[0].size = sizeof(Display*);
2058 num_args++;
2059
2060 fromVal.addr = _XmRendFontName(rend);
2061 fromVal.size = strlen(_XmRendFontName(rend));
2062
2063 toVal.addr = (XPointer) &font;
2064 toVal.size = sizeof (XtPointer);
2065
2066 switch (_XmRendFontType(rend))
2067 {
2068 case XmFONT_IS_FONT:
2069 result =
2070 XtCallConverter(display, XtCvtStringToFontStruct,
2071 args, num_args, &fromVal, &toVal, NULL);
2072 break;
2073 case XmFONT_IS_FONTSET:
2074 locale =
2075 XrmQuarkToString(XrmStringToQuark(setlocale(LC_ALL, NULL)));
2076 args[1].addr = (XPointer) &locale;
2077 args[1].size = sizeof(XrmString);
2078 num_args++;
2079
2080 result = XtCallConverter (display, XtCvtStringToFontSet, args,
2081 num_args, &fromVal, &toVal, NULL);
2082 break;
2083 #ifdef USE_XFT
2084 case XmFONT_IS_XFT:
2085 {
2086 FcResult res;
2087 FcPattern *p;
2088
2089 #ifdef FIX_1414
2090 static XmRendition *rend_cache;
2091 static int count_rend=0, num_rend;
2092 num_rend = GetSameRenditions(rend_cache, rend, count_rend);
2093
2094 if (num_rend>=0)
2095 _XmRendXftFont(rend) = _XmRendXftFont(rend_cache[num_rend]);
2096 else
2097 {
2098 #endif
2099 _XmRendPattern(rend) = FcPatternCreate();
2100 if (_XmRendFontName(rend))
2101 FcPatternAddString(_XmRendPattern(rend), FC_FAMILY,
2102 (XftChar8 *)_XmRendFontName(rend));
2103 if (_XmRendFontFoundry(rend))
2104 FcPatternAddString(_XmRendPattern(rend), FC_FOUNDRY,
2105 (XftChar8 *)_XmRendFontFoundry(rend));
2106 if (_XmRendFontEncoding(rend))
2107 FcPatternAddString(_XmRendPattern(rend), XFT_ENCODING,
2108 (XftChar8 *)_XmRendFontEncoding(rend));
2109 if (_XmRendFontStyle(rend))
2110 FcPatternAddString(_XmRendPattern(rend), FC_STYLE,
2111 (XftChar8 *)_XmRendFontStyle(rend));
2112 if (_XmRendFontSize(rend))
2113 FcPatternAddInteger(_XmRendPattern(rend), FC_SIZE,
2114 _XmRendFontSize(rend));
2115 if (_XmRendPixelSize(rend))
2116 FcPatternAddInteger(_XmRendPattern(rend), FC_PIXEL_SIZE,
2117 _XmRendPixelSize(rend));
2118 if (_XmRendFontSlant(rend))
2119 FcPatternAddInteger(_XmRendPattern(rend), FC_SLANT,
2120 _XmRendFontSlant(rend));
2121 if (_XmRendFontWeight(rend))
2122 FcPatternAddInteger(_XmRendPattern(rend), FC_WEIGHT,
2123 _XmRendFontWeight(rend));
2124 if (_XmRendFontSpacing(rend))
2125 FcPatternAddInteger(_XmRendPattern(rend), FC_SPACING,
2126 _XmRendFontSpacing(rend));
2127 p = XftFontMatch(display, 0, _XmRendPattern(rend), &res);
2128 #ifdef FIX_1414
2129 _XmRendXftFont(rend) = XftFontOpenPattern(display, p);
2130 rend_cache = (XmRendition *) XtRealloc((char *)rend_cache,
2131 (Cardinal)(sizeof(XmRendition) * (count_rend + 1)));
2132 rend_cache[count_rend] =_XmRenditionCopy(rend, TRUE);
2133 count_rend++;
2134 }
2135
2136 #else
2137 _XmRendXftFont(rend) = XftFontOpenPattern(display, p);
2138 #endif
2139 }
2140 result = _XmRendXftFont(rend) != NULL;
2141 break;
2142 #endif
2143 default:
2144 RenditionWarning(_XmRendTag(rend), "INVALID_TYPE",
2145 INVALID_TYPE_MSG,
2146 _XmRendDisplay(rend));
2147 break;
2148 }
2149
2150 /* NoFontCallback. */
2151 if (!result)
2152 {
2153 if (display != NULL)
2154 {
2155 dsp = (XmDisplay) XmGetXmDisplay(display);
2156 cb.reason = XmCR_NO_FONT;
2157 cb.event = NULL;
2158 cb.rendition = rend;
2159 cb.font_name = _XmRendFontName(rend);
2160
2161 /* We must know for sure whether there are any */
2162 /* callbacks, so we have to use XtHasCallbacks. */
2163 if (XtHasCallbacks((Widget)dsp, XmNnoFontCallback) ==
2164 XtCallbackHasSome)
2165 {
2166 XtCallCallbackList((Widget)dsp,
2167 dsp->display.noFontCallback,
2168 &cb);
2169 return;
2170 }
2171 }
2172
2173 RenditionWarning(_XmRendTag(rend), "CONVERSION_FAILED",
2174 CONVERSION_FAILED_MSG,
2175 _XmRendDisplay(rend));
2176 }
2177 else
2178 {
2179 #ifdef USE_XFT
2180 if (_XmRendFontType(rend) != XmFONT_IS_XFT)
2181 #endif
2182 _XmRendFont(rend) = font;
2183 }
2184 }
2185 else
2186 {
2187 RenditionWarning(_XmRendTag(rend), "NULL_FONT_TYPE",
2188 NULL_FONT_TYPE_MSG,
2189 _XmRendDisplay(rend));
2190 }
2191 }
2192 else if ((_XmRendLoadModel(rend) == XmLOAD_IMMEDIATE) &&
2193 (_XmRendFont(rend) == NULL) &&
2194 #ifdef USE_XFT
2195 (_XmRendXftFont (rend) == NULL) &&
2196 #endif
2197 (_XmRendFontName(rend) == NULL))
2198 {
2199 RenditionWarning(_XmRendTag(rend), "NULL_LOAD_IMMEDIATE",
2200 NULL_LOAD_IMMEDIATE_MSG,
2201 _XmRendDisplay(rend));
2202 }
2203 }
2204 }
2205
2206 /* Create new rendition. */
2207 XmRendition
XmRenditionCreate(Widget widget,XmStringTag tag,ArgList arglist,Cardinal argcount)2208 XmRenditionCreate(Widget widget,
2209 XmStringTag tag,
2210 ArgList arglist,
2211 Cardinal argcount)
2212 {
2213 XmRendition ret_val;
2214 XtAppContext app=NULL;
2215
2216 /* If cannot applock, assume its an internal call (from
2217 * fontlist code, etc.) and already process locked.
2218 */
2219 if (widget)
2220 app = XtWidgetToApplicationContext(widget);
2221 if (app) {
2222 _XmAppLock(app);
2223 }
2224 else {
2225 _XmProcessLock();
2226 }
2227 ret_val = _XmRenditionCreate(NULL, widget, XmS, XmCRenderTable,
2228 tag, arglist, argcount, NULL);
2229 if (app) {
2230 _XmAppUnlock(app);
2231 }
2232 else {
2233 _XmProcessUnlock();
2234 }
2235
2236 return ret_val;
2237 }
2238
2239 /* Internal function. Called from XmRenditionCreate, resource */
2240 /* converter, and Mrm create function. */
2241 XmRendition
_XmRenditionCreate(Display * display,Widget widget,String resname,String resclass,XmStringTag tag,ArgList arglist,Cardinal argcount,Boolean * in_db)2242 _XmRenditionCreate(Display *display,
2243 Widget widget,
2244 String resname,
2245 String resclass,
2246 XmStringTag tag,
2247 ArgList arglist,
2248 Cardinal argcount,
2249 Boolean *in_db)
2250 {
2251 XmRendition rend;
2252 _XmRendition rend_int;
2253 Boolean result;
2254
2255 if ((display == NULL) && (widget != NULL))
2256 display = XtDisplayOfObject(widget);
2257
2258 if ((tag != NULL) &&
2259 (tag != XmFONTLIST_DEFAULT_TAG) &&
2260 (strcmp(tag, XmSTRING_DEFAULT_CHARSET) == 0))
2261 tag = _XmStringGetCurrentCharset();
2262
2263 /* Allocate rendition. */
2264 rend_int = (_XmRendition)XtMalloc(sizeof(_XmRenditionRec));
2265 bzero((char*)rend_int, sizeof(_XmRenditionRec));
2266 rend = GetHandle(_XmRendition);
2267 SetPtr(rend, rend_int);
2268
2269 _XmRendRefcount(rend) = 1;
2270
2271 /* For now, FontOnly renditions aren't implemented. */
2272 _XmRendFontOnly(rend) = FALSE;
2273
2274 /* X resource DB query */
2275 result =
2276 GetResources(rend, display, widget, resname, resclass, tag,
2277 arglist, argcount);
2278
2279 if (in_db != NULL) *in_db = result;
2280
2281 if (tag == NULL)
2282 {
2283 if (result == FALSE)
2284 {
2285 XtFree((char *)rend_int);
2286 FreeHandle(rend);
2287 return(NULL);
2288 }
2289 else tag = _MOTIF_DEFAULT_LOCALE;
2290 }
2291
2292 _XmRendTag(rend) = _XmStringCacheTag(tag, XmSTRING_TAG_STRLEN);
2293
2294 /* Cleanup and validate resources. */
2295
2296 CleanupResources(rend, TRUE);
2297
2298 ValidateTag(rend, XmS);
2299
2300 ValidateAndLoadFont(rend, display);
2301
2302 return(rend);
2303 }
2304
2305 /* Mrm create function for rendertables. */
2306 /*ARGSUSED*/
2307 Widget
_XmCreateRenderTable(Widget parent,String name,ArgList arglist,Cardinal argcount)2308 _XmCreateRenderTable(Widget parent,
2309 String name, /* unused */
2310 ArgList arglist, /* unused */
2311 Cardinal argcount) /* unused */
2312 {
2313 XmRenderTable newtable;
2314 _XmRenderTable table;
2315
2316 /* Malloc new table */
2317 table = (_XmRenderTable)XtMalloc(sizeof(_XmRenderTableRec));
2318 newtable = GetHandle(_XmRenderTable);
2319 SetPtr(newtable, table);
2320 _XmRTCount(newtable) = 0;
2321 _XmRTRefcount(newtable) = 1;
2322 _XmRTDisplay(newtable) = XtDisplay(parent);
2323
2324 return((Widget)newtable);
2325 }
2326
2327 /* Mrm create function for renditions. */
2328 Widget
_XmCreateRendition(Widget parent,String name,ArgList arglist,Cardinal argcount)2329 _XmCreateRendition(Widget parent,
2330 String name,
2331 ArgList arglist,
2332 Cardinal argcount)
2333 {
2334 XmRenderTable rt = (XmRenderTable)parent;
2335 _XmRenderTable table;
2336 XmRendition rend;
2337
2338 table = GetPtr(rt);
2339
2340 rend = _XmRenditionCreate(_XmRTDisplay(rt), NULL, XmS, XmCRenderTable,
2341 name, arglist, argcount, NULL);
2342
2343 /* Ignore repeats */
2344 if (_XmRenderTableFindRendition(rt, _XmRendTag(rend),
2345 TRUE, FALSE, FALSE, NULL)
2346 != NULL)
2347 {
2348 if (FreeRendition(rend)) FreeHandle(rend);
2349 return((Widget)NULL);
2350 }
2351
2352 table = (_XmRenderTable)
2353 XtRealloc((char *)table,
2354 sizeof(_XmRenderTableRec) +
2355 (sizeof(XmRendition) *
2356 ((_XmRTCount(rt) + 1) - RENDITIONS_IN_STRUCT)));
2357 SetPtr(rt, table);
2358
2359 /* Copy new rendition. */
2360 _XmRTRenditions(rt)[_XmRTCount(rt)] = CopyRendition(rend);
2361 _XmRTCount(rt)++;
2362
2363 return((Widget)rend);
2364 }
2365
2366 /* Free data structure and any copied values. */
2367 /* TRUE return -> freed. FALSE -> just decremented. */
2368 static Boolean
FreeRendition(XmRendition rendition)2369 FreeRendition(XmRendition rendition)
2370 {
2371 if (rendition == NULL) return(FALSE);
2372
2373 if (_XmRendRefcountDec(rendition) == 0)
2374 {
2375 /* CR 7890 - the fontName might be XmAS_IS here */
2376 if (NameIsString(_XmRendFontName(rendition)))
2377 XtFree(_XmRendFontName(rendition));
2378 if (ListIsList(_XmRendTabs(rendition)))
2379 XmTabListFree(_XmRendTabs(rendition));
2380 if (_XmRendTagCount(rendition) != 0)
2381 XtFree((char *)_XmRendTags(rendition));
2382 #ifdef USE_XFT
2383 if (_XmRendXftFont(rendition))
2384 {
2385 XftFontClose(_XmRendDisplay(rendition),
2386 _XmRendXftFont(rendition));
2387 _XmRendXftFont(rendition) = NULL;
2388 }
2389 if (_XmRendPattern(rendition))
2390 {
2391 FcPatternDestroy(_XmRendPattern(rendition));
2392 _XmRendPattern(rendition) = NULL;
2393 }
2394 #endif
2395
2396 XtFree((char *)GetPtr(rendition));
2397 return(TRUE);
2398 }
2399 return(FALSE);
2400 }
2401
2402 void
XmRenditionFree(XmRendition rendition)2403 XmRenditionFree(XmRendition rendition)
2404 {
2405 XtAppContext app;
2406
2407 if (rendition == NULL) return;
2408
2409 _XmProcessLock();
2410 FreeRendition(rendition);
2411 FreeHandle(rendition);
2412 _XmProcessUnlock();
2413 }
2414
2415 /* Get resource values from rendition. */
2416 void
XmRenditionRetrieve(XmRendition rendition,ArgList arglist,Cardinal argcount)2417 XmRenditionRetrieve(XmRendition rendition,
2418 ArgList arglist,
2419 Cardinal argcount)
2420 {
2421 int i, j;
2422 Arg *arg;
2423 XtResource *res;
2424 char *as_is = (char *)XmAS_IS;
2425
2426 if (rendition == NULL) return;
2427
2428 _XmProcessLock();
2429 /* Get resources */
2430 for (i = 0; i < argcount; i++)
2431 {
2432 arg = &(arglist[i]);
2433
2434 for (j = 0; j < _XmNumRenditionResources; j++)
2435 {
2436 res = &(_XmRenditionResources[j]);
2437
2438 if (strcmp(res->resource_name, arg->name) == 0)
2439 {
2440 /* CR 7890: Font hook - if there's a fontName but the
2441 ** font hasn't been fetched yet, now's a good time to
2442 ** get it - if the caller wants to use the font to, say,
2443 ** compute font metrics for layout (as CSText does), it won't
2444 ** like to get NULL back
2445 */
2446 if (strcmp(res->resource_name, XmNfont) == 0)
2447 {
2448 if ((_XmRendFont(rendition) == NULL) &&
2449 #ifdef USE_XFT
2450 (_XmRendXftFont (rendition) == NULL) &&
2451 #endif
2452 (_XmRendFontName(rendition) != NULL))
2453 {
2454 if (_XmRendLoadModel(rendition) == XmLOAD_DEFERRED)
2455 _XmRendLoadModel(rendition) = XmLOAD_IMMEDIATE;
2456 ValidateAndLoadFont(rendition, _XmRendDisplay(rendition));
2457 }
2458 if (_XmRendFont (rendition) == NULL
2459 #ifdef USE_XFT
2460 && _XmRendXftFont (rendition) == NULL
2461 #endif
2462 )
2463 CopyToArg((char*)&as_is, &(arg->value), sizeof(char*));
2464 else CopyToArg(((char *)GetPtr(rendition) +
2465 res->resource_offset),
2466 &(arg->value),
2467 res->resource_size);
2468 }
2469 else if (((strcmp(res->resource_name, XmNfontName) == 0) &&
2470 (_XmRendFontName(rendition) == NULL)) ||
2471 ((strcmp(res->resource_name, XmNtabList) == 0) &&
2472 (_XmRendTabs(rendition) == NULL)))
2473 CopyToArg((char*)&as_is, &(arg->value), sizeof(char*));
2474 else CopyToArg(((char *)GetPtr(rendition) + res->resource_offset),
2475 &(arg->value),
2476 res->resource_size);
2477 break;
2478 }
2479 }
2480 }
2481 _XmProcessUnlock();
2482 }
2483
2484 /* Set resources in rendition. */
2485 /* Renew rendition if necessary, then update resources. */
2486 void
XmRenditionUpdate(XmRendition rendition,ArgList arglist,Cardinal argcount)2487 XmRenditionUpdate(XmRendition rendition,
2488 ArgList arglist,
2489 Cardinal argcount)
2490 {
2491 XmStringTag oldtag;
2492 char *oldname;
2493 XtPointer oldfont;
2494 XmTabList oldtabs;
2495 int i, j;
2496 XtResource *res;
2497 Arg *arg;
2498 Display *display = _XmGetDefaultDisplay();
2499 Boolean can_free;
2500 XtAppContext app = NULL;
2501
2502 if (rendition == NULL) return;
2503
2504 #ifdef XTHREADS
2505 if (_XmRendDisplay(rendition))
2506 {
2507 app = XtDisplayToApplicationContext(_XmRendDisplay(rendition));
2508 _XmAppLock(app);
2509 }
2510 if (_XmRendDisplay(rendition) && (_XmRendDisplay(rendition) !=
2511 display) )
2512 display = _XmRendDisplay(rendition);
2513 #endif
2514 /* Save old values to check for dependencies and free memory. */
2515 oldtag = _XmRendTag(rendition);
2516 oldname = _XmRendFontName(rendition);
2517 oldfont = _XmRendFont(rendition);
2518 oldtabs = _XmRendTabs(rendition);
2519 can_free = TRUE;
2520
2521 /* New memory if needed. */
2522 if (_XmRendRefcount(rendition) > 1)
2523 {
2524 _XmRendRefcountDec(rendition);
2525 RenewRendition(rendition);
2526 can_free = FALSE;
2527 }
2528
2529 for (i = 0; i < argcount; i++)
2530 {
2531 arg = &(arglist[i]);
2532
2533 for (j = 0; j < _XmNumRenditionResources; j++)
2534 {
2535 res = &(_XmRenditionResources[j]);
2536
2537 if (strcmp(res->resource_name, arg->name) == 0)
2538 {
2539 CopyFromArg((arg->value),
2540 ((char *)GetPtr(rendition) + res->resource_offset),
2541 res->resource_size);
2542 break;
2543 }
2544 }
2545 }
2546
2547 CopyInto(rendition, rendition);
2548
2549 /** Validate resources **/
2550
2551 /* CR 7890 - handle cases of fontName == NULL and fontName == XmAS_IS */
2552
2553 /* If fontName changed but not font, NULL font so it's updated.
2554 ** (first make sure we won't crash on the strcmp) */
2555
2556 if (NameIsString(oldname) && NameIsString(_XmRendFontName(rendition))) {
2557 if (strcmp(oldname, _XmRendFontName(rendition)) != 0)
2558 {
2559 if (oldfont == _XmRendFont(rendition))
2560 _XmRendFont(rendition) = NULL;
2561 }
2562 if (can_free) XtFree(oldname);
2563 }
2564 /* Also handle the case where we started with a NULL fontName and
2565 ** had a real fontName specified */
2566 else if ((oldname == NULL) && NameIsString(_XmRendFontName(rendition)))
2567 {
2568 if (oldfont == _XmRendFontName(rendition))
2569 _XmRendFont(rendition) = NULL;
2570 }
2571
2572 if (_XmRendFont(rendition) == (XtPointer)XmAS_IS)
2573 _XmRendFont(rendition) = NULL;
2574
2575 if ((oldtabs != _XmRendTabs(rendition)) && can_free) XmTabListFree(oldtabs);
2576
2577 ValidateTag(rendition, oldtag);
2578
2579 ValidateAndLoadFont(rendition, display);
2580 #ifdef XTHREADS
2581 if (app) {
2582 _XmAppUnlock(app);
2583 }
2584 #endif
2585 }
2586
2587 /*****************************************************************************/
2588 /* XmRenderTableCvtToProp takes a rendertable and converts it to */
2589 /* an ascii string in the following format: */
2590 /* tag : char* */
2591 /* font : either fontid (integer) or [ fontid, fontid ... fontid ] or -1 */
2592 /* tablist : [ tab1, ... tabn ] or -1 */
2593 /* background : pixel or -1 */
2594 /* foreground : pixel or -1 */
2595 /* underlineType : integer (from enum in Xm.h ) or -1 */
2596 /* strikethruType : integer (from enum in Xm.h ) or -1 */
2597 /* */
2598 /* example: */
2599 /* "tag, font, tablist, background, foreground, underlineType, */
2600 /* strikethruType\n */
2601 /* bold, 10000031, -1, -1, -1, -1, -1\n */
2602 /* underline, 10000029, -1, -1, -1, -1, -1\n */
2603 /* default, 10000029, [ 1.234 1 0 0, 2.43 2 0 2], 1, 2, 0, 0\n */
2604 /* japanese, [10000029, 10000030], -1, -1, -1, -1, -1" */
2605 /* */
2606 /* The first line gives a complete list of the attributes by name. */
2607 /* on the destination side, attributes which are not understood */
2608 /* or are outdated can be ignored. The conversion of each rendition */
2609 /* passes a single "line" which contains the fields in order. */
2610 /*****************************************************************************/
2611
2612 /* Note that this MUST be in the same order as the output conversion
2613 below!! */
2614 static XmConst char *CVTproperties[] = {
2615 XmNtag,
2616 XmNfont,
2617 XmNtabList,
2618 XmNbackground,
2619 XmNforeground,
2620 XmNunderlineType,
2621 XmNstrikethruType,
2622 NULL,
2623 };
2624
2625 /* Must be big enough to take all the above strings concatenated with
2626 commas separating them */
2627 static char CVTtransfervector[256];
2628 static int CVTtvinited = 0;
2629
2630 /* Use this macro to encapsulate the code that extends the output
2631 buffer as needed */
2632 #define CVTaddString(dest, src, srcsize)\
2633 {\
2634 if ((chars_used + srcsize) > allocated_size) {\
2635 allocated_size *= 2;\
2636 buffer = XtRealloc(buffer, allocated_size);\
2637 }\
2638 strcat(buffer, src);\
2639 chars_used += srcsize;\
2640 }
2641
2642 /*ARGSUSED*/
2643 unsigned int
XmRenderTableCvtToProp(Widget widget,XmRenderTable table,char ** prop_return)2644 XmRenderTableCvtToProp(Widget widget, /* unused */
2645 XmRenderTable table,
2646 char **prop_return)
2647 {
2648 int i;
2649 int allocated_size = 256;
2650 int chars_used = 0, size;
2651 char *buffer;
2652 char *str;
2653 XmRendition rendition;
2654 _XmWidgetToAppContext(widget);
2655
2656 _XmAppLock(app);
2657 buffer = XtMalloc(allocated_size);
2658
2659 _XmProcessLock();
2660 if (CVTtvinited == 0) {
2661 CVTtvinited = 1;
2662 strcpy(CVTtransfervector, "");
2663 for(i = 0; CVTproperties[i] != NULL; i++) {
2664 strcat(CVTtransfervector, CVTproperties[i]);
2665 strcat(CVTtransfervector, ",");
2666 }
2667 strcat(CVTtransfervector, "\n");
2668 }
2669
2670 /* Copy the transfer vector into the output buffer. */
2671 strcpy(buffer, CVTtransfervector);
2672 chars_used = strlen(buffer);
2673 _XmProcessUnlock();
2674
2675 /* Now iterate over the list of renditions */
2676 for(i = 0; i < _XmRTCount(table); i++) {
2677 char temp[2048];
2678
2679 rendition = _XmRTRenditions(table)[i];
2680 sprintf(temp, "\"%s\", ", _XmRendTag(rendition));
2681 size = strlen(temp);
2682 CVTaddString(buffer, temp, size);
2683
2684 if (_XmRendFontType(rendition) == XmAS_IS)
2685 str = "-1, ";
2686 else {
2687 sprintf(temp, "%d \"%s\" %d,", _XmRendFontType(rendition),
2688 _XmRendFontName(rendition), _XmRendLoadModel(rendition));
2689 str = temp;
2690 }
2691 size = strlen(str);
2692 CVTaddString(buffer, str, size);
2693
2694 if ((unsigned int)(unsigned long)_XmRendTabs(rendition) == XmAS_IS ||
2695 _XmRendTabs(rendition) == NULL)
2696 str = "-1, ";
2697 else {
2698 _XmTab tab;
2699 _XmTabList tlist;
2700 int number;
2701 strcpy(temp, "[ ");
2702 tlist = (_XmTabList) _XmRendTabs(rendition);
2703 number = tlist -> count;
2704 tab = (_XmTab) tlist -> start;
2705 while(number > 0) {
2706 sprintf(temp, "%s %f %d %d %d, ", temp, tab -> value,
2707 tab -> units, tab -> alignment, tab -> offsetModel);
2708 tab = (_XmTab) tab -> next;
2709 number--;
2710 }
2711 strcat(temp, " ], ");
2712 str = temp;
2713 }
2714 size = strlen(str);
2715 CVTaddString(buffer, str, size);
2716
2717 if (_XmRendBG(rendition) == XmAS_IS)
2718 str = "-1, ";
2719 else {
2720 sprintf(temp, "%ld, ", _XmRendBG(rendition));
2721 str = temp;
2722 }
2723 size = strlen(str);
2724 CVTaddString(buffer, str, size);
2725
2726 if (_XmRendFG(rendition) == XmAS_IS)
2727 str = "-1, ";
2728 else {
2729 sprintf(temp, "%ld, ", _XmRendFG(rendition));
2730 str = temp;
2731 }
2732 size = strlen(str);
2733 CVTaddString(buffer, str, size);
2734
2735 if (_XmRendUnderlineType(rendition) == XmAS_IS)
2736 str = "-1, ";
2737 else {
2738 sprintf(temp, "%d, ", _XmRendUnderlineType(rendition));
2739 str = temp;
2740 }
2741 size = strlen(str);
2742 CVTaddString(buffer, str, size);
2743
2744 if (_XmRendStrikethruType(rendition) == XmAS_IS)
2745 str = "-1, ";
2746 else {
2747 sprintf(temp, "%d, ", _XmRendStrikethruType(rendition));
2748 str = temp;
2749 }
2750 size = strlen(str);
2751 CVTaddString(buffer, str, size);
2752 CVTaddString(buffer, "\n", size);
2753 }
2754
2755 /* Return the converted rendertable string */
2756 *prop_return = buffer;
2757
2758 _XmAppUnlock(app);
2759 /* chars_used is always the size - the NULL terminator */
2760 return(chars_used + 1);
2761 }
2762
2763 typedef enum { T_NL, T_INT, T_FLOAT, T_SEP,
2764 T_OPEN, T_CLOSE, T_STR, T_EOF } TokenType;
2765
2766 typedef struct _TokenRec {
2767 TokenType type;
2768 int integer;
2769 float real;
2770 char *string;
2771 } TokenRec, *Token;
2772
2773
2774 #ifndef XTHREADS
2775 static TokenRec reusetoken;
2776 #endif
2777
2778 static Token
ReadToken(char * string,int * position)2779 ReadToken(char *string, int *position)
2780 {
2781 #ifdef XTHREADS
2782 TokenRec reusetoken;
2783 Token new_token = &reusetoken;
2784 #else
2785 Token new_token = &reusetoken;
2786 #endif
2787 int pos = *position;
2788 int count;
2789
2790 /* Skip whitespace but not newlines */
2791 while (isspace(string[pos]) && ! (string[pos] == '\n'))
2792 pos++;
2793
2794 /* Select token type */
2795 switch(string[pos]) {
2796 case '\0':
2797 new_token -> type = T_EOF;
2798 break;
2799 case '\n':
2800 new_token -> type = T_NL;
2801 pos++;
2802 break;
2803 case ',':
2804 new_token -> type = T_SEP;
2805 pos++;
2806 break;
2807 case '[':
2808 new_token -> type = T_OPEN;
2809 pos++;
2810 break;
2811 case ']':
2812 new_token -> type = T_CLOSE;
2813 pos++;
2814 break;
2815 case '"': /* String result */
2816 count = 1;
2817 while (string[pos + count] != '"' &&
2818 string[pos + count] != '\0')
2819 count++; /* Scan for end of string */
2820 new_token -> type = T_STR;
2821 new_token -> string = NULL;
2822 count -= 1;
2823 if (count > 0) {
2824 new_token -> string = (char*) XtMalloc(count + 1);
2825 strncpy(new_token -> string, &string[pos + 1], count);
2826 pos += count + 2; /* Move past end quote */
2827 new_token -> string[count] = 0; /* Null terminate */
2828 }
2829 break;
2830 default:
2831 if (isalpha(string[pos])) /* String result */
2832 {
2833 char temp[80];
2834 int count;
2835 for(count = 0;
2836 isalpha(string[pos + count]) && count < 79;
2837 count++) temp[count] = string[pos + count];
2838 temp[count] = 0;
2839 pos += count;
2840 new_token -> type = T_STR;
2841 new_token -> string = XtNewString(temp);
2842 }
2843 else
2844 {
2845 /* start converting a float number. If it is exactly integer
2846 then we return an int, otherwise return a float */
2847 double result;
2848 int intresult;
2849 char *newpos;
2850 result=strtod(&(string[pos]), &newpos);
2851 intresult= (int) result;
2852 pos = newpos - string;
2853 if (((double) intresult) == result) /* Integer result */
2854 {
2855 new_token -> type = T_INT;
2856 new_token -> integer = intresult;
2857 }
2858 else
2859 {
2860 new_token -> type = T_FLOAT;
2861 new_token -> real = (float) result;
2862 }
2863 }
2864 }
2865
2866 *position = pos;
2867 return(new_token);
2868 }
2869
2870 #ifdef USE_XFT
2871 static struct _XmXftDrawCacheStruct {
2872 Display *display;
2873 Window window;
2874 XftDraw *draw;
2875 } *_XmXftDrawCache = NULL;
2876 static int _XmXftDrawCacheSize = 0;
2877
2878 static XErrorHandler oldErrorHandler;
2879 static int xft_error;
2880
2881 static int
_XmXftErrorHandler(Display * display,XErrorEvent * error)2882 _XmXftErrorHandler(
2883 Display *display,
2884 XErrorEvent *error )
2885 {
2886 (void) fprintf(stderr,
2887 "Ignoring Xlib error: error code %d request code %d\n",
2888 error->error_code,
2889 error->request_code) ;
2890 xft_error = BadWindow;
2891
2892 /* No exit! - but keep lint happy */
2893
2894 return 0 ;
2895 }
2896
2897 XftDraw *
_XmXftDrawCreate(Display * display,Window window)2898 _XmXftDrawCreate(Display *display, Window window)
2899 {
2900 XftDraw *draw;
2901 XWindowAttributes wa;
2902 int i;
2903 Status status;
2904
2905 for (i=0; i<_XmXftDrawCacheSize; i++) {
2906 if (_XmXftDrawCache[i].display == display &&
2907 _XmXftDrawCache[i].window == window) {
2908 return _XmXftDrawCache[i].draw;
2909 }
2910 }
2911
2912 #ifdef FIX_1444
2913 if (!(draw = XftDrawCreate(display, window,
2914 DefaultVisual(display, DefaultScreen(display)),
2915 DefaultColormap(display, DefaultScreen(display)))))
2916 draw = XftDrawCreateBitmap(display, window);
2917 #else
2918 oldErrorHandler = XSetErrorHandler (_XmXftErrorHandler);
2919 xft_error = 0;
2920 XGetWindowAttributes(display, window, &wa);
2921 XSetErrorHandler(oldErrorHandler);
2922 if (xft_error != BadWindow) {
2923 draw = XftDrawCreate(display, window,
2924 DefaultVisual(display, DefaultScreen(display)),
2925 DefaultColormap(display, DefaultScreen(display)));
2926 } else {
2927 draw = XftDrawCreateBitmap(display, window);
2928 }
2929 #endif
2930 /* Store it in the cache. Look for an empty slot first */
2931 for (i=0; i<_XmXftDrawCacheSize; i++)
2932 if (_XmXftDrawCache[i].display == NULL) {
2933 _XmXftDrawCache[i].display = display;
2934 _XmXftDrawCache[i].draw = draw;
2935 _XmXftDrawCache[i].window = window;
2936 return draw;
2937 }
2938 i = _XmXftDrawCacheSize; /* Next free index */
2939 _XmXftDrawCacheSize = _XmXftDrawCacheSize * 2 + 8;
2940 _XmXftDrawCache = (struct _XmXftDrawCacheStruct *)
2941 XtRealloc((char *)_XmXftDrawCache,
2942 sizeof(struct _XmXftDrawCacheStruct) * _XmXftDrawCacheSize);
2943 #ifdef FIX_1449
2944 memset(_XmXftDrawCache + i, 0, (_XmXftDrawCacheSize - i) * sizeof(*_XmXftDrawCache));
2945 #endif
2946
2947 _XmXftDrawCache[i].display = display;
2948 _XmXftDrawCache[i].draw = draw;
2949 _XmXftDrawCache[i].window = window;
2950
2951 return draw;
2952 }
2953
2954 void
_XmXftDrawDestroy(Display * display,Window window,XftDraw * draw)2955 _XmXftDrawDestroy(Display *display, Window window, XftDraw *draw)
2956 {
2957 int i;
2958
2959 for (i=0; i<_XmXftDrawCacheSize; i++)
2960 if (_XmXftDrawCache[i].display == display &&
2961 _XmXftDrawCache[i].window == window) {
2962 _XmXftDrawCache[i].display = NULL;
2963 _XmXftDrawCache[i].draw = NULL;
2964 _XmXftDrawCache[i].window = None;
2965 XftDrawDestroy(draw);
2966 return;
2967 }
2968 XmeWarning(NULL, "_XmXftDrawDestroy() this should not happen\n");
2969 }
2970
2971 void
_XmXftDrawString2(Display * display,Window window,GC gc,XftFont * font,int bpc,int x,int y,char * s,int len)2972 _XmXftDrawString2(Display *display, Window window, GC gc, XftFont *font, int bpc,
2973 #if NeedWidePrototypes
2974 int x, int y,
2975 #else
2976 Position x, Position y,
2977 #endif
2978 char *s, int len)
2979 {
2980 XftDraw *draw = _XmXftDrawCreate(display, window);
2981 XGCValues gc_val;
2982 XColor xcol;
2983 XftColor xftcol;
2984
2985 XGetGCValues(display, gc, GCForeground, &gc_val);
2986
2987 xcol.pixel = gc_val.foreground;
2988 XQueryColor(display, DefaultColormap(display,
2989 DefaultScreen(display)), &xcol);
2990 xftcol.color.red = xcol.red;
2991 xftcol.color.blue = xcol.blue;
2992 xftcol.color.green = xcol.green;
2993 xftcol.color.alpha = 0xFFFF;
2994
2995 switch (bpc)
2996 {
2997 case 1:
2998 XftDrawStringUtf8(draw, &xftcol, font,
2999 x, y, (XftChar8 *)s, len);
3000 break;
3001 case 2:
3002 XftDrawString16(draw, &xftcol, font,
3003 x, y, (XftChar16 *)s, len);
3004 break;
3005 case 4:
3006 XftDrawString32(draw, &xftcol, font,
3007 x, y, (XftChar32 *)s, len);
3008 break;
3009 default:
3010 XmeWarning(NULL, "_XmXftDrawString(unsupported bpc)\n");
3011 }
3012 }
3013
3014 void
_XmXftDrawString(Display * display,Window window,XmRendition rend,int bpc,int x,int y,char * s,int len,int image)3015 _XmXftDrawString(Display *display, Window window, XmRendition rend, int bpc,
3016 #if NeedWidePrototypes
3017 int x, int y,
3018 #else
3019 Position x, Position y,
3020 #endif
3021 char *s, int len,
3022 #if NeedWidePrototypes
3023 int image
3024 #else
3025 Boolean image
3026 #endif
3027 )
3028 {
3029 XftDraw *draw = _XmXftDrawCreate(display, window);
3030 XftColor fg_color = _XmRendXftFG(rend);
3031
3032 if (image)
3033 {
3034 XftColor bg_color = _XmRendXftBG(rend);
3035 XGlyphInfo ext;
3036 ext.xOff = 0;
3037
3038 switch (bpc)
3039 {
3040 case 1:
3041 XftTextExtentsUtf8(display, _XmRendXftFont(rend),
3042 (FcChar8*)s, len, &ext);
3043 break;
3044 case 2:
3045 XftTextExtents16(display, _XmRendXftFont(rend),
3046 (FcChar16*)s, len, &ext);
3047 break;
3048 case 4:
3049 XftTextExtents32(display, _XmRendXftFont(rend),
3050 (FcChar32*)s, len, &ext);
3051 break;
3052 }
3053
3054 if (_XmRendBG(rend) == XmUNSPECIFIED_PIXEL)
3055 {
3056 XGCValues gc_val;
3057 XColor xcol;
3058
3059 XGetGCValues(display, _XmRendGC(rend), GCBackground, &gc_val);
3060 xcol.pixel = gc_val.background;
3061 XQueryColor(display, DefaultColormapOfScreen(
3062 DefaultScreenOfDisplay(display)), &xcol);
3063 bg_color.pixel = xcol.pixel;
3064 bg_color.color.red = xcol.red;
3065 bg_color.color.green = xcol.green;
3066 bg_color.color.blue = xcol.blue;
3067 bg_color.color.alpha = 0xFFFF;
3068 }
3069 #ifdef FIX_1451
3070 XftDrawRect(draw, &bg_color, x, y - _XmRendXftFont(rend)->ascent,
3071 ext.xOff,
3072 _XmRendXftFont(rend)->ascent +
3073 _XmRendXftFont(rend)->descent);
3074 #else
3075 XftDrawRect(draw, &bg_color, x - 10, y - _XmRendXftFont(rend)->ascent - 10,
3076 ext.xOff +20,
3077 _XmRendXftFont(rend)->ascent +
3078 _XmRendXftFont(rend)->descent + 20);
3079 #endif
3080 }
3081
3082 if (_XmRendFG(rend) == XmUNSPECIFIED_PIXEL)
3083 {
3084 XGCValues gc_val;
3085 XColor xcol;
3086 XGetGCValues(display, _XmRendGC(rend), GCForeground, &gc_val);
3087 xcol.pixel = gc_val.foreground;
3088 XQueryColor(display, DefaultColormapOfScreen(
3089 DefaultScreenOfDisplay(display)), &xcol);
3090 fg_color.pixel = xcol.pixel;
3091 fg_color.color.red = xcol.red;
3092 fg_color.color.green = xcol.green;
3093 fg_color.color.blue = xcol.blue;
3094 fg_color.color.alpha = 0xFFFF;
3095 }
3096
3097 switch (bpc)
3098 {
3099 case 1:
3100 XftDrawStringUtf8(draw, &fg_color, _XmRendXftFont(rend),
3101 x, y, (XftChar8 *)s, len);
3102 break;
3103 case 2:
3104 XftDrawString16(draw, &fg_color, _XmRendXftFont(rend),
3105 x, y, (XftChar16 *)s, len);
3106 break;
3107 case 4:
3108 XftDrawString32(draw, &fg_color, _XmRendXftFont(rend),
3109 x, y, (XftChar32 *)s, len);
3110 break;
3111 default:
3112 XmeWarning(NULL, "_XmXftDrawString(unsupported bpc)\n");
3113 }
3114 }
3115
3116 void
_XmXftSetClipRectangles(Display * display,Window window,Position x,Position y,XRectangle * rects,int n)3117 _XmXftSetClipRectangles(Display *display, Window window, Position x, Position y, XRectangle *rects, int n)
3118 {
3119 XftDraw *d = _XmXftDrawCreate(display, window);
3120
3121 XftDrawSetClipRectangles(d, x, y, rects, n);
3122 }
3123
3124 #ifdef FIX_1536
3125 static XftColor
GetCachedXftColor(Display * display,Pixel color)3126 GetCachedXftColor(Display *display, Pixel color)
3127 {
3128 static XftColor *color_cache = NULL;
3129 static int colors_count = 0;
3130
3131 XftColor xftcol = {0, {0,0,0,0xFFFF}};
3132 XColor xcol;
3133 Boolean color_exist = FALSE;
3134 int i;
3135
3136 if (color_cache != NULL)
3137 {
3138 for (i = 0; i < colors_count; ++i)
3139 {
3140 if (color_cache[i].pixel == color)
3141 {
3142 xftcol = color_cache[i];
3143 color_exist = TRUE;
3144 break;
3145 }
3146 }
3147 }
3148
3149 if (!color_exist)
3150 {
3151 xcol.pixel = color;
3152 XQueryColor(display, DefaultColormap(display,
3153 DefaultScreen(display)), &xcol);
3154 xftcol.pixel = color;
3155 xftcol.color.red = xcol.red;
3156 xftcol.color.blue = xcol.blue;
3157 xftcol.color.green = xcol.green;
3158 xftcol.color.alpha = 0xFFFF;
3159
3160 color_cache = (XftColor *) XtRealloc((char *) color_cache,
3161 (Cardinal) (sizeof(XftColor) * (colors_count + 1)));
3162 if (color_cache != NULL)
3163 color_cache[colors_count++] = xftcol;
3164 }
3165
3166 return xftcol;
3167 }
3168 #endif
3169
3170 XftColor
_XmXftGetXftColor(Display * display,Pixel color)3171 _XmXftGetXftColor(Display *display, Pixel color)
3172 {
3173 #ifdef FIX_1536
3174 return GetCachedXftColor(display, color);
3175 #else
3176 XColor xcol;
3177 XftColor xftcol;
3178
3179 xcol.pixel = color;
3180 XQueryColor(display, DefaultColormap(display,
3181 DefaultScreen(display)), &xcol);
3182 xftcol.pixel = color;
3183 xftcol.color.red = xcol.red;
3184 xftcol.color.blue = xcol.blue;
3185 xftcol.color.green = xcol.green;
3186 xftcol.color.alpha = 0xFFFF;
3187 return xftcol;
3188 #endif
3189 }
3190
3191 #ifdef FIX_1415
_XmXftFontAverageWidth(Widget w,XtPointer f,int * width)3192 void _XmXftFontAverageWidth(Widget w, XtPointer f, int *width)
3193 {
3194 XftFont *fp = (XftFont *)f;
3195 static char *s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
3196 int l = 62; /* strlen(s) */
3197 XGlyphInfo ext;
3198
3199 XftTextExtents8(XtDisplay(w), fp, (unsigned char *)s, l, &ext);
3200 if (width)
3201 *width = ext.width / l;
3202 }
3203 #endif
3204
3205 #endif
3206
3207 /*ARGSUSED*/
3208 XmRenderTable
XmRenderTableCvtFromProp(Widget w,char * prop,unsigned int len)3209 XmRenderTableCvtFromProp(Widget w,
3210 char *prop,
3211 unsigned int len) /* unused */
3212 {
3213 XmRenderTable new_rt;
3214 XmRendition rendition;
3215 XmRendition *rarray;
3216 int rarray_count, rarray_max;
3217 /* These must both be big enough for the number of passed parameters */
3218 char *items[20];
3219 char *name;
3220 Arg args[20];
3221 /* This must be big enough to hold all the strings returned by
3222 readtoken */
3223 char *freelater[5];
3224 int scanpointer, j, count, freecount, i;
3225 Token token;
3226 _XmWidgetToAppContext(w);
3227
3228 _XmAppLock(app);
3229 new_rt = NULL;
3230 scanpointer = 0;
3231 rarray_max = 10;
3232 rarray_count = 0;
3233 rarray = (XmRendition *) XtMalloc(sizeof(XmRendition) * rarray_max);
3234 name = "";
3235
3236 for(j = 0; j < 20; j++) items[j] = NULL;
3237 /* Read the list of items */
3238 for(j = 0; j < 20; ) {
3239 token = ReadToken(prop, &scanpointer);
3240 if (token -> type == T_NL) break;
3241 if (token -> type == T_STR) {
3242 items[j] = token -> string;
3243 j++;
3244 }
3245 }
3246
3247 j = -1;
3248 count = 0;
3249 freecount = 0;
3250 while(True) {
3251 token = ReadToken(prop, &scanpointer);
3252 /* We skip the separators */
3253 while(token -> type == T_SEP &&
3254 token -> type != T_EOF)
3255 token = ReadToken(prop, &scanpointer);
3256 if (token -> type == T_EOF) goto finish;
3257
3258 j++; /* Go to next item in items array */
3259
3260 if (items[j] == NULL) {
3261 /* End of line processing. Scan for NewLine */
3262 while(token -> type != T_NL &&
3263 token -> type != T_EOF)
3264 token = ReadToken(prop, &scanpointer);
3265 /* Store rendition */
3266 rendition = XmRenditionCreate(w, name, args, count);
3267 name = "";
3268 count = 0;
3269 /* Reset index into namelist */
3270 j = -1;
3271 /* Free temp strings returned by ReadToken */
3272 for(i = 0; i < freecount; i++) XtFree(freelater[i]);
3273 freecount = 0;
3274 /* Record rendition in array */
3275 if (rarray_count >= rarray_max) {
3276 /* Extend array if necessary */
3277 rarray_max += 10;
3278 rarray = (XmRendition *) XtRealloc((char*) rarray,
3279 sizeof(XmRendition) * rarray_max);
3280 }
3281 if (token -> type == T_EOF) goto finish;
3282 rarray[rarray_count] = rendition;
3283 rarray_count++;
3284 } else if (strcmp(items[j], XmNtag) == 0) {
3285 /* Next item should be a string with the name of the new
3286 rendition to create */
3287 if (token -> type == T_STR) {
3288 name = token -> string;
3289 freelater[freecount] = token -> string; freecount++;
3290 } else {
3291 goto error;
3292 }
3293 } else if (strcmp(items[j], XmNfont) == 0) {
3294 /* If the next item is a number then we have a font
3295 id, otherwise we are reading in a fontset */
3296 if (token -> type != T_INT) goto error;
3297 if (token -> integer != -1) { /* AS IS */
3298 XtSetArg(args[count], XmNfontType, token -> integer); count++;
3299 token = ReadToken(prop, &scanpointer);
3300 if (token -> type != T_STR) goto error;
3301 XtSetArg(args[count], XmNfontName, token -> string); count++;
3302 freelater[freecount] = token -> string; freecount++;
3303 token = ReadToken(prop, &scanpointer);
3304 if (token -> type != T_INT) goto error;
3305 XtSetArg(args[count], XmNloadModel, token -> integer); count++;
3306 }
3307 } else if (strcmp(items[j], XmNtabList) == 0) {
3308 /* This starts with an OPEN then a number of
3309 FLOAT INT INT INT then CLOSE and SEP */
3310 if (token -> type == T_INT) { /* Should be AS IS */
3311 if (token -> integer != -1) goto error;
3312 } else if (token -> type == T_OPEN) {
3313 float value;
3314 int units, align;
3315 XmOffsetModel model;
3316 XmTabList tablist;
3317 XmTab tabs[1];
3318
3319 tablist = NULL;
3320 token = ReadToken(prop, &scanpointer);
3321 while(token -> type != T_CLOSE) {
3322 if (token -> type != T_FLOAT &&
3323 token -> type != T_INT) goto error;
3324 if (token -> type == T_FLOAT)
3325 value = token -> real;
3326 else
3327 value = (float) token -> integer;
3328 token = ReadToken(prop, &scanpointer);
3329 if (token -> type != T_INT) goto error;
3330 units = token -> integer;
3331 token = ReadToken(prop, &scanpointer);
3332 if (token -> type != T_INT) goto error;
3333 align = token -> integer;
3334 token = ReadToken(prop, &scanpointer);
3335 if (token -> type != T_INT) goto error;
3336 model = (XmOffsetModel) token -> integer;
3337 tabs[0] = XmTabCreate(value, units, model, align, NULL);
3338 tablist = XmTabListInsertTabs(tablist, tabs, 1, 1000);
3339 XtFree((char*) tabs[0]);
3340 /* Go to next separator to skip unknown future values */
3341 while(token -> type != T_SEP)
3342 token = ReadToken(prop, &scanpointer);
3343 if (token -> type == T_SEP)
3344 token = ReadToken(prop, &scanpointer);
3345 }
3346 XtSetArg(args[count], XmNtabList, tablist); count++;
3347 } else
3348 goto error;
3349 } else if (strcmp(items[j], XmNbackground) == 0) {
3350 if (token -> type != T_INT) goto error;
3351 if (token -> type != -1) {
3352 XtSetArg(args[count], XmNrenditionBackground, token -> integer); count++;
3353 }
3354 } else if (strcmp(items[j], XmNforeground) == 0) {
3355 if (token -> type != T_INT) goto error;
3356 if (token -> type != -1) {
3357 XtSetArg(args[count], XmNrenditionForeground, token -> integer); count++;
3358 }
3359 } else if (strcmp(items[j], XmNunderlineType) == 0) {
3360 if (token -> type != T_INT) goto error;
3361 if (token -> type != -1) {
3362 XtSetArg(args[count], XmNunderlineType, token -> integer); count++;
3363 }
3364 } else if (strcmp(items[j], XmNstrikethruType) == 0) {
3365 if (token -> type != T_INT) goto error;
3366 if (token -> type != -1) {
3367 XtSetArg(args[count], XmNstrikethruType, token -> integer); count++;
3368 }
3369 }
3370 }
3371
3372 finish:
3373 new_rt = XmRenderTableAddRenditions(new_rt, rarray, rarray_count, XmMERGE_REPLACE);
3374 for (i = 0; i < rarray_count; i++) XmRenditionFree(rarray[i]);
3375 _XmAppUnlock(app);
3376 return(new_rt);
3377
3378 error:
3379 /* Free temp strings returned by ReadToken */
3380 for(i = 0; i < freecount; i++) XtFree((char*) freelater[i]);
3381 freecount = 0;
3382 goto finish;
3383 }
3384
3385 void
XmRenderTableGetDefaultFontExtents(XmRenderTable rendertable,int * height,int * ascent,int * descent)3386 XmRenderTableGetDefaultFontExtents(XmRenderTable rendertable,
3387 int *height,
3388 int *ascent,
3389 int *descent)
3390 {
3391 XmStringTag tag = XmFONTLIST_DEFAULT_TAG;
3392 XmRendition rend;
3393 Boolean success;
3394 short indx;
3395 int h,a,d;
3396
3397 #ifdef XTHREADS
3398 XtAppContext app=NULL;
3399
3400 if ( _XmRTDisplay(rendertable) )
3401 app = XtDisplayToApplicationContext(_XmRTDisplay(rendertable));
3402
3403 if (app)
3404 _XmAppLock(app);
3405 else
3406 _XmProcessLock();
3407 #endif
3408
3409 a = d = h = 0;
3410 /* Get default rendition */
3411 success = _XmRenderTableFindFallback(rendertable, tag, FALSE, &indx, &rend);
3412
3413 /* For backward compatibility we must try to return something for */
3414 /* any non-null charset, not just XmFONTLIST_DEFAULT_TAG. */
3415 if (rendertable && tag && !success)
3416 success = _XmRenderTableFindFirstFont(rendertable, &indx, &rend);
3417
3418 if (success) {
3419 /* Find font height */
3420 switch (_XmRendFontType(rend)) {
3421 case XmFONT_IS_FONT:
3422 if (_XmRendFont(rend)) {
3423 a = ((XFontStruct*)_XmRendFont(rend))->ascent;
3424 d = ((XFontStruct*)_XmRendFont(rend))->descent;
3425 h = a + d;
3426 }
3427 break;
3428 case XmFONT_IS_FONTSET:
3429 if (_XmRendFont(rend)) {
3430 XFontStruct **font_struct_list;
3431 char **font_name_list;
3432
3433 if (XFontsOfFontSet((XFontSet)_XmRendFont(rend),
3434 &font_struct_list, &font_name_list)) {
3435 a = font_struct_list[0]->ascent;
3436 d = font_struct_list[0]->descent;
3437 h = a + d;
3438 }
3439 }
3440 break;
3441 #ifdef USE_XFT
3442 case XmFONT_IS_XFT:
3443 if (_XmRendXftFont(rend)) {
3444 a = _XmRendXftFont(rend)->ascent;
3445 d = _XmRendXftFont(rend)->descent;
3446 h = a + d;
3447 }
3448 break;
3449 #endif
3450 }
3451 }
3452
3453 #ifdef XTHREADS
3454 if (app)
3455 _XmAppUnlock(app);
3456 else
3457 _XmProcessUnlock();
3458 #endif
3459
3460 if (ascent) *ascent = a;
3461 if (descent) *descent = d;
3462 if (height) *height = h;
3463 }
3464