1 /* $XConsortium: SetList.c /main/16 1996/11/18 16:35:22 cde-hp $ */
2 /************************************<+>*************************************
3 ****************************************************************************
7 ** Project: Text Graphic Display Library
9 ** Description: This body of code creates the Line and Graphic Tables for
13 ****************************************************************************
14 ************************************<+>*************************************/
16 * (c) Copyright 1996 Digital Equipment Corporation.
17 * (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992,
18 1993, 1994, 1996 Hewlett-Packard Company.
19 * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
20 * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
21 * (c) Copyright 1993, 1994, 1996 Novell, Inc.
22 * (c) Copyright 1996 FUJITSU LIMITED.
23 * (c) Copyright 1996 Hitachi.
38 #include "CanvasSegP.h"
45 #include "DisplayAreaP.h"
46 #include "CallbacksI.h"
47 #include "FontAttrI.h"
49 #include "XInterfaceI.h"
50 #include "XUICreateI.h"
56 /******** Private Function Declarations ********/
57 /******** End Public Function Declarations ********/
59 /******************************************************************************
61 * Private defines and variables
63 *****************************************************************************/
68 /******************************************************************************
72 *****************************************************************************/
73 #define NeedVertScrollbar(x) \
74 _DtHelpIS_AS_NEEDED((x)->neededFlags,_DtHelpVERTICAL_SCROLLBAR)
75 #define NeedHorzScrollbar(x) \
76 _DtHelpIS_AS_NEEDED((x)->neededFlags,_DtHelpHORIZONTAL_SCROLLBAR)
77 /******************************************************************************
81 *****************************************************************************/
84 DtHelpDispAreaStruct *pDAS,
89 pDAS->maxYpos = max_y + pDAS->marginHeight;
92 /******************************************************************************
94 * Semi Public Functions - these routines called by other modules within
97 *****************************************************************************/
98 /******************************************************************************
99 * Function: _DtHelpSetScrollBars
101 * Sets/Resets the vertical scroll bar values.
102 *****************************************************************************/
103 enum DoSomething { DoNothing, DoManage, DoUnmanage };
105 _DtHelpSetScrollBars (
106 XtPointer client_data,
108 Dimension new_height)
114 int changeHeight = 0;
120 int oldScrollPercent = 10000;
123 _DtCvUnit ret_height;
128 Dimension marginWidth;
129 Dimension marginHeight;
130 Dimension horzHeight;
135 XRectangle rectangle[1];
137 enum DoSomething doVert = DoNothing;
138 enum DoSomething doHorz = DoNothing;
139 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
142 * remember the old first line.
144 oldMaxYpos = pDAS->maxYpos;
145 if (pDAS->firstVisible && pDAS->maxYpos)
146 oldScrollPercent = pDAS->firstVisible * 10000 / pDAS->maxYpos;
149 * get the width and height of the scroll bars.
151 if (pDAS->vertScrollWid)
153 XtSetArg (args[0], XmNwidth , &vertWidth);
154 XtGetValues (pDAS->vertScrollWid, args, 1);
157 if (pDAS->horzScrollWid)
159 XtSetArg (args[0], XmNheight , &horzHeight);
160 XtGetValues (pDAS->horzScrollWid, args, 1);
164 * remember our old width and height
166 oldWidth = pDAS->dispWidth;
167 oldHeight = pDAS->dispHeight;
170 * Settle the sizing issue before we remap the scroll bars.
177 if (new_height != pDAS->dispHeight)
179 pDAS->dispHeight = new_height;
180 pDAS->dispUseHeight = new_height - 2 * pDAS->decorThickness;
181 if (((int) new_height) < 2 * ((int) pDAS->decorThickness))
182 pDAS->dispUseHeight = 0;
184 pDAS->visibleCount = ((int) pDAS->dispUseHeight) /
187 if (pDAS->visibleCount < 0)
188 pDAS->visibleCount = 0;
192 * check to see if we've changed width
194 if (new_width != pDAS->dispWidth)
199 pDAS->dispWidth = new_width;
200 pDAS->dispUseWidth = new_width - 2 * pDAS->decorThickness;
201 if (((int)new_width) < 2 * ((int) pDAS->decorThickness))
202 pDAS->dispUseWidth = 0;
205 * re-layout the information.
207 if (_DtCvSTATUS_OK ==
208 _DtCanvasResize(pDAS->canvas, _DtCvFALSE,
209 &ret_width, &ret_height))
210 SetMaxPositions (pDAS, ret_width, ret_height);
215 * Check to see if we have a vertical scrollbar and whether it
216 * is as_needed. If static, it is always mapped.
218 if (NULL != pDAS->vertScrollWid && NeedVertScrollbar(pDAS))
221 * will the information fit on one page?
223 if (pDAS->maxYpos <= ((int) pDAS->dispUseHeight))
226 * If the window has not already been 'stretched' by
227 * the width of the scrollbar and if the scrollbar is
228 * mapped, grow the window width.
230 if (0 == changeWidth && pDAS->vertIsMapped)
233 * set the flag to indicate that the window width
234 * has grown. This can occur only if the window
235 * has its vertical scrollbar already mapped.
238 new_width += vertWidth;
241 * Else check to see if the window has been shrunk.
242 * If so, then stretch it back out to its original
245 * This can occur only if
246 * a) The vertical scrollbar is not mapped.
247 * b) The previous pass through this code indicates
248 * that the window could not hold the length of
249 * the information, and therefore calculations and
250 * flags were set to map the vertical scrollbar.
251 * But a _DtCanvasResize() now indicates that a
252 * vertical scrollbar is not needed. So we don't
253 * need the vertical scrollbar and have to nuliify
254 * the calculation to include it.
256 else if (-1 == changeWidth)
259 new_width += vertWidth;
263 * The information will not fit on one page.
268 * If the window has not already been shrunk to
269 * accomidate the vertical scrollbar (and the scrollbar
270 * is not already mapped) then set the flags and
273 if (False == pDAS->vertIsMapped && 0 == changeWidth)
276 * set the flag to indicate that the window width
277 * has shrunk (and that consequently, the vertical
278 * scrollbar is not mapped).
281 if (new_width > vertWidth)
282 new_width -= vertWidth;
287 * Else check to see if the window has been streched.
288 * If so, then shrink it back out to its original
291 * This can occur only if
292 * a) The vertical scrollbar is mapped.
293 * b) The previous pass through this code indicates
294 * that the window could hold the length of
295 * the information, and therefore calculations and
296 * flags were set to unmap the vertical scrollbar.
297 * But a _DtCanvasResize() now indicates that a
298 * vertical scrollbar is needed. So we need
299 * the vertical scrollbar and have to nuliify
300 * the calculation to eliminate it.
302 else if (1 == changeWidth)
305 new_width -= vertWidth;
311 * Check to see if we have a horizontal scrollbar and whether it
312 * is as_needed. If static, it is always mapped.
314 if (NULL != pDAS->horzScrollWid && NeedHorzScrollbar(pDAS))
317 * will the information fit within the right border?
319 if (pDAS->maxX <= ((int) pDAS->dispUseWidth))
322 * If the window has not already been 'stretched' by
323 * the height of the scrollbar and if the scrollbar is
324 * mapped, grow the window.
326 if (0 == changeHeight && pDAS->horzIsMapped)
329 * set the flag to indicate that the window has
330 * grown. This can occur only if the window has
331 * its horizontal scrollbar already mapped.
334 new_height += horzHeight;
337 * Else check to see if the window has been shrunk.
338 * If so, stretch it back to its original height.
340 * This can occur only if
341 * a) The horizontal scrollbar is not mapped.
342 * b) The previous pass through the code indicated
343 * that the information exceeded the right border
344 * and therefore calculations and flags were set
345 * to map the horizontal scrollbar. But a
346 * _DtCanvasResize() now indicates that the
347 * horizontal scrollbar is not needed. So we
348 * have to nullify the calculations and flags
351 else if (-1 == changeHeight)
354 new_height += horzHeight;
358 * The information exceeds the right border of the window.
363 * If the window has no already been shrunk to
364 * accomidate the horizontal scrollbar (and the
365 * scrollbar is not already mapped), then set the
366 * flags and shrink the height.
368 if (False == pDAS->horzIsMapped && 0 == changeHeight)
371 * set the flag to indicate that the window height
372 * has shrunk (and that the scrollbar needs mapping).
375 if (new_height > horzHeight)
376 new_height -= horzHeight;
381 * Else check to see if the window has been streched.
382 * If so, then shrink it back out to its original
385 * This can occur only if
386 * a) The horizontal scrollbar is mapped.
387 * b) The previous pass through the code indicated
388 * that the information did not exceeded the right
389 * border and therefore calculations and flags were
390 * set to unmap the horizontal scrollbar. But a
391 * _DtCanvasResize() now indicates that the
392 * horizontal scrollbar is needed. So we
393 * have to nullify the calculations and flags
396 else if (1 == changeHeight)
399 new_height -= horzHeight;
404 } while (new_height != pDAS->dispHeight || new_width != pDAS->dispWidth);
407 * reset the first visible line, if needed.
409 if (oldScrollPercent != 10000 && pDAS->maxYpos != oldMaxYpos)
410 pDAS->firstVisible = pDAS->maxYpos * oldScrollPercent / 10000;
412 if (pDAS->firstVisible + ((int)pDAS->dispUseHeight) > pDAS->maxYpos)
413 pDAS->firstVisible = pDAS->maxYpos - pDAS->dispUseHeight;
415 if (pDAS->firstVisible < 0)
416 pDAS->firstVisible = 0;
419 * Reset the virtual X value, if needed
421 if (pDAS->virtualX &&
422 (pDAS->maxX - pDAS->virtualX < ((int) pDAS->dispUseWidth)))
424 pDAS->virtualX = pDAS->maxX - pDAS->dispUseWidth;
425 if (pDAS->virtualX < 0)
430 * If I've changed my size, I've got to change my clip masks.
432 if (oldWidth != pDAS->dispWidth || oldHeight != pDAS->dispHeight)
435 * If the display area hasn't been realized, the resetting of
436 * the bottom right corner offsets will not cause a resize
437 * event to occur. Rather the overall window will grow by
438 * the width or height of the scroll bar and not cause the
439 * display area to shrink. Therefore when the exposure event
440 * is called the width or height will be not be equal to what
441 * I think it should be causing the code to believe a resize
442 * is in process. The short of the matter is that the exposure
443 * will not happen and we end up with a blank window.
445 * So for this case, resize the display area to what we think it
446 * should be and the exposure event will then happen.
447 if (!XtIsRealized (pDAS->dispWid))
450 XtSetArg(dispArgs[dispN], XmNwidth, pDAS->dispWidth); ++dispN;
451 XtSetArg(dispArgs[dispN], XmNheight, pDAS->dispHeight); ++dispN;
454 rectangle[0].x = pDAS->decorThickness;
455 rectangle[0].y = pDAS->decorThickness;
456 rectangle[0].width = pDAS->dispUseWidth;
457 rectangle[0].height = pDAS->dispUseHeight;
459 XSetClipRectangles(XtDisplay(pDAS->dispWid), pDAS->normalGC, 0, 0,
460 rectangle, 1, Unsorted);
461 XSetClipRectangles(XtDisplay(pDAS->dispWid), pDAS->invertGC, 0, 0,
462 rectangle, 1, Unsorted);
464 if (pDAS->resizeCall)
465 (*(pDAS->resizeCall)) (pDAS->clientData);
469 * Has the width changed? If so, then we are mapping or unmapping
470 * the vertical scrollbar.
472 if (-1 == changeWidth)
475 * manage the scrollbar, the window has shrunk.
479 XtSetArg(dispArgs[dispN], XmNrightAttachment, XmATTACH_WIDGET);
481 XtSetArg(dispArgs[dispN], XmNrightWidget, pDAS->vertScrollWid);
484 else if (1 == changeWidth)
487 * unmanage the scrollbar, the window has grown.
491 XtSetArg(dispArgs[dispN], XmNrightAttachment, XmATTACH_FORM);
496 * Has the height changed? If so, then we are mapping or unmapping
497 * the horizontal scrollbar.
499 if (-1 == changeHeight)
502 * manage the scrollbar, the window has shrunk.
506 XtSetArg(dispArgs[dispN], XmNbottomAttachment,XmATTACH_WIDGET);
508 XtSetArg(dispArgs[dispN], XmNbottomWidget,pDAS->horzScrollWid);
511 else if (1 == changeHeight)
514 * unmanage the scrollbar, the window has grown.
518 XtSetArg(dispArgs[dispN], XmNbottomAttachment, XmATTACH_FORM);
523 * get the margins, widths and height.
525 XtSetArg (args[0], XmNmarginWidth , &marginWidth);
526 XtSetArg (args[1], XmNmarginHeight, &marginHeight);
527 XtGetValues (XtParent (pDAS->dispWid), args, 2);
530 * have to map the scroll bars before the drawn button can be
531 * attached to them and can't unmap the scroll bars until
532 * the drawn button has been unattached from them. But we
533 * want to do the re-attachments all at once to minimize the
536 if (doHorz == DoManage)
538 if (!XtIsRealized(pDAS->horzScrollWid))
539 XtSetMappedWhenManaged (pDAS->horzScrollWid, True);
541 XtMapWidget (pDAS->horzScrollWid);
542 pDAS->horzIsMapped = True;
545 if (doVert == DoManage)
547 if (!XtIsRealized(pDAS->vertScrollWid))
548 XtSetMappedWhenManaged (pDAS->vertScrollWid, True);
550 XtMapWidget (pDAS->vertScrollWid);
551 pDAS->vertIsMapped = True;
554 if (pDAS->vertScrollWid && pDAS->vertIsMapped && doVert != DoUnmanage)
556 if (pDAS->horzScrollWid && pDAS->horzIsMapped && doHorz != DoUnmanage)
557 XtSetArg(args[0], XmNbottomOffset, (marginHeight + horzHeight));
559 XtSetArg(args[0], XmNbottomOffset, marginHeight);
564 * set the slider size.
566 slideSize = pDAS->dispUseHeight;
571 * determine the maximum size
573 maximum = pDAS->maxYpos;
575 if (maximum < slideSize)
582 * determine the page increment.
585 if (((int)pDAS->dispUseHeight) - pDAS->lineHeight > 2)
586 pageInc = pDAS->dispUseHeight - pDAS->lineHeight;
588 XtSetArg (args[n], XmNvalue , pDAS->firstVisible); ++n;
589 XtSetArg (args[n], XmNsliderSize , slideSize); ++n;
590 XtSetArg (args[n], XmNmaximum , maximum); ++n;
591 XtSetArg (args[n], XmNpageIncrement, pageInc); ++n;
592 XtSetValues (pDAS->vertScrollWid, args, n);
595 if (pDAS->horzScrollWid && pDAS->horzIsMapped && doHorz != DoUnmanage)
597 if (pDAS->vertScrollWid && pDAS->vertIsMapped && doVert != DoUnmanage)
598 XtSetArg(args[0], XmNrightOffset, (marginWidth + vertWidth));
600 XtSetArg(args[0], XmNrightOffset, marginWidth);
604 * determine the slider size.
606 slideSize = pDAS->dispUseWidth - 1;
611 * determine the maximum size
614 if (maximum < pDAS->maxX)
615 maximum = pDAS->maxX - 1;
621 * determine the page increment.
624 if (((int) pDAS->dispUseWidth) > 2)
625 pageInc = pDAS->dispUseWidth - 1;
627 XtSetArg (args[n], XmNvalue , pDAS->virtualX); n++;
628 XtSetArg (args[n], XmNsliderSize , slideSize); n++;
629 XtSetArg (args[n], XmNmaximum , maximum); n++;
630 XtSetArg (args[n], XmNpageIncrement, pageInc); ++n;
631 XtSetValues (pDAS->horzScrollWid, args, n);
635 * set the display area args
638 XtSetValues (pDAS->dispWid, dispArgs, dispN);
641 * unmap those we don't want.
643 if (doHorz == DoUnmanage)
645 if (!XtIsRealized(pDAS->horzScrollWid))
646 XtSetMappedWhenManaged (pDAS->horzScrollWid, False);
648 XtUnmapWidget (pDAS->horzScrollWid);
649 pDAS->horzIsMapped = False;
652 if (doVert == DoUnmanage)
654 if (!XtIsRealized(pDAS->vertScrollWid))
655 XtSetMappedWhenManaged (pDAS->vertScrollWid, False);
657 XtUnmapWidget (pDAS->vertScrollWid);
658 pDAS->vertIsMapped = False;
662 * return whether or not we generated a resize (and hence an expose
663 * event) by resizing the display area.
665 return (dispN ? True : False);
667 } /* End _DtHelpSetScrollBars */
669 /******************************************************************************
671 * Public Functions - those an application developer can call.
673 *****************************************************************************/
675 /*********************************************************************
678 * SetList creates a Text Graphic area with the appropriate scroll bars.
680 *********************************************************************/
682 _DtHelpDisplayAreaSetList (
683 XtPointer client_data,
684 XtPointer topic_handle,
691 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
694 * clear the selection
696 _DtHelpClearSelection (client_data);
699 * If there is anything to do
701 _DtCanvasSetTopic (pDAS->canvas, (_DtCvTopicPtr) topic_handle,
703 &width, &height, &scrollY);
706 * free the old topic and remember the new
708 _DtHelpDestroyTopicData(pDAS->lst_topic, _DtHelpDADestroyRegion,
709 (_DtCvPointer) pDAS);
711 pDAS->lst_topic = (_DtCvTopicPtr) topic_handle;
714 * do we want to scroll?
716 if (scroll_percent != -1)
717 scrollY = scroll_percent * height / 1000;
720 * Reset the scroll bars and perhaps do an expose.
722 SetMaxPositions (pDAS, width, height);
724 pDAS->firstVisible = scrollY;
726 if (pDAS->firstVisible + ((int)pDAS->dispUseHeight) > pDAS->maxYpos)
727 pDAS->firstVisible = pDAS->maxYpos - pDAS->dispUseHeight;
729 if (pDAS->firstVisible < 0)
730 pDAS->firstVisible = 0;
732 (void) _DtHelpSetScrollBars (client_data, pDAS->dispWidth, pDAS->dispHeight);
733 if (XtIsRealized (pDAS->dispWid))
734 _DtHelpCleanAndDrawWholeCanvas(client_data);
736 } /* End _DtHelpDisplayAreaSetList */
738 /*****************************************************************************
739 * Function: void _DtHelpDisplayAreaDimensionsReturn (DtHelpDispAreaStruct *pDAS,
740 * int *ret_width, int *ret_height)
742 * Parameters pDAS Specifies the Display Area.
743 * ret_rows Returns the number of rows in
745 * ret_columns Returns the number of columns in
750 * Purpose: Allows access to the height and width of a Display Area.
752 *****************************************************************************/
754 _DtHelpDisplayAreaDimensionsReturn (
755 XtPointer client_data,
759 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
761 *ret_rows = ((int)pDAS->dispUseHeight) / pDAS->lineHeight;
762 *ret_columns = ((int) pDAS->dispUseWidth) / (pDAS->charWidth / 10);
764 } /* End _DtHelpDisplayAreaDimensionsReturn */
766 /*****************************************************************************
767 * Function: int _DtHelpGetScrollbarValue (DtHelpDispAreaStruct *pDAS)
769 * Parameters pDAS Specifies the Display Area.
771 * Returns: a value from -1 to 100.
772 * -1 means the vertical scrollbar was not created when
773 * the display area was created.
774 * 0 to 100 is the percentage the vertical scroll bar is
775 * scrolled displaying the current topic.
777 * Purpose: Allows the system to query the location of the scrollbar
778 * and remember for smart-backtracking.
780 *****************************************************************************/
782 _DtHelpGetScrollbarValue (XtPointer client_data)
784 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
788 if (pDAS->vertScrollWid != NULL)
791 if (pDAS->firstVisible && pDAS->maxYpos)
792 percent = (pDAS->firstVisible * 1000) / pDAS->maxYpos;
797 } /* End _DtHelpGetScrollbarValue */
799 /*****************************************************************************
800 * Function: int _DtHelpUpdatePath (DtHelpDispAreaStruct *pDAS,
802 * Parameters pDAS Specifies the Display Area.
804 * Returns: a value from -1 to 100.
805 * -1 means the vertical scrollbar was not created when
806 * the display area was created.
807 * 0 to 100 is the percentage the vertical scroll bar is
808 * scrolled displaying the current topic.
810 * Purpose: Allows the system to query the location of the scrollbar
811 * and remember for smart-backtracking.
813 *****************************************************************************/
816 DtHelpDispAreaStruct *pDAS,
817 _DtHelpVolumeHdl volume_handle,
826 XtPointer topic_handle;
829 * turn off the toc marker
831 _DtHelpDATocMarker(pDAS, False);
832 (void) _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_OFF, False,
833 ((_DtCvValue) XtIsRealized(pDAS->dispWid)),
834 NULL, NULL, NULL, NULL, NULL);
837 * now create and set the topic
839 result = _DtHelpFormatToc(pDAS,volume_handle,loc_id,&realId,&topic_handle);
843 _DtCanvasSetTopic (pDAS->canvas, (_DtCvTopicPtr) topic_handle,
845 &width, &height, NULL);
848 * free the old topic and remember the new
850 _DtHelpDestroyTopicData(pDAS->lst_topic, _DtHelpDADestroyRegion,
851 (_DtCvPointer) pDAS);
853 pDAS->lst_topic = (_DtCvTopicPtr) topic_handle;
856 * Reset the scroll bars and perhaps do an expose.
858 SetMaxPositions (pDAS, width, height);
861 * now turn the traversal on - but only if there is a path in
866 (void) _DtCanvasMoveTraversal(pDAS->canvas, _DtCvTRAVERSAL_ID, False,
867 ((_DtCvStatus) XtIsRealized(pDAS->dispWid)), realId,
868 NULL, &(pDAS->toc_y), &(pDAS->toc_base), &(pDAS->toc_height));
871 * figure out where the first line should be...
873 tocY = pDAS->toc_y - pDAS->lineThickness;
874 tocHeight = pDAS->toc_height + (2 * pDAS->lineThickness);
876 if (tocY < pDAS->firstVisible ||
877 tocY + tocHeight > pDAS->firstVisible + ((int)pDAS->dispUseHeight))
879 pDAS->firstVisible = tocY;
880 if (pDAS->firstVisible + ((int)pDAS->dispUseHeight) > pDAS->maxYpos)
881 pDAS->firstVisible = pDAS->maxYpos - pDAS->dispUseHeight;
883 if (pDAS->firstVisible < 0)
884 pDAS->firstVisible = 0;
889 * Reset the scroll bars and perhaps do an expose.
891 (void) _DtHelpSetScrollBars((XtPointer) pDAS, pDAS->dispWidth, pDAS->dispHeight);
892 if (XtIsRealized (pDAS->dispWid))
893 _DtHelpCleanAndDrawWholeCanvas((XtPointer) pDAS);
896 _DtHelpDATocMarker((XtPointer) pDAS, True);
900 } /* End _DtHelpUpdatePath */
902 /*****************************************************************************
903 * Function: Widget _DtHelpDisplayAreaWidget ();
906 * client_data Specifies the display area pointer.
908 * Returns: the widget associated with the display area.
912 *****************************************************************************/
914 _DtHelpDisplayAreaWidget (
915 XtPointer client_data)
917 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
919 return (pDAS->dispWid);
922 /*****************************************************************************
923 * Function: XtPointer _DtHelpDisplayAreaData ();
926 * client_data Specifies the display area pointer.
928 * Returns: the client data associated with the display area.
932 *****************************************************************************/
934 _DtHelpDisplayAreaData (
935 XtPointer client_data)
937 DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
939 return (pDAS->clientData);