dtcalc: change from obsoleted MAXFLOAT to FLT_MAX from std C
[oweals/cde.git] / cde / lib / DtHelp / Format.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 librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: Format.c /main/18 1996/11/22 12:23:59 cde-hp $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  **
27  **   File:     Format.c
28  **
29  **   Project:     Text Graphic Display Library
30  **
31  **   Description: This body of formats the input into a form understood by
32  **             a Display Area.
33  **
34  **  (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
35  **
36  **  (c) Copyright 1993, 1994 Hewlett-Packard Company
37  **  (c) Copyright 1993, 1994 International Business Machines Corp.
38  **  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
39  **  (c) Copyright 1993, 1994 Novell, Inc.
40  **
41  **
42  ****************************************************************************
43  ************************************<+>*************************************/
44
45 /*
46  * system includes
47  */
48 #include <stdio.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <locale.h>
52 #include <stdlib.h>
53 #include <unistd.h>
54 #include <X11/Xlib.h>
55 #include <X11/Xresource.h>
56 #include <Xm/Xm.h>
57
58 #ifdef X_NOT_STDC_ENV
59 extern int errno;
60 #endif
61
62 /*
63  * Core Engine includes
64  */
65 #include "CanvasP.h"
66 #include "CanvasSegP.h"
67
68 /*
69  * private includes
70  */
71 #include "bufioI.h"
72 #include "CvtToArrayP.h"
73 #include "DisplayAreaP.h"
74 #include "FontAttrI.h"
75 #include "FontI.h"
76 #include "HelpXlate.h"
77 #include "XInterfaceI.h"
78 #include "Lock.h"
79
80 /*
81  * private core engine
82  */
83 #include "Access.h"
84 #include "AccessP.h"
85 #include "AccessI.h"
86 #include "AccessCCDFI.h"
87 #include "SDLI.h"
88 #include "FormatUtilI.h"
89 #include "FormatCCDFI.h"
90 #include "FormatSDLI.h"
91 #include "StringFuncsI.h"
92
93
94 #ifdef NLS16
95 #endif
96
97 /********    Private Function Declarations    ********/
98
99 /********    End Public Function Declarations    ********/
100
101 /******************************************************************************
102  *
103  * Private variables and defines.
104  *
105  *****************************************************************************/
106 #define BUFF_SIZE       1024
107
108 static  char    *ScanString = "\n\t";
109 static const _FrmtUiInfo defUiInfo = { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1, False };
110
111 /******************************************************************************
112  *
113  * Private Functions
114  *
115  *****************************************************************************/
116 /******************************************************************************
117  * Function:    int FormatChunksToXmString ()
118  *
119  * Parameters:
120  *               *ret_list may be NULL when called
121  *
122  * Returns:     0 if successful, -1 if errors
123  *
124  * errno Values:
125  *
126  * Purpose:     Take some rich text chunks and turn it into an XmString.
127  *
128  ******************************************************************************/
129 static int
130 FormatChunksToXmString(
131     DtHelpDispAreaStruct *pDAS,
132     Boolean               free_flag,
133     void                **title_chunks,
134     XmString             *ret_title,
135     XmFontList           *ret_list,
136     Boolean              *ret_mod )
137 {
138     int                  result = 0;
139     int                  i;
140     long                 j;
141     int                  quarkCount;
142     long                 chunkType;
143     long                 myIdx;
144     _DtCvPointer         fontPtr;
145     char                *charSet;
146     const char          *strChunk;
147     char                 buffer[16];
148     _DtHelpFontHints             fontSpecs;
149     XmFontContext        fontContext;
150     XmString             partTitle;
151     XmString             newTitle;
152     XrmQuark             charSetQuark;
153     XrmName              myCharSetQuarks[20];
154     XrmName              xrmName[_CEFontAttrNumber];
155     Boolean              myMore;
156
157     /*
158      * Initialize the pointers.
159      */
160     *ret_title = NULL;
161     *ret_mod   = False;
162
163     if (title_chunks == NULL)
164         return -1;
165
166     /*
167      * initialize the font context
168      */
169     _DtHelpCeCopyDefFontAttrList(&fontSpecs);
170     if ( NULL != *ret_list )
171       {
172         if (XmFontListInitFontContext (&fontContext, *ret_list) == False)
173             result = -1;
174         else 
175           {
176             XFontStruct *myFontStruct;
177             /*
178              * quarkize all the character sets found.
179              */
180             quarkCount = 0;
181             do
182               {
183                 myMore = XmFontListGetNextFont (fontContext, &charSet,
184                                                                 &myFontStruct);
185                 if (myMore)
186                   {
187                     myCharSetQuarks[quarkCount++] = 
188                                                 XrmStringToQuark (charSet);
189                     XtFree (charSet);
190                   }
191               } while (myMore);
192     
193             XmFontListFreeFontContext (fontContext);
194           }
195       } /* if NULL != *ret_list */
196     else
197       { /* if NULL == *ret_list */
198          quarkCount = 0;
199          myCharSetQuarks[0] = 0;
200       }
201
202     /*
203      * Build the XrmString based on the segments.
204      * The format of the returned information is
205      *          'DT_HELP_CE_CHARSET  locale  string'
206      *          'DT_HELP_CE_FONT_PTR fontptr string'
207      *          'DT_HELP_CE_SPC      spc'
208      *          'DT_HELP_CE_STRING   string' - uses last specified
209      *                                         charset/font_ptr.
210      *
211      * The order and manner in which the title_chunks are processed
212      * is known and depended upon in several locations.
213      * Do not change this without changing the other locations.
214      * See the _DtHelpFormatxxx() routines and the ones that
215      * create the title_chunk arrays in FormatSDL.c and FormatCCDF.c
216      */
217     myIdx = __DtHelpDefaultFontIndexGet(pDAS);
218     _DtHelpCopyDefaultList(xrmName);
219     for (i = 0; result == 0 && title_chunks[i] != DT_HELP_CE_END; i++)
220       {
221         /*
222          * create a string for the char set and a quark for it.
223          */
224         chunkType = (long) title_chunks[i++];
225
226         /*
227          * i now points to the first value after the type
228          */
229         if (chunkType & DT_HELP_CE_CHARSET)
230           {
231             char *charSet;
232             char *lang = (char *) title_chunks[i];
233
234             /*
235              * test to see if the locale is in a lang.codeset form
236              */
237             if (_DtHelpCeStrchr(lang, ".", 1, &charSet) == 0)
238               {
239                 *charSet = '\0';
240                 charSet++;
241               }
242             else
243               {
244                 charSet = lang;
245                 lang    = NULL;
246               }
247
248             /*
249              * resolve/load the font for the default fonts
250              */
251             _DtHelpDAResolveFont(pDAS, lang, charSet, fontSpecs, &fontPtr);
252             myIdx = (long) fontPtr;
253             if (lang != NULL)
254               {
255                 charSet--;
256                 *charSet = '.';
257               }
258
259             if (free_flag)
260                 free(title_chunks[i]);
261
262             /*
263              * move the i to point to the string.
264              */
265             i++;
266           }
267         else if (chunkType & DT_HELP_CE_FONT_PTR)
268           {
269             /*
270              * get the default font for the language and code set.
271              */
272             (void) __DtHelpFontCharSetQuarkGet(pDAS, (long)title_chunks[i],
273                                         &xrmName[_DT_HELP_FONT_CHAR_SET]);
274             (void) __DtHelpFontLangQuarkGet(pDAS, (long)title_chunks[i],
275                                         &xrmName[_DT_HELP_FONT_LANG_TER]);
276             (void) __DtHelpFontIndexGet(pDAS, xrmName, &myIdx);
277
278             /*
279              * move the i to point to the string.
280              */
281             i++;
282           }
283
284         /*
285          * the i point spc or string.
286          */
287         if (chunkType & DT_HELP_CE_SPC)
288           {
289             j        = (long) title_chunks[i];
290             strChunk = _DtHelpDAGetSpcString(pDAS->spc_chars[j].spc_idx);
291             fontPtr  = pDAS->spc_chars[j].font_ptr;
292
293             /*
294              * get the default font for the language and code set.
295              */
296             (void) __DtHelpFontCharSetQuarkGet(pDAS, (long)fontPtr,
297                                         &xrmName[_DT_HELP_FONT_CHAR_SET]);
298             (void) __DtHelpFontLangQuarkGet(pDAS, (long)fontPtr,
299                                         &xrmName[_DT_HELP_FONT_LANG_TER]);
300             (void) __DtHelpFontIndexGet(pDAS, xrmName, &myIdx);
301           }
302         else /* if (chunkType & _DT_HELP_CE_STRING) */
303             strChunk = (char *) title_chunks[i];
304
305         sprintf(buffer, "%ld", myIdx);
306         charSetQuark = XrmStringToQuark(buffer);
307
308         j = 0;
309         while (j < quarkCount && myCharSetQuarks[j] != charSetQuark)
310             j++;
311
312         /*
313          * If we didn't find a matching character set,
314          * add it to the list.
315          */
316         if (j >= quarkCount)
317           {
318             /* Copy the input list so XmFontListAppendEntry can mangle it. */
319             /* But only do it once! */
320             if (False == *ret_mod)
321                *ret_list = XmFontListCopy(*ret_list);
322
323             if (myIdx < 0)
324               {
325                 XFontSet fontSet = __DtHelpFontSetGet(pDAS->font_info, myIdx);
326                 XmFontListEntry fontEntry;
327
328                 fontEntry = XmFontListEntryCreate (buffer,
329                                                 XmFONT_IS_FONTSET,
330                                                 (XtPointer) fontSet);
331                 *ret_list = XmFontListAppendEntry (*ret_list, fontEntry);
332                 XmFontListEntryFree (&fontEntry);
333               }
334             else
335               {
336                 XFontStruct *fontStruct =
337                                 __DtHelpFontStructGet(pDAS->font_info, myIdx);
338                 XmFontListEntry fontEntry;
339
340                 fontEntry = XmFontListEntryCreate (buffer,
341                                                 XmFONT_IS_FONT,
342                                                 (XtPointer) fontStruct);
343                 *ret_list = XmFontListAppendEntry (*ret_list, fontEntry);
344                 XmFontListEntryFree (&fontEntry);
345               }
346
347            *ret_mod = True;
348             if (*ret_list == NULL)
349                 result = -1;
350
351             myCharSetQuarks[quarkCount++] = charSetQuark;
352           }
353
354         /*
355          * add this segment to the XmString.
356          */
357         if (result == 0)
358           {
359             if (*ret_title == NULL)
360                 *ret_title = XmStringGenerate ((char *) strChunk, buffer, 
361                                                XmCHARSET_TEXT, NULL);
362             else
363               {
364                 partTitle = XmStringGenerate ((char *) strChunk, buffer,
365                                               XmCHARSET_TEXT, NULL);
366
367                 newTitle = XmStringConcat (*ret_title, partTitle);
368
369                 XmStringFree (*ret_title);
370                 XmStringFree (partTitle);
371                 *ret_title = newTitle;
372               }
373
374             /*
375              * if a newline was specified,
376              * replace it with a blank.
377              */
378             if (*ret_title != NULL && (chunkType & DT_HELP_CE_NEWLINE))
379               {
380                 partTitle = XmStringGenerate (" ", buffer, XmCHARSET_TEXT, NULL);
381                 newTitle = XmStringConcat (*ret_title, partTitle);
382                 XmStringFree (*ret_title);
383                 XmStringFree (partTitle);
384                 *ret_title = newTitle;
385               }
386
387             if (*ret_title == NULL)
388                 result = -1;
389           }
390
391         if (free_flag && (chunkType & DT_HELP_CE_STRING))
392             free(title_chunks[i]);
393       }
394     /*
395      * deallocate the memory.
396      */
397     if (free_flag) free(title_chunks);
398     return result;
399 }
400
401 /******************************************************************************
402  *
403  * Semi-Public Functions
404  *
405  *****************************************************************************/
406 /*****************************************************************************
407  * Function:    int _DtHelpFormatAsciiFile (char *filename,
408  *                                      CEParagraph **ret_para, int *ret_num)
409  *
410  * Parameters:
411  *              filename        Specifies the ascii file to read.
412  *              ret_para        Returns a pointer to a list of CEParagraph
413  *                              structures.
414  *              ret_num         Returns the number of structures in 'ret_para'.
415  *
416  * Returns:     0 if successful, -1 if errors
417  *
418  * errno Values:
419  *              EINVAL
420  *
421  * Purpose:     _DtHelpFormatAsciiFile formats Ascii Files into a list of
422  *              CEParagraph structures.
423  *
424  *****************************************************************************/
425 int
426 _DtHelpFormatAsciiFile(
427         XtPointer         client_data,
428         char             *filename,
429         XtPointer        *ret_handle)
430 {
431     int        myFile;
432     int        result = -1;
433     _DtHelpFontHints fontAttrs;
434     char       buffer [BUFF_SIZE];
435     BufFilePtr rawInput;
436     XtPointer   varHandle;
437     _DtCvTopicPtr         topic    = NULL;
438     DtHelpDispAreaStruct *pDAS     = (DtHelpDispAreaStruct *) client_data;
439     _FrmtUiInfo           myUiInfo = defUiInfo;
440
441     /*
442      * check the parameters
443      */
444     if (filename == NULL || ret_handle == NULL)
445       {
446         errno = EINVAL;
447         return -1;
448       }
449
450     /*
451      * Initialize the pointers, buffers and counters
452      */
453     *ret_handle  = NULL;
454
455     /*
456      * open the file.
457      */
458     myFile = open (filename, O_RDONLY);
459     if (myFile != -1)
460       {
461         /*
462          * set the information
463          */
464         rawInput = _DtHelpCeBufFileRdWithFd(myFile);
465         if (rawInput == 0)
466           {
467             close (myFile);
468             return -1;
469           }
470
471         result = _DtHelpCeReadBuf (rawInput, buffer, BUFF_SIZE);
472
473         if (result != -1)
474           {
475             _DtHelpCeCopyDefFontAttrList (&fontAttrs);
476             fontAttrs.spacing = _DtHelpFontSpacingMono;
477             _DtHelpCeXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,
478                                 setlocale(LC_CTYPE,NULL), NULL,
479                                 &(fontAttrs.language), &(fontAttrs.char_set));
480
481             /*
482              * fill out the ui information
483              */
484             myUiInfo.load_font    = _DtHelpDAResolveFont;
485             myUiInfo.client_data  = (_DtCvPointer) pDAS;
486             myUiInfo.line_width   = pDAS->lineThickness;
487             myUiInfo.line_height  = pDAS->lineHeight;
488             myUiInfo.leading      = pDAS->leading;
489             myUiInfo.avg_char     = (int)(pDAS->charWidth / 10 +
490                                         ((pDAS->charWidth % 10) ? 1 : 0));
491             myUiInfo.nl_to_space  = pDAS->nl_to_space;
492
493             /*
494              * get the formatting structure.
495              */
496             varHandle = __DtHelpCeSetUpVars(fontAttrs.language,
497                                                 fontAttrs.char_set, &myUiInfo);
498             if (varHandle == NULL)
499               {
500                 free(fontAttrs.language);
501                 free(fontAttrs.char_set);
502                 return -1;
503               }
504
505             result = __DtHelpCeProcessString (varHandle, rawInput,
506                                 _DtCvLITERAL,
507                                 ScanString, buffer, BUFF_SIZE,
508                                 0, False, &fontAttrs);
509
510             if (result != -1)
511                 result = __DtHelpCeGetParagraphList (varHandle, True,
512                                                 _DtCvLITERAL,
513                                                 &topic);
514
515             free(fontAttrs.language);
516             free(fontAttrs.char_set);
517             free(varHandle);
518           }
519
520         _DtHelpCeBufFileClose(rawInput, True);
521       }
522
523     *ret_handle = (XtPointer) topic;
524     return result;
525
526 }  /* End _DtHelpFormatAsciiFile */
527
528 /*****************************************************************************
529  * Function:    int _DtHelpFormatAsciiString (char *input_string,
530  *                                      CEParagraph **ret_para, int *ret_num)
531  *
532  * Parameters:
533  *              input_string    Specifies the ascii string to format.
534  *              ret_para        Returns a pointer to a list of CEParagraph
535  *                              structures.
536  *              ret_num         Returns the number of structures in 'ret_para'.
537  *
538  * Returns:     0 if successful, -1 if errors
539  *
540  * errno Values:
541  *
542  * Purpose:     _DtHelpFormatAsciiString formats a string as if it were a
543  *              static string - watching for newlines and using them
544  *              to force a break in the line.
545  *
546  *****************************************************************************/
547 int
548 _DtHelpFormatAsciiString(
549         XtPointer         client_data,
550         char             *input_string,
551         XtPointer        *ret_handle)
552 {
553     int      result = -1;
554     _DtHelpFontHints fontAttrs;
555     XtPointer varHandle;
556     _DtCvTopicPtr         topic    = NULL;
557     DtHelpDispAreaStruct *pDAS     = (DtHelpDispAreaStruct *) client_data;
558     _FrmtUiInfo           myUiInfo = defUiInfo;
559
560     /*
561      * check the parameters.
562      */
563     if (input_string == NULL || ret_handle == NULL)
564       {
565         errno = EINVAL;
566         return -1;
567       }
568
569     /*
570      * fill out the ui information
571      */
572     myUiInfo.load_font    = _DtHelpDAResolveFont;
573     myUiInfo.client_data  = (_DtCvPointer) pDAS;
574     myUiInfo.line_width   = pDAS->lineThickness;
575     myUiInfo.line_height  = pDAS->lineHeight;
576     myUiInfo.leading      = pDAS->leading;
577     myUiInfo.avg_char     = (int)(pDAS->charWidth / 10 +
578                                     ((pDAS->charWidth % 10) ? 1 : 0));
579     myUiInfo.nl_to_space  = pDAS->nl_to_space;
580
581     /*
582      * Get the initialized variables
583      */
584     *ret_handle  = NULL;
585
586     _DtHelpCeCopyDefFontAttrList (&fontAttrs);
587     _DtHelpCeXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,setlocale(LC_CTYPE,NULL),
588                                 NULL, &(fontAttrs.language),
589                                 &(fontAttrs.char_set));
590
591     varHandle = __DtHelpCeSetUpVars(fontAttrs.language, fontAttrs.char_set,
592                                                 &myUiInfo);
593     if (varHandle == NULL)
594       {
595         free(fontAttrs.language);
596         free(fontAttrs.char_set);
597         return -1;
598       }
599
600     result = __DtHelpCeProcessString (varHandle, NULL,
601                                 _DtCvLITERAL,
602                                 ScanString, input_string,
603                                 strlen(input_string),
604                                 0, False,
605                                 &fontAttrs);
606
607     if (result != -1)
608         result = __DtHelpCeGetParagraphList (varHandle, True, _DtCvLITERAL,
609                                                                 &topic);
610
611     *ret_handle = (XtPointer) topic;
612
613     free(fontAttrs.language);
614     free(fontAttrs.char_set);
615     free(varHandle);
616
617     return result;
618
619 }  /* End _DtHelpFormatAsciiString */
620
621 /*****************************************************************************
622  * Function:    int _DtHelpFormatAsciiStringDynamic (char *input_string,
623  *                                      CEParagraph **ret_para, int *ret_num)
624  *
625  * Parameters:
626  *              input_string    Specifies the ascii string to format.
627  *              ret_para        Returns a pointer to a list of CEParagraph
628  *                              structures.
629  *              ret_num         Returns the number of structures in 'ret_para'.
630  *
631  * Returns:     0 if successful, -1 if errors
632  *
633  * errno Values:
634  *
635  * Purpose:     _DtHelpFormatAsciiStringDynamic formats a string as if it were
636  *              a dynamic string - it uses newline characters to terminate
637  *              the current paragraph, not a line.
638  *
639  *****************************************************************************/
640 int
641 _DtHelpFormatAsciiStringDynamic(
642         XtPointer         client_data,
643         char             *input_string,
644         XtPointer        *ret_handle)
645 {
646     int      result = -1;
647     _DtHelpFontHints fontAttrs;
648     XtPointer varHandle;
649     _DtCvTopicPtr         topic    = NULL;
650     DtHelpDispAreaStruct *pDAS     = (DtHelpDispAreaStruct *) client_data;
651     _FrmtUiInfo           myUiInfo = defUiInfo;
652
653     /*
654      * check the parameters.
655      */
656     if (input_string == NULL || ret_handle == NULL)
657       {
658         errno = EINVAL;
659         return -1;
660       }
661
662     /*
663      * fill out the ui information
664      */
665     myUiInfo.load_font    = _DtHelpDAResolveFont;
666     myUiInfo.client_data  = (_DtCvPointer) pDAS;
667     myUiInfo.line_width   = pDAS->lineThickness;
668     myUiInfo.line_height  = pDAS->lineHeight;
669     myUiInfo.leading      = pDAS->leading;
670     myUiInfo.avg_char     = (int)(pDAS->charWidth / 10 +
671                                     ((pDAS->charWidth % 10) ? 1 : 0));
672     myUiInfo.nl_to_space  = pDAS->nl_to_space;
673
674     /*
675      * Fake the flag and give the string as the input buffer.
676      */
677     *ret_handle  = NULL;
678
679     _DtHelpCeCopyDefFontAttrList (&fontAttrs);
680     _DtHelpCeXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,setlocale(LC_CTYPE,NULL),
681                                 NULL, &(fontAttrs.language),
682                                 &(fontAttrs.char_set));
683
684     varHandle = __DtHelpCeSetUpVars(fontAttrs.language, fontAttrs.char_set,
685                                                 &myUiInfo);
686     if (varHandle == NULL)
687       {
688         free(fontAttrs.language);
689         free(fontAttrs.char_set);
690         return -1;
691       }
692
693     result = __DtHelpCeProcessString (varHandle, NULL,
694                                 _DtCvDYNAMIC,
695                                 ScanString, input_string,
696                                 strlen(input_string),
697                                 0, True,
698                                 &fontAttrs);
699
700     if (result != -1)
701         result = __DtHelpCeGetParagraphList (varHandle, False, _DtCvDYNAMIC,
702                                                                 &topic);
703     *ret_handle = (XtPointer) topic;
704
705     free(fontAttrs.language);
706     free(fontAttrs.char_set);
707     free(varHandle);
708
709     return result;
710
711 }  /* End _DtHelpFormatAsciiStringDynamic */
712
713 /******************************************************************************
714  * Function:    int _DtHelpFormatTopicTitle (Display *dpy, _XvhVolume volume,
715  *                              char *filename, int offset,
716  *                              XmString *ret_title, XmFontList *ret_list,
717  *                              Boolean *ret_mod)
718  *
719  * Parameters:
720  *              dpy             Specifies the connection to the server.
721  *              volume          Specifies the Help Volume the information
722  *                              is associated with.
723  *              filename        Specifies the file containing the Help Topic
724  *                              desired.
725  *              offset          Specifies the offset into 'filename' to
726  *                              the Help Topic desired.
727  *              ret_title       Returns XmString containing the title.
728  *              ret_list        Specifies the current font list being used.
729  *                              Returns a new font list if new character
730  *                              sets are added to it.
731  *              ret_mod         Returns True if fonts were added to the
732  *                              font list.
733  *
734  * Returns:     0 if successful, -1 if errors
735  *
736  * errno Values:
737  *
738  * Purpose:     _DtHelpFormatTopicTitle formats a topic title and associates
739  *              the correct font with it.
740  *
741  ******************************************************************************/
742 int
743 _DtHelpFormatTopicTitle(
744     XtPointer             client_data,
745     _DtHelpVolumeHdl      volume_handle,
746     char                 *location_id,
747     XmString             *ret_title,
748     XmFontList           *ret_list,
749     Boolean              *ret_mod )
750 {
751     int          result = -1;
752     void        **titleChunks = NULL;
753     _FrmtUiInfo           myUiInfo = defUiInfo;
754     _DtHelpCeLockInfo     lockInfo;
755     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
756
757     /*
758      * Check the parameters
759      */
760     if (ret_title == NULL || ret_list == NULL || ret_mod == NULL)
761       {
762         errno = EINVAL;
763         return -1;
764       }
765
766     /*
767      * lock the volume
768      */
769     if (_DtHelpCeLockVolume(volume_handle, &lockInfo) != 0)
770         return -1;
771
772     /*
773      * set up my UI information
774      */
775     myUiInfo.load_graphic = _DtHelpDALoadGraphic;
776     myUiInfo.resolve_spc  = _DtHelpDAResolveSpc;
777     myUiInfo.load_font    = _DtHelpDAResolveFont;
778     myUiInfo.exec_filter  = pDAS->exec_filter;
779     myUiInfo.destroy_region = _DtHelpDADestroyRegion;
780     myUiInfo.client_data  = (_DtCvPointer) pDAS;
781     /* since we're going for chunks, set avg_char width to 1 */
782     myUiInfo.line_width   = 0;
783     myUiInfo.line_height  = 0;
784     myUiInfo.leading      = 0;
785     myUiInfo.avg_char     = 1;
786     myUiInfo.nl_to_space  = pDAS->nl_to_space;
787
788     /*
789      * Get the title and charsets associated with the title segments.
790      * The format of the returned information is
791      *          [type,charset/fontptr,]type,string/spc
792      */
793     result = _DtHelpCeGetVolumeFlag(volume_handle);
794     _DtHelpProcessLock();
795     if (result == 1)
796         result = _DtHelpCeGetSdlTitleChunks(volume_handle, location_id,
797                                 &myUiInfo, &titleChunks);
798     else if (result == 0)
799         result = _DtHelpCeGetCcdfTitleChunks( volume_handle, location_id,
800                                 &myUiInfo, &titleChunks);
801     _DtHelpProcessUnlock();
802     if (result != -1)
803         result = FormatChunksToXmString(pDAS, True, titleChunks,
804                                                 ret_title, ret_list, ret_mod);
805     _DtHelpCeUnlockVolume(lockInfo);
806     return result;
807
808 }  /* End _DtHelpFormatTopicTitle */
809
810 /******************************************************************************
811  * Function:    int _DtHelpFormatVolumeTitle (DtHelpDispAreaStruct *pDAS,
812  *                              _XvhVolume volume,
813  *                              XmString *ret_title, XmFontList *ret_list,
814  *                              Boolean *ret_mod)
815  *
816  * Parameters:
817  *              volume          Specifies the Help Volume the information
818  *                              is associated with.
819  *              ret_title       Returns XmString containing the title.
820  *              ret_list        Specifies the current font list being used.
821  *                              Returns a new font list if new character
822  *                              sets are added to it.
823  *              ret_mod         Returns True if fonts were added to the
824  *                              font list.
825  *
826  * Returns:     0 if successful, -1 if errors
827  *
828  * errno Values:
829  *
830  * Purpose:     _DtHelpFormatVolumeTitle formats a volume title and associates
831  *              the correct font with it.
832  *
833  ******************************************************************************/
834 int
835 _DtHelpFormatVolumeTitle(
836     XtPointer             client_data,
837     _DtHelpVolumeHdl      volume_handle,
838     XmString             *ret_title,
839     XmFontList           *ret_list,
840     Boolean              *ret_mod )
841 {
842     int          result = -1;
843     void        **titleChunks = NULL;
844     _FrmtUiInfo           myUiInfo = defUiInfo;
845     _DtHelpCeLockInfo lockInfo;
846     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
847
848     /*
849      * Check the parameters
850      */
851     if (ret_title == NULL || ret_list == NULL || ret_mod == NULL)
852       {
853         errno = EINVAL;
854         return -1;
855       }
856
857     /*
858      * lock the volume
859      */
860     *ret_title = NULL;
861     if (_DtHelpCeLockVolume(volume_handle, &lockInfo) != 0)
862         return -1;
863
864     /*
865      * set up my UI information
866      */
867     myUiInfo.load_graphic = _DtHelpDALoadGraphic;
868     myUiInfo.resolve_spc  = _DtHelpDAResolveSpc;
869     myUiInfo.load_font    = _DtHelpDAResolveFont;
870     myUiInfo.exec_filter  = pDAS->exec_filter;
871     myUiInfo.destroy_region = _DtHelpDADestroyRegion;
872     myUiInfo.client_data  = (_DtCvPointer) pDAS;
873     /* since we're going for chunks, set avg_char width to 1 */
874     myUiInfo.line_width   = 0;
875     myUiInfo.line_height  = 0;
876     myUiInfo.leading      = 0;
877     myUiInfo.avg_char     = 1;
878     myUiInfo.nl_to_space  = pDAS->nl_to_space;
879
880     /*
881      * Get the title and charsets associated with the volume title.
882      * The format of the returned information is
883      *          [type,charset/fontptr,]type,string/spc
884      */
885     result = _DtHelpCeGetVolumeFlag(volume_handle);
886     _DtHelpProcessLock();
887     if (result == 1)
888         result = _DtHelpCeGetSdlVolTitleChunks(volume_handle, &myUiInfo,
889                                 &titleChunks);
890     else if (result == 0)
891         result = _DtHelpCeGetCcdfVolTitleChunks(
892                                 (_DtHelpVolume) volume_handle,
893                                 &myUiInfo,
894                                 &titleChunks);
895     _DtHelpProcessUnlock();
896     if (result != -1)
897         result = FormatChunksToXmString(pDAS, True, titleChunks,
898                                                 ret_title, ret_list, ret_mod);
899     _DtHelpCeUnlockVolume(lockInfo);
900     return result;
901
902 }  /* End _DtHelpFormatVolumeTitle */
903
904 /******************************************************************************
905  * Function:    int _DtHelpFormatIndexEntries (DtHelpDispAreaStruct *pDAS,
906  *                              _XvhVolume volume,
907  *                              XmString *ret_title, XmFontList *ret_list,
908  *                              Boolean *ret_mod)
909  *
910  * Parameters:
911  *              volume          Specifies the Help Volume the information
912  *                              is associated with.
913  *              ret_cnt         number of valid entries in the array
914  *              ret_words       Returns NULL-termintaed array of 
915  *                                XmStrings containing the words.
916  *              ret_list        Specifies the current font list being used.
917  *                              Returns a new font list if new character
918  *                              sets are added to it.
919  *              ret_mod         Returns True if fonts were added to the
920  *                              font list.
921  *
922  * Returns:     0 if successful, -1 if errors
923  *
924  * errno Values:
925  *
926  * Purpose:     _DtHelpFormatIndexEntries formats index entries and associates
927  *              the correct font with it.
928  *
929  ******************************************************************************/
930 int
931 _DtHelpFormatIndexEntries(
932     XtPointer             client_data,
933     _DtHelpVolumeHdl      volume_handle,
934     int                  *ret_cnt,
935     XmString            **ret_words,
936     XmFontList           *ret_list,
937     Boolean              *ret_mod )
938 {
939     int           i;
940     int           result = -1;
941     void         *titleChunks[4];
942     char         *charSet;
943     char        **keyWords;
944     Boolean       myMod = False;
945     XmFontList    oldList;
946     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
947
948     /*
949      * Check the parameters
950      */
951     if (ret_words == NULL || ret_list == NULL || ret_mod == NULL)
952       {
953         errno = EINVAL;
954         return -1;
955       }
956
957     *ret_mod = False;
958
959     charSet = _DtHelpGetVolumeLocale(volume_handle);
960     if (charSet != NULL)
961       {
962         *ret_cnt = _DtHelpCeGetKeywordList(volume_handle, &keyWords);
963         if (*ret_cnt > 0)
964           {
965
966             *ret_words = (XmString *) malloc (sizeof(XmString) * (*ret_cnt+1));
967             if (*ret_words == NULL)
968                 return -1;
969
970             /* the order of the string ptr and charset ptr in the titleChunks
971                is determined by the order of the if(..) tests on the
972                flags and subsequent processing in FormatChunksToXmString() */
973             titleChunks[0] = (void *) (DT_HELP_CE_STRING | DT_HELP_CE_CHARSET);
974             titleChunks[1] = (void *) charSet;
975             titleChunks[3] = (void *) DT_HELP_CE_END;
976             for (i = 0, result = 0; result == 0 && i < *ret_cnt; i++)
977               {
978                 oldList        = *ret_list;
979                 titleChunks[2] = (void *) keyWords[i];
980                 result = FormatChunksToXmString(pDAS, False, titleChunks,
981                                 &(*ret_words)[i], ret_list, &myMod);
982                 if (myMod == True)
983                   {
984                     /*
985                      * if the list has been modified before,
986                      * free the previously modified list.
987                      */
988                     if (True == *ret_mod)
989                         XmFontListFree(oldList);
990
991                     *ret_mod = True;
992                   }
993               }
994             (*ret_words)[i] = NULL;
995           }
996         free(charSet);
997       }
998
999     return result;
1000
1001 }  /* End _DtHelpFormatIndexEntries */
1002
1003 /******************************************************************************
1004  * Function:    int _DtHelpFormatTopic (
1005  *                              DtHelpDispAreaStruct *pDAS,
1006  *                              _DtHelpVolumeHdl volume,
1007  *                              char *id_string,
1008  *                              Boolean look_at_id,
1009  *                              XtPointer *ret_handle)
1010  *
1011  * Parameters:
1012  *              pDAS            Specifies the display area to use.
1013  *              volume          Specifies the Help Volume the information
1014  *                              is associated with.
1015  *              id_string       Specifies the location id for the topic.
1016  *                              This location id can be contained in a
1017  *                              topic.
1018  *              look_at_id      Specifies whether or not to start the
1019  *                              display of the topic at the location id.
1020  *              ret_handle      Returns a handle to the topic information
1021  *                              including the number of paragraphs and the
1022  *                              id match segment.
1023  *
1024  * Returns:     0       if successful.
1025  *              -1      if errors.
1026  *              -2      if the id was not found.
1027  *              -3      if unable to format the topic.
1028  *
1029  * errno Values:
1030  *
1031  * Purpose:     _DtHelpParseTopic accesses and parses Help topics.
1032  *
1033  ******************************************************************************/
1034 int
1035 _DtHelpFormatTopic(
1036         XtPointer         client_data,
1037         _DtHelpVolumeHdl  volume,
1038         char             *id_string,
1039         Boolean           look_at_id,
1040         XtPointer        *ret_handle )
1041 {
1042     char  *filename = NULL;
1043     int    offset;
1044     int    result = -2;
1045     _DtHelpCeLockInfo   lockInfo;
1046     _FrmtUiInfo           myUiInfo = defUiInfo;
1047     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
1048     _DtCvTopicInfo      *topic;
1049
1050     if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
1051         return -1;
1052
1053     if (_DtHelpCeFindId(volume,id_string,lockInfo.fd,&filename,&offset)==True)
1054       {
1055         if (look_at_id == False)
1056             id_string = NULL;
1057
1058         myUiInfo.load_graphic = _DtHelpDALoadGraphic;
1059         myUiInfo.resolve_spc  = _DtHelpDAResolveSpc;
1060         myUiInfo.load_font    = _DtHelpDAResolveFont;
1061         myUiInfo.exec_filter  = pDAS->exec_filter;
1062         myUiInfo.destroy_region = _DtHelpDADestroyRegion;
1063         myUiInfo.client_data  = (_DtCvPointer) pDAS;
1064         myUiInfo.line_width   = pDAS->lineThickness;
1065         myUiInfo.line_height  = pDAS->lineHeight;
1066         myUiInfo.leading      = pDAS->leading;
1067         myUiInfo.avg_char     = (int)(pDAS->charWidth / 10 +
1068                                         ((pDAS->charWidth % 10) ? 1 : 0));
1069         myUiInfo.nl_to_space  = pDAS->nl_to_space;
1070
1071         result = _DtHelpCeGetVolumeFlag(volume);
1072         _DtHelpProcessLock();
1073         if (result == 1)
1074             result = _DtHelpCeParseSdlTopic(volume,
1075                                                 &myUiInfo,
1076                                                 lockInfo.fd, offset,
1077                                                 id_string, True, &topic);
1078         else if (result == 0)
1079             result = _DtHelpCeFrmtCcdfTopic((_DtHelpVolume) volume,
1080                                                 filename, offset,
1081                                                 id_string,
1082                                                 &myUiInfo, &topic);
1083         _DtHelpProcessUnlock();
1084         *ret_handle = (XtPointer) topic;
1085         if (result != 0)
1086             result = -3;
1087
1088         if (filename != NULL)
1089             free(filename);
1090       }
1091
1092     _DtHelpCeUnlockVolume(lockInfo);
1093
1094     return result;
1095
1096 }  /* End _DtHelpFormatTopic */
1097
1098
1099 /******************************************************************************
1100  * Function:    int _DtHelpGetAsciiVolumeTitle (
1101  *
1102  * Parameters:  vol             Specifies the loaded volume.
1103  *              retTitle        Returns the title of the volume. This string is
1104  *                              owned by the caller and must be freed.
1105  *
1106  * Return Value: 0 if successful, -1 if a failure occurs
1107  *
1108  * errno Values:        CEErrorMalloc
1109  *                      EINVAL          'vol' or 'retTitle' is NULL.
1110  *                      CEErrorMissingTitleRes
1111  *                                      'vol' does not contain the resource
1112  *                                      'Title' or 'title' or the resource
1113  *                                      is zero length.
1114  *
1115  * Purpose:     Get the title of a volume.
1116  *
1117  ******************************************************************************/
1118 int 
1119 _DtHelpGetAsciiVolumeTitle (
1120      XtPointer            client_data,
1121     _DtHelpVolumeHdl      volume,
1122     char                **ret_title)
1123 {
1124     int                   result;
1125     _FrmtUiInfo           myUiInfo = defUiInfo;
1126     DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
1127
1128     /*
1129      * What type of volume is it?
1130      */
1131     result = _DtHelpCeGetVolumeFlag(volume);
1132     if (1 == result)
1133       {
1134         /*
1135          * set up my UI information
1136          */
1137         myUiInfo.load_graphic = _DtHelpDALoadGraphic;
1138         myUiInfo.resolve_spc  = _DtHelpDAResolveSpc;
1139         myUiInfo.load_font    = _DtHelpDAResolveFont;
1140         myUiInfo.exec_filter  = pDAS->exec_filter;
1141         myUiInfo.destroy_region = _DtHelpDADestroyRegion;
1142         myUiInfo.client_data  = (_DtCvPointer) pDAS;
1143         /* since we're going for a string, set avg_char width to 1 */
1144         myUiInfo.line_width   = 0;
1145         myUiInfo.line_height  = 0;
1146         myUiInfo.leading      = 0;
1147         myUiInfo.avg_char     = 1;
1148         myUiInfo.nl_to_space  = pDAS->nl_to_space;
1149
1150         _DtHelpProcessLock();
1151         result = _DtHelpCeFrmtSDLVolTitleToAscii(volume, &myUiInfo, ret_title);
1152       }
1153     else if (0 == result)
1154       {
1155         _DtHelpProcessLock();
1156         result = _DtHelpCeGetCcdfVolumeTitle(volume, ret_title);
1157       }
1158     _DtHelpProcessUnlock();
1159     return result;
1160 }
1161
1162 /*****************************************************************************
1163  * Function:    int _DtHelpFormatToc (
1164  *                      _DtHelpVolumeHdl volume, id);
1165  *
1166  * Parameters:
1167  *              canvas          Specifies the handle for the canvas.
1168  *
1169  * Returns:     -1 if errors.
1170  *               0 if no errors. 
1171  *               1 if empty path.
1172  *
1173  * Purpose:
1174  *
1175  *****************************************************************************/
1176 int
1177 _DtHelpFormatToc (
1178     DtHelpDispAreaStruct        *pDAS,
1179     _DtHelpVolumeHdl             volume,
1180     char                         *id,
1181     char                        **ret_id,
1182     XtPointer                    *ret_handle)
1183 {
1184     int             result   = 0;
1185     _DtCvTopicPtr    topic;
1186     _DtHelpCeLockInfo lockInfo;
1187
1188     if (volume == NULL || id == NULL)
1189         return -1;
1190
1191     /*
1192      * This becomes my volume; want to ensure that it doesn't
1193      * get closed out from under me, so tell the system that
1194      * i'm using it.
1195      */
1196     if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
1197         return -1;
1198
1199     result = _DtHelpCeMapTargetToId(volume, id, ret_id);
1200
1201     if (result == 0)
1202       {
1203         _FrmtUiInfo  myUiInfo = defUiInfo;
1204
1205         myUiInfo.client_data  = (XtPointer) pDAS;
1206         myUiInfo.load_graphic = _DtHelpDALoadGraphic;
1207         myUiInfo.resolve_spc  = _DtHelpDAResolveSpc;
1208         myUiInfo.load_font    = _DtHelpDAResolveFont;
1209         myUiInfo.exec_filter  = pDAS->exec_filter;
1210         myUiInfo.destroy_region = _DtHelpDADestroyRegion;
1211         myUiInfo.client_data  = (_DtCvPointer) pDAS;
1212         myUiInfo.line_width   = pDAS->lineThickness;
1213         myUiInfo.line_height  = pDAS->lineHeight;
1214         myUiInfo.leading      = pDAS->leading;
1215         myUiInfo.avg_char     = (int)(pDAS->charWidth / 10 +
1216                                         ((pDAS->charWidth % 10) ? 1 : 0));
1217         myUiInfo.nl_to_space  = pDAS->nl_to_space;
1218
1219         result = _DtHelpCeGetVolumeFlag(volume);
1220         _DtHelpProcessLock();
1221         if (result == 1)
1222             result = _DtHelpCeFrmtSdlPathAndChildren(volume,
1223                                                         &myUiInfo,
1224                                                         lockInfo.fd,
1225                                                         *ret_id, &topic);
1226         else if (result == 0)
1227             result = _DtHelpCeFrmtCcdfPathAndChildren(volume,
1228                                                         *ret_id,
1229                                                         &myUiInfo, &topic);
1230         _DtHelpProcessUnlock();
1231         *ret_handle = (XtPointer) topic;
1232       }
1233     /*
1234      * didn't successfully format a path, so close my copy
1235      * of the volume.
1236      */
1237     else
1238         _DtHelpCloseVolume (volume);
1239
1240     _DtHelpCeUnlockVolume(lockInfo);
1241     return result;
1242
1243 } /* End _DtHelpFormatToc */