dtprintinfo: Coverity 89561
[oweals/cde.git] / cde / programs / dtcalc / help.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: help.c /main/4 1996/03/25 13:12:20 ageorge $ */
24 /*                                                                      *
25  *  help.c                                                              *
26  *   Contains all support for help in the Calculator.                   *
27  *                                                                      *
28  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
29  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
30  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
31  * (c) Copyright 1993, 1994 Novell, Inc.                                *
32  */
33
34 #include <Xm/Xm.h>
35 #include <Xm/XmP.h>
36 #include <Xm/MwmUtil.h>
37 #include <Xm/MessageB.h>
38
39 #include <Dt/Dt.h>
40 #include <Dt/Wsm.h>
41 #include <Dt/HelpDialog.h>
42
43 #include <stdint.h>
44 #include "calctool.h"
45 #include "motif.h"
46
47 #define  DIALOG_MWM_FUNC MWM_FUNC_MOVE | MWM_FUNC_CLOSE
48
49 extern char *base_str[] ;       /* Strings for each base value. */
50 extern char *dtype_str[] ;      /* Strings for each display mode value. */
51 extern char *mode_str[] ;       /* Strings for each mode value. */
52 extern char *ttype_str[] ;      /* Strings for each trig type value. */
53 extern Vars v ;                 /* Calctool variables and options. */
54 extern struct button buttons[] ;           /* Calculator button values. */
55
56
57 extern Boolean ignore_event;
58 extern XtIntervalId timerId;
59 extern void _DtChildPosition     P((Widget, Widget, Position *, Position *)) ;
60
61 typedef struct _helpStruct {
62     struct _helpStruct *pNext;
63     struct _helpStruct *pPrev;
64     Widget dialog;
65     Boolean inUse;
66 } HelpStruct;
67
68 static Widget GetHelpDialog     P(()) ;
69 static void UnmanageCB          P(()) ;
70
71 void
72 Help(char *helpVolume, char *locationId)
73 {
74     Arg args[10];
75     Position newX, newY;
76     int n;
77
78     if(X->helpDialog == NULL)
79     {
80         n = 0;
81         XtSetArg(args[n], DtNhelpType, DtHELP_TYPE_TOPIC); n++;
82         XtSetArg(args[n], DtNhelpVolume, helpVolume);   n++;
83         XtSetArg(args[n], DtNlocationId, locationId);   n++;
84         XtSetArg(args[n], XmNtitle, GETMESSAGE(4, 1, "Calculator - Help")); n++;
85         X->helpDialog = DtCreateHelpDialog(X->mainWin, "helpDlg", args, n);
86
87         DtWsmRemoveWorkspaceFunctions(X->dpy,
88                       XtWindow(XtParent(X->helpDialog)));
89         XtAddCallback(X->helpDialog, DtNhyperLinkCallback,
90                       (XtCallbackProc)HelpHyperlinkCB, NULL);
91         XtAddCallback(X->helpDialog, DtNcloseCallback,
92                       (XtCallbackProc)HelpCloseCB, NULL);
93     }
94     else
95     {
96         n = 0;
97         XtSetArg(args[n], DtNhelpType, DtHELP_TYPE_TOPIC); n++;
98         XtSetArg(args[n], DtNhelpVolume, helpVolume);   n++;
99         XtSetArg(args[n], DtNlocationId, locationId);   n++;
100         XtSetValues(X->helpDialog, args, n);
101     }
102
103     XtSetMappedWhenManaged(XtParent(X->helpDialog), False);
104     XSync(X->dpy, False);
105
106     XtManageChild(X->helpDialog) ;
107
108     _DtChildPosition(X->helpDialog, X->kframe, &newX, &newY);
109     XtSetArg(args[0], XmNx, newX);
110     XtSetArg(args[1], XmNy, newY);
111     XtSetValues(X->helpDialog, args, 2);
112
113     XtSetMappedWhenManaged(XtParent(X->helpDialog), True);
114     XSync(X->dpy, False);
115
116     XtMapWidget(XtParent(X->helpDialog));
117     X->helpMapped = True;
118
119 }
120
121 void
122 HelpCloseCB(Widget widget, caddr_t client_data, caddr_t call_data)
123 {
124
125   HelpStruct *pHelpCache = (HelpStruct *)client_data;
126   HelpStruct *pHelp;
127  
128   for (pHelp = pHelpCache; pHelp != (HelpStruct *)NULL && pHelp->dialog !=widget;
129                            pHelp = pHelp->pNext);
130   if (pHelp != (HelpStruct *)NULL)
131   {
132      pHelp->inUse = False;
133   }
134   XtUnmapWidget(XtParent(widget));
135   X->helpMapped = False;
136 }
137
138 void 
139 HelpHyperlinkCB(Widget widget, caddr_t client_data, caddr_t call_data)
140 {
141   DtHelpDialogCallbackStruct *pHyper = (DtHelpDialogCallbackStruct *) call_data;
142   
143   switch(pHyper->hyperType)
144   {
145      case DtHELP_LINK_TOPIC:
146           DisplayHelp(pHyper->helpVolume, pHyper->locationId);
147           break;
148      default:
149           ;
150    }
151 }
152  
153
154 void 
155 HelpRequestCB(Widget widget, caddr_t client_data, caddr_t call_data)
156 {
157   char  *helpVolume, *locationId;
158   intptr_t   topic;
159
160   topic = ((intptr_t) client_data) & 0xFFFF;
161   helpVolume = HELP_VOLUME;
162
163   if(topic < 56)
164   {
165      switch (topic)
166      {
167            case 0:
168                locationId = HELP_BLANK_STR;
169                break;
170            case 8:
171                locationId = HELP_ACC_STR;
172                break;
173            case 12:
174                if(v->modetype == LOGICAL)
175                   locationId = HELP_LSHIFT_STR;
176                else
177                   locationId = buttons[topic].str;
178                break;
179            case 13:
180                if(v->modetype == LOGICAL)
181                   locationId = HELP_RSHIFT_STR;
182                else if(v->modetype == FINANCIAL)
183                   locationId = HELP_INT_STR;
184                else
185                   locationId = buttons[topic].str;
186                break;
187            case 14:
188                if(v->modetype == LOGICAL)
189                   locationId = HELP_TRUNC16_STR;
190                else if(v->modetype == SCIENTIFIC)
191                   locationId = HELP_ETOX_STR;
192                else
193                   locationId = buttons[topic].str;
194                break;
195            case 15:
196                if(v->modetype == LOGICAL)
197                   locationId = HELP_TRUNC32_STR;
198                else if(v->modetype == SCIENTIFIC)
199                   locationId = HELP_TENTOX_STR;
200                else
201                   locationId = buttons[topic].str;
202                break;
203            case 16:
204                if(v->modetype == SCIENTIFIC)
205                   locationId = HELP_YTOX_STR;
206                else
207                   locationId = buttons[topic].str;
208                break;
209            case 17:
210                if(v->modetype == SCIENTIFIC)
211                   locationId = HELP_XFACT_STR;
212                else if(v->modetype == FINANCIAL)
213                   locationId = HELP_PAYPYR_STR;
214                else
215                   locationId = buttons[topic].str;
216                break;
217            case 21:
218                if(v->modetype == LOGICAL)
219                   locationId = HELP_BLANK_STR;
220                else
221                   locationId = buttons[topic].str;
222                break;
223            case 22:
224                if(v->modetype == LOGICAL)
225                   locationId = HELP_BLANK_STR;
226                else
227                   locationId = buttons[topic].str;
228                break;
229            case 23:
230                if(v->modetype == LOGICAL || v->modetype == FINANCIAL)
231                   locationId = HELP_BLANK_STR;
232                else
233                   locationId = buttons[topic].str;
234                break;
235            case 24:
236                locationId = HELP_RECIP_STR;
237                break;
238            case 25:
239                locationId = HELP_SQUARE_STR;
240                break;
241            case 26:
242                locationId = HELP_SQRT_STR;
243                break;
244            case 27:
245                locationId = HELP_PERCENT_STR;
246                break;
247            case 28:
248                locationId = HELP_LPAREN_STR;
249                break;
250            case 29:
251                locationId = HELP_RPAREN_STR;
252                break;
253            case 35:
254                locationId = HELP_CHGSIGN_STR;
255                break;
256            case 39:
257                locationId = HELP_TIMES_STR;
258                break;
259            case 40:
260                locationId = HELP_SEVEN_STR;
261                break;
262            case 41:
263                locationId = HELP_EIGHT_STR;
264                break;
265            case 42:
266                locationId = HELP_NINE_STR;
267                break;
268            case 43:
269                locationId = HELP_DIVIDE_STR;
270                break;
271            case 44:
272                locationId = HELP_FOUR_STR;
273                break;
274            case 45:
275                locationId = HELP_FIVE_STR;
276                break;
277            case 46:
278                locationId = HELP_SIX_STR;
279                break;
280            case 47:
281                locationId = HELP_MINUS_STR;
282                break;
283            case 48:
284                locationId = HELP_ONE_STR;
285                break;
286            case 49:
287                locationId = HELP_TWO_STR;
288                break;
289            case 50:
290                locationId = HELP_THREE_STR;
291                break;
292            case 51:
293                locationId = HELP_PLUS_STR;
294                break;
295            case 52:
296                locationId = HELP_ZERO_STR;
297                break;
298            case 53:
299                locationId = HELP_DECIMAL_STR;
300                break;
301            case 54:
302                locationId = HELP_EQUAL_STR;
303                break;
304            default:
305                locationId = buttons[topic].str;
306      }
307   }
308   else
309   {
310      switch (topic)
311      {
312            case HELP_HELP_MENU:
313                locationId = HELP_HELP_MENU_STR;
314                break;
315            case HELP_INTRODUCTION:
316                locationId = HELP_INTRODUCTION_STR;
317                break;
318            case HELP_TABLEOFCONTENTS:
319                locationId = HELP_TABLEOFCONTENTS_STR;
320                break;
321            case HELP_TASKS:
322                locationId = HELP_TASKS_STR;
323                break;
324            case HELP_REFERENCE:
325                locationId = HELP_REFERENCE_STR;
326                break;
327            case HELP_ITEM:
328                locationId = HELP_ITEM_STR;
329                break;
330            case HELP_USING:
331                locationId = HELP_USING_STR;
332                helpVolume = HELP_USING_HELP_VOLUME;
333                break;
334            case HELP_VERSION:
335                locationId = HELP_VERSION_STR;
336                break;
337            case HELP_ASCII:
338                locationId = HELP_ASCII_STR;
339                break;
340            case HELP_CONSTANT:
341                locationId = HELP_CONSTANT_STR;
342                break;
343            case HELP_FUNCTION:
344                locationId = HELP_FUNCTION_STR;
345                break;
346            case HELP_DISPLAY:
347                locationId = HELP_DISPLAY_STR;
348                break;
349            case HELP_MODELINE:
350                locationId = HELP_MODELINE_STR;
351                break;
352            case HELP_MODE:
353                locationId = mode_str[(int) v->modetype];
354                break;
355            case HELP_BASE:
356                locationId = base_str[(int) v->base];
357                break;
358            case HELP_NOTATION:
359                locationId = dtype_str[(int) v->dtype];
360                break;
361            case HELP_TRIG:
362                locationId = ttype_str[(int) v->ttype];
363                break;
364            case HELP_MENUBAR:
365                locationId = HELP_MENUBAR_STR;
366                break;
367            default:
368                locationId = HELP_INTRODUCTION_STR;
369      }
370   }
371   Help(helpVolume, locationId);
372   ignore_event = True;
373   timerId = XtAppAddTimeOut (XtWidgetToApplicationContext (X->kframe), 300,
374                          (XtTimerCallbackProc) TimerEvent, (XtPointer) NULL);
375 }
376
377 void
378 HelpModeCB(Widget w, caddr_t client_data, caddr_t call_data)
379 {
380   Widget widget;
381   char *errorMsg, *tmp;
382  
383   switch(DtHelpReturnSelectedWidgetId(X->mainWin, (Cursor)NULL, &widget))
384    {
385       case DtHELP_SELECT_VALID:
386         while (!XtIsShell(widget))
387         {
388                 if(XtHasCallbacks(widget, XmNhelpCallback) == XtCallbackHasSome)
389                 {
390                         XtCallCallbacks(widget, XmNhelpCallback, 
391                                                        (XtPointer)client_data);
392                         return;
393                 }
394                 widget = XtParent(widget);
395         }
396         break;
397
398      case DtHELP_SELECT_INVALID:
399         errorMsg = GETMESSAGE(4, 2, "You must select an item within Calculator");
400         tmp = XtNewString(errorMsg);
401         ErrDialog((char *) tmp, X->mainWin);
402         XtFree(tmp);
403         break;
404    }
405 }
406
407 void
408 DisplayHelp(char *helpVolume, char *locationId)
409 {
410     Arg args[10];
411     int n;
412
413     X->helpDialog = GetHelpDialog();
414
415     n = 0;
416     XtSetArg(args[n], DtNhelpType, DtHELP_TYPE_TOPIC); n++;
417     XtSetArg(args[n], DtNhelpVolume, helpVolume);       n++;
418     XtSetArg(args[n], DtNlocationId, locationId);       n++;
419     XtSetValues(X->helpDialog, args, n);
420
421     XtManageChild(X->helpDialog);
422     XtMapWidget(XtParent(X->helpDialog));
423     X->helpMapped = True;
424 }
425
426
427 static Widget
428 GetHelpDialog(void)
429 {
430     static HelpStruct       *pHelpCache;
431
432     HelpStruct *pHelp;
433     Arg args[5];
434
435     if(pHelpCache == (HelpStruct *)NULL)
436     {
437         pHelp = pHelpCache = (HelpStruct *)XtMalloc(sizeof(HelpStruct));
438         pHelp->pNext = (HelpStruct *)NULL;
439         pHelp->pPrev = (HelpStruct *)NULL;
440         pHelp->inUse = True;
441
442         XtSetArg(args[0], XmNtitle, GETMESSAGE(4, 1, "Calculator - Help"));
443         pHelp->dialog = DtCreateHelpDialog(X->mainWin, "helpDlg",  args, 1);
444
445         DtWsmRemoveWorkspaceFunctions(X->dpy,
446                 XtWindow(XtParent(pHelp->dialog)));
447         XtAddCallback(pHelp->dialog, DtNhyperLinkCallback,
448                       (XtCallbackProc)HelpHyperlinkCB, NULL);
449         XtAddCallback(pHelp->dialog, DtNcloseCallback,
450                       (XtCallbackProc)HelpCloseCB, pHelpCache);
451         return pHelp->dialog;
452     }
453     else
454     {
455         for(pHelp = pHelpCache;
456             pHelp != (HelpStruct *)NULL;
457             pHelp = pHelp->pNext)
458         {
459             if(pHelp->inUse == False)
460             {
461                 pHelp->inUse = True;
462                 return pHelp->dialog;
463             }
464         }
465         pHelp = (HelpStruct *) XtMalloc(sizeof(HelpStruct));
466         pHelpCache->pPrev = pHelp;
467         pHelp->pNext = pHelpCache;
468         pHelpCache = pHelp;
469         pHelp->pPrev = (HelpStruct *)NULL;
470         pHelp->inUse = True;
471
472         XtSetArg(args[0], XmNtitle, GETMESSAGE(4, 1, "Calculator - Help"));
473         pHelp->dialog = DtCreateHelpDialog(X->mainWin, "helpDlg",  args, 1);
474         DtWsmRemoveWorkspaceFunctions(X->dpy,
475                       XtWindow(XtParent(pHelp->dialog)));
476         XtAddCallback(pHelp->dialog, DtNhyperLinkCallback,
477                       (XtCallbackProc)HelpHyperlinkCB, NULL);
478         XtAddCallback(pHelp->dialog, DtNcloseCallback,
479                       (XtCallbackProc)HelpCloseCB, pHelpCache);
480         return pHelp->dialog;
481     }
482 }
483
484 void
485 ErrDialog(char *errString, Widget visualParent)
486 {
487   int   n;
488   Arg   args[10];
489   XmString label, ok;
490
491   label = XmStringCreateLocalized(errString) ;
492   X->errParent = visualParent;
493
494   if (X->errDialog == NULL)
495   {
496     ok = XmStringCreateLocalized(GETMESSAGE(4, 4, "OK"));
497
498     n = 0;
499     XtSetArg (args[n], XmNokLabelString, ok);           n++;
500     XtSetArg (args[n], XmNmessageString, label);        n++;
501     XtSetArg (args[n], XmNmwmFunctions, DIALOG_MWM_FUNC); n++;
502     XtSetArg (args[n], XmNautoUnmanage,  FALSE);        n++;
503     XtSetArg (args[n], XmNdefaultPosition, FALSE);      n++;
504
505     X->errDialog = XmCreateErrorDialog (X->mainWin, "ErroNotice", args, n);
506
507     XtAddCallback (X->errDialog, XmNokCallback, UnmanageCB, NULL);
508     XtAddCallback (X->errDialog, XmNmapCallback, CenterMsgCB, NULL);
509
510     XtUnmanageChild (XmMessageBoxGetChild (X->errDialog, 
511                                                     XmDIALOG_CANCEL_BUTTON));
512
513     XtUnmanageChild (XmMessageBoxGetChild (X->errDialog, XmDIALOG_HELP_BUTTON));
514
515     n = 0;
516     XtSetArg (args[n], XmNmwmInputMode, 
517                                   MWM_INPUT_PRIMARY_APPLICATION_MODAL);n++;
518     XtSetArg (args[n], XmNuseAsyncGeometry, TRUE); n++;
519     XtSetArg (args[n], XmNtitle, GETMESSAGE(4, 3, "Error")); n++;
520     XtSetValues (XtParent(X->errDialog), args, n);
521   }
522   else
523   {
524      XtSetArg (args[0], XmNmessageString, label);
525      XtSetValues (X->errDialog, args, 1);
526   }
527   XmStringFree (label);
528   XtManageChild(X->errDialog);
529 }
530
531 static void
532 UnmanageCB(Widget  widget, XtPointer client_data, XtPointer call_data)
533 {
534     XtUnmanageChild(widget);
535 }
536
537 void
538 CenterMsgCB (Widget widget, XtPointer client_data, XtPointer call_data)
539 {
540     int n;
541     Position newX, newY;
542     Arg args[4];
543     Widget   shell;
544
545     shell = (Widget)client_data;
546     if (shell == NULL)
547     {
548         if (!X->errParent || !XtParent(X->errParent) ||
549                 !XtIsManaged(X->errParent))
550                         shell = X->mainWin;
551         else
552                 shell = XtParent(X->errParent);
553     }
554     else
555         shell = XtParent (shell);
556
557     newX = XtX(shell) + XtWidth(shell)/2 - XtWidth(widget)/2;
558     newY = XtY(shell) + XtHeight(shell)/2 - XtHeight(widget)/2;
559
560     if (newX < 0) newX = 0;
561     if (newY < 0) newY = 0;
562
563     n = 0;
564     XtSetArg (args[n], XmNx, newX);             n++;
565     XtSetArg (args[n], XmNy, newY);             n++;
566     XtSetValues(widget, args, n);
567 }
568