2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: HelpCache.c /main/4 1995/11/08 09:17:54 rswiston $ */
24 /*************************************<+>*************************************
25 *****************************************************************************
29 ** Project: dthelpdemo demo program
31 ** Description: Contains the Help Callbacks and Utility functions for our
32 ** demo tool dthelpdemo.
35 ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
36 ** 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 Unix System Labs, Inc., a subsidiary of
42 ****************************************************************************
43 ************************************<+>*************************************/
45 /* System Include Files */
53 #include <Dt/HelpDialog.h>
54 #include <Dt/HelpQuickD.h>
58 #include "HelpCacheI.h"
59 #include "HourGlassI.h"
62 /******** Static Function Declarations ********/
65 static void CloseHelpCB (
69 static Boolean GetFromCache(
71 CacheListStruct **pCurrentNode);
75 /* Global Main Help Dialog Widget */
76 static Widget helpMain=NULL;
77 static Widget versionMain=NULL;
80 /*****************************************************************************
81 * Function: void HelpMapCB()
85 * Parameters: clientData is the widget in reference to
86 * which widget w is placed
90 * Purpose: Determins where a new child dialog should be mapped in
91 * relation to its parent.
93 * Algorithm: 1. attempt left or right placement with no overlap
94 * 2. if fails, attempt up or down placement with no overlap
95 * 3. if fails, determines location with least
96 * amount of overlap, and places there.
98 *****************************************************************************/
99 XtCallbackProc HelpMapCB(
101 XtPointer clientData,
108 Position centeredY, bestX, bestY, pX, pY;
109 Dimension pHeight, myHeight, pWidth, myWidth;
110 Dimension maxX, maxY;
111 int rhsX, lhsX, topY, botY; /* needs to be int, not Dimension */
116 parent = (Widget)clientData;
117 display = XtDisplay(w);
118 screen = XtScreen(w);
119 screenNumber = XScreenNumberOfScreen(screen);
124 pHeight = XtHeight(parent);
125 pWidth = XtWidth(parent);
126 myHeight = XtHeight(w);
127 myWidth = XtWidth(w);
128 maxX = XDisplayWidth(display,screenNumber);
129 maxY = XDisplayHeight(display,screenNumber);
132 * 1. attempt left or right placement with no overlap
133 * 2. if fails, attempt up or down placement with no overlap
134 * 3. if fails, places on the right in the middle
137 /* first try left right placement */
138 bestY = pY + pHeight/2 - myHeight/2;
141 lhsX = pX - myWidth - 8; /* 8: account for border */
142 if ( (rhsX + myWidth) < maxX ) bestX = rhsX;
143 else if ( lhsX > 0 ) bestX = lhsX;
146 /* then try up down placement */
147 bestX = pX + pWidth/2 - myWidth/2;
149 topY = pY - myHeight - 44; /* 44: account for menu border */
150 if ( (botY + myWidth) < maxY ) bestY = botY;
151 else if ( topY > 0 ) bestY = topY;
154 /* otherwise, center vertically and on the right */
155 bestX = maxX - myWidth;
160 XtSetArg(args[0], XmNx, bestX);
161 XtSetArg(args[1], XmNy, bestY);
162 XtSetValues(w, args, 2);
164 return((XtCallbackProc) NULL);
169 /****************************************************************************
170 * Function: CloseHelpCB(
172 * XtPointer clientData,
177 * Return Value: Void.
179 * Purpose: Process close requests on all Help Dialog widgets
180 * created and managed by this application.
182 ***************************************************************************/
183 static void CloseHelpCB (
185 XtPointer clientData,
189 Widget helpDialog = (Widget) clientData;
191 CacheListStruct *pTemp;
193 pTemp = pCacheListHead;
195 /* Search our Cache List for the closed help dialog */
196 while ((pTemp->helpDialog != helpDialog) && (pTemp != NULL))
197 pTemp = pTemp->pNext;
202 printf("We did not find our help dialog widget in the cache list??? /n");
204 /* Un Map and Clean up the help widget */
205 XtUnmanageChild(helpDialog);
206 pTemp->inUseFlag = FALSE;
213 /****************************************************************************
214 * Function: CloseMainCB(
216 * XtPointer clientData,
221 * Return Value: Void.
223 * Purpose: Process close requests on our main help dialog.
225 ***************************************************************************/
226 static void CloseMainCB (
228 XtPointer clientData,
231 Widget currentDialog = (Widget) clientData;
235 /* Un Map and Clean up the help widget */
236 XtUnmanageChild(currentDialog);
243 /****************************************************************************
244 * Function: void ProcessLinkCB(
246 * XtPointer clientData,
251 * Return Value: Void.
253 * Purpose: Process JUMP-NEW and APP-LINK hypertext requests in a
254 * given Help Dialog Window.
256 * This is the callback used for the DtNhyperLinkCallback
257 * on each of the help dialog widges created.
259 ****************************************************************************/
262 XtPointer clientData,
271 static Dimension width=0;
272 static Dimension height=0;
273 static Boolean goBigger=TRUE;
275 DtHelpDialogCallbackStruct * hyperData =
276 (DtHelpDialogCallbackStruct *) callData;
279 switch (hyperData->hyperType)
281 case DtHELP_LINK_JUMP_NEW:
283 DisplayTopic (XtParent(w), hyperData->helpVolume,
284 hyperData->locationId);
288 case DtHELP_LINK_MAN_PAGE:
290 /* Create and display the requested man page */
291 DisplayMan(XtParent(w), hyperData->specification);
296 case DtHELP_LINK_TEXT_FILE:
298 /* Create a quick help dialog and display the text file in it */
302 case DtHELP_LINK_APP_DEFINE:
304 appLinkNum = atoi(hyperData->specification);
306 if (appLinkNum == 100) /* Move the window */
309 /* First Place the window in the upper left */
311 XtSetArg(args[n], XmNx, 0); ++n;
312 XtSetArg(args[n], XmNy, 0); ++n;
313 XtSetValues(topLevel, args, n);
315 /* Now move it down to the center of the display */
317 for (count = 1;count < 500; count= count+5)
320 XtSetArg(args[n], XmNx, count); ++n;
321 XtSetArg(args[n], XmNy, count); ++n;
322 XtSetValues(topLevel, args, n);
323 XmUpdateDisplay(topLevel);
329 if (appLinkNum == 101) /* Resize the window */
334 /* Get the current dialog size */
336 XtSetArg (args[n], XmNheight, &height); n++;
337 XtSetArg (args[n], XmNwidth, &width); n++;
338 XtGetValues(topLevel, args, n);
344 XtSetArg (args[n], XmNheight, height+100); n++;
345 XtSetArg (args[n], XmNwidth, width+50); n++;
346 XtSetValues(topLevel, args, n);
353 XtSetArg (args[n], XmNheight, height); n++;
354 XtSetArg (args[n], XmNwidth, width); n++;
355 XtSetValues(topLevel, args, n);
362 if (appLinkNum == 102)
367 if (appLinkNum == 103)
374 default: /* Catches any other applicaion definded link types */
376 printf("We some how got a bogus hyptertext link type/n");
379 } /* End Switch Statement */
386 /****************************************************************************
387 * Function: void DisplayMan()
391 * Return Value: Void.
393 * Purpose: Displays a UNIX man page in a quick help dialog.
395 ****************************************************************************/
407 XmUpdateDisplay(topLevel);
411 if (manWidget == NULL)
413 /* Create the QuickHelpDialog widget for help on help */
414 title = XtNewString(man);
417 XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
418 XtSetArg (args[n], XmNtitle, title); n++;
419 XtSetArg (args[n], DtNhelpType,DtHELP_TYPE_MAN_PAGE); n++;
420 XtSetArg (args[n], DtNmanPage, man); n++;
421 manWidget = DtCreateHelpQuickDialog(topLevel,"manBox", args, n);
422 XtFree((char*) title);
425 XtAddCallback(manWidget, DtNcloseCallback,
426 CloseMainCB, (XtPointer) manWidget);
428 /* Add the popup position callback to our man dialog */
429 XtAddCallback (XtParent(manWidget), XmNpopupCallback,
430 (XtCallbackProc)HelpMapCB,
431 (XtPointer)topLevel);
436 /* We do not want a help button for now so we unmap it */
437 helpWidget = DtHelpQuickDialogGetChild (manWidget,
438 DtHELP_QUICK_HELP_BUTTON);
439 XtUnmanageChild (helpWidget);
441 XtManageChild(manWidget);
445 TurnOnHourGlass(manWidget);
447 /* We already have a quick help dialog so re-use it */
449 XtSetArg (args[n], DtNhelpType,DtHELP_TYPE_MAN_PAGE); n++;
450 XtSetArg (args[n], DtNmanPage, man); n++;
452 XtSetValues(manWidget, args, n);
455 title = XtNewString(man);
457 XtSetArg (args[n], XmNtitle, title); n++;
458 XtSetValues(XtParent(manWidget), args, n);
459 XtFree((char*) title);
461 XtManageChild(manWidget);
462 XtMapWidget(XtParent(manWidget));
463 XRaiseWindow(XtDisplay(parent), XtWindow(XtParent(manWidget)));
464 TurnOffHourGlass(manWidget);
471 /****************************************************************************
472 * Function: void DisplayTopic(
479 * Return Value: Void.
481 * Purpose: Creats and displays a new help dialog w/the requested help
484 ****************************************************************************/
494 CacheListStruct *pCurrentNode = NULL;
495 Boolean cachedNode = FALSE;
498 /* Get a inuse node if we have one or a Cached one */
499 cachedNode = GetFromCache(parent, &pCurrentNode);
502 /* If we got a free one from the Cache, use it */
503 /* Set Values on current free one, then map it */
507 XtSetArg (args[n], XmNtitle, "HelpDemo Help"); n++;
508 if (helpVolume != NULL)
510 XtSetArg (args[n],DtNhelpVolume,helpVolume); n++;
512 XtSetArg (args[n], DtNlocationId,locationId); n++;
513 XtSetValues(pCurrentNode->helpDialog, args, n);
515 XtManageChild(pCurrentNode->helpDialog);
516 XtMapWidget(XtParent(pCurrentNode->helpDialog));
520 while (!XtIsSubclass(parent, applicationShellWidgetClass))
521 parent = XtParent(parent);
525 /* Build a new one in our cached list */
527 XtSetArg (args[n], XmNtitle, "Helpdemo Help"); n++;
528 if (helpVolume != NULL)
530 XtSetArg (args[n],DtNhelpVolume,helpVolume); n++;
532 XtSetArg (args[n], DtNlocationId,locationId); n++;
533 pCurrentNode->helpDialog =
534 DtCreateHelpDialog(parent, "helpWidget", args, n);
537 XtAddCallback(pCurrentNode->helpDialog, DtNhyperLinkCallback,
538 ProcessLinkCB, NULL);
540 XtAddCallback(pCurrentNode->helpDialog, DtNcloseCallback,
541 CloseHelpCB, (XtPointer) pCurrentNode->helpDialog);
543 XtManageChild(pCurrentNode->helpDialog);
544 XtMapWidget(XtParent(pCurrentNode->helpDialog));
552 /****************************************************************************
553 * Function: void DisplayMain(
560 * Return Value: Void.
562 * Purpose: Displays help for helpdemo in the one helpDialog window
563 * created for the applicaiton.
565 ****************************************************************************/
575 if (helpMain != NULL)
578 XtSetArg (args[n], XmNtitle, "hemodemo Help"); n++;
579 if (helpVolume != NULL)
581 XtSetArg (args[n],DtNhelpVolume,helpVolume); n++;
583 XtSetArg (args[n], DtNlocationId,locationId); n++;
584 XtSetValues(helpMain, args, n);
586 XtManageChild(helpMain);
591 while (!XtIsSubclass(parent, applicationShellWidgetClass))
592 parent = XtParent(parent);
595 /* Build a new one in our cached list */
597 XtSetArg (args[n], XmNtitle, "Helpdemo Help"); n++;
598 if (helpVolume != NULL)
600 XtSetArg (args[n],DtNhelpVolume,helpVolume); n++;
602 XtSetArg (args[n], DtNlocationId,locationId); n++;
603 helpMain = DtCreateHelpDialog(parent, "helpWidget", args, n);
605 XtAddCallback(helpMain, DtNhyperLinkCallback,
606 ProcessLinkCB, NULL);
608 XtAddCallback(helpMain, DtNcloseCallback,
609 CloseMainCB, (XtPointer) helpMain);
611 /* Add the popup position callback to our main help dialog */
612 XtAddCallback (XtParent(helpMain), XmNpopupCallback,
613 (XtCallbackProc)HelpMapCB,
616 XtManageChild(helpMain);
626 /****************************************************************************
627 * Function: void DisplayVersion(
634 * Return Value: Void.
636 * Purpose: Displays the version dialog for the helpdemo program.
638 ****************************************************************************/
639 void DisplayVersion (
652 if (versionMain != NULL)
655 XtSetArg (args[n], XmNtitle, "Helpdemo Version Dialog"); n++;
656 if (helpVolume != NULL)
658 XtSetArg (args[n],DtNhelpVolume,helpVolume); n++;
660 XtSetArg (args[n], DtNlocationId,locationId); n++;
661 XtSetValues(versionMain, args, n);
663 XtManageChild(versionMain);
668 while (!XtIsSubclass(parent, applicationShellWidgetClass))
669 parent = XtParent(parent);
672 /* Build a new one in our cached list */
674 XtSetArg (args[n], XmNtitle, "Helpdemo Version Dialog"); n++;
675 if (helpVolume != NULL)
677 XtSetArg (args[n],DtNhelpVolume,helpVolume); n++;
679 XtSetArg (args[n], DtNlocationId,locationId); n++;
680 XtSetArg (args[n], DtNhelpType, DtHELP_TYPE_TOPIC); n++;
681 versionMain = DtCreateHelpQuickDialog(parent,"versionWidget",args,n);
683 XtAddCallback(versionMain, DtNcloseCallback,
684 CloseMainCB, (XtPointer) versionMain);
687 /* We do not want a print button for now so we unmap it */
688 printWidget = DtHelpQuickDialogGetChild (versionMain,
689 DtHELP_QUICK_PRINT_BUTTON);
690 XtUnmanageChild (printWidget);
693 /* We do not want a help button for now so we unmap it */
694 helpWidget = DtHelpQuickDialogGetChild (versionMain,
695 DtHELP_QUICK_HELP_BUTTON);
696 XtUnmanageChild (helpWidget);
698 backWidget = DtHelpQuickDialogGetChild (versionMain,
699 DtHELP_QUICK_BACK_BUTTON);
700 XtUnmanageChild (backWidget);
702 XtManageChild(versionMain);
712 /****************************************************************************
713 * Function: static CacheListStruct GetFromCache(
718 * Return Value: Void.
720 * Purpose: Gets a free help node form our cache list. If none are
721 * free, it will return fallse and the calling routine will
722 * create a new help dialog widget.
724 ****************************************************************************/
725 static Boolean GetFromCache(
727 CacheListStruct **pCurrentNode)
731 CacheListStruct *pTemp;
733 if (pCacheListHead == NULL)
735 /* We have a new list so lets create one and pass it back */
737 (CacheListStruct *) XtMalloc((sizeof(CacheListStruct)));
739 /* Assign the default values to our node */
740 pCacheListHead->helpDialog = NULL;
741 pCacheListHead->inUseFlag = TRUE;
742 pCacheListHead->pNext = NULL;
743 pCacheListHead->pPrevious = NULL;
745 /* Assign our tale pointer */
746 pCacheListTale = pCacheListHead;
748 /* Make sure or totalNodes counter is correct, e.g. force it to 1 */
751 /* Return our head pointer because it's our first and only node */
752 *pCurrentNode = pCacheListHead;
758 /* We have need for an in-use help dialog or a new one, so look */
759 pTemp = pCacheListHead;
761 while (pTemp != NULL)
763 if (pTemp->inUseFlag == FALSE)
765 pTemp->inUseFlag = TRUE;
766 *pCurrentNode = pTemp;
770 pTemp = pTemp->pNext;
774 /* If we did not find a free nod then we must add a new one to the
775 * top of the list, and return it.
778 pTemp = (CacheListStruct *) XtMalloc((sizeof(CacheListStruct)));
780 /* Assign the default values to our node */
781 pTemp->helpDialog = NULL;
782 pTemp->inUseFlag = TRUE;
784 pTemp->pNext = pCacheListHead;
785 pTemp->pPrevious = NULL;
787 pCacheListHead->pPrevious = pTemp;
789 /* Re-Assign our head pointer to point to the new head of the list */
790 pCacheListHead = pTemp;
792 /* Make sure or totalNodes counter is correct, e.g. force it to 1 */
793 totalCacheNodes = totalCacheNodes + 1;
795 /* Return our head pointer because it's our new node */
796 *pCurrentNode = pCacheListHead;