Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / DtHelp / XInterface.c
1 /* $XConsortium: XInterface.c /main/37 1996/11/11 12:28:19 cde-hp $ */
2 /************************************<+>*************************************
3  ****************************************************************************
4  **
5  **   File:        XInterface.c
6  **
7  **   Project:     Cde Help System
8  **
9  **   Description: This is the UI dependant layer to the Help System.
10  **                It recieves requests from the Core Engine for
11  **                information or to do rendering.  It does the
12  **                appropriate work based on a Motif and X Lib
13  **                interface.
14  **
15  **  (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
16  **
17  **  (c) Copyright 1993, 1994 Hewlett-Packard Company
18  **  (c) Copyright 1993, 1994 International Business Machines Corp.
19  **  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
20  **  (c) Copyright 1993, 1994 Novell, Inc.
21  **
22  ****************************************************************************
23  ************************************<+>*************************************/
24
25 /*
26  * system includes
27  */
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include <X11/Xlib.h>
32
33 #include <X11/Xos.h>
34 #ifdef X_NOT_STDC_ENV
35 extern int errno;
36 #endif
37
38 /*
39  * Canvas Engine
40  */
41 #include "CanvasP.h"
42 #include "CanvasSegP.h"
43
44 /*
45  * private includes
46  */
47 #include "AsciiSpcI.h"
48 #include "DisplayAreaP.h"
49 #include "HelpErrorP.h"
50 #include "FontAttrI.h"
51 #include "FontI.h"
52 #include "GraphicsI.h"
53 #include "RegionI.h"
54 #include "StringFuncsI.h"
55 #include "XInterfaceI.h"
56
57 #include <X11/bitmaps/root_weave>
58
59 #ifdef NLS16
60 #endif
61
62 /********    Private Function Declarations    ********/
63 static void     DADrawSpc (
64                         _DtCvPointer    client_data,
65                         _DtCvPointer    spc_handle,
66                         _DtCvUnit       x,
67                         _DtCvUnit       y,
68                         _DtCvUnit       box_x,
69                         _DtCvUnit       box_y,
70                         _DtCvUnit       box_height,
71                         int             link_type,
72                         _DtCvFlags      old_flags,
73                         _DtCvFlags      new_flags );
74 /********    End Private Function Declarations    ********/
75
76 /*****************************************************************************
77  *              Private Defines
78  *****************************************************************************/
79 #define GROW_SIZE       3
80
81 /*****************************************************************************
82  *              Private Macros
83  *****************************************************************************/
84 #define IsHyperLink(x)          ((x) & _DtCvLINK_FLAG)
85 #define IsHyperBegin(x)         ((x) & _DtCvLINK_BEGIN)
86 #define IsHyperEnd(x)           ((x) & _DtCvLINK_END)
87 #define IsPopUp(x)              ((x) & _DtCvLINK_POP_UP)
88 #define IsNewWindow(x)          ((x) & _DtCvLINK_NEW_WINDOW)
89
90 #define HasTraversal(x)         ((x) & _DtCvTRAVERSAL_FLAG)
91 #define IsTraversalBegin(x)     ((x) & _DtCvTRAVERSAL_BEGIN)
92 #define IsTraversalEnd(x)       ((x) & _DtCvTRAVERSAL_END)
93
94 #define IsSelected(x)           ((x) & _DtCvSELECTED_FLAG)
95
96 #define IsMarkOn(x)             (((x) & _DtCvMARK_FLAG) && ((x) & _DtCvMARK_ON))
97
98 #define TocIsOn(x)              ((x) & _DT_HELP_TOC_ON)
99 #define TocIsOff(x)             (!((x) & _DT_HELP_TOC_ON))
100
101 #define TurnTocOn(x)            (x) |= _DT_HELP_TOC_ON
102 #define TurnTocOff(x)           (x) &= ~(_DT_HELP_TOC_ON)
103
104 #define IsEndOfLine(x)          ((x) & _DtCvEND_OF_LINE)
105
106 /*****************************************************************************
107  *              Private Variables
108  *****************************************************************************/
109 static  const char      IsoString[]    = "ISO-8859-1";
110 static  const char      SymbolString[] = "DT-SYMBOL-1";
111 static  const char      DefaultStr[]   = "default_spc";
112
113 #define MAX_STR_LEN     5
114
115 typedef struct {
116         const char      *symbol;
117         const char       spc_string[MAX_STR_LEN];
118         const char      *spc_value;
119 } SpecialSymbolTable;
120
121
122 static  SpecialSymbolTable SpcTable[] =
123
124  {"[aacute]", {'\341','\0'}, IsoString   }, /*ISOlat1, small a, acute accent */ 
125  {"[acirc ]", {'\342','\0'}, IsoString   }, /*ISOlat1, small a, circumflex   */ 
126  {"[aelig ]", {'\346','\0'}, IsoString   }, /*ISOlat1, small ae diphthong    */ 
127  {"[agrave]", {'\340','\0'}, IsoString   }, /*ISOlat1, small a, grave accent */ 
128  {"[alpha ]", {'\141','\0'}, SymbolString}, /*ISOgrk3, Greek, small alpha    */ 
129  {"[aleph ]", {'\300','\0'}, SymbolString}, /*ISOtech, aleph, Hebrews        */ 
130  {"[amp   ]", {  '&' ,'\0'}, IsoString   }, /*ISOnum , ampersand             */ 
131  {"[and   ]", {'\331','\0'}, SymbolString}, /*ISOtech, wedge, logical and    */ 
132  {"[ang   ]", {'\320','\0'}, SymbolString}, /*ISOamso, angle                 */ 
133  {"[angst ]", {'\305','\0'}, IsoString   }, /*ISOtech, Angstrom, cap A, ring */ 
134  {"[ap    ]", {'\273','\0'}, SymbolString}, /*ISOtech, approximately equal   */ 
135  {"[apos  ]", { '\'' ,'\0'}, IsoString   }, /*ISOnum , apostrophe            */ 
136  {"[aring ]", {'\345','\0'}, IsoString   }, /*ISOlat1, small a, ring         */ 
137  {"[ast   ]", {  '*' ,'\0'}, IsoString   }, /*ISOnum , asterisk              */ 
138  {"[atilde]", {'\343','\0'}, IsoString   }, /*ISOlat1, small a, tilde        */ 
139  {"[auml  ]", {'\344','\0'}, IsoString   }, /*ISOlat1, small a, umlaut mark  */ 
140  {"[beta  ]", {'\142','\0'}, SymbolString}, /*ISOgrk3, Greek, small beta     */ 
141  {"[blank ]", {  ' ' ,'\0'}, IsoString   }, /*ISOpub , significant blank     */ 
142  {"[bottom]", {'\136','\0'}, SymbolString}, /*ISOtech, bottom symbol         */ 
143  {"[brvbar]", {'\246','\0'}, IsoString   }, /*ISOnum , broken vertical bar   */ 
144  {"[bsol  ]", { '\\' ,'\0'}, IsoString   }, /*ISOnum , backslash, rev solidus*/ 
145  {"[bull  ]", {'\267','\0'}, SymbolString}, /*ISOpub , round bullet,filled   */ 
146  {"[cap   ]", {'\307','\0'}, SymbolString}, /*ISOtech, intersection          */ 
147  {"[ccedil]", {'\347','\0'}, IsoString   }, /*ISOlat1, small c, cedilla      */ 
148  {"[cent  ]", {'\242','\0'}, IsoString   }, /*ISOnum , cent sign             */ 
149  {"[chi   ]", {'\143','\0'}, SymbolString}, /*ISOgrk3, Greek, small chi      */ 
150  {"[clubs ]", {'\247','\0'}, SymbolString}, /*ISOpub , clubs suit symbol     */ 
151  {"[colon ]", {  ':' ,'\0'}, IsoString   }, /*ISOnum , colon                 */ 
152  {"[comma ]", {  ',' ,'\0'}, IsoString   }, /*ISOnum , comma                 */ 
153  {"[commat]", {  '@' ,'\0'}, IsoString   }, /*ISOnum , commercial at         */ 
154  {"[cong  ]", {'\100','\0'}, SymbolString}, /*ISOtech, congruent with        */ 
155  {"[copy  ]", {'\323','\0'}, SymbolString}, /*ISOnum , copyright symbol      */ 
156  {"[cup   ]", {'\310','\0'}, SymbolString}, /*ISOtech, union or logical sum  */ 
157  {"[curren]", {'\244','\0'}, IsoString   }, /*ISOnum , general currency sign */ 
158  {"[darr  ]", {'\257','\0'}, SymbolString}, /*ISOnum , downward arrow        */ 
159  {"[dArr  ]", {'\337','\0'}, SymbolString}, /*ISOamsa, down double arrow     */ 
160  {"[dash  ]", {  '-' ,'\0'}, IsoString   }, /*ISOpub , dash                  */ 
161  {"[deg   ]", {'\260','\0'}, SymbolString}, /*ISOnum , degree sign           */ 
162  {"[delta ]", {'\144','\0'}, SymbolString}, /*ISOgrk3, Greek, small delta    */ 
163  {"[diams ]", {'\250','\0'}, SymbolString}, /*ISOpub , diamond suit symbol   */ 
164  {"[divide]", {'\270','\0'}, SymbolString}, /*ISOnum , divide sign           */ 
165  {"[dollar]", {  '$' ,'\0'}, IsoString   }, /*ISOnum , dollar sign           */ 
166  {"[eacute]", {'\351','\0'}, IsoString   }, /*ISOlat1, small e, acute accent */ 
167  {"[ecirc ]", {'\352','\0'}, IsoString   }, /*ISOlat1, small e, circumflex   */ 
168  {"[egrave]", {'\350','\0'}, IsoString   }, /*ISOlat1, small e, grave accent */ 
169  {"[empty ]", {'\370','\0'}, IsoString   }, /*ISOamso, empty string          */ 
170  {"[epsiv ]", {'\145','\0'}, SymbolString}, /*ISOgrk3, Greek,sm epsilon, var */ 
171  {"[equals]", {  '=' ,'\0'}, IsoString   }, /*ISOnum , equals sign           */ 
172  {"[equiv ]", {'\272','\0'}, SymbolString}, /*ISOtech, identical with        */ 
173  {"[eta   ]", {'\150','\0'}, SymbolString}, /*ISOgrk3, Greek, small eta      */ 
174  {"[eth   ]", {'\360','\0'}, IsoString   }, /*ISOlat1, small eth, Icelandic  */ 
175  {"[euml  ]", {'\353','\0'}, IsoString   }, /*ISOlat1, small e, umlaut mark  */ 
176  {"[excl  ]", {  '!' ,'\0'}, IsoString   }, /*ISOnum , exclamation mark      */ 
177  {"[exist ]", {'\044','\0'}, SymbolString}, /*ISOtech, at least one exists   */ 
178  {"[forall]", {'\042','\0'}, SymbolString}, /*ISOtech, for all               */ 
179  {"[frac12]", {'\275','\0'}, IsoString   }, /*ISOnum , fraction one-half     */ 
180  {"[frac13]", {'1','/','3','\0'},
181                              IsoString   }, /*ISOnum , fraction one-third    */ 
182  {"[frac14]", {'\274','\0'}, IsoString   }, /*ISOnum , fraction one-quarter  */ 
183  {"[frac15]", {'1','/','5','\0'},
184                              IsoString   }, /*ISOnum , fraction one-fifth    */ 
185  {"[frac16]", {'1','/','6','\0'},
186                              IsoString   }, /*ISOnum , fraction one-sixth    */ 
187  {"[frac18]", {'1','/','8','\0'},
188                              IsoString   }, /*ISOnum , fraction one-eight    */ 
189  {"[frac23]", {'2','/','3','\0'},
190                              IsoString   }, /*ISOnum , fraction two-thirds   */ 
191  {"[frac25]", {'2','/','5','\0'},
192                              IsoString   }, /*ISOnum , fraction two-fifths   */ 
193  {"[frac34]", {'\276','\0'}, IsoString   }, /*ISOnum , fraction three-quarter*/ 
194  {"[frac35]", {'3','/','5','\0'},
195                              IsoString   }, /*ISOnum , fraction three-fifths */ 
196  {"[frac38]", {'3','/','8','\0'},
197                              IsoString   }, /*ISOnum , fraction three-eights */ 
198  {"[frac45]", {'4','/','5','\0'},
199                              IsoString   }, /*ISOnum , fraction four-fifths  */ 
200  {"[frac56]", {'5','/','6','\0'},
201                              IsoString   }, /*ISOnum , fraction five-sixths  */ 
202  {"[frac58]", {'5','/','8','\0'},
203                              IsoString   }, /*ISOnum , fraction five-eights  */ 
204  {"[frac78]", {'7','/','8','\0'},
205                              IsoString   }, /*ISOnum , fraction seven-eights */ 
206  {"[gamma ]", {'\147','\0'}, SymbolString}, /*ISOgrk3, Greek, small gamma    */ 
207  {"[ge    ]", {'\263','\0'}, SymbolString}, /*ISOtech, greater-than-or-equal */ 
208  {"[gt    ]", {  '>' ,'\0'}, IsoString   }, /*ISOnum , greater than sign     */ 
209  {"[half  ]", {'\275','\0'}, IsoString   }, /*ISOnum , fraction one-half     */ 
210  {"[harr  ]", {'\253','\0'}, SymbolString}, /*ISOamsa, left & right arrow    */ 
211  {"[hArr  ]", {'\333','\0'}, SymbolString}, /*ISOamsa, l & r double arrow    */ 
212  {"[hearts]", {'\251','\0'}, SymbolString}, /*ISOpub , hearts suit symbol    */ 
213  {"[hellip]", {'\274','\0'}, SymbolString}, /*ISOpub , ellipsis(horizontal)  */ 
214  {"[horbar]", {'\276','\0'}, SymbolString}, /*ISOnum , horizontal bar        */ 
215  {"[hyphen]", {  '-' ,'\0'}, IsoString   }, /*ISOnum , hyphen                */ 
216  {"[iacute]", {'\355','\0'}, IsoString   }, /*ISOlat1, small i, acute accent */ 
217  {"[icirc ]", {'\356','\0'}, IsoString   }, /*ISOlat1, small i, circumflex   */ 
218  {"[iexcl ]", {'\241','\0'}, IsoString   }, /*ISOnum , inverted ! mark       */ 
219  {"[igrave]", {'\354','\0'}, IsoString   }, /*ISOlat1, small i, grave accent */ 
220  {"[image ]", {'\301','\0'}, SymbolString}, /*ISOamso,imaginary number symbol*/ 
221  {"[infin ]", {'\245','\0'}, SymbolString}, /*ISOtech, infinity              */ 
222  {"[int   ]", {'\246','\0'}, SymbolString}, /*ISOtech, intergral operator    */ 
223  {"[iota  ]", {'\151','\0'}, SymbolString}, /*ISOgrk3, Greek, small iota     */ 
224  {"[iquest]", {'\277','\0'}, IsoString   }, /*ISOnum , inverted ? mark       */ 
225  {"[isin  ]", {'\316','\0'}, SymbolString}, /*ISOtech, set membership        */ 
226  {"[iuml  ]", {'\357','\0'}, IsoString   }, /*ISOlat1, small i, umlaut mark  */ 
227  {"[kappa ]", {'\153','\0'}, SymbolString}, /*ISOgrk3, Greek, small kappa    */ 
228  {"[lambda]", {'\154','\0'}, SymbolString}, /*ISOgrk3, Greek, small lambda   */ 
229  {"[lang  ]", {'\341','\0'}, SymbolString}, /*ISOtech, left angle bracket    */ 
230  {"[laquo ]", {'\253','\0'}, IsoString   }, /*ISOnum , left angle quotation  */ 
231  {"[larr  ]", {'\254','\0'}, SymbolString}, /*ISOnum , leftward arrow        */ 
232  {"[lArr  ]", {'\334','\0'}, SymbolString}, /*ISOtech, is implied by         */ 
233  {"[lcub  ]", {  '{' ,'\0'}, IsoString   }, /*ISOnum , left curly brace      */ 
234  {"[ldquo ]", {  '"' ,'\0'}, IsoString   }, /*ISOnum , left double quote     */ 
235  {"[le    ]", {'\243','\0'}, SymbolString}, /*ISOtech, less-than-or-equal    */ 
236  {"[lowbar]", {  '_' ,'\0'}, IsoString   }, /*ISOnum , low line              */ 
237  {"[lpar  ]", {  '(' ,'\0'}, IsoString   }, /*ISOnum , left parenthesis      */ 
238  {"[lsqb  ]", {  '[' ,'\0'}, IsoString   }, /*ISOnum , left square bracket   */ 
239  {"[lsquo ]", {  '`' ,'\0'}, IsoString   }, /*ISOnum , left single quote     */ 
240  {"[lsquor]", {  ',' ,'\0'}, IsoString   }, /*ISOnum,rising single quote(low)*/ 
241  {"[lt    ]", {  '<' ,'\0'}, IsoString   }, /*ISOnum , less-than sign        */ 
242  {"[mdash ]", {'\276','\0'}, SymbolString}, /*ISOpub , em dash(long dash)    */ 
243  {"[micro ]", {'\155','\0'}, SymbolString}, /*ISOnum , micro                 */ 
244  {"[middot]", {'\267','\0'}, IsoString   }, /*ISOnum , middle dot            */ 
245  {"[minus ]", {  '-' ,'\0'}, IsoString   }, /*ISOtech, minus sign            */ 
246  {"[mldr  ]", {'.','.','.','.','\0'},
247                              IsoString   }, /*ISOpub , em leader             */
248  {"[mnplus]", {'\140','\b','+','\0'},
249                              SymbolString}, /*ISOtech, minus-or-plus sign    */
250  {"[mu    ]", {'\155','\0'}, SymbolString}, /*ISOgrk3, Greek, small mu       */ 
251  {"[nabla ]", {'\321','\0'}, SymbolString}, /*ISOtech, del, Hamilton operator*/ 
252  {"[nbsp  ]", {  ' ' ,'\0'}, IsoString   }, /*ISOnum , no break space        */ 
253  {"[ndash ]", {  '-' ,'\0'}, IsoString   }, /*ISOpub , en dash(short dash)   */ 
254  {"[ne    ]", {'\271','\0'}, SymbolString}, /*ISOtech, not equal             */ 
255  {"[ni    ]", {'\047','\0'}, SymbolString}, /*ISOtech, contains              */ 
256  {"[nldr  ]", {'.','.','\0'},IsoString   }, /*ISOpub , double baseline dot   */
257  {"[not   ]", {'\330','\0'}, SymbolString}, /*ISOnum , not                   */ 
258  {"[notin ]", {'\317','\0'}, SymbolString}, /*ISOtech, negated set membership*/ 
259  {"[ntilde]", {'\361','\0'}, IsoString   }, /*ISOlat1, small N, tilde        */ 
260  {"[nu    ]", {'\156','\0'}, SymbolString}, /*ISOgrk3, Greek, small nu       */ 
261  {"[num   ]", {  '#' ,'\0'}, IsoString   }, /*ISOnum , number sign           */ 
262  {"[oacute]", {'\363','\0'}, IsoString   }, /*ISOlat1, small o, acute accent */ 
263  {"[ocirc ]", {'\364','\0'}, IsoString   }, /*ISOlat1, small o, circumflex   */ 
264  {"[ograve]", {'\362','\0'}, IsoString   }, /*ISOlat1, small o, grave accent */ 
265  {"[ohm   ]", {'\127','\0'}, SymbolString}, /*ISOnum , ohm                   */ 
266  {"[omega ]", {'\167','\0'}, SymbolString}, /*ISOgrk3, Greek, small omega    */ 
267  {"[oplus ]", {'\305','\0'}, SymbolString}, /*ISOamsb, plus sign in circle   */ 
268  {"[or    ]", {'\332','\0'}, SymbolString}, /*ISOtech, vee, logical or       */ 
269  {"[ordf  ]", {'\252','\0'}, IsoString   }, /*ISOnum , ordinal indicator, fem*/ 
270  {"[ordm  ]", {'\272','\0'}, IsoString   }, /*ISOnum , ordinal indicator,male*/ 
271  {"[oslash]", {'\370','\0'}, IsoString   }, /*ISOlat1, small o, slash        */ 
272  {"[osol  ]", {'\306','\0'}, SymbolString}, /*ISOamsb, slash in circle       */ 
273  {"[otilde]", {'\365','\0'}, IsoString   }, /*ISOlat1, small o, tilde        */ 
274  {"[otimes]", {'\304','\0'}, SymbolString}, /*ISOamsb,multiply sign in circle*/ 
275  {"[ouml  ]", {'\366','\0'}, IsoString   }, /*ISOlat1, small o, umlaut mark  */ 
276  {"[over  ]", {'\140','\0'}, SymbolString}, /*made up, over symbol           */ 
277  {"[par   ]", {'\275', '\275', '\0'},
278                              SymbolString}, /*ISOtech, parallel              */ 
279  {"[para  ]", {'\266','\0'}, IsoString   }, /*ISOnum , paragraph sign        */ 
280  {"[part  ]", {'\266','\0'}, SymbolString}, /*ISOtech, partial differential  */ 
281  {"[percnt]", {  '%' ,'\0'}, IsoString   }, /*ISOnum , percent sign          */ 
282  {"[period]", {  '.' ,'\0'}, IsoString   }, /*ISOnum , full stop, period     */ 
283  {"[perp  ]", {'\136','\0'}, SymbolString}, /*ISOtech, perpendicular         */ 
284  {"[phis  ]", {'\146','\0'}, SymbolString}, /*ISOgrk3, Greek, small phi      */ 
285  {"[pi    ]", {'\160','\0'}, SymbolString}, /*ISOgrk3, Greek, small pi       */ 
286  {"[piv   ]", {'\166','\0'}, SymbolString}, /*ISOgrk3, Greek, small pi, var  */ 
287  {"[plus  ]", {  '+' ,'\0'}, IsoString   }, /*ISOnum , plus sign             */ 
288  {"[plusmn]", {'\261','\0'}, SymbolString}, /*ISOnum , plus or minus sign    */ 
289  {"[pound ]", {'\243','\0'}, IsoString   }, /*ISOnum , pound sign            */ 
290  {"[prime ]", {'\242','\0'}, SymbolString}, /*ISOtech, prime or minute       */ 
291  {"[prop  ]", {'\265','\0'}, SymbolString}, /*ISOtech, proportional to       */ 
292  {"[psi   ]", {'\171','\0'}, SymbolString}, /*ISOgrk3, Greek, small psi      */ 
293  {"[quest ]", {  '?' ,'\0'}, IsoString   }, /*ISOnum , question mark         */ 
294  {"[quot  ]", { '\'' ,'\0'}, IsoString   }, /*ISOnum , quote mark            */ 
295  {"[radic ]", {'\326','\0'}, SymbolString}, /*ISOtech, radical               */ 
296  {"[rang  ]", {'\361','\0'}, SymbolString}, /*ISOtech, right angle bracket   */ 
297  {"[raquo ]", {'\273','\0'}, IsoString   }, /*ISOnum , right angle quotation */ 
298  {"[rarr  ]", {'\256','\0'}, SymbolString}, /*ISOnum , rightward arrow       */ 
299  {"[rArr  ]", {'\336','\0'}, SymbolString}, /*ISOtech, rt dbl arrow,implies  */ 
300  {"[rcub  ]", {  '}' ,'\0'}, IsoString   }, /*ISOnum , right curly brace     */ 
301  {"[rdquo ]", {  '"' ,'\0'}, IsoString   }, /*ISOnum , right double quote    */ 
302  {"[real  ]", {'\302','\0'}, SymbolString}, /*ISOamso, real number symbol    */ 
303  {"[reg   ]", {'\322','\0'}, SymbolString}, /*ISOnum,circledR,registered sign*/ 
304  {"[rho   ]", {'\162','\0'}, SymbolString}, /*ISOgrk3, Greek, small rho      */ 
305  {"[rpar  ]", {  ')' ,'\0'}, IsoString   }, /*ISOnum , right parenthesis     */ 
306  {"[rsqb  ]", {  ']' ,'\0'}, IsoString   }, /*ISOnum , right square bracket  */ 
307  {"[rsquo ]", { '\'' ,'\0'}, IsoString   }, /*ISOnum , right single quote    */ 
308  {"[sect  ]", {'\247','\0'}, IsoString   }, /*ISOnum , section sign          */ 
309  {"[semi  ]", {  ';' ,'\0'}, IsoString   }, /*ISOnum , semicolon             */ 
310  {"[shy   ]", {'\255','\0'}, IsoString   }, /*ISOnum , soft hypen            */ 
311  {"[sigma ]", {'\163','\0'}, SymbolString}, /*ISOgrk3, Greek, small sigma    */ 
312  {"[sim   ]", {  '~' ,'\0'}, IsoString   }, /*ISOtech, similar to            */ 
313  {"[sime  ]", {'\100','\0'}, SymbolString}, /*ISOtech, similar, equals       */ 
314  {"[sol   ]", {  '/' ,'\0'}, IsoString   }, /*ISOnum , solidus               */ 
315  {"[spades]", {'\252','\0'}, SymbolString}, /*ISOpub , spades suit symbol    */ 
316  {"[sub   ]", {'\314','\0'}, SymbolString}, /*ISOtech, subset/is implied by  */ 
317  {"[sube  ]", {'\315','\0'}, SymbolString}, /*ISOtech, subset, equals        */ 
318 /*"[sung  ]", { ??   ,'\0'},             }, /*ISOnum , musical note(sung txt)*/ 
319  {"[sup   ]", {'\311','\0'}, SymbolString}, /*ISOtech, superset or implies   */ 
320  {"[sup1  ]", {'\271','\0'}, IsoString   }, /*ISOnum , superscript one       */ 
321  {"[sup2  ]", {'\262','\0'}, IsoString   }, /*ISOnum , superscript two       */ 
322  {"[sup3  ]", {'\263','\0'}, IsoString   }, /*ISOnum , superscript three     */ 
323  {"[supe  ]", {'\312','\0'}, SymbolString}, /*ISOtech, superset, equals      */ 
324  {"[szlig ]", {'\337','\0'}, IsoString   }, /*ISOlat1, small sharp s, German */ 
325  {"[tau   ]", {'\164','\0'}, SymbolString}, /*ISOgrk3, Greek, small tau      */ 
326  {"[there4]", {'\134','\0'}, SymbolString}, /*ISOtech, therefore             */ 
327  {"[thetas]", {'\161','\0'}, SymbolString}, /*ISOgrk3, Greek, small theta    */ 
328  {"[thetav]", {'\112','\0'}, SymbolString}, /*ISOgrk3, Greek, small theta,var*/ 
329  {"[times ]", {'\264','\0'}, SymbolString}, /*ISOnum , multipy sign          */ 
330  {"[thorn ]", {'\376','\0'}, IsoString   }, /*ISOlat1, small thorn, Icelandic*/ 
331  {"[tprime]", {'\242', '\242', '\242', '\0'},
332                              SymbolString}, /*ISOtech, triple prime          */ 
333  {"[trade ]", {'\324','\0'}, SymbolString}, /*ISOnum , trade mark sign       */ 
334  {"[uarr  ]", {'\255','\0'}, SymbolString}, /*ISOnum , upward arrow          */ 
335  {"[uArr  ]", {'\335','\0'}, SymbolString}, /*ISOamsa, up double arrow       */ 
336  {"[uacute]", {'\372','\0'}, IsoString   }, /*ISOlat1, small u, acute accent */ 
337  {"[ucirc ]", {'\373','\0'}, IsoString   }, /*ISOlat1, small u, circumflex   */ 
338  {"[ugrave]", {'\371','\0'}, IsoString   }, /*ISOlat1, small u, grave accent */ 
339  {"[upsi  ]", {'\165','\0'}, SymbolString}, /*ISOgrk3, Greek, small upsilon  */ 
340  {"[uuml  ]", {'\374','\0'}, IsoString   }, /*ISOlat1, small u, umlaut mark  */ 
341  {"[vellip]", {':','\n',':','\0'},
342                              SymbolString}, /*ISOpub , vertical ellipsis     */ 
343  {"[verbar]", {'\174','\0'}, IsoString   }, /*ISOnum , vertical bar          */ 
344  {"[weierp]", {'\303','\0'}, SymbolString}, /*ISOamso, Weierstrass p         */ 
345  {"[xi    ]", {'\170','\0'}, SymbolString}, /*ISOgrk3, Greek, small xi       */ 
346  {"[yacute]", {'\375','\0'}, IsoString   }, /*ISOlat1, small y, acute accent */ 
347  {"[yen   ]", {'\245','\0'}, IsoString   }, /*ISOnum , yen sign              */ 
348  {"[yuml  ]", {'\377','\0'}, IsoString   }, /*ISOlat1, small y, umlaut mark  */ 
349  {"[zeta  ]", {'\172','\0'}, SymbolString}, /*ISOgrk3, Greek, small zeta     */ 
350
351  {"[Aacute]", {'\301','\0'}, IsoString   }, /*ISOlat1, capital a,acute accent*/ 
352  {"[Acirc ]", {'\302','\0'}, IsoString   }, /*ISOlat1, capital a,circumflex  */ 
353  {"[AElig ]", {'\306','\0'}, IsoString   }, /*ISOlat1, capital ae diphthong  */ 
354  {"[Agrave]", {'\300','\0'}, IsoString   }, /*ISOlat1, capital a,grave accent*/ 
355  {"[Aring ]", {'\305','\0'}, IsoString   }, /*ISOlat1, capital a,ring        */ 
356  {"[Atilde]", {'\303','\0'}, IsoString   }, /*ISOlat1, capital a,tilde       */ 
357  {"[Auml  ]", {'\304','\0'}, IsoString   }, /*ISOlat1, capital a,umlaut mark */ 
358  {"[Ccedil]", {'\307','\0'}, IsoString   }, /*ISOlat1, capital c, cedilla    */ 
359  {"[Delta ]", {'\104','\0'}, SymbolString}, /*ISOgrk3, Greek, large delta    */ 
360  {"[Dot   ]", {'\250','\0'}, IsoString   }, /*ISOtech, dieresis or umlaut mrk*/ 
361  {"[DotDot]", {'\250', '\250', '\0'},
362                              IsoString   }, /*ISOtech, four dots above       */ 
363  {"[Eacute]", {'\311','\0'}, IsoString   }, /*ISOlat1, capital E,acute accent*/ 
364  {"[Ecirc ]", {'\312','\0'}, IsoString   }, /*ISOlat1, capital E,circumflex  */ 
365  {"[Egrave]", {'\310','\0'}, IsoString   }, /*ISOlat1, capital E,grave accent*/ 
366  {"[ETH   ]", {'\320','\0'}, IsoString   }, /*ISOlat1, capital Eth, Icelandic*/ 
367  {"[Euml  ]", {'\313','\0'}, IsoString   }, /*ISOlat1, capital E,umlaut mark */ 
368  {"[Gamma ]", {'\107','\0'}, SymbolString}, /*ISOgrk3, Greek, large gamma    */ 
369  {"[Iacute]", {'\315','\0'}, IsoString   }, /*ISOlat1, capital I,acute accent*/ 
370  {"[Icirc ]", {'\316','\0'}, IsoString   }, /*ISOlat1, capital I,circumflex  */ 
371  {"[Igrave]", {'\314','\0'}, IsoString   }, /*ISOlat1, capital I,grave accent*/ 
372  {"[Iuml  ]", {'\317','\0'}, IsoString   }, /*ISOlat1, capital I,umlaut mark */ 
373  {"[Lambda]", {'\114','\0'}, SymbolString}, /*ISOgrk3, Greek, large lambda   */ 
374  {"[Ntilde]", {'\321','\0'}, IsoString   }, /*ISOlat1, capital N, tilde      */ 
375  {"[Oacute]", {'\323','\0'}, IsoString   }, /*ISOlat1, capital O,acute accent*/ 
376  {"[Ocirc ]", {'\324','\0'}, IsoString   }, /*ISOlat1, capital O,circumflex  */ 
377  {"[Ograve]", {'\322','\0'}, IsoString   }, /*ISOlat1, capital O,grave accent*/ 
378  {"[Oslash]", {'\330','\0'}, IsoString   }, /*ISOlat1, capital O, slash      */ 
379  {"[Otilde]", {'\325','\0'}, IsoString   }, /*ISOlat1, capital O, tilde      */ 
380  {"[Omega ]", {'\127','\0'}, SymbolString}, /*ISOgrk3, Greek, large omega    */ 
381  {"[Ouml  ]", {'\326','\0'}, IsoString   }, /*ISOlat1, capital O,umlaut mark */ 
382  {"[Pi    ]", {'\120','\0'}, SymbolString}, /*ISOgrk3, Greek, large pi       */ 
383  {"[Prime ]", {'\262','\0'}, SymbolString}, /*ISOtech, double prime/second   */ 
384  {"[Phi   ]", {'\106','\0'}, SymbolString}, /*ISOgrk3, Greek, large phi      */ 
385  {"[Psi   ]", {'\131','\0'}, SymbolString}, /*ISOgrk3, Greek, large psi      */ 
386  {"[Sigma ]", {'\123','\0'}, SymbolString}, /*ISOgrk3, Greek, large sigma    */ 
387  {"[THORN ]", {'\336','\0'}, IsoString   }, /*ISOlat1,capital THORN,Icelandic*/ 
388  {"[Theta ]", {'\121','\0'}, SymbolString}, /*ISOgrk3, Greek, large theta    */ 
389  {"[Uacute]", {'\332','\0'}, IsoString   }, /*ISOlat1, capital U,acute accent*/ 
390  {"[Ucirc ]", {'\333','\0'}, IsoString   }, /*ISOlat1, capital U,circumflex  */ 
391  {"[Ugrave]", {'\331','\0'}, IsoString   }, /*ISOlat1, capital U,grave accent*/ 
392  {"[Upsi  ]", {'\125','\0'}, SymbolString}, /*ISOgrk3, Greek, large upsilon  */ 
393  {"[Uuml  ]", {'\334','\0'}, IsoString   }, /*ISOlat1, capital U,umlaut mark */ 
394  {"[Verbar]", {'\174', '\174', '\0'},
395                              IsoString   }, /*ISOtech, dbl vertical bar      */ 
396  {"[Xi    ]", {'\130','\0'}, SymbolString}, /*ISOgrk3, Greek, large xi       */ 
397  {"[Yacute]", {'\335','\0'}, IsoString   }, /*ISOlat1, capital Y,acute accent*/ 
398  { NULL     , {' '   ,'\0'}, IsoString   }, /* default character to use      */
399 };
400
401
402 /*****************************************************************************
403  *              Semi-Private Variables
404  *****************************************************************************/
405 /*****************************************************************************
406  *              Private Functions
407  *****************************************************************************/
408 /*****************************************************************************
409  * Function:    _DtCvUnit GetTocIndicator(pDAS);
410  *
411  * Parameters:
412  *
413  * Returns:
414  *
415  * Purpose:
416  *
417  *****************************************************************************/
418 static  _DtHelpFontHints        DefFontAttrs = {
419                 NULL, NULL,
420                 10, 10, NULL,
421                 NULL, NULL, NULL, NULL,
422                 NULL, NULL, NULL, NULL,
423                 _DtHelpFontStyleSerif,
424                 _DtHelpFontSpacingProp,
425                 _DtHelpFontWeightMedium,
426                 _DtHelpFontSlantRoman,
427                 _DtHelpFontSpecialNone };
428
429 static void
430 GetTocIndicator (
431     DtHelpDispAreaStruct        *pDAS)
432 {
433     _DtCvUnit   ascent;
434
435     pDAS->toc_width  = 0;
436     pDAS->toc_height = 0;
437     pDAS->toc_indicator = NULL;
438     if (_DtHelpDAResolveSpc (pDAS, "C", IsoString, DefFontAttrs, "[rArr  ]",
439                              &(pDAS->toc_indicator), &(pDAS->toc_width),
440                              &(pDAS->toc_height), &ascent))
441         _DtHelpDAResolveSpc (pDAS, "C", IsoString, DefFontAttrs, "[ndash ]",
442                              &(pDAS->toc_indicator), &(pDAS->toc_width),
443                              &(pDAS->toc_height), &ascent);
444 }
445
446 static void
447 ClearTocMarker (
448     DtHelpDispAreaStruct        *pDAS,
449     _DtCvFlags                   flag)
450 {
451     _DtCvUnit clearHeight;
452     _DtCvUnit clearWidth;
453     _DtCvUnit clearY      = pDAS->toc_y + pDAS->decorThickness
454                                         - pDAS->firstVisible;
455     _DtCvUnit clearX      = pDAS->decorThickness - pDAS->virtualX;
456
457     clearHeight = pDAS->toc_height;
458     clearWidth  = pDAS->toc_width;
459
460     if (clearY < pDAS->decorThickness)
461       {
462         clearHeight = clearHeight - pDAS->decorThickness + clearY;
463         clearY      = pDAS->decorThickness;
464       }
465     if (clearX < pDAS->decorThickness)
466       {
467         clearWidth = clearWidth - pDAS->decorThickness + clearX;
468         clearX     = pDAS->decorThickness;
469       }
470
471     if (clearWidth > 0 && clearHeight > 0)
472       {
473         if (IsSelected(flag))
474             XFillRectangle (XtDisplay(pDAS->dispWid), XtWindow(pDAS->dispWid),
475                                 pDAS->invertGC,
476                                 clearX, clearY, clearWidth, clearHeight);
477         else
478             XClearArea(XtDisplay(pDAS->dispWid), XtWindow(pDAS->dispWid),
479                         clearX, clearY, clearWidth, clearHeight, False);
480       }
481 }
482
483 /*****************************************************************************
484  * Function:    void DrawTocIndicator ();
485  *
486  * Parameters:
487  *
488  * Returns:
489  *
490  * Purpose:
491  *
492  *****************************************************************************/
493 static void
494 DrawTocIndicator (
495     DtHelpDispAreaStruct *pDAS,
496     _DtCvFlags  flag)
497 {
498
499     if (XtIsRealized(pDAS->dispWid)
500         && TocIsOn(pDAS->toc_flag)
501         && ((int)(pDAS->toc_y+pDAS->toc_height)) >= ((int) pDAS->firstVisible)
502         && ((int)pDAS->toc_y) < ((int)(pDAS->firstVisible+pDAS->dispUseHeight))
503         && pDAS->toc_indicator)
504       {
505         _DtHelpDARegion *regInfo = (_DtHelpDARegion *) pDAS->toc_indicator;
506
507         DADrawSpc (((_DtCvPointer) pDAS), regInfo->handle,
508                         0, pDAS->toc_base,
509                         0, pDAS->toc_y,
510                         pDAS->toc_height, 0, 0, 0);
511       }
512 }
513
514 /*****************************************************************************
515  * Function:    void DrawTraversal ();
516  *
517  * Parameters:
518  *              pDAS    Specifies the display area.
519  *              dst_x   Specifies the inside boundary of the segment.
520  *                      This is where the segment starts, so the
521  *                      traversal box must end at dst_x - 1.
522  *              dst_y   Specifies the upper pixel that the traversal
523  *                      will cover. 
524  *              width   Specifies the inner width of the traversal box.
525  *              height  Specifies the outer height of the traversal box
526  *                      including the leading. But since the leading is
527  *                      also used for the bottom traversal line, its
528  *                      okay.
529  *              flag    Specifies whether to turn the traversal box on
530  *                      or off.
531  *
532  * Returns: Nothing.
533  *
534  * Purpose: Draw the traversal box.
535  *
536  *****************************************************************************/
537 static void
538 DrawTraversal (
539     DtHelpDispAreaStruct        *pDAS,
540     _DtCvUnit   dst_x,
541     _DtCvUnit   dst_y,
542     _DtCvUnit   width,
543     _DtCvUnit   height,
544     _DtCvFlags  flag)
545 {
546     int     copyY1;
547     int     copyY2;
548
549     int     lineX1;
550     int     lineY1;
551     int     lineX2;
552     int     lineY2;
553
554     int     onLeftTop;
555     int     onRightBot;
556     Display     *dpy = XtDisplay(pDAS->dispWid);
557     Window       win = XtWindow(pDAS->dispWid);
558
559     if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
560       {
561         XGCValues saved, gc_values;
562 /*
563  * SYSTEM
564  * see the SYSTEM note in XUICreate.c
565  */
566         /*
567          * how many pixels will be above or to the left of the
568          * destination position.
569          */
570         onLeftTop = pDAS->lineThickness / 2;
571
572         /*
573          * how many pixels will be on and inside the destination.
574          */
575         onRightBot = pDAS->lineThickness - onLeftTop;
576
577         /*
578          * calculate the y position of the traversal lines
579          * for the top and bottom lines.
580          */
581         lineY1 = dst_y + onLeftTop;
582         lineY2 = dst_y + height - onRightBot;
583
584         /*
585          * get the extreme y positions.
586          */
587         copyY1 = dst_y;
588         copyY2 = dst_y + height;
589
590         /*
591          * adjust the source and destination positions.
592          */
593         lineX1 = dst_x;
594         if (IsTraversalBegin (flag))
595             lineX1 = lineX1 - onRightBot;
596
597         lineX2 = dst_x + width;
598         if (IsTraversalEnd (flag))
599             lineX2 = lineX2 + onLeftTop;
600
601         XGetGCValues(dpy, pDAS->normalGC, GCLineStyle | GCForeground, &saved);
602         gc_values.line_style = saved.line_style;
603         if (HasTraversal(flag)) {
604             if (flag & _DtCvAPP_FLAG2) {
605                 XSetForeground (dpy, pDAS->normalGC, pDAS->searchColor);
606                 gc_values.line_style = LineOnOffDash;
607             }
608             else
609                 XSetForeground (dpy, pDAS->normalGC, pDAS->traversalColor);
610         }
611         else
612             XSetForeground (dpy, pDAS->normalGC, pDAS->backgroundColor);
613
614         if (gc_values.line_style != saved.line_style)
615             XChangeGC(dpy, pDAS->normalGC, GCLineStyle, &gc_values);
616
617         /*
618          * draw the top and bottom lines
619          */
620         if (lineX1 - onLeftTop < ((int) pDAS->dispWidth) &&
621                                                 lineX2 + onRightBot - 1 > 0)
622           {
623             /*
624              * draw the top line
625              */
626             if (copyY1 < ((int) pDAS->dispHeight) &&
627                       copyY1 + ((int)pDAS->lineThickness) >
628                                                 ((int)pDAS->decorThickness))
629                 XDrawLine(dpy,win,pDAS->normalGC,lineX1,lineY1,lineX2,lineY1);
630
631             /*
632              * draw the bottom line
633              */
634             if (copyY2 - ((int)pDAS->lineThickness) < ((int)pDAS->dispHeight)
635                                 && copyY2 > ((int)pDAS->decorThickness))
636                 XDrawLine(dpy,win,pDAS->normalGC,lineX1,lineY2,lineX2,lineY2);
637           }
638
639         /*
640          * draw the left end
641          */
642         if (IsTraversalBegin(flag)
643                 && lineX1 - onLeftTop < ((int)pDAS->dispWidth)
644                 && lineX1 + onRightBot - 1 > 0
645                 && copyY1 < ((int) pDAS->dispHeight)
646                 && copyY2 > ((int)pDAS->decorThickness))
647             XDrawLine(dpy, win, pDAS->normalGC, lineX1, copyY1, lineX1, copyY2);
648
649         /*
650          * draw the right end
651          */
652         if (IsTraversalEnd(flag)
653                 && lineX2 - onLeftTop < ((int) pDAS->dispWidth)
654                 && lineX2 + onRightBot - 1 > 0
655                 && copyY1 < ((int) pDAS->dispHeight)
656                 && copyY2 > ((int) pDAS->decorThickness))
657             XDrawLine(dpy, win, pDAS->normalGC, lineX2, copyY1, lineX2, copyY2);
658
659         XSetForeground (dpy, pDAS->normalGC, saved.foreground);
660         XSetFillStyle(dpy, pDAS->normalGC, FillSolid);
661
662         if (gc_values.line_style != saved.line_style)
663             XChangeGC(dpy, pDAS->normalGC, GCLineStyle, &saved);
664       }
665 }
666
667 static void
668 DrawSearchTraversal(DtHelpDispAreaStruct* pDAS,
669                         _DtCvUnit dst_x, _DtCvUnit dst_y,
670                         _DtCvUnit width, _DtCvUnit height, _DtCvFlags flag)
671 {
672     short save = pDAS->neededFlags;
673
674     pDAS->neededFlags |= _DT_HELP_FOCUS_FLAG;
675
676     DrawTraversal(pDAS, dst_x, dst_y, width, height, flag);
677
678     pDAS->neededFlags = save;
679 }
680
681 /*****************************************************************************
682  * Function:    void MyDrawString (Display *dpy, Drawable d, GC gc,
683  *                              int font_index,
684  *                              int x, int y, char *string, int length,
685  *                              int wc, DtHelpDAFontInfo font_info)
686  *
687  * Parameters:
688  *              dpy             Specifies the connection to the X Server.
689  *              d               Specifies the drawable.
690  *              gc              Specifies the graphic's context.
691  *              font_index      Specifies the font structure or set to use.
692  *                              If the value is positive, it indicates a
693  *                              font structure. If negative, it indicates
694  *                              a font set.
695  *              x               Specifies the x coordinate.
696  *              y               Specifies the y coordinate.
697  *              string          Specifies the string to render.
698  *              length          Specifies the number of bytes in 'string'
699  *                              to render.
700  *              wc              Flag to designate wide character data
701  *
702  * Return Value:        Nothing
703  *
704  * Purpose:     Renders an text string to the specified drawable.
705  *
706  *****************************************************************************/
707 static void
708 MyDrawString (
709     Display     *dpy,
710     Drawable     d,
711     GC           gc,
712     int          font_index,
713     int          x,
714     int          y,
715     const void  *string,
716     int          length,
717     int          wc,
718     int          image,
719     DtHelpDAFontInfo    font_info)
720 {
721
722 /*
723  * If the 'font_index' is a negative number, it indicates a font set was
724  * opened for this string. Use the X11R5 I18N routines to render the
725  * glyphs. Otherwise use the standard X11 drawing routines.
726  */
727
728     if (font_index < 0)
729       {
730         XFontSet  mySet;
731
732         mySet = __DtHelpFontSetGet(font_info, font_index);
733
734         if (wc) {
735             if (image)
736                 XwcDrawImageString(dpy, d, mySet, gc, x, y,
737                                                 (wchar_t*)string, length);
738             else
739                 XwcDrawString (dpy, d, mySet, gc, x, y,
740                                                 (wchar_t*)string, length);
741         }
742         else {
743             /*
744              * have to use XmbDrawString here instead of XDrawString
745              * because we need to use a font set to render the string.
746              */
747             if (image)
748                 XmbDrawImageString (dpy, d, mySet, gc, x, y, string, length);
749             else
750                 XmbDrawString (dpy, d, mySet, gc, x, y, string, length);
751         }
752       }
753     else
754       {
755         XFontStruct  *myFont;
756
757         myFont = __DtHelpFontStructGet(font_info, font_index);
758         XSetFont (dpy, gc, myFont->fid);
759
760         if (image)
761             XDrawImageString (dpy, d, gc, x, y, string, length);
762         else
763             XDrawString (dpy, d, gc, x, y, string, length);
764       }
765 }
766
767 /*****************************************************************************
768  * Function:    void ResolveFont ();
769  *
770  * Parameters:
771  *
772  * Returns:
773  *
774  * Purpose:
775  *
776  *****************************************************************************/
777 static int
778 ResolveFont (
779     _DtCvPointer         client_data,
780     char                *lang,
781     const char          *charset,
782     _DtHelpFontHints     font_attr,
783     int                 *ret_idx )
784 {
785     int    result = -1;
786     char  *xlfdSpec = font_attr.xlfd;
787     char   buffer[10];
788     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
789     XrmName     xrmList[_DtHelpFontQuarkNumber];
790
791     _DtHelpCopyDefaultList(xrmList);
792
793     if (font_attr.spacing != _DtHelpFontSpacingProp)
794         xrmList[_DT_HELP_FONT_SPACING] = XrmStringToQuark("m");
795
796     sprintf(buffer, "%d", font_attr.pointsz);
797     xrmList[_DT_HELP_FONT_SIZE]    = XrmStringToQuark(buffer);
798
799     if (font_attr.slant != _DtHelpFontSlantRoman)
800       {
801         xrmList[_DT_HELP_FONT_ANGLE]  = XrmStringToQuark("italic");
802         if (font_attr.xlfdi != NULL)
803             xlfdSpec = font_attr.xlfdi;
804       }
805
806     if (font_attr.weight == _DtHelpFontWeightBold)
807       {
808         xrmList[_DT_HELP_FONT_WEIGHT] = XrmStringToQuark("bold");
809         if (xrmList[_DT_HELP_FONT_ANGLE] == XrmStringToQuark("italic"))
810           {
811             if (font_attr.xlfdib != NULL)
812                 xlfdSpec = font_attr.xlfdib;
813           }
814         else if (font_attr.xlfdb != NULL)
815             xlfdSpec = font_attr.xlfdb;
816       }
817
818     if (font_attr.style == _DtHelpFontStyleSerif)
819         xrmList[_DT_HELP_FONT_TYPE] = XrmStringToQuark("serif");
820     else if (font_attr.style == _DtHelpFontStyleSymbol)
821         xrmList[_DT_HELP_FONT_TYPE] = XrmStringToQuark("symbol");
822
823     xrmList[_DT_HELP_FONT_LANG_TER] = XrmStringToQuark ("C");
824     if (lang != NULL)
825         xrmList[_DT_HELP_FONT_LANG_TER] = XrmStringToQuark(lang);
826
827     if (charset != NULL)
828         xrmList[_DT_HELP_FONT_CHAR_SET] = XrmStringToQuark(charset);
829
830     if (NULL == xlfdSpec ||
831                 _DtHelpGetExactFontIndex(pDAS,lang,charset,xlfdSpec,ret_idx)!=0)
832         result = __DtHelpFontIndexGet (pDAS, xrmList, ret_idx);
833
834     return result;
835 }
836
837 /*****************************************************************************
838  * Function:    void DADrawLine ();
839  *
840  * Parameters:
841  *
842  * Returns:
843  *
844  * Purpose:
845  *
846  *****************************************************************************/
847 static void
848 DADrawLine (
849     _DtCvPointer client_data,
850     _DtCvUnit    x1,
851     _DtCvUnit    y1,
852     _DtCvUnit    x2,
853     _DtCvUnit    y2,
854     _DtCvUnit    line_width)
855 {
856     int          offset;
857     Display     *dpy;
858     Window       win;
859     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
860     XGCValues    saved, gcValues;
861
862     gcValues.line_width = line_width;
863     offset = line_width / 2;
864     dpy    = XtDisplay(pDAS->dispWid);
865     win    = XtWindow(pDAS->dispWid);
866
867     /*
868      * get the current value of the gc.
869      */
870     XGetGCValues(dpy, pDAS->normalGC, GCLineWidth, &saved);
871
872     /*
873      * does the old line width equal the width we want?
874      * If no, then change it to the desired width.
875      */
876     if (line_width != saved.line_width)
877         XChangeGC(dpy, pDAS->normalGC, GCLineWidth, &gcValues);
878
879     /*
880      * drawing a horizontal line?
881      */
882     if (x1 == x2)
883       {
884         x1 += offset;
885         x2  = x1;
886       }
887     else
888       {
889         y1 += offset;
890         y2  = y1;
891       }
892
893     y1 = y1 + pDAS->decorThickness - pDAS->firstVisible;
894     x1 = x1 + pDAS->decorThickness - pDAS->virtualX;
895
896     y2 = y2 + pDAS->decorThickness - pDAS->firstVisible;
897     x2 = x2 + pDAS->decorThickness - pDAS->virtualX;
898
899     XDrawLine (dpy, win, pDAS->normalGC, x1, y1, x2, y2);
900
901     /*
902      * did we change the gc's line_width? If so, change it back.
903      */
904     if (line_width != saved.line_width)
905         XChangeGC(dpy, pDAS->normalGC, GCLineWidth, &saved);
906 }
907
908 /*****************************************************************************
909  * Function:    void DADrawString ();
910  *
911  * Parameters:
912  *              client_data     Specifies the client specific data
913  *                              associated with this canvas.
914  *              x               Specifies the x unit at which the
915  *                              string is to be rendered.
916  *              y               Specifes the y unit at which the baseline
917  *                              of the string is to be rendered.
918  *              string          Specifies the string to render.
919  *              byte_len        Specifies the number of bytes of the
920  *                              string to render.
921  *              char_len        Specifies the number of bytes that
922  *                              comprise one character.
923  *              font_ptr        Specifies the font associated with this
924  *                              string.
925  *              box_x,box_y     Specifies the upper left hand corner of
926  *                              the bounding box for this string. This
927  *                              includes any traversal and/or link offsets
928  *                              relevent for the line this segment occupies.
929  *              box_height      Specifies the maximum height of the bounding
930  *                              box for this string. This includes any
931  *                              traversal and/or offsets relevent to this
932  *                              line.
933  *              old_flags       Specifies .............
934  *              new_flags       Specifies .............
935  *
936  * Returns: Nothing
937  *
938  * Purpose:
939  *
940  *****************************************************************************/
941 static void
942 DADrawString (
943     _DtCvPointer client_data,
944     _DtCvPointer data,
945     _DtCvUnit    x,
946     _DtCvUnit    y,
947     const void  *string,
948     int          byte_len,
949     int          wc,
950     _DtCvPointer font_ptr,
951     _DtCvPointer scd,
952     _DtCvUnit    box_x,
953     _DtCvUnit    box_y,
954     _DtCvUnit    box_height,
955     _DtCvFlags   old_flags,
956     _DtCvFlags   new_flags )
957 {
958     Boolean      image_flag = False;
959     int          strWidth = 0;
960     int          width;
961     Display     *dpy;
962     Window       win;
963     GC           drawGC;
964     GC           fillGC;
965     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
966     _DtCvStringClientData* pSCD = (_DtCvStringClientData*)scd;
967
968     unsigned long mask1 = 0x00; /* to be replaced with highlight attrs */
969     unsigned long mask2 = 0x00; /* to be replaced with stippling attrs */
970     XGCValues gcValues;
971     XGCValues saved1, saved2;
972
973     /*
974      * if this is outside our display area, ignore it.
975      */
976     if (box_y + box_height < pDAS->firstVisible ||
977                         box_y > pDAS->firstVisible + pDAS->dispHeight)
978         return;
979
980     y = y + pDAS->decorThickness - pDAS->firstVisible;
981     x = x + pDAS->decorThickness - pDAS->virtualX;
982
983     box_x = box_x + pDAS->decorThickness - pDAS->virtualX;
984     box_y = box_y + pDAS->decorThickness - pDAS->firstVisible;
985
986     if (byte_len)
987         strWidth = _DtHelpDAGetStrWidth(client_data, _DtCvSTRING_TYPE, data);
988
989     width = strWidth + (x - box_x);
990
991     dpy = XtDisplay(pDAS->dispWid);
992     win = XtWindow(pDAS->dispWid);
993
994     /*
995      * initial colors for rendering.
996      */
997     drawGC = pDAS->normalGC;
998     fillGC = pDAS->invertGC;
999
1000     /*
1001      * is this a search hit or does this string have its own color?
1002      */
1003     if (strWidth && pDAS->dtinfo &&
1004         ((new_flags & _DtCvSEARCH_FLAG) || 
1005                 (NULL != pSCD && (pSCD->fg_color || pSCD->bg_color))))
1006       {
1007         XColor screen, exact;
1008
1009         /*
1010          * indicate that we are going to change the foreground and background.
1011          */
1012         mask1 = (GCForeground | GCBackground);
1013         mask2 = (GCForeground | GCBackground);
1014
1015         /*
1016          * remember the current values of the gc.
1017          */
1018         XGetGCValues(dpy, drawGC, mask1, &saved1);
1019         XGetGCValues(dpy, fillGC, mask2, &saved2);
1020
1021         /* search highlight should precede stylesheet-driven highlights */
1022         /*
1023          * is the search flag set? Set the foreground to the search color.
1024          */
1025         if (new_flags & _DtCvSEARCH_FLAG)
1026           {
1027             XSetForeground(dpy, drawGC, pDAS->searchColor);
1028             XSetBackground(dpy, fillGC, pDAS->searchColor);
1029           }
1030         /*
1031          * is there a foreground color specified?
1032          */
1033         else if (pSCD->fg_color)
1034           {
1035             /*
1036              * does the foreground color need allocating?
1037              */
1038             if (pSCD->fg_pixel == (unsigned long)-1)
1039               {
1040                 if (XAllocNamedColor(dpy, pDAS->colormap, pSCD->fg_color,
1041                                                         &screen, &exact))
1042                   {
1043                     XSetForeground(dpy, drawGC, screen.pixel);
1044                     XSetBackground(dpy, fillGC, screen.pixel);
1045                   }
1046                 else /* the allocation went badly */
1047                   {
1048                     mask1 &= ~GCForeground;
1049                     mask2 &= ~GCBackground;
1050                   }
1051               }
1052             else /* dtinfo has calculated pSCD->fg_pixel */
1053               {
1054                 XSetForeground(dpy, drawGC, pSCD->fg_pixel);
1055                 XSetBackground(dpy, fillGC, pSCD->fg_pixel);
1056               }
1057           }
1058         else /* no foreground color specified */
1059           {
1060             mask1 &= ~GCForeground;
1061             mask2 &= ~GCBackground;
1062           }
1063
1064         /*
1065          * was a background color specified?
1066          */
1067         if (pSCD->bg_color)
1068           {
1069             /*
1070              * does the background color need allocating?
1071              */
1072             if (pSCD->bg_pixel == (unsigned long)-1)
1073               {
1074                 if (XAllocNamedColor(dpy, pDAS->colormap, pSCD->bg_color,
1075                                                         &screen, &exact))
1076                   {
1077                     XSetBackground(dpy, drawGC, screen.pixel);
1078                     XSetForeground(dpy, fillGC, screen.pixel);
1079                   }
1080                 else /* the allocation went badly */
1081                   {
1082                     mask1 &= ~GCBackground;
1083                     mask2 &= ~GCForeground;
1084                   }
1085               }
1086             else /* the background color's been allocated */
1087               {
1088                 XSetBackground(dpy, drawGC, pSCD->bg_pixel);
1089                 XSetForeground(dpy, fillGC, pSCD->bg_pixel);
1090               }
1091           }
1092         else  /* no background color specified */
1093           {
1094             mask1 &= ~GCBackground;
1095             mask2 &= ~GCForeground;
1096           }
1097       }
1098
1099     /*
1100      * if selected, reverse the foreground and background colors
1101      */
1102     if (IsSelected(new_flags))
1103       {
1104         unsigned long   tmpMsk;
1105         GC              tmpGC;
1106
1107         /*
1108          * swap the gc's
1109          */
1110         tmpGC  = drawGC;
1111         drawGC = fillGC;
1112         fillGC = tmpGC;
1113
1114         /*
1115          * swap the saved values!
1116          */
1117         if (mask1 || mask2)
1118           {
1119             /*
1120              * swap the masks!
1121              */
1122             tmpMsk = mask1;
1123             mask1  = mask2;
1124             mask2  = tmpMsk;
1125
1126             /*
1127              * swap the saved values
1128              */
1129             gcValues = saved1;
1130             saved1   = saved2;
1131             saved2   = gcValues;
1132           }
1133       }
1134
1135     /*
1136      * if the segment had the hypertext/mark traversal, turn it off
1137      * this has the added benefit of also turning of the search hit
1138      * traversal.
1139      */
1140     if (HasTraversal(old_flags))
1141         DrawTraversal (pDAS, x, box_y, strWidth, box_height,
1142                                         (old_flags & (~_DtCvTRAVERSAL_FLAG)));
1143
1144     /*
1145      * band-aid for Search traversal support (since it isn't there).
1146      * simply draw a negative search traversal (if the link traversal
1147      * hasn't already blanked it out) for *every* search hit because
1148      * it may have had the current search flag and now doesn't.
1149      */
1150     else if (pDAS->dtinfo && (new_flags & _DtCvSEARCH_FLAG))
1151         DrawSearchTraversal(pDAS, x, box_y, strWidth, box_height,
1152                                 (new_flags & (~_DtCvTRAVERSAL_FLAG)) |
1153                                 _DtCvTRAVERSAL_BEGIN | _DtCvTRAVERSAL_END);
1154
1155     /*
1156      * if the item was selected or is selected, we need to draw the
1157      * inverse video rectangle.
1158      */
1159     if (IsSelected(new_flags) || IsSelected(old_flags)
1160                               || IsMarkOn(new_flags) || IsMarkOn(old_flags))
1161         image_flag = True;
1162
1163     /*
1164      * do we need to allocate the stipple pattern?
1165      */
1166     if (IsMarkOn(new_flags) && None == pDAS->stipple)
1167         pDAS->stipple = XCreateBitmapFromData(dpy, win, root_weave_bits,
1168                                           root_weave_width, root_weave_height);
1169
1170
1171     /*
1172      * do we need to draw a rectangle?
1173      */
1174     if (image_flag)
1175       {
1176         _DtCvUnit eff_x, eff_width;
1177
1178         /*
1179          * do we need to stipple the rectangle for marks?
1180          */
1181         if (pDAS->dtinfo && IsMarkOn(new_flags) && None != pDAS->stipple)
1182           {
1183             /*
1184              * include the fill style and stipple in the mask.
1185              * it will be used later to restore the gc.
1186              *
1187              * Don't bother to reset the stipple pattern. As long
1188              * as FillStyle is set to FillSolid (or FillTiled)
1189              * the stipple is ignored.
1190              */
1191             mask2 = mask2 | GCFillStyle;
1192             XSetFillStyle(dpy, fillGC, FillOpaqueStippled);
1193             XSetStipple(dpy, fillGC, pDAS->stipple);
1194
1195             /*
1196              * initialize the saved fill_style and stipple fields
1197              * to what they should be restored to.
1198              */
1199             saved2.fill_style = FillSolid;
1200           }
1201
1202         if (HasTraversal(new_flags) && IsTraversalEnd(new_flags))
1203             width += pDAS->lineThickness;
1204
1205         eff_x     = box_x;
1206         eff_width = width;
1207
1208         if (pDAS->dtinfo) {
1209             /*
1210              * search rending info
1211              */
1212             if (new_flags & _DtCvAPP_FLAG3) {
1213                 eff_x     += pDAS->lineThickness;
1214                 eff_width -= pDAS->lineThickness;
1215             }
1216             else if (new_flags & _DtCvAPP_FLAG4)
1217                 eff_width += pDAS->lineThickness;
1218         }
1219
1220         XFillRectangle (dpy, win, fillGC, eff_x, (int) box_y,
1221                                         eff_width, box_height);
1222       }
1223
1224     if (strWidth)
1225       {
1226         MyDrawString (dpy, win, drawGC,
1227                         (int) font_ptr,
1228                         (int) x, (int) y, string, byte_len,
1229                         wc, False, pDAS->font_info);
1230
1231         if (pDAS->dtinfo && NULL != pSCD) {
1232             _DtCvUnit line_y;
1233             if (pSCD->hilite_type & hilite_underline) {
1234                 line_y = box_y + box_height - pDAS->lineThickness / 2;
1235                 XDrawLine (dpy, win, drawGC, x, line_y, x + strWidth, line_y);
1236             }
1237             if (pSCD->hilite_type & hilite_strikethrough) {
1238                 line_y = box_y + box_height / 2;
1239                 XDrawLine (dpy, win, drawGC, x, line_y, x + strWidth, line_y);
1240             }
1241             if (pSCD->hilite_type & hilite_overline) {
1242                 line_y = box_y + pDAS->lineThickness / 2;
1243                 XDrawLine (dpy, win, drawGC, x, line_y, x + strWidth, line_y);
1244             }
1245         }
1246
1247         if (IsHyperLink(new_flags))
1248           {
1249             y   = y + pDAS->underLine;
1250
1251             if (IsPopUp(new_flags))
1252               {
1253                 gcValues.line_style = LineOnOffDash;
1254                 XChangeGC (dpy, drawGC, GCLineStyle, &gcValues);
1255               }
1256
1257             XDrawLine (dpy, win, drawGC, (int) x, (int) y,
1258                                                 (int) (x + strWidth), (int) y);
1259
1260             if (IsPopUp(new_flags))
1261               {
1262                 gcValues.line_style = LineSolid;
1263                 XChangeGC (dpy, drawGC, GCLineStyle, &gcValues);
1264               }
1265           }
1266       }
1267
1268     /*
1269      * draw the traversal first
1270      */
1271     if (HasTraversal(new_flags))
1272         DrawTraversal (pDAS, x, box_y, strWidth, box_height, new_flags);
1273
1274     /*
1275      * draw the search traversal
1276      */
1277     if (pDAS->dtinfo && (new_flags & _DtCvAPP_FLAG2)) {
1278         _DtCvFlags eff_flags = new_flags;
1279         eff_flags |= _DtCvTRAVERSAL_FLAG;
1280         if (new_flags & _DtCvSEARCH_BEGIN)
1281             eff_flags |= _DtCvTRAVERSAL_BEGIN;
1282         else
1283             eff_flags &= ~_DtCvTRAVERSAL_BEGIN;
1284
1285         if (new_flags & _DtCvSEARCH_END)
1286             eff_flags |= _DtCvTRAVERSAL_END;
1287         else
1288             eff_flags &= ~_DtCvTRAVERSAL_END;
1289
1290         DrawSearchTraversal(pDAS, x, box_y, strWidth, box_height, eff_flags);
1291     }
1292
1293     /*
1294      * restore the gcs.
1295      */
1296     if (mask1)
1297         XChangeGC(dpy, drawGC, mask1, &saved1);
1298     if (mask2)
1299         XChangeGC(dpy, fillGC, mask2, &saved2);
1300 }
1301
1302 /*****************************************************************************
1303  * Function:    void DADrawSpc ();
1304  *
1305  * Parameters:
1306  *              client_data     Specifies the client specific data
1307  *                              associated with this canvas.
1308  *              spc_handle      Specifies the handle of the special
1309  *                              character to render.
1310  *              x               Specifies the x unit at which the
1311  *                              spc is to be rendered.
1312  *              y               Specifes the y unit at which the baseline
1313  *                              of the spc is to be rendered.
1314  *              box_x,box_y     Specifies the upper left hand corner of
1315  *                              the bounding box for this string. This
1316  *                              includes any traversal and/or link offsets
1317  *                              relevent for the line this segment occupies.
1318  *              box_height      Specifies the maximum height of the bounding
1319  *                              box for this string. This includes any
1320  *                              traversal and/or offsets relevent to this
1321  *                              line.
1322  *              link_type       Specifies the link type if this spc is
1323  *                              part of a link.
1324  *              old_flags       Specifies .............
1325  *              new_flags       Specifies .............
1326  *
1327  * Returns:
1328  *
1329  * Purpose:
1330  *
1331  *****************************************************************************/
1332 static void
1333 DADrawSpc (
1334     _DtCvPointer client_data,
1335     _DtCvPointer spc_handle,
1336     _DtCvUnit    x,
1337     _DtCvUnit    y,
1338     _DtCvUnit    box_x,
1339     _DtCvUnit    box_y,
1340     _DtCvUnit    box_height,
1341     int          link_type,
1342     _DtCvFlags   old_flags,
1343     _DtCvFlags   new_flags )
1344 {
1345     int                   i;
1346     int                   spcLstIdx = (int) spc_handle;
1347     _DtCvUnit             ascent;
1348     _DtCvUnit             descent;
1349     const char           *spcStr;
1350     DtHelpDispAreaStruct *pDAS      = (DtHelpDispAreaStruct *) client_data;
1351     _DtCvStringInfo       strInfo;
1352
1353     if (pDAS->max_spc == 0)
1354         return;
1355
1356     spcStr    = SpcTable[pDAS->spc_chars[spcLstIdx].spc_idx].spc_string;
1357     _DtHelpDAGetFontMetrics(client_data, pDAS->spc_chars[spcLstIdx].font_ptr,
1358                                         &ascent, &descent, NULL, NULL, NULL);
1359
1360     do
1361       {
1362         /*
1363          * display the string up to the next newline or backspace
1364          */
1365         i = 0;
1366         while ('\0' != spcStr[i] && '\n' != spcStr[i] && '\b' != spcStr[i])
1367             i++;
1368
1369         strInfo.string   = (void *) spcStr;
1370         strInfo.byte_len = i;
1371         strInfo.wc       = 0;
1372         strInfo.font_ptr = (_DtCvPointer)(pDAS->spc_chars[spcLstIdx].font_ptr);
1373
1374         DADrawString (client_data, (_DtCvPointer) &strInfo, x, y,
1375                         spcStr, i, 0,
1376                         pDAS->spc_chars[spcLstIdx].font_ptr, NULL,
1377                         box_x, box_y, box_height, old_flags,
1378                         new_flags);
1379
1380         /*
1381          * if we are looking at a newline character, that means that
1382          * the special character takes up several 'lines' of height.
1383          * So increment the next y position to go to the next 'line'.
1384          */
1385         if ('\n' == spcStr[i])
1386             y  = y + ascent + descent;
1387
1388         /*
1389          * if we are looking at a newline or a backspace, skip over it.
1390          */
1391         if ('\n' == spcStr[i] || '\b' == spcStr[i])
1392             i++;
1393
1394         /*
1395          * reset the string pointer.
1396          */
1397         spcStr += i;
1398
1399         /*
1400          * do this while there is any string to display.
1401          */
1402       } while ('\0' != *spcStr);
1403 }
1404
1405 /*****************************************************************************
1406  * Function:    void DADrawGraphic ();
1407  *
1408  * Parameters:
1409  *
1410  * Returns:
1411  *
1412  * Purpose:
1413  *
1414  *****************************************************************************/
1415 static void
1416 DADrawGraphic (
1417     _DtCvPointer client_data,
1418     _DtCvPointer graphic_ptr,
1419     _DtCvUnit    x,
1420     _DtCvUnit    y,
1421     _DtCvUnit    box_width,
1422     _DtCvUnit    box_height,
1423     _DtCvFlags   old_flags,
1424     _DtCvFlags   new_flags )
1425 {
1426     int    width;
1427     int    height;
1428     int    old_x;
1429     int    old_y;
1430     int    srcX;
1431     int    srcY;
1432
1433     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
1434     DtHelpGraphicStruct  *pGS  = (DtHelpGraphicStruct *)     graphic_ptr;
1435     Display              *dpy  = XtDisplay(pDAS->dispWid);
1436     Window                win  = XtWindow(pDAS->dispWid);
1437     XGCValues    gcValues;
1438
1439     /*
1440      * adjust for the scrolled window.
1441      */
1442     y = y + pDAS->decorThickness - pDAS->firstVisible;
1443     x = x + pDAS->decorThickness - pDAS->virtualX;
1444
1445     /*
1446      * save away.
1447      */
1448     old_x = x;
1449     old_y = y;
1450
1451     /*
1452      * adjust to get the correct y position for the graphic.
1453      */
1454     y = y + box_height - pGS->height - 1;
1455
1456     /*
1457      * add the line thickness of the traversal to the height.
1458      */
1459     if (HasTraversal(old_flags))
1460         DrawTraversal (pDAS, old_x, old_y, pGS->width, box_height,
1461                         (old_flags & (~_DtCvTRAVERSAL_FLAG)));
1462
1463     srcX   = 0;
1464     srcY   = 0;
1465     width  = pGS->width;
1466     height = 0;
1467
1468     /*
1469      * Check and adjust the width of the graphic if it is
1470      * to be displayed
1471      */
1472     if (x < 0)
1473       {
1474         srcX  = srcX - x;
1475         width = width + x;
1476         x     = 0;
1477       }
1478
1479     if (width > 0)
1480       {
1481         height = pGS->height;
1482
1483         if (y < pDAS->decorThickness)
1484           {
1485             srcY    = pDAS->decorThickness - y;
1486             height -= srcY;
1487             y       = pDAS->decorThickness;
1488           }
1489         if (y + height > ((int)(pDAS->dispHeight - pDAS->decorThickness)))
1490             height = pDAS->dispHeight - pDAS->decorThickness - y;
1491       }
1492
1493     /*
1494      * If we found something to write out,
1495      * height and width will/should be greater than zero.
1496      */
1497     if (height > 0 && width > 0)
1498         XCopyArea (dpy, pGS->pix, win, pDAS->normalGC,
1499                                         srcX, srcY, width, height, x, y);
1500
1501
1502     if (HasTraversal(new_flags))
1503         DrawTraversal (pDAS, old_x, old_y, pGS->width, box_height, new_flags);
1504
1505     else if (IsHyperLink(new_flags))
1506       {
1507         int x,y;
1508
1509         XSetFillStyle(dpy, pDAS->normalGC, FillTiled);
1510
1511         if (IsPopUp(new_flags))
1512           {
1513             gcValues.line_style = LineOnOffDash;
1514             XChangeGC (dpy, pDAS->normalGC, GCLineStyle, &gcValues);
1515           }
1516
1517         x   = old_x + 2;
1518         y   = old_y + pDAS->lineThickness / 2;
1519
1520         XDrawLine(dpy, win, pDAS->normalGC, x, y, x + box_width - 4, y);
1521
1522         y   = old_y + box_height - pDAS->lineThickness
1523                                                 + pDAS->lineThickness / 2;
1524
1525         XDrawLine(dpy, win, pDAS->normalGC, x, y, x + box_width - 4, y);
1526
1527         y   = old_y + 2;
1528         x   = old_x - pDAS->lineThickness + pDAS->lineThickness / 2;
1529
1530         XDrawLine(dpy, win, pDAS->normalGC, x, y, x, y + box_height - 4);
1531
1532         x   = old_x + box_width + pDAS->lineThickness / 2;
1533
1534         XDrawLine(dpy, win, pDAS->normalGC, x, y, x, y + box_height - 4);
1535
1536         if (IsPopUp(new_flags))
1537           {
1538             gcValues.line_style = LineSolid;
1539             XChangeGC (dpy, pDAS->normalGC, GCLineStyle, &gcValues);
1540           }
1541         XSetFillStyle(dpy, pDAS->normalGC, FillSolid);
1542       }
1543 }
1544
1545 /*****************************************************************************
1546  * Function:    _DtCvPointer DABuildSelectedString ();
1547  *
1548  * Parameters:
1549  *
1550  * Returns:
1551  *
1552  * Purpose:
1553  *
1554  *****************************************************************************/
1555 static _DtCvStatus
1556 DABuildSelectedString (
1557     _DtCvPointer         client_data,
1558     _DtCvPointer        *prev_info,
1559     const char          *string,
1560     int                  byte_len,
1561     int                  wc,
1562     _DtCvPointer         font_ptr,
1563     _DtCvUnit            space,
1564     _DtCvFlags           flags )
1565 {
1566     int    i;
1567     int    j;
1568     int    mbLen;
1569     int    totalLen;
1570     int    spaceNum  = 0;
1571     int    stringLen = 0;
1572     long   spaceLong = space * 10;
1573     char  *myString  = (char *)(*prev_info);
1574     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
1575
1576     if (spaceLong > 0)
1577         spaceNum = (int) (spaceLong / pDAS->charWidth +
1578                 ((spaceLong % pDAS->charWidth) < pDAS->charWidth / 2 ? 0 : 1));
1579
1580     if (string == NULL)
1581         byte_len = 0;
1582
1583     /*
1584      * if we are processing a wide character string, we need to
1585      * allocate MB_CUR_MAX bytes per character
1586      */
1587     mbLen = 1;
1588     if (0 != wc)
1589         mbLen = MB_CUR_MAX;
1590
1591     totalLen = byte_len * mbLen + spaceNum + 1 + (IsEndOfLine(flags) ? 1 : 0);
1592
1593     /*
1594      * allocate the string
1595      */
1596     if (myString == NULL)
1597         myString = (char *) malloc (sizeof(char) * totalLen);
1598     else
1599       {
1600         stringLen = strlen(myString);
1601         myString  = (char *) realloc ((void *) myString,
1602                                 (sizeof(char) * (stringLen + totalLen)));
1603       }
1604
1605     if (myString == NULL)
1606         return _DtCvSTATUS_BAD;
1607
1608     /*
1609      * tack on the leading spaces.
1610      */
1611     for (i = stringLen; spaceNum > 0; spaceNum--)
1612         myString[i++] = ' ';
1613
1614     /*
1615      * now tack on the characters.
1616      */
1617     if (0 != wc)
1618       {
1619         /*
1620          * have to translate the wide character into a multi-byte
1621          * character.
1622          */
1623         wchar_t  *wStr = (wchar_t *) string;
1624
1625         for (j = 0; 0 < byte_len; byte_len--)
1626           {
1627             /*
1628              * convert the next character
1629              */
1630             mbLen = wctomb(&myString[i], wStr[j++]);
1631
1632             /*
1633              * if a valid character, increase the destination pointer
1634              */
1635             if (0 <= mbLen)
1636                 i += mbLen;
1637           }
1638       }
1639     else
1640         /*
1641          * transfer the single byte string to the destination string
1642          */
1643         for (j = 0; byte_len > 0 && string[j] != '\0'; byte_len--)
1644             myString[i++] = string[j++];
1645
1646     if (flags)
1647         myString[i++] = '\n';
1648
1649     myString[i] = '\0';
1650
1651     *prev_info = (_DtCvPointer) myString;
1652
1653     return _DtCvSTATUS_OK;
1654 }
1655
1656 /*****************************************************************************
1657  * Function:    _DtCvPointer DABuildSelectedSpc ();
1658  *
1659  * Parameters:
1660  *
1661  * Returns:
1662  *
1663  * Purpose:
1664  *
1665  *****************************************************************************/
1666 static _DtCvStatus
1667 DABuildSelectedSpc (
1668     _DtCvPointer         client_data,
1669     _DtCvPointer        *prev_info,
1670     _DtCvPointer         spc_handle,
1671     _DtCvUnit            space,
1672     _DtCvFlags           flags )
1673 {
1674     int    spcIdx = (int) spc_handle;
1675     int    i;
1676     int    totalLen;
1677     int    spaceNum  = 0;
1678     int    stringLen = 0;
1679     long   spaceLong = space * 10;
1680     const char *spcStr;
1681     char  *myString  = (char *)(*prev_info);
1682     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
1683
1684     /*
1685      * find the ascii version of this spc
1686      */
1687     spcIdx = pDAS->spc_chars[spcIdx].spc_idx;
1688     spcStr = _DtHelpCeResolveSpcToAscii(SpcTable[spcIdx].symbol);
1689
1690     if (spcStr == NULL)
1691         return _DtCvSTATUS_BAD;
1692
1693     /*
1694      * get the length to realloc
1695      */
1696     totalLen = strlen(spcStr);
1697
1698     if (spaceLong > 0)
1699         spaceNum = (int)(spaceLong / pDAS->charWidth +
1700                 ((spaceLong % pDAS->charWidth) < pDAS->charWidth / 2 ? 0 : 1));
1701
1702     totalLen = totalLen + spaceNum + 1 + (IsEndOfLine(flags) ? 1 : 0);
1703
1704     if (myString == NULL)
1705         myString = (char *) malloc (sizeof(char) * totalLen);
1706     else
1707       {
1708         stringLen = strlen(myString);
1709         myString  = (char *) realloc ((void *) myString,
1710                                 (sizeof(char) * (stringLen + totalLen)));
1711       }
1712
1713     if (myString == NULL)
1714         return _DtCvSTATUS_BAD;
1715
1716     for (i = stringLen; spaceNum > 0; spaceNum--)
1717         myString[i++] = ' ';
1718
1719     while (*spcStr != '\0')
1720         myString[i++] = *spcStr++;
1721
1722     if (flags)
1723         myString[i++] = '\n';
1724
1725     myString[i] = '\0';
1726
1727     *prev_info = (_DtCvPointer) myString;
1728     return _DtCvSTATUS_OK;
1729 }
1730
1731 /*****************************************************************************
1732  *              Semi-Public Functions
1733  *****************************************************************************/
1734 /*****************************************************************************
1735  * Function:    char * _DtHelpDAGetSpcString ();
1736  *
1737  * Parameters:
1738  *
1739  * Returns:
1740  *
1741  * Purpose:
1742  *
1743  *****************************************************************************/
1744 const char *
1745 _DtHelpDAGetSpcString (
1746     int         idx)
1747 {
1748     return (SpcTable[idx].spc_string);
1749 }
1750
1751 /*****************************************************************************
1752  * Function:    void _DtHelpDAResolveFont ();
1753  *
1754  * Parameters:
1755  *
1756  * Returns:
1757  *
1758  * Purpose:
1759  *
1760  *****************************************************************************/
1761 void
1762 _DtHelpDAResolveFont (
1763     _DtCvPointer         client_data,
1764     char                *lang,
1765     const char          *charset,
1766     _DtHelpFontHints     font_attr,
1767     _DtCvPointer        *ret_font )
1768 {
1769     /*
1770      * note - if the mod_string comes in with a NULL pointer,
1771      * it came from our own call rather than the Core Engine.
1772      */
1773     int idx;
1774
1775     (void) ResolveFont(client_data, lang, charset, font_attr, &idx);
1776     *ret_font = (_DtCvPointer) idx;
1777 }
1778
1779 /*****************************************************************************
1780  * Function:    _DtCvStatus _DtHelpDAResolveSpc ();
1781  *
1782  * Parameters:
1783  *
1784  * Returns:
1785  *
1786  * Purpose:
1787  *
1788  *****************************************************************************/
1789 _DtCvStatus
1790 _DtHelpDAResolveSpc (
1791     _DtCvPointer         client_data,
1792     char                *lang,
1793     const char          *charset,
1794     _DtHelpFontHints     font_attr,
1795     const char          *spc_symbol,
1796     _DtCvPointer        *ret_handle,
1797     _DtCvUnit           *ret_width,
1798     _DtCvUnit           *ret_height,
1799     _DtCvUnit           *ret_ascent)
1800 {
1801     register int          i = 0;
1802     int                   result = -1;
1803     int                   fontIdx;
1804     int                   spcTbIdx = 0;
1805     _DtCvUnit             ascent;
1806     _DtCvUnit             descent;
1807     const char           *newSet;
1808     const char           *spcStr;
1809     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
1810     _DtCvStringInfo       strInfo;
1811
1812     while (SpcTable[spcTbIdx].symbol != NULL &&
1813                         strcmp(SpcTable[spcTbIdx].symbol, spc_symbol) != 0)
1814         spcTbIdx++;
1815
1816     newSet = SpcTable[spcTbIdx].spc_value;
1817     spcStr = SpcTable[spcTbIdx].spc_string;
1818
1819     result = ResolveFont(client_data, lang, newSet, font_attr, &fontIdx);
1820
1821     if (result == 0)
1822       {
1823         int              spcLstIdx = 0;
1824         _DtCvUnit        maxWidth;
1825         _DtHelpDARegion *pReg;
1826
1827         pReg = (_DtHelpDARegion *) malloc (sizeof(_DtHelpDARegion));
1828         if (NULL == pReg)
1829             return -1;
1830
1831         while (spcLstIdx < pDAS->cur_spc &&
1832                                 pDAS->spc_chars[spcLstIdx].spc_idx != -1)
1833             spcLstIdx++;
1834
1835         if (spcLstIdx == pDAS->cur_spc)
1836           {
1837             if (pDAS->cur_spc >= pDAS->max_spc)
1838               {
1839                 pDAS->max_spc += GROW_SIZE;
1840                 if (pDAS->cur_spc > 0)
1841                     pDAS->spc_chars = (DtHelpSpecialChars *) realloc(
1842                                 (void *)pDAS->spc_chars,
1843                                 (sizeof(DtHelpSpecialChars)*pDAS->max_spc));
1844                 else
1845                     pDAS->spc_chars = (DtHelpSpecialChars *) malloc(
1846                                 (sizeof(DtHelpSpecialChars)*pDAS->max_spc));
1847
1848                 if (pDAS->spc_chars == NULL)
1849                     return -1;
1850
1851                 for (i = pDAS->cur_spc; i < pDAS->max_spc; i++)
1852                     pDAS->spc_chars[i].spc_idx = -1;
1853               }
1854             pDAS->cur_spc++;
1855           }
1856
1857         pDAS->spc_chars[spcLstIdx].font_ptr = (_DtCvPointer)fontIdx;
1858         pDAS->spc_chars[spcLstIdx].spc_idx  = spcTbIdx;
1859
1860         /*
1861          * fill in the region information
1862          */
1863         pReg->inited = True;
1864         pReg->type   = _DtHelpDASpc;
1865         pReg->handle = (_DtCvPointer) spcLstIdx;
1866
1867         /*
1868          * fill out the return information
1869          */
1870         *ret_handle = (_DtCvPointer) pReg;
1871
1872         *ret_height = 0;
1873         *ret_width  = 0;
1874
1875         /*
1876          * get the maximum ascent and descent for the font. Set the return
1877          * ascent.
1878          */
1879         _DtHelpDAGetFontMetrics(client_data, (_DtCvPointer)fontIdx,
1880                                         &ascent, &descent, NULL, NULL, NULL);
1881         *ret_ascent = ascent;
1882
1883         /*
1884          * now go through the string and get the maximum width
1885          * and total height of the special character.
1886          */
1887         do
1888           {
1889             /*
1890              * find the first 'break' in the string sequence.
1891              */
1892             i = 0;
1893             while ('\0' != spcStr[i] && '\n' != spcStr[i] && '\b' != spcStr[i])
1894                 i++;
1895
1896             /*
1897              * set the height if it is zero or if this is a multi-height
1898              * special character.
1899              */
1900             if ('\n' == spcStr[i] || 0 == *ret_height)
1901                 *ret_height = *ret_height + ascent + descent;
1902
1903             /*
1904              * now get the maximum width of the special character.
1905              */
1906             strInfo.string   = spcStr;
1907             strInfo.byte_len = i;
1908             strInfo.wc       = 0;
1909             strInfo.font_ptr = (_DtCvPointer)fontIdx;
1910
1911             maxWidth  = _DtHelpDAGetStrWidth (client_data, _DtCvSTRING_TYPE,
1912                                                 (_DtCvPointer) &strInfo);
1913             if (*ret_width < maxWidth)
1914                 *ret_width = maxWidth;
1915
1916             /*
1917              * if this is a multi-height or a composite character
1918              * skip the newline or backspace.
1919              */
1920             if ('\n' == spcStr[i] || '\b' == spcStr[i])
1921                 i++;
1922
1923             /*
1924              * reset the string pointer
1925              */
1926             spcStr += i;
1927           } while (*spcStr != '\0');
1928         result = 0;
1929       }
1930     else if (spc_symbol != DefaultStr)
1931         result = _DtHelpDAResolveSpc (client_data, lang, charset,
1932                                         font_attr, DefaultStr,
1933                                         ret_handle, ret_width,
1934                                         ret_height, ret_ascent);
1935     return result;
1936 }
1937
1938
1939 /*****************************************************************************
1940  * Function:    _DtCvStatus GraphicLoad ();
1941  *
1942  * Parameters:
1943  *
1944  * Returns:
1945  *
1946  * Purpose:
1947  *
1948  *****************************************************************************/
1949 _DtCvStatus
1950 _DtHelpDALoadGraphic (
1951     _DtCvPointer client_data,
1952     char        *vol_xid,
1953     char        *topic_xid,
1954     char        *file_xid,
1955     char        *format,
1956     char        *method,
1957     _DtCvUnit   *ret_width,
1958     _DtCvUnit   *ret_height,
1959     _DtCvPointer *ret_region)
1960 {
1961     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
1962     DtHelpGraphicStruct  *pGS;
1963     _DtHelpDARegion      *pReg;
1964     Widget                wid;
1965     Window                win;
1966     char                 *ptr;
1967     char                 *extptr;
1968     char                 *fileName = file_xid;        
1969     Screen               *retScr;
1970     int                  screen;
1971
1972     pGS  = (DtHelpGraphicStruct *) malloc (sizeof(DtHelpGraphicStruct));
1973     pReg = (_DtHelpDARegion     *) malloc (sizeof(_DtHelpDARegion));
1974     if (pGS == NULL || NULL == pReg)
1975       {
1976         if (NULL != pGS)
1977             free(pGS);
1978         if (NULL != pReg)
1979             free(pReg);
1980         return -1;
1981       }
1982
1983     wid = pDAS->dispWid;
1984     retScr = XtScreen(wid);
1985     screen = XScreenNumberOfScreen(retScr);
1986
1987     while (!XtIsRealized(wid) && XtParent(wid) != NULL)
1988         wid = XtParent(wid);
1989
1990     win = XtWindow(wid);
1991     if (!XtIsRealized(wid))
1992         win = RootWindow(XtDisplay(pDAS->dispWid), screen);
1993
1994     if (fileName != NULL && *fileName != '/')
1995       {
1996         fileName = (char *) malloc (strlen(vol_xid) + strlen (file_xid) + 2);
1997         if (fileName == NULL)
1998             return -1;
1999
2000         strcpy(fileName, vol_xid);
2001
2002         if (_DtHelpCeStrrchr(fileName, "/", MB_CUR_MAX, &ptr) != -1)
2003             *ptr = '\0';
2004
2005         strcat(fileName, "/");
2006         strcat(fileName, file_xid);
2007       }
2008
2009     /*
2010      * Find out if this is a X Pixmap graphic and set flag if it is.
2011      * This will be used later when/if colors need to be freed.
2012      */
2013     if (fileName != NULL && _DtHelpCeStrrchr(fileName, ".", MB_CUR_MAX, &extptr) != -1)
2014         if (strcmp (extptr, ".xpm") == 0 || strcmp (extptr, ".pm") == 0)
2015                 pGS->used = -1;
2016
2017     if (pDAS->context == NULL)
2018     {
2019         pDAS->context = (_DtGrContext *) XtMalloc(sizeof(_DtGrContext));
2020         pDAS->context->image_type = NULL;
2021         pDAS->context->context = NULL;
2022     }
2023
2024     pGS->pix = _DtHelpProcessGraphic (XtDisplay(pDAS->dispWid), win,
2025                                 XScreenNumberOfScreen(XtScreen(pDAS->dispWid)),
2026                                 pDAS->depth,
2027                                 pDAS->pixmapGC,
2028                                 &(pDAS->def_pix),
2029                                 &(pDAS->def_pix_width),
2030                                 &(pDAS->def_pix_height),
2031                                 pDAS->context,
2032                                 pDAS->colormap,
2033                                 pDAS->visual,
2034                                 pDAS->foregroundColor,
2035                                 pDAS->backgroundColor, fileName,
2036                                 pDAS->media_resolution,
2037                                 &(pGS->width), &(pGS->height), &(pGS->mask),
2038                                 &(pGS->pixels), &(pGS->num_pixels));
2039
2040     if (pDAS->context->image_type == NULL)
2041     {
2042         XtFree((char *) pDAS->context);
2043         pDAS->context = NULL;
2044     }
2045
2046     if (fileName != file_xid)
2047         free (fileName);
2048
2049     if (pGS->pix == NULL)
2050       {
2051         free(pReg);
2052         free(pGS);
2053         return -1;
2054       }
2055
2056     /*
2057      * fill in the region information
2058      */
2059     pReg->inited = True;
2060     pReg->type   = _DtHelpDAGraphic;
2061     pReg->handle = (_DtCvPointer) pGS;
2062
2063     /*
2064      * fill out the return information
2065      */
2066     *ret_width  = pGS->width;
2067     *ret_height = pGS->height;
2068     *ret_region = (_DtCvPointer) pReg;
2069
2070     return 0;
2071 }
2072
2073 /*****************************************************************************
2074  * Function:    void _DtHelpDADestroyGraphic ();
2075  *
2076  * Parameters:
2077  *
2078  * Returns:
2079  *
2080  * Purpose:
2081  *
2082  *****************************************************************************/
2083 void
2084 _DtHelpDADestroyGraphic (
2085     _DtCvPointer        client_data,
2086     _DtCvPointer        graphic_ptr )
2087 {
2088     Arg   args[5];
2089     int   i;
2090
2091     Colormap colormap;
2092
2093     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
2094     DtHelpGraphicStruct  *pGS  = (DtHelpGraphicStruct *)     graphic_ptr;
2095     Display              *dpy  = XtDisplay(pDAS->dispWid);
2096
2097     if (pGS->pix != pDAS->def_pix)
2098         XFreePixmap(dpy, pGS->pix);
2099
2100     if (pGS->mask != None)
2101         XFreePixmap(dpy, pGS->mask);
2102
2103     if (pGS->num_pixels)
2104       {
2105         XtSetArg (args[0], XmNcolormap, &colormap);
2106         XtGetValues (pDAS->dispWid, args, 1);
2107
2108         /*
2109          * This will only be set to -1 if the original graphic was an X Pixmap,
2110          * <filename>.pm or <filename>.xpm.
2111          */
2112         if (pGS->used != -1)
2113                 XFreeColors (dpy, colormap, pGS->pixels, pGS->num_pixels, 0);
2114
2115         free((void *) pGS->pixels);
2116       }
2117
2118     free((char *) pGS);
2119 }
2120
2121 /*****************************************************************************
2122  * Function:    void _DtHelpDADestroySpc ();
2123  *
2124  * Parameters:
2125  *
2126  * Returns:
2127  *
2128  * Purpose:
2129  *
2130  *****************************************************************************/
2131 void
2132 _DtHelpDADestroySpc (
2133     _DtCvPointer        client_data,
2134     _DtCvPointer        spc_handle)
2135 {
2136     int                   spc_index = (int) spc_handle;
2137     DtHelpDispAreaStruct *pDAS      = (DtHelpDispAreaStruct *) client_data;
2138
2139     if (pDAS->max_spc == 0)
2140         return;
2141
2142     pDAS->spc_chars[spc_index].spc_idx = -1;
2143 }
2144
2145 /*****************************************************************************
2146  * Function:    void _DtHelpDADestroyRegion ();
2147  *
2148  * Parameters:
2149  *
2150  * Returns:
2151  *
2152  * Purpose:
2153  *
2154  *****************************************************************************/
2155 void
2156 _DtHelpDADestroyRegion (
2157     _DtCvPointer        client_data,
2158     _DtCvPointer        reg_info)
2159 {
2160     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
2161     _DtHelpDARegion      *pReg = (_DtHelpDARegion *) reg_info;
2162
2163     if (True == pReg->inited)
2164       {
2165         if (_DtHelpDASpc == pReg->type)
2166             _DtHelpDADestroySpc(client_data, pReg->handle);
2167         else if (_DtHelpDAGraphic == pReg->type)
2168             _DtHelpDADestroyGraphic(client_data, pReg->handle);
2169       }
2170     else if (False == pReg->inited && _DtHelpDASpc == pReg->type)
2171       {
2172         _DtHelpDASpcInfo *pSpc = (_DtHelpDASpcInfo *) pReg->handle;
2173
2174         free(pSpc->name);
2175         _DtHelpFreeFontHints(&(pSpc->spc_fonts));
2176         free(pReg->handle);
2177       }
2178
2179     free (pReg);
2180 }
2181
2182 /*****************************************************************************
2183  * Function:    Widget _DtHelpDATocMarker ();
2184  *
2185  * Parameters:
2186  *              client_data     Specifies the display area pointer.
2187  *
2188  * Returns: nothing
2189  *
2190  * Purpose: Turns on/off the toc marker. This includes setting the correct
2191  *          bit in pDAS->toc_flag and doing a physical XDraw or XClearArea.
2192  *
2193  *****************************************************************************/
2194 void
2195 _DtHelpDATocMarker (
2196     XtPointer    client_data,
2197     Boolean      draw)
2198 {
2199     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
2200
2201     if (pDAS->toc_flag & _DT_HELP_SHADOW_TRAVERSAL)
2202       {
2203         if (False == draw)
2204           {
2205             if (XtIsRealized(pDAS->dispWid))
2206                 ClearTocMarker(pDAS, 0);
2207             TurnTocOff(pDAS->toc_flag);
2208           }
2209         else if (True == draw)
2210           {
2211             TurnTocOn(pDAS->toc_flag);
2212             DrawTocIndicator(pDAS, 0);
2213           }
2214       }
2215 }
2216
2217 /*****************************************************************************
2218  *              Virtual UI Functions
2219  *****************************************************************************/
2220 /*****************************************************************************
2221  * Function:    void _DtHelpDAGetCvsMetrics ();
2222  *
2223  * Parameters:
2224  *
2225  * Returns:
2226  *
2227  * Purpose:
2228  *
2229  *****************************************************************************/
2230 void
2231 _DtHelpDAGetCvsMetrics (
2232     _DtCvPointer                 client_data,
2233     _DtCvElemType       elem_type,
2234     _DtCvPointer        ret_metrics)
2235 {
2236     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
2237     _DtCvSpaceMetrics    *retSpace = (_DtCvSpaceMetrics *) ret_metrics;
2238
2239     if (_DtCvCANVAS_TYPE == elem_type)
2240       {
2241         _DtCvMetrics  *retCanvas = (_DtCvMetrics *) ret_metrics;
2242
2243         retCanvas->width          = pDAS->dispUseWidth;
2244         retCanvas->height         = pDAS->dispUseHeight;
2245         retCanvas->top_margin     = pDAS->marginHeight;
2246         retCanvas->side_margin    = pDAS->marginWidth;
2247         retCanvas->line_height    = pDAS->lineHeight;
2248         retCanvas->horiz_pad_hint = pDAS->charWidth / 10;
2249       }
2250
2251     else if (_DtCvLINK_TYPE == elem_type)
2252       {
2253         retSpace->space_before = 0;
2254         retSpace->space_after  = 0;
2255         retSpace->space_above  = 0;
2256         retSpace->space_below  = 0;
2257       }
2258     else if (_DtCvTRAVERSAL_TYPE == elem_type)
2259       {
2260         retSpace->space_before = pDAS->lineThickness;
2261         if (pDAS->toc_flag & _DT_HELP_SHADOW_TRAVERSAL)
2262           {
2263             if (pDAS->toc_flag & _DT_HELP_NOT_INITIALIZED)
2264               {
2265                 GetTocIndicator(pDAS);
2266                 pDAS->toc_flag &= (~(_DT_HELP_NOT_INITIALIZED));
2267               }
2268             retSpace->space_before += pDAS->toc_width;
2269           }
2270
2271         retSpace->space_after  = pDAS->lineThickness;
2272         retSpace->space_above  = pDAS->lineThickness;
2273         retSpace->space_below  = 0;
2274       }
2275     else if (_DtCvLOCALE_TYPE == elem_type)
2276       {
2277         _DtCvLocale  *retLocale = (_DtCvLocale *) ret_metrics;
2278
2279         retLocale->line_wrap_mode = _DtCvModeWrapNone;
2280         retLocale->cant_begin_chars = pDAS->cant_begin_chars;
2281         retLocale->cant_end_chars   = pDAS->cant_end_chars;
2282       }
2283 }
2284
2285 /*****************************************************************************
2286  * Function:    void _DtHelpDAGetFontMetrics ();
2287  *
2288  * Parameters:
2289  *
2290  * Returns:
2291  *
2292  * Purpose:
2293  *
2294  *****************************************************************************/
2295 void
2296 _DtHelpDAGetFontMetrics (
2297     _DtCvPointer         client_data,
2298     _DtCvPointer         font_ptr,
2299     _DtCvUnit           *ret_ascent,
2300     _DtCvUnit           *ret_descent,
2301     _DtCvUnit           *ret_width,
2302     _DtCvUnit           *ret_super,
2303     _DtCvUnit           *ret_sub)
2304 {
2305     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
2306
2307     __DtHelpFontMetrics (pDAS->font_info, (int) font_ptr,
2308                 ret_ascent, ret_descent, ret_width, ret_super, ret_sub);
2309 }
2310
2311 /*****************************************************************************
2312  * Function:    _DtCvUnit _DtHelpDAGetStrWidth ();
2313  *
2314  * Parameters:
2315  *
2316  * Returns:
2317  *
2318  * Purpose:
2319  *
2320  *****************************************************************************/
2321 _DtCvUnit
2322 _DtHelpDAGetStrWidth (
2323     _DtCvPointer        client_data,
2324     _DtCvElemType       elem_type,
2325     _DtCvPointer        data)
2326 {
2327     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
2328     int   length;
2329     int   font_index;
2330     _DtCvStringInfo *strInfo;
2331
2332     if (elem_type != _DtCvSTRING_TYPE)
2333         return 0;
2334
2335     /*
2336      * cast the data to a string information structure.
2337      */
2338     strInfo = (_DtCvStringInfo *) data;
2339
2340     /*
2341      * If the 'font_index' is a negative number, it indicates a font set
2342      * was opened for this string.  Use the X11R5 I18N routine to figure
2343      * out its length.  Otherwise use the standard X11 text width call.
2344      */
2345     font_index = (int) strInfo->font_ptr;
2346     if (font_index < 0)
2347       {
2348         if (0 == strInfo->wc)
2349         length = XmbTextEscapement(
2350                         __DtHelpFontSetGet(pDAS->font_info, font_index),
2351                                 (char *) strInfo->string, strInfo->byte_len);
2352     else
2353             length = XwcTextEscapement(
2354                         __DtHelpFontSetGet(pDAS->font_info, font_index),
2355                                 (wchar_t *) strInfo->string, strInfo->byte_len);
2356       }
2357     else
2358         length = XTextWidth(__DtHelpFontStructGet(pDAS->font_info, font_index),
2359                                 (char *) strInfo->string, strInfo->byte_len);
2360
2361    return ((_DtCvUnit) length);
2362 }
2363
2364 /*****************************************************************************
2365  * Function:    void _DtHelpDARenderElem ();
2366  *
2367  * Parameters:
2368  *              client_data     Specifies the client specific data
2369  *                              associated with this canvas.
2370  *              elem_type       Specifies the element type that will be
2371  *                              rendered.
2372  *              x               Specifies the x unit at which the
2373  *                              string is to be rendered.
2374  *              y               Specifes the y unit at which the baseline
2375  *                              of the string is to be rendered.
2376  *              link_type       Specifies the link type if this element is
2377  *                              part of a link.
2378  *              old_flags       Specifies the old flags.
2379  *              new_flags       Specifies the new flags.
2380  *              data            Contains a pointer to the element specific
2381  *                              structures required for rendering.
2382  *
2383  * Returns: Nothing
2384  *
2385  * Purpose:
2386  *
2387  *****************************************************************************/
2388 void
2389 _DtHelpDARenderElem (
2390     _DtCvPointer        client_data,
2391     _DtCvElemType       elem_type,
2392     _DtCvUnit           x,
2393     _DtCvUnit           y,
2394     int                 link_type,
2395     _DtCvFlags          old_flags,
2396     _DtCvFlags          new_flags,
2397     _DtCvElemType       trav_type,
2398     _DtCvPointer        trav_data,
2399     _DtCvPointer        data )
2400 {
2401     _DtCvStringInfo *strInfo;
2402     _DtCvLineInfo   *lnInfo  = (_DtCvLineInfo *) data;
2403     _DtCvRenderInfo *posInfo = (_DtCvRenderInfo *) data;
2404
2405     /*
2406      * nothing is done with trav_type or trav_data for DtHelp.
2407      */
2408
2409     /*
2410      * render the element based on its type.
2411      */
2412     if (_DtCvSTRING_TYPE == elem_type)
2413       {
2414         strInfo = (_DtCvStringInfo *) posInfo->info;
2415         DADrawString(client_data, posInfo->info, x, y, strInfo->string,
2416                                 strInfo->byte_len, strInfo->wc,
2417                                 strInfo->font_ptr, strInfo->csd,
2418                                 posInfo->box_x, posInfo->box_y,
2419                                 posInfo->box_height,
2420                                 old_flags, new_flags);
2421       }
2422     else if (_DtCvLINE_TYPE == elem_type)
2423       {
2424         DADrawLine(client_data, x, y, lnInfo->x2, lnInfo->y2, lnInfo->width);
2425       }
2426     else if (_DtCvREGION_TYPE == elem_type)
2427       {
2428         _DtHelpDARegion *regInfo = (_DtHelpDARegion *) posInfo->info;
2429
2430         if (_DtHelpDAGraphic == regInfo->type)
2431           {
2432             DADrawGraphic(client_data, regInfo->handle,
2433                                 posInfo->box_x,
2434                                 posInfo->box_y,
2435                                 posInfo->box_width,
2436                                 posInfo->box_height,
2437                                 old_flags, new_flags);
2438           }
2439         else if (_DtHelpDASpc == regInfo->type)
2440           {
2441             DADrawSpc (client_data, regInfo->handle, x, y,
2442                                 posInfo->box_x   ,
2443                                 posInfo->box_y   , posInfo->box_height,
2444                                 link_type        , old_flags,
2445                                 new_flags);
2446           }
2447       }
2448 }
2449
2450 /*****************************************************************************
2451  * Function:    _DtCvStatus _DtHelpDABuildSelection ();
2452  *
2453  * Parameters:
2454  *              client_data     Specifies the client specific data
2455  *                              associated with this canvas.
2456  *              elem_type       Specifies the element type that will be
2457  *                              rendered.
2458  *              x               Specifies the x unit at which the
2459  *                              string is to be rendered.
2460  *              y               Specifes the y unit at which the baseline
2461  *                              of the string is to be rendered.
2462  *              link_type       Specifies the link type if this element is
2463  *                              part of a link.
2464  *              old_flags       Specifies the old flags.
2465  *              new_flags       Specifies the new flags.
2466  *              data            Contains a pointer to the element specific
2467  *                              structures required for rendering.
2468  *
2469  * Returns: Nothing
2470  *
2471  * Purpose:
2472  *
2473  *****************************************************************************/
2474 _DtCvStatus
2475 _DtHelpDABuildSelection (
2476     _DtCvPointer         client_data,
2477     _DtCvElemType        elem_type,
2478     unsigned int         mask,
2479     _DtCvPointer        *prev_info,
2480     _DtCvUnit            space,
2481     _DtCvUnit            width,
2482     _DtCvFlags           flags,
2483     _DtCvPointer         data)
2484 {
2485     _DtCvStatus result = _DtCvSTATUS_NONE;
2486
2487     if (_DtCvSTRING_TYPE == elem_type)
2488       {
2489         _DtCvStringInfo *strInfo = (_DtCvStringInfo *) data;
2490
2491         result = DABuildSelectedString(client_data, prev_info,
2492                                 strInfo->string  , strInfo->byte_len,
2493                                 strInfo->wc,
2494                                 strInfo->font_ptr, space, flags);
2495       }
2496     else if (_DtCvREGION_TYPE == elem_type)
2497       {
2498         _DtHelpDARegion *regInfo = (_DtHelpDARegion *) data;
2499
2500         if (_DtHelpDASpc == regInfo->type)
2501             result = DABuildSelectedSpc (client_data, prev_info,
2502                                 regInfo->handle, space, flags);
2503       }
2504
2505     return result;
2506 }