Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / DtHelp / XUICreate.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 /* $TOG: XUICreate.c /main/22 1997/06/18 17:33:46 samborn $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  **
27  **   File:        XUICreate.c
28  **
29  **   Project:     Cde Help System
30  **
31  **   Description: Builds a GUI containing a Drawn Button with scroll
32  **                bars and wraps it around a canvas.
33  **
34  ****************************************************************************
35  ************************************<+>*************************************/
36 /*
37  * (c) Copyright 1996 Digital Equipment Corporation.
38  * (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992,
39                  1993, 1994, 1996 Hewlett-Packard Company.
40  * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
41  * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
42  * (c) Copyright 1993, 1994, 1996 Novell, Inc. 
43  * (c) Copyright 1996 FUJITSU LIMITED.
44  * (c) Copyright 1996 Hitachi.
45  */
46
47 /*
48  * system includes
49  */
50 #include <stdlib.h>
51 #include <string.h>
52 #include <Xm/Xm.h>
53 #include <Xm/XmP.h>
54 #include <Xm/AtomMgr.h>
55 #include <Xm/DrawnB.h>
56 #include <Xm/Form.h>
57 #include <Xm/ScrollBar.h>
58
59 /*
60  * Canvas Engine
61  */
62 #include "CanvasP.h"
63 #include "CanvasSegP.h"
64
65 /*
66  * private includes
67  */
68 #include "bufioI.h"
69 #include "DisplayAreaP.h"
70 #include "CallbacksI.h"
71 #include "XUICreateI.h"
72 #include "FontI.h"
73 #include "FontAttrI.h"
74 #include "DestroyI.h"
75 #include "FormatUtilI.h"
76 #include "SetListI.h"
77 #include "XInterfaceI.h"
78 #include "Lock.h"
79
80 #ifdef NLS16
81 #endif
82
83 /********    Private Function Declarations    ********/
84 static  Boolean    get_fontsetproperty(
85                         XFontSet        fontset,
86                         Atom            atom,
87                         unsigned long   *value_return);
88 /********    End Private Function Declarations    ********/
89
90 /********    Private Variables    ********/
91
92 static  _DtCvVirtualInfo DefVirtFunctions =
93   {
94         _DtHelpDAGetCvsMetrics,         /* void (*_DtCvGetMetrics)()     */
95         _DtHelpDARenderElem,            /* void (*_DtCvRenderElem)()     */
96         _DtHelpDAGetStrWidth,           /* _DtCvUnit (*_DtCvGetElemWidth)()  */
97         _DtHelpDAGetFontMetrics,        /* void (*_DtCvGetFontMetrics)() */
98         _DtHelpDABuildSelection,        /* void (*_DtCvBuildSelection)() */
99         NULL,                           /* _DtCvStatus (*_DtCvFilterExecCmd)()*/
100   };
101
102 /********    End Private Variables  ********/
103
104 /********    Semi-Private Variables    ********/
105 /********    End Semi-Private Variables  ********/
106
107 /******************************************************************************
108  *
109  * Here are the type and variable declarations for finding view subresources.
110  *
111  *****************************************************************************/
112
113 /*
114  * These are used to parse subresources for the text display areas.
115  */
116
117 typedef struct 
118   {
119     int    marginWidth;
120     int    marginHeight;
121     int    leading;
122     int    moveThreshold;
123     int    initialDelay;
124     int    repeatDelay;
125
126     XmFontList userFont;
127     Pixel  search_color;
128   }
129   DAArgs, *DAArgsPtr;
130
131 static XtResource Resources[] = {
132    {
133      "leading", "Leading", XmRInt, sizeof(int),
134      XtOffset(DAArgsPtr, leading), XmRImmediate, (XtPointer) 1
135    },
136     
137    {
138      XmNmarginWidth, XmCMarginWidth, XmRInt, sizeof(int),
139      XtOffset(DAArgsPtr, marginWidth), XmRImmediate, (XtPointer) 5
140    },
141     
142    {
143      XmNmarginHeight, XmCMarginHeight, XmRInt, sizeof(int),
144      XtOffset(DAArgsPtr, marginHeight), XmRImmediate, (XtPointer) 5
145    },
146
147    {
148      "moveThreshold", "MoveThreshold", XmRInt, sizeof(int),
149      XtOffset(DAArgsPtr, moveThreshold), XmRImmediate, (XtPointer) 10
150    },
151     
152    {
153      XmNinitialDelay, XmCInitialDelay, XmRInt, sizeof(int),
154      XtOffset(DAArgsPtr, initialDelay), XmRImmediate, (XtPointer) 250
155    },
156     
157    {
158      XmNrepeatDelay, XmCRepeatDelay, XmRInt, sizeof(int),
159      XtOffset(DAArgsPtr, repeatDelay), XmRImmediate, (XtPointer) 50
160    },
161     
162    {
163      "userFont", XmCFontList, XmRFontList, sizeof (XmFontList),
164      XtOffset(DAArgsPtr, userFont), XmRString, "Fixed"
165    },
166
167    {
168      "searchColor", "SearchColor", XtRPixel, sizeof (Pixel),
169      XtOffset(DAArgsPtr, search_color), XmRString, "blue"
170    },
171
172 };
173
174 static String       DrawnBTransTable = "\
175 ~s    ~m ~a <Key>Return:      ActivateLink()\n\
176 ~s  c ~m ~a <Key>backslash:   DeSelectAll()\n\
177 ~s  c ~m ~a <Key>slash:       SelectAll()\n\
178 ~s    ~m ~a <Key>space:       ActivateLink()\n\
179             <Key>osfActivate: ActivateLink()\n\
180             <Key>osfCopy:     CopyToClipboard()\n\
181    ~c       <Key>osfDown:     NextLink(1)\n\
182     c       <Key>osfDown:     PageUpOrDown(1)\n\
183 ~s  c ~m ~a <Key>osfInsert:   CopyToClipboard()\n\
184    ~c       <Key>osfLeft:      NextLink(0)\n\
185     c       <Key>osfLeft:      PageLeftOrRight(0)\n\
186    ~c       <Key>osfPageDown:  PageUpOrDown(1)\n\
187     c       <Key>osfPageDown:  PageLeftOrRight(1)\n\
188             <Key>osfPageLeft:  PageLeftOrRight(0)\n\
189             <Key>osfPageRight: PageLeftOrRight(1)\n\
190    ~c       <Key>osfPageUp:    PageUpOrDown(0)\n\
191     c       <Key>osfPageUp:    PageLeftOrRight(0)\n\
192    ~c       <Key>osfRight:     NextLink(1)\n\
193     c       <Key>osfRight:     PageLeftOrRight(1)\n\
194 ~s ~c       <Key>osfSelect:    ActivateLink()\n\
195    ~c       <Key>osfUp:        NextLink(0)\n\
196     c       <Key>osfUp:        PageUpOrDown(0)\n\
197     c       <Key>osfBeginLine: NextLink(2)\n\
198     c       <Key>osfEndLine:   NextLink(3)\
199 ";
200
201 static  XtTranslations  DrawnBTrans = NULL;
202
203 /*********************************************************************
204  *              Private Functions
205  *********************************************************************/
206 /* This function returns the max value of XGetFontProperty calls for each
207  * font in the fontset.
208  */
209 static Boolean
210 get_fontsetproperty(
211         XFontSet fontset,
212         Atom atom,
213         unsigned long *value_return)
214 {
215     int numfont;
216     XFontStruct **font_list;
217     char **name_list;
218     int i;
219     Bool ret = FALSE;
220     unsigned long value;
221
222     numfont=XFontsOfFontSet(fontset,&font_list,&name_list);
223     for(i = 0; i < numfont; i++) {
224         if(XGetFontProperty(font_list[i], atom, &value) == TRUE) {
225             if(ret == FALSE) {
226                 *value_return = value;
227                 ret = TRUE;
228             }
229             else {
230                 if(value > *value_return)
231                     *value_return = value;
232             }
233         }
234     }
235     return(ret);
236 }
237
238 /*
239  * This function returns the underline distance and size for the base
240  * font.
241  */
242 static  void
243 GetUnderLineInfo (
244         Display                 *dpy,
245         DtHelpDispAreaStruct    *pDAS,
246         int                     *ret_underThick )
247 {
248     int   idx;
249     XtPointer myFont;
250     XFontSetExtents *extents;
251
252     /*
253      * cast the parameter as a pointer to a long though the value
254      * returned is really a int.
255      */
256     idx = __DtHelpDefaultFontIndexGet(pDAS);
257     if (idx < 0)
258       {
259         myFont = (XtPointer)__DtHelpFontSetGet(pDAS->font_info, idx);
260         if (get_fontsetproperty((XFontSet)myFont, XA_UNDERLINE_POSITION,
261                 ((unsigned long *) &(pDAS->underLine))) == FALSE)
262           {
263             extents = XExtentsOfFontSet((XFontSet)myFont);
264             pDAS->underLine = ((int)(extents->max_ink_extent.height +
265                                extents->max_ink_extent.y)) / 2;
266           }
267       }
268     else
269       {
270         myFont = (XtPointer)__DtHelpFontStructGet(pDAS->font_info, idx);
271         if (XGetFontProperty((XFontStruct *)myFont, XA_UNDERLINE_POSITION, 
272                              ((unsigned long *) &(pDAS->underLine))) == FALSE)
273             pDAS->underLine = ((XFontStruct *)myFont)->max_bounds.descent / 2;
274       }
275
276     /*
277      * if we do not find an underline thickness for the font
278      * use 15% of the font height.
279      *
280      * cast the parameter to a pointer to a long though the value
281      * returned is really a unsigned int.
282      */
283     if (idx < 0)
284       {
285         if (get_fontsetproperty((XFontSet)myFont, XA_UNDERLINE_THICKNESS,
286                 ((unsigned long *) ret_underThick)) == FALSE)
287             *ret_underThick = pDAS->lineHeight * 15 / 100;
288       }
289     else
290       {
291         if (XGetFontProperty((XFontStruct *)myFont, XA_UNDERLINE_THICKNESS, 
292                              ((unsigned long *) ret_underThick)) == FALSE)
293             *ret_underThick = pDAS->lineHeight * 15 / 100;
294       }
295
296
297     /*
298      * now adjust the underline depth so that the when the underline is
299      * drawn the top of the line is UNDERLINE_POSITION pixels below
300      * the base line.
301      */
302 /*
303  * SYSTEM - ifdef this for other architectures.
304  * an example of Hewlett-Packard's implementation is given for reference.
305  */
306                 /* On Hewlett-Packard machines lines are */
307                 /* drawn like this:                      */
308                 /*                                       */
309                 /*  line width 1:  y-> ****************  */
310                 /*                                       */
311                 /*                     ****************  */
312                 /*  line width 2:  y-> ****************  */
313                 /*                                       */
314                 /*                     ****************  */
315                 /*  line width 3:  y-> ****************  */
316                 /*                     ****************  */
317                 /*                                       */
318                 /*                     ****************  */
319                 /*                     ****************  */
320                 /*  line width 4:  y-> ****************  */
321                 /*                     ****************  */
322                 /*                                       */
323                 /*                     ****************  */
324                 /*                     ****************  */
325                 /*  line width 5:  y-> ****************  */
326                 /*                     ****************  */
327                 /*                     ****************  */
328                 /* etc......                             */
329                 /*                                       */
330     pDAS->underLine = pDAS->underLine + (*ret_underThick) / 2;
331
332 }
333
334 /*********************************************************************
335  *              Public Functions
336  *********************************************************************/
337 /*********************************************************************
338  * Function: CreateDA
339  *
340  *    CreateDA creates a Text Graphic area with the appropriate scroll bars.
341  *
342  *********************************************************************/
343 static XtPointer
344 HelpCreateDA(
345     Widget       parent,
346     char        *name,
347     short        vert_flag,
348     short        horz_flag,
349     Boolean      traversal_flag,
350     _DtCvValue   honor_size,
351     _DtCvRenderType render_type,
352     int          rows,
353     int          columns,
354     unsigned short media_resolution,
355     void        (*hyperTextCB)(),
356     void        (*resizeCB)(),
357     int         (*exec_ok_routine)(),
358     XtPointer    client_data,
359     XmFontList   default_list )
360 {
361     DtHelpDispAreaStruct *pDAS;
362     DAArgs DA_args;
363     Arg args[20];
364     int n;
365     int maxFontAscent;
366     int maxFontDescent;
367     int maxFontCharWidth;
368   
369     short margin_width;
370     short margin_height;
371     short shadowThick, highThick;
372     Dimension hBarHeight = 0;
373     Dimension vBarWidth  = 0;
374     Dimension width;
375     Boolean   value;
376
377     Widget form;
378     Display *dpy = XtDisplay(parent);
379     Screen      *retScr = XtScreen(parent);
380     int          screen = XScreenNumberOfScreen(retScr);
381
382     Colormap colormap;
383
384     Pixmap               tile;
385     XGCValues            gcValues;
386     unsigned long        gcMask;
387
388     unsigned long char_width;
389
390     Atom xa_ave_width;
391
392     XFontStruct *tmpFont = NULL;
393     XtPointer    default_font = NULL;
394     XRectangle   rectangle[1];
395
396     XmFontContext       fontContext;
397     XmFontListEntry     fontEntry;
398     XmFontType          fontType;
399
400     /* Allocate the Display Area. */
401     pDAS = (DtHelpDispAreaStruct *) XtMalloc(sizeof(DtHelpDispAreaStruct));
402
403    /*
404      * get the resources
405      */
406     XtGetSubresources(parent, &DA_args, name, "XmDrawnButton",
407                     Resources, XtNumber(Resources), NULL, 0);
408
409     if (rows <= 0)
410         rows = 1;
411     if (columns <= 0)
412         columns = 1;
413
414     /*
415      * initialize the structure variables.
416      */
417     pDAS->text_selected = False;
418     pDAS->primary       = False;
419     pDAS->select_state  = _DtHelpNothingDoing;
420     pDAS->toc_y         = 0;
421     pDAS->toc_base      = 0;
422     pDAS->toc_flag      = 0;
423     if (traversal_flag)
424         pDAS->toc_flag  = _DT_HELP_SHADOW_TRAVERSAL | _DT_HELP_NOT_INITIALIZED;
425
426     pDAS->max_spc       = 0;
427     pDAS->cur_spc       = 0;
428     pDAS->maxX          = 0;
429     pDAS->virtualX      = 0;
430     pDAS->firstVisible  = 0;
431     pDAS->visibleCount  = rows;
432     pDAS->maxYpos       = 0;
433     pDAS->neededFlags   = 0;
434     pDAS->vert_init_scr = DA_args.initialDelay;
435     pDAS->vert_rep_scr  = DA_args.repeatDelay;
436     pDAS->horz_init_scr = DA_args.initialDelay;
437     pDAS->horz_rep_scr  = DA_args.repeatDelay;
438     pDAS->moveThreshold = DA_args.moveThreshold;
439     pDAS->marginWidth   = DA_args.marginWidth;
440     pDAS->marginHeight  = DA_args.marginHeight;
441     pDAS->searchColor   = DA_args.search_color;
442     pDAS->depth         = 0;
443     pDAS->spc_chars     = NULL;
444     pDAS->scr_timer_id  = NULL;
445     pDAS->def_pix       = NULL;
446     pDAS->context       = NULL;
447     pDAS->vertIsMapped  = False;
448     pDAS->horzIsMapped  = False;
449     pDAS->lst_topic     = NULL;
450     pDAS->nextNonVisible = 0;
451     pDAS->media_resolution = media_resolution;
452     pDAS->honor_size = honor_size;
453     pDAS->render_type = render_type;
454     pDAS->dtinfo = 0;
455     pDAS->stipple = None;
456
457     /*
458      * locale dependant information
459      */
460     pDAS->nl_to_space      = 1;
461     pDAS->cant_begin_chars = NULL;
462     pDAS->cant_end_chars   = NULL;
463     if (1 < MB_CUR_MAX)
464         _DtHelpLoadMultiInfo (&(pDAS->cant_begin_chars),
465                                 &(pDAS->cant_end_chars), &(pDAS->nl_to_space));
466
467     /*
468      * initialize the hypertext callback pointer
469      */
470     pDAS->exec_filter = exec_ok_routine;
471     pDAS->hyperCall   = hyperTextCB;
472     pDAS->resizeCall  = resizeCB;
473     pDAS->clientData  = client_data;
474
475     /*
476      * zero out other callback fields
477      */
478     pDAS->vScrollNotify = NULL ;
479     pDAS->armCallback = NULL ;
480
481     /*
482      * create the atoms needed
483      */
484     xa_ave_width = XmInternAtom(dpy, "AVERAGE_WIDTH"     , False);
485
486     /*
487      * Malloc for the default font.
488      */
489     (void) XmeRenderTableGetDefaultFont(DA_args.userFont, &tmpFont);
490     if (default_list != NULL &&
491                 XmFontListInitFontContext (&fontContext, default_list))
492       {
493         fontEntry = XmFontListNextEntry (fontContext);
494         if (fontEntry != NULL)
495             default_font = XmFontListEntryGetFont (fontEntry, &fontType);
496
497         XmFontListFreeFontContext (fontContext);
498       }
499
500     /*
501      * fake out the next call by using the parent as the display widget
502      */
503     pDAS->dispWid = parent;
504     __DtHelpFontDatabaseInit (pDAS, default_font, fontType, tmpFont);
505
506     /*
507      * Get the base font meterics.
508      */
509     __DtHelpFontMetrics (pDAS->font_info, __DtHelpDefaultFontIndexGet(pDAS),
510                         &maxFontAscent, &maxFontDescent, &maxFontCharWidth,
511                         NULL, NULL);
512
513     pDAS->leading    = DA_args.leading;
514     pDAS->fontAscent = maxFontAscent;
515     pDAS->lineHeight = maxFontAscent + maxFontDescent + pDAS->leading + 1;
516
517     n = __DtHelpDefaultFontIndexGet(pDAS);
518     if (n < 0)
519         value = get_fontsetproperty(__DtHelpFontSetGet(pDAS->font_info, n),
520                         xa_ave_width, ((unsigned long *) &(pDAS->charWidth)));
521     else
522         value = XGetFontProperty(__DtHelpFontStructGet(pDAS->font_info, n),
523                         xa_ave_width, ((unsigned long *) &(pDAS->charWidth)));
524
525     if (False == value || 0 == pDAS->charWidth)
526       {
527         int len = maxFontCharWidth;
528
529         if (n < 0)
530             len += XmbTextEscapement(
531                                 __DtHelpFontSetGet(pDAS->font_info,n),"1",1);
532         else
533             len += XTextWidth(__DtHelpFontStructGet(pDAS->font_info, n),"1",1);
534
535         pDAS->charWidth = 10 * len / 2;
536       }
537
538     /*
539      * Create the form to manage the window and scroll bars.
540      */
541     n = 0;
542     XtSetArg(args[n], XmNresizePolicy      , XmRESIZE_ANY);             ++n;
543     XtSetArg(args[n], XmNshadowType     , XmSHADOW_OUT);                ++n;
544     form = XmCreateForm(parent, "DisplayAreaForm", args, n);
545     XtManageChild(form);
546
547     /*
548      * force the shadowThickness to zero. The XmManager will try to set
549      * this to one.
550      */
551     n = 0;
552     XtSetArg(args[n], XmNshadowThickness   , 0);                        ++n;
553     XtSetArg(args[n], XmNhighlightThickness, 0);                        ++n;
554     XtSetValues (form, args, n);
555
556     /*
557      * get the colors and margin widths and heights
558      */
559     n = 0;
560     XtSetArg (args[n], XmNmarginWidth , &margin_width);         ++n;
561     XtSetArg (args[n], XmNmarginHeight, &margin_height);        ++n;
562     XtSetArg (args[n], XmNcolormap    , &colormap);             ++n;
563     XtGetValues(form, args, n);
564
565     /* Create the vertical scrollbar. */
566     pDAS->vertScrollWid = NULL;
567     if (vert_flag != _DtHelpNONE)
568       {
569         if (vert_flag == _DtHelpSTATIC)
570             pDAS->vertIsMapped = True;
571
572         n = 0;
573         XtSetArg(args[n], XmNtopAttachment     , XmATTACH_FORM);        ++n;
574         XtSetArg(args[n], XmNtopOffset         , 0);                    ++n;
575         XtSetArg(args[n], XmNbottomAttachment  , XmATTACH_FORM);        ++n;
576         XtSetArg(args[n], XmNbottomOffset      , margin_height);        ++n;
577         XtSetArg(args[n], XmNrightAttachment   , XmATTACH_FORM);        ++n;
578         XtSetArg(args[n], XmNrightOffset       , 0);                    ++n;
579         XtSetArg(args[n], XmNorientation       , XmVERTICAL);           ++n;
580         XtSetArg(args[n], XmNtraversalOn       , True);                 ++n;
581         XtSetArg(args[n], XmNhighlightThickness, 1);                    ++n;
582         XtSetArg(args[n], XmNshadowType        , XmSHADOW_IN);          ++n;
583         XtSetArg(args[n], XmNvalue             , 0);                    ++n;
584         XtSetArg(args[n], XmNminimum           , 0);                    ++n;
585         /* fake out the scrollbar manager, who will init dims to 100 */
586         XtSetArg(args[n], XmNheight            , 1);                    ++n;
587         XtSetArg(args[n], XmNmaximum           , 1);                    ++n;
588         XtSetArg(args[n], XmNincrement         , 1);                    ++n;
589         XtSetArg(args[n], XmNpageIncrement     , 1);                    ++n;
590         XtSetArg(args[n], XmNsliderSize        , 1);                    ++n;
591         XtSetArg(args[n], XtNmappedWhenManaged , pDAS->vertIsMapped);   ++n;
592         pDAS->vertScrollWid = XmCreateScrollBar(form,
593                                         "DisplayDtHelpVertScrollBar", args, n);
594
595         XtManageChild(pDAS->vertScrollWid);
596         if (vert_flag != _DtHelpSTATIC)
597             pDAS->neededFlags = _DtHelpSET_AS_NEEDED (pDAS->neededFlags,
598                                                 _DtHelpVERTICAL_SCROLLBAR);
599   
600         XtAddCallback(pDAS->vertScrollWid, XmNdragCallback,
601                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
602         XtAddCallback(pDAS->vertScrollWid, XmNincrementCallback,
603                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
604         XtAddCallback(pDAS->vertScrollWid, XmNdecrementCallback,
605                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
606         XtAddCallback(pDAS->vertScrollWid, XmNpageIncrementCallback,
607                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
608         XtAddCallback(pDAS->vertScrollWid, XmNpageDecrementCallback,
609                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
610         XtAddCallback(pDAS->vertScrollWid, XmNtoBottomCallback,
611                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
612         XtAddCallback(pDAS->vertScrollWid, XmNtoTopCallback,
613                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
614         XtAddCallback(pDAS->vertScrollWid, XmNvalueChangedCallback,
615                                         _DtHelpVertScrollCB, (XtPointer) pDAS);
616
617         XtAddEventHandler (pDAS->vertScrollWid, ButtonPressMask, True,
618                         (XtEventHandler)_DtHelpMoveBtnFocusCB,(XtPointer) pDAS);
619
620       }
621
622     /* Create the horizontal scrollbar. */
623     pDAS->horzScrollWid = NULL;
624     if (horz_flag != _DtHelpNONE)
625       {
626         if (horz_flag == _DtHelpSTATIC)
627             pDAS->horzIsMapped = True;
628
629         n = 0;
630         XtSetArg(args[n], XmNbottomAttachment  , XmATTACH_FORM);        ++n;
631         XtSetArg(args[n], XmNbottomOffset      , 0);                    ++n;
632         XtSetArg(args[n], XmNrightAttachment   , XmATTACH_FORM);        ++n;
633         XtSetArg(args[n], XmNrightOffset       , margin_width);         ++n;
634         XtSetArg(args[n], XmNleftAttachment    , XmATTACH_FORM);        ++n;
635         XtSetArg(args[n], XmNleftOffset        , 0);                    ++n;
636         XtSetArg(args[n], XmNorientation       , XmHORIZONTAL);         ++n;
637         XtSetArg(args[n], XmNtraversalOn       , True);                 ++n;
638         XtSetArg(args[n], XmNhighlightThickness, 1);                    ++n;
639         XtSetArg(args[n], XmNshadowType        , XmSHADOW_IN);          ++n;
640         XtSetArg(args[n], XmNvalue             , 0);                    ++n;
641         XtSetArg(args[n], XmNminimum           , 0);                    ++n;
642         XtSetArg(args[n], XmNmaximum           , (pDAS->charWidth/10)); ++n;
643         /* fake out the scrollbar manager, who will init dims to 100 */
644         XtSetArg(args[n], XmNwidth             , 1);                    ++n;
645         XtSetArg(args[n], XmNincrement         , (pDAS->charWidth/10)); ++n;
646         XtSetArg(args[n], XmNpageIncrement     , (pDAS->charWidth/10)); ++n;
647         XtSetArg(args[n], XmNsliderSize        , (pDAS->charWidth/10)); ++n;
648         XtSetArg(args[n], XtNmappedWhenManaged , pDAS->horzIsMapped);   ++n;
649         pDAS->horzScrollWid = XmCreateScrollBar(form,
650                                         "DisplayHorzScrollBar", args, n);
651         XtManageChild(pDAS->horzScrollWid);
652         if (horz_flag != _DtHelpSTATIC)
653             pDAS->neededFlags = _DtHelpSET_AS_NEEDED (pDAS->neededFlags,
654                                                 _DtHelpHORIZONTAL_SCROLLBAR);
655   
656         XtAddCallback(pDAS->horzScrollWid, XmNdragCallback,
657                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
658         XtAddCallback(pDAS->horzScrollWid, XmNincrementCallback,
659                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
660         XtAddCallback(pDAS->horzScrollWid, XmNdecrementCallback,
661                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
662         XtAddCallback(pDAS->horzScrollWid, XmNpageIncrementCallback,
663                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
664         XtAddCallback(pDAS->horzScrollWid, XmNpageDecrementCallback,
665                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
666         XtAddCallback(pDAS->horzScrollWid, XmNtoBottomCallback,
667                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
668         XtAddCallback(pDAS->horzScrollWid, XmNtoTopCallback,
669                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
670         XtAddCallback(pDAS->horzScrollWid, XmNvalueChangedCallback,
671                                         _DtHelpHorzScrollCB, (XtPointer) pDAS);
672       }
673
674     /*
675      * check for the horizontal attachments
676      */
677     n = 0;
678     if (horz_flag == _DtHelpSTATIC)
679       {
680         XtSetArg(args[n], XmNbottomAttachment  , XmATTACH_WIDGET);      ++n;
681         XtSetArg(args[n], XmNbottomWidget      , pDAS->horzScrollWid);  ++n;
682       }
683     else
684       {
685         XtSetArg(args[n], XmNbottomAttachment  , XmATTACH_FORM);        ++n;
686       }
687
688     /*
689      * check for the vertical attachments
690      */
691     if (vert_flag == _DtHelpSTATIC)
692       {
693         XtSetArg(args[n], XmNrightAttachment   , XmATTACH_WIDGET);      ++n;
694         XtSetArg(args[n], XmNrightWidget       , pDAS->vertScrollWid);  ++n;
695       }
696     else
697       {
698         XtSetArg(args[n], XmNrightAttachment  , XmATTACH_FORM);         ++n;
699       }
700
701     /*
702      * do the rest of the arguments
703      */
704     XtSetArg(args[n], XmNbottomOffset      , margin_height);            ++n;
705     XtSetArg(args[n], XmNrightOffset       , margin_width);             ++n;
706     XtSetArg(args[n], XmNtopAttachment     , XmATTACH_FORM);            ++n;
707     XtSetArg(args[n], XmNtopOffset         , 0);                        ++n;
708     XtSetArg(args[n], XmNleftAttachment    , XmATTACH_FORM);            ++n;
709     XtSetArg(args[n], XmNleftOffset        , 0);                        ++n;
710     XtSetArg(args[n], XmNrecomputeSize     , False);                    ++n;
711     XtSetArg(args[n], XmNpushButtonEnabled , False);                    ++n;
712     XtSetArg(args[n], XmNtraversalOn       , True);                     ++n;
713     XtSetArg(args[n], XmNhighlightThickness, 1);                        ++n;
714     XtSetArg(args[n], XmNshadowType        , XmSHADOW_IN);              ++n;
715     XtSetArg(args[n], XmNmultiClick        , XmMULTICLICK_DISCARD);     ++n;
716     XtSetArg(args[n], XmNuserData          , pDAS);                     ++n;
717     pDAS->dispWid = XmCreateDrawnButton(form, name, args, n);
718     XtManageChild(pDAS->dispWid);
719   
720     XtAddCallback(pDAS->dispWid, XmNexposeCallback, _DtHelpExposeCB,
721                                                 (XtPointer) pDAS);
722     XtAddCallback(pDAS->dispWid, XmNresizeCallback, _DtHelpResizeCB,
723                                                 (XtPointer) pDAS);
724     XtAddCallback(pDAS->dispWid, XmNarmCallback, _DtHelpClickOrSelectCB,
725                                                 (XtPointer) pDAS);
726     XtAddCallback(pDAS->dispWid, XmNdisarmCallback, _DtHelpEndSelectionCB,
727                                                 (XtPointer) pDAS);
728
729     XtAddEventHandler (pDAS->dispWid, Button1MotionMask, True,
730                         (XtEventHandler)_DtHelpMouseMoveCB, (XtPointer) pDAS);
731
732     /*
733      * add my actions
734      * parse the translations.
735      */
736     _DtHelpProcessLock();
737     if (DrawnBTrans == NULL)
738         DrawnBTrans = XtParseTranslationTable(DrawnBTransTable);
739
740      /*
741      * override the translations
742     XtSetArg(args[n], XmNtranslations      , DrawnBTrans);              ++n;
743      */
744     if (DrawnBTrans != NULL)
745         XtOverrideTranslations(pDAS->dispWid, DrawnBTrans);
746     _DtHelpProcessUnlock();
747   
748     if (_XmGetFocusPolicy(parent) == XmPOINTER)
749       {
750         XtAddEventHandler (pDAS->dispWid, EnterWindowMask, True,
751                         (XtEventHandler)_DtHelpEnterLeaveCB, (XtPointer) pDAS);
752         XtAddEventHandler (pDAS->dispWid, LeaveWindowMask, True,
753                         (XtEventHandler)_DtHelpEnterLeaveCB, (XtPointer) pDAS);
754       }
755     else
756         XtAddEventHandler (pDAS->dispWid, FocusChangeMask, True,
757                         (XtEventHandler)_DtHelpFocusCB, (XtPointer) pDAS);
758
759     XtAddEventHandler (pDAS->dispWid, VisibilityChangeMask, True,
760                         (XtEventHandler)_DtHelpVisibilityCB, (XtPointer) pDAS);
761   
762
763     /* Add a destroy callback so that the display area can clean up prior to
764      * the help widget getting destroyed (e.g. display area's parent) 
765      */
766     XtAddCallback(pDAS->dispWid, XmNdestroyCallback,
767                                 _DtHelpDisplayAreaDestroyCB, (XtPointer) pDAS);
768   
769     n = 0;
770     XtSetArg(args[n], XmNshadowThickness   , &shadowThick);     ++n;
771     XtSetArg(args[n], XmNhighlightThickness, &highThick);       ++n;
772     XtSetArg(args[n], XmNforeground    , &(pDAS->foregroundColor)); ++n;
773     XtSetArg(args[n], XmNbackground    , &(pDAS->backgroundColor)); ++n;
774     XtSetArg(args[n], XmNhighlightColor, &(pDAS->traversalColor) ); ++n;
775     XtSetArg(args[n], XmNdepth         , &(pDAS->depth)          ); ++n;
776     XtGetValues(pDAS->dispWid, args, n);
777     pDAS->decorThickness = shadowThick + highThick;
778
779     /*
780      * Get the underline information
781      */
782     GetUnderLineInfo (dpy, pDAS, &(pDAS->lineThickness));
783
784     /*
785      * get the tiling pattern.
786      */
787     tile = XmGetPixmap (XtScreen(pDAS->dispWid), "50_foreground",
788                                 pDAS->foregroundColor, pDAS->backgroundColor);
789
790     /*
791      * Get the data for the graphics contexts and create the GC's.
792      */
793     gcMask = (GCFunction   | GCPlaneMask   | GCForeground  |
794                 GCBackground  | GCLineWidth   | GCLineStyle   |
795                 GCClipXOrigin | GCClipYOrigin | GCClipMask);
796
797     gcValues.function      = GXcopy;
798     gcValues.plane_mask    = AllPlanes;
799     gcValues.foreground    = pDAS->foregroundColor;
800     gcValues.background    = pDAS->backgroundColor;
801     gcValues.line_style    = LineSolid;
802     gcValues.line_width    = pDAS->lineThickness;
803     gcValues.clip_x_origin = 0;
804     gcValues.clip_y_origin = 0;
805     gcValues.clip_mask     = None;
806     if (tile)
807       {
808         gcMask |= GCTile;
809         gcValues.tile = tile;
810       }
811  
812     pDAS->normalGC = XCreateGC(dpy,
813                 RootWindowOfScreen(XtScreen(pDAS->dispWid)), gcMask, &gcValues);
814
815     gcMask &= (~GCTile);
816     pDAS->pixmapGC = XCreateGC(dpy,
817                 RootWindowOfScreen(XtScreen(pDAS->dispWid)), gcMask, &gcValues);
818   
819     gcValues.foreground = pDAS->backgroundColor;
820     gcValues.background = pDAS->foregroundColor;
821     pDAS->invertGC = XCreateGC(dpy,
822                 RootWindowOfScreen(XtScreen(pDAS->dispWid)), gcMask, &gcValues);
823   
824     /*
825      * Set the size of the text view area to the requested
826      * number of columns and lines.
827      */
828     char_width          = pDAS->charWidth * columns;
829
830     /*
831      * Make sure the margins include enough room for a traversal line
832      */
833     if (((int) pDAS->marginWidth) < pDAS->lineThickness)
834         pDAS->marginWidth = pDAS->lineThickness;
835     if (((int) pDAS->marginHeight) < pDAS->lineThickness)
836         pDAS->marginHeight = pDAS->lineThickness;
837     if (pDAS->leading < pDAS->lineThickness)
838         pDAS->leading = pDAS->lineThickness;
839
840     /*
841      * get the scrollbar widths.
842      */
843     if (NULL != pDAS->horzScrollWid)
844       {
845         n = 0;
846         XtSetArg(args[n], XmNheight      , &hBarHeight); n++;
847         XtSetArg(args[n], XmNinitialDelay, &(pDAS->horz_init_scr)); n++;
848         XtSetArg(args[n], XmNrepeatDelay , &(pDAS->horz_rep_scr));  n++;
849         XtGetValues(pDAS->horzScrollWid, args, n);
850       }
851
852     if (NULL != pDAS->vertScrollWid)
853       {
854         n = 0;
855         XtSetArg(args[n], XmNwidth       , &vBarWidth);             n++;
856         XtSetArg(args[n], XmNinitialDelay, &(pDAS->vert_init_scr)); n++;
857         XtSetArg(args[n], XmNrepeatDelay , &(pDAS->vert_rep_scr));  n++;
858         XtGetValues(pDAS->vertScrollWid, args, n);
859       }
860
861     /*
862      * calculate the display area height/width
863      */
864     pDAS->dispUseWidth  = ((int) (char_width / 10 + (char_width % 10 ? 1 : 0)))
865                                               + 2 * pDAS->marginWidth;
866     if (vert_flag != _DtHelpSTATIC && pDAS->dispUseWidth < vBarWidth)
867         pDAS->dispUseWidth = vBarWidth;
868     pDAS->dispWidth     = pDAS->dispUseWidth  + 2 * pDAS->decorThickness;
869
870     pDAS->dispUseHeight = pDAS->lineHeight * rows;
871     if (horz_flag != _DtHelpSTATIC && pDAS->dispUseHeight < hBarHeight)
872         pDAS->dispUseHeight = hBarHeight;
873     pDAS->dispHeight    = pDAS->dispUseHeight + 2 * pDAS->decorThickness;
874
875     /*
876      * Truncate the width and height to the size of the display.
877      * This will prevent an X protocal error when it is asked for
878      * a too large size. Besides, any decent window manager will
879      * force the overall size to the height and width of the display.
880      * This simply refines the size down to a closer (but not perfect)
881      * fit.
882      */
883     if (((int) pDAS->dispWidth) > XDisplayWidth (dpy, screen)) {
884         pDAS->dispWidth = XDisplayWidth (dpy, screen);
885     }
886     if (((int) pDAS->dispHeight) > XDisplayHeight (dpy, screen)) {
887         pDAS->dispHeight = XDisplayHeight (dpy, screen);
888     }
889
890     n = 0;
891     pDAS->formWidth  = 0;
892     pDAS->formHeight = 0;
893     XtSetArg(args[n], XmNwidth, pDAS->dispWidth);               ++n;
894     XtSetArg(args[n], XmNheight, pDAS->dispHeight);             ++n;
895     XtSetValues(pDAS->dispWid, args, n);
896
897     /*
898      * set the scroll bar values
899      */
900     if (pDAS->vertScrollWid != NULL)
901       {
902         n = 0;
903         XtSetArg(args[n], XmNmaximum           , pDAS->dispUseHeight);  ++n;
904         XtSetArg(args[n], XmNincrement         , pDAS->lineHeight);     ++n;
905         XtSetArg(args[n], XmNpageIncrement     , pDAS->lineHeight);     ++n;
906         XtSetArg(args[n], XmNsliderSize        , pDAS->dispUseHeight);  ++n;
907         XtSetValues(pDAS->vertScrollWid, args, n);
908       }
909   
910     if (pDAS->resizeCall)
911         (*(pDAS->resizeCall)) (pDAS->clientData);
912
913     /*
914      * calculate the offset for the right edge of the
915      * horizontal scrollbar.
916      */
917     if (vert_flag == _DtHelpSTATIC && pDAS->horzScrollWid)
918       {
919         width = vBarWidth + margin_width;
920
921         XtSetArg(args[0], XmNrightOffset , width);
922         XtSetValues(pDAS->horzScrollWid, args, 1);
923       }
924
925     /*
926      * calculate the offset for the bottom end of the
927      * vertical scrollbar.
928      */
929     if (horz_flag == _DtHelpSTATIC && pDAS->vertScrollWid)
930       {
931         width = hBarHeight + margin_height;
932
933         XtSetArg(args[0], XmNbottomOffset , width);
934         XtSetValues(pDAS->vertScrollWid, args, 1);
935       }
936
937     rectangle[0].x      = pDAS->decorThickness;
938     rectangle[0].y      = pDAS->decorThickness;
939     rectangle[0].width  = pDAS->dispUseWidth;
940     rectangle[0].height = pDAS->dispUseHeight;
941     XSetClipRectangles(XtDisplay(pDAS->dispWid), pDAS->normalGC, 0, 0,
942                                                 rectangle, 1, Unsorted);
943     XSetClipRectangles(XtDisplay(pDAS->dispWid), pDAS->invertGC, 0, 0,
944                                                 rectangle, 1, Unsorted);
945
946     /*
947      * get the colormap and the visual
948      */
949     if (!XtIsShell(parent) && XtParent(parent) != NULL)
950         parent = XtParent(parent);
951
952     pDAS->visual = NULL;
953
954     n = 0;
955     XtSetArg (args[n], XmNcolormap, &(pDAS->colormap)); n++;
956     XtSetArg (args[n], XmNvisual  , &(pDAS->visual  )); n++;
957     XtGetValues (parent, args, n);
958
959     if (pDAS->visual == NULL)
960         pDAS->visual = XDefaultVisualOfScreen(XtScreen(pDAS->dispWid));
961
962     /*
963      * set up the canvas
964      */
965     _DtHelpProcessLock();
966     DefVirtFunctions.exec_cmd_filter = exec_ok_routine;
967
968     pDAS->canvas = _DtCanvasCreate (DefVirtFunctions, (_DtCvPointer) pDAS);
969     _DtHelpProcessUnlock();
970
971     return (XtPointer) pDAS;
972
973 }  /* End _DtHelpCreateDA */
974
975
976 /*********************************************************************
977  * Function: CreateDisplayArea
978  *
979  *    Creates a Text Graphic area with the appropriate scroll bars.
980  *    specifying the size with rows and columns
981  *
982  *********************************************************************/
983 XtPointer
984 _DtHelpCreateDisplayArea(
985     Widget       parent,
986     char        *name,
987     short        vert_flag,
988     short        horz_flag,
989     Boolean      traversal_flag,
990     int          rows,
991     int          columns,
992     void        (*hyperTextCB)(),
993     void        (*resizeCB)(),
994     int         (*exec_ok_routine)(),
995     XtPointer    client_data,
996     XmFontList   default_list )
997 {
998     return HelpCreateDA(parent, name,
999                         vert_flag, horz_flag,
1000                         traversal_flag,
1001                         _DtCvIGNORE_BOUNDARY, _DtCvRENDER_PARTIAL,
1002                         rows, columns, 100,
1003                         hyperTextCB, resizeCB, exec_ok_routine,
1004                         client_data, default_list);
1005 }
1006
1007 /*********************************************************************
1008  * Function: CreateOutputArea
1009  *
1010  *    Creates a Text Graphic area with the appropriate scroll bars.
1011  *    specifying the size with width and height
1012  *
1013  *********************************************************************/
1014 XtPointer
1015 _DtHelpCreateOutputArea(
1016     Widget       parent,
1017     char        *name,
1018     short        vert_flag,
1019     short        horz_flag,
1020     Boolean      traversal_flag,
1021     _DtCvValue   honor_size,
1022     _DtCvRenderType render_type,
1023     Dimension    width,
1024     Dimension    height,
1025     unsigned short media_resolution,
1026     void        (*hyperTextCB)(),
1027     void        (*resizeCB)(),
1028     int         (*exec_ok_routine)(),
1029     XtPointer    client_data,
1030     XmFontList   default_list )
1031 {
1032     DtHelpDispAreaStruct *pDAS;
1033
1034     pDAS = HelpCreateDA(parent, name,
1035                         vert_flag, horz_flag,
1036                         traversal_flag, honor_size, render_type,
1037                         1, 1, media_resolution,
1038                         hyperTextCB, resizeCB, exec_ok_routine,
1039                         client_data, default_list);
1040     /* if area created successfully, then resize it to the given size */
1041     if (pDAS)
1042         _DtHelpSetScrollBars(pDAS, width, height);
1043
1044     return pDAS;
1045 }