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