1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11 
12 #if defined(HAVE_UNISTD_H)
13 #include <unistd.h>
14 #endif
15 
16 #if defined(HAVE_SYS_STAT_H)
17 #include <sys/stat.h>
18 #endif
19 
20 #include "IBMApplication.h"
21 #include "HelpMenuCommand.h"
22 #include "MainWindow.h"
23 #include "../widgets/XmDX.h"
24 #include "../widgets/findcolor.h"
25 #include "HelpWin.h"
26 #include "ErrorDialogManager.h"
27 #include "WarningDialogManager.h"
28 #include "DXStrings.h"
29 #include "IBMVersion.h"
30 #include "lex.h"
31 #include "logo.h"
32 #include "icon50.h"
33 #include "ListIterator.h"
34 #include "StartWebBrowser.h"
35 
36 #if defined (HAVE_XPM_H)
37 #include <xpm.h>
38 #endif
39 #if defined (HAVE_X11_XPM_H)
40 #include <X11/xpm.h>
41 #endif
42 
43 IBMApplication *theIBMApplication = NULL;
44 IBMResource IBMApplication::resource;
45 
46 XmColorProc IBMApplication::DefColorProc = NULL;
47 
48 static
49 XrmOptionDescRec _IBMOptionList[] =
50 {
51     {
52 	"-uiroot",
53 	"*UIRoot",
54 	XrmoptionSepArg,
55 	NULL
56     },
57     {
58 	"-wizard",
59 	"*wizard",
60 	XrmoptionNoArg,
61 	"True"
62     },
63     {
64 	"-dismissedWizards",
65 	"*dismissedWizards",
66 	XrmoptionSepArg,
67 	NULL
68     },
69 };
70 
71 
72 static
73 XtResource _IBMResourceList[] =
74 {
75     {
76 	"UIRoot",
77 	"Pathname",
78 	XmRString,
79 	sizeof(String),
80 	XtOffset(IBMResource*, UIRoot),
81 	XmRString,
82 	NULL
83     },
84     {
85 	"wizard",
86 	"Flag",
87 	XmRBoolean,
88 	sizeof(Boolean),
89 	XtOffset(IBMResource*, wizard),
90 	XmRImmediate,
91 	(XtPointer)False
92     },
93     {
94 	"dismissedWizards",
95 	"Pathname",
96 	XmRString,
97 	sizeof(String),
98 	XtOffset(IBMResource*, noWizardNames),
99 	XmRString,
100 	(XtPointer)NULL
101     },
102 
103 };
104 
105 const String IBMApplication::DefaultResources[] =
106 {
107     "*background:              #b4b4b4b4b4b4",
108     "*foreground:              black",
109 #if defined(DXD_OS_NON_UNIX)
110     "*fontList:\
111 -adobe-helvetica-bold-r-normal--12-*iso8859-1=bold,\
112 -adobe-helvetica-bold-r-normal--14-*iso8859-1=canvas,\
113 -adobe-helvetica-bold-r-normal--10-*=small_bold,\
114 -adobe-helvetica-bold-r-normal--12-*=small_canvas,\
115 -adobe-helvetica-bold-r-normal--14-*=big_bold,\
116 -adobe-helvetica-bold-r-normal--20-*=huge_bold,\
117 -adobe-helvetica-medium-r-normal--12-*=normal,\
118 -adobe-helvetica-medium-r-normal--10-*=small_normal,\
119 -adobe-helvetica-medium-r-normal--14-*=big_normal,\
120 -adobe-helvetica-medium-r-normal--20-*=huge_normal,\
121 -adobe-helvetica-medium-o-normal--10-*=small_oblique,\
122 -adobe-helvetica-medium-o-normal--14-*=big_oblique,\
123 -adobe-helvetica-medium-o-normal--20-*=huge_oblique,\
124 -adobe-helvetica-medium-o-normal--12-*=oblique",
125 #else
126     "*fontList:\
127 -adobe-helvetica-bold-r-normal--12-*iso8859-1=bold,\
128 -adobe-helvetica-bold-r-normal--14-*iso8859-1=canvas,\
129 -adobe-helvetica-bold-r-normal--10-*iso8859-1=small_bold,\
130 -adobe-helvetica-bold-r-normal--12-*iso8859-1=small_canvas,\
131 -adobe-helvetica-bold-r-normal--14-*iso8859-1=big_bold,\
132 -adobe-helvetica-bold-r-normal--20-*iso8859-1=huge_bold,\
133 -adobe-helvetica-medium-r-normal--12-*iso8859-1=normal,\
134 -adobe-helvetica-medium-r-normal--10-*iso8859-1=small_normal,\
135 -adobe-helvetica-medium-r-normal--14-*iso8859-1=big_normal,\
136 -adobe-helvetica-medium-r-normal--20-*iso8859-1=huge_normal,\
137 -adobe-helvetica-medium-o-normal--10-*iso8859-1=small_oblique,\
138 -adobe-helvetica-medium-o-normal--14-*iso8859-1=big_oblique,\
139 -adobe-helvetica-medium-o-normal--20-*iso8859-1=huge_oblique,\
140 -adobe-helvetica-medium-o-normal--12-*iso8859-1=oblique",
141 #endif
142     "*keyboardFocusPolicy:     explicit",
143     "*highlightOnEnter:	       false",
144     "*highlightThickness:      0",
145     "*XmPushButton*traversalOn:    false",
146     "*XmPushButtonGadget*traversalOn:    false",
147     "*XmToggleButton*traversalOn:  false",
148     "*XmDial*width:                100",
149     "*XmDial*height:	           100",
150     "*XmDial*numMarkers:           60",
151     "*XmDial*majorMarkerWidth:     10",
152     "*XmDial*minorMarkerWidth:     5",
153     "*XmDial*majorPosition:        5",
154     "*XmDial*startingMarkerPos:    0",
155     "*XmDial*shadePercentShadow:   0",
156     "*XmDial*shading:              True",
157     "*XmDial*shadowThickness:      0",
158     "*XmDial*shadeIncreasingColor: #b4b4c9c9dddd",
159     "*XmDial*shadeDecreasingColor: #7e7e7e7eb4b4",
160     "*XmDial*majorMarkerColor:     Black",
161     "*XmDial*minorMarkerColor:     Black",
162     "*XmDial*indicatorColor:       Black",
163     "*XmDial*indicatorWidth:       20",
164 
165     "*XmNumber.navigationType:     XmTAB_GROUP",
166 
167     "*XmScrollBar*foreground:      #b4b4b4b4b4b4",
168 
169     "*XmSlideBar*alignOnDrop:      True",
170 
171     "*XmToggleButton.selectColor:  #5F9EA0",
172     "*XmToggleButton.indicatorSize:15",
173 
174     "*XmArrowButton.shadowThickness:         1",
175     "*XmCascadeButton.shadowThickness:       1",
176     "*XmCascadeButtonGadget.shadowThickness: 1",
177     "*XmColorMapEditor*shadowThickness:      1",
178     "*XmDrawnButton.shadowThickness:         1",
179     "*XmForm.shadowThickness:                0",
180     "*XmFrame.shadowThickness:               1",
181     "*XmList.shadowThickness:                1",
182     "*XmMenuBar.shadowThickness:             1",
183     "*XmNumber*shadowThickness:              1",
184     "*XmPushButton.shadowThickness:          1",
185     "*XmPushButtonGadget.shadowThickness:    1",
186     "*XmRowColumn.shadowThickness:           1",
187     "*XmScrollBar.shadowThickness:           1",
188     "*XmScrolledList.shadowThickness:        1",
189     "*XmScrolledWindow.shadowThickness:      1",
190     "*XmText.shadowThickness:                1",
191     "*XmTextField.shadowThickness:           1",
192     "*XmToggleButton.shadowThickness:        1",
193     NULL
194 };
195 
196 XtActionsRec IBMApplication::actions[] = {
197     {"IBMButtonHelp", (XtActionProc)IBMApplication_IBMButtonHelpAP}
198 };
199 
200 
IBMApplication(char * className)201 IBMApplication::IBMApplication(char* className): Application(className)
202 {
203     theIBMApplication = this;
204     this->helpWindow = NULL;
205     this->logo_pmap = XtUnspecifiedPixmap;
206     this->icon_pmap = XtUnspecifiedPixmap;
207     this->genericHelpCmd  = new HelpMenuCommand("genericAppHelp",
208 				NULL,
209 				TRUE,HelpMenuCommand::GenericHelp);
210     this->helpTutorialCmd = new HelpMenuCommand("helpTutorial",
211 				NULL,
212 				TRUE,
213 				HelpMenuCommand::HelpTutorial);
214 
215     this->aboutAppString = NULL;
216 
217     this->noWizards = NUL(List*);
218     this->techSupportString = NUL(char*);
219 }
220 
221 
~IBMApplication()222 IBMApplication::~IBMApplication()
223 {
224     theIBMApplication = NULL;
225 
226 #ifdef __PURIFY__
227     delete this->genericHelpCmd;
228     delete this->helpTutorialCmd;
229     if (this->helpWindow)
230         delete this->helpWindow;
231     if (this->aboutAppString)
232 	delete[] this->aboutAppString;
233     if (this->techSupportString)
234 	delete[] this->techSupportString;
235 
236     if (this->noWizards) {
237 	ListIterator it(*this->noWizards);
238 	char *nowiz;
239 	while ( (nowiz = (char*)it.getNext()) )
240 	    delete[] nowiz;
241 	delete this->noWizards;
242 	this->noWizards = NUL(List*);
243     }
244 #endif
245 }
246 
247 //
248 // Install the default resources for this class.
249 //
installDefaultResources(Widget baseWidget)250 void IBMApplication::installDefaultResources(Widget baseWidget)
251 {
252     this->setDefaultResources(baseWidget, IBMApplication::DefaultResources);
253     this->Application::installDefaultResources(baseWidget);
254 }
255 
256 //
257 // Motif has opened up its scheme for calculating shadow colors.  The routine
258 // XmGetColors() tells what motif will use given a particaluar background
259 // pixel.  I have replaced Motif's own color calculation with ::ColorProc.
260 // As a result, if the normal color calculation proc (saved in ::DefColorProc)
261 // fails, then I use find_color to find replacements.  The alternative would
262 // have been to get stuck with crap (or probably just white for most color
263 // resources).
264 // So we do what Motif normally does.  Then error check the results the way Motif
265 // doesn't.  If the hoped-for colors aren't available then find colors that are.
266 // -Martin 5/25/95
267 //
268 extern "C"
269 void
IBMApplication_ColorProc(XColor * bgdef,XColor * fgdef,XColor * seldef,XColor * tsdef,XColor * bsdef)270 IBMApplication_ColorProc (XColor *bgdef, XColor *fgdef,
271         XColor *seldef, XColor *tsdef, XColor *bsdef)
272 {
273 Display *d = theApplication->getDisplay();
274 Widget rw = theApplication->getRootWidget();
275 XColor cdef, *defs[4];
276 int i;
277 Colormap colormap;
278 Status success;
279 
280     IBMApplication::DefColorProc (bgdef, fgdef, seldef, tsdef, bsdef);
281     XtVaGetValues (rw, XmNcolormap, &colormap, NULL);
282     ASSERT(colormap);
283     defs[0] = fgdef; defs[1] = seldef;
284     defs[2] = tsdef; defs[3] = bsdef;
285 
286     for (i=0; i<4; i++) {
287 	success = XAllocColor (d, colormap, defs[i]);
288 	if (!success) {
289 	    cdef.red = defs[i]->red; cdef.blue = defs[i]->blue;
290 	    cdef.green = defs[i]->green;
291 	    find_color (rw, &cdef);
292 	    success = XAllocColor(d, colormap, &cdef);
293 	    if (success) {
294 		memcpy (defs[i], &cdef, sizeof(XColor));
295 	    }
296 	}
297     }
298 }
299 
300 
301 // String to Pixel type converter
IBMApplication_String2Pixel(Display * d,XrmValue[],Cardinal,XrmValue * from,XrmValue * to,XtPointer * closure)302 extern "C" Boolean IBMApplication_String2Pixel (Display *d, XrmValue [], Cardinal ,
303 	XrmValue *from, XrmValue *to, XtPointer *closure)
304 {
305 static XColor cdef;
306 Colormap colormap;
307 Screen *screen;
308 int status;
309 
310     String colorname = (String)from[0].addr;
311     Widget self = theApplication->getRootWidget();
312     XtVaGetValues (self, XmNcolormap, &colormap, XmNscreen, &screen, NULL);
313     ASSERT (colormap);
314     ASSERT (screen);
315 
316     if (!strcmp(colorname, XtDefaultForeground)) colorname = "Black";
317     else if (!strcmp(colorname, XtDefaultBackground)) colorname = "#b4b4b4b4b4b4";
318 
319     status = XParseColor (d, colormap, colorname, &cdef);
320     if (!status) {
321 	char errmsg[128];
322 	sprintf (errmsg, "Unrecognized color entry: %s\n", colorname);
323 	XtWarning (errmsg);
324 	*closure = (XtPointer)False;
325 	return False;
326     }
327 
328     status = XAllocColor (d, colormap, &cdef);
329     if (!status) {
330 	find_color (self, &cdef);
331 	Pixel tmp = cdef.pixel;
332 	status = XAllocColor (d, colormap, &cdef);
333 	if (!status)
334 	    cdef.pixel = tmp;
335     }
336 
337     *closure = (XtPointer)True;
338     if (to->addr != NULL) {
339 	if (to->size < sizeof(Pixel)) {
340 	    to->size = sizeof(Pixel);
341 	    return False;
342 	}
343 	*(Pixel*)(to->addr) = cdef.pixel;
344     } else {
345 	to->addr = (XPointer )&cdef.pixel;
346     }
347     to->size = sizeof(Pixel);
348     return True;
349 }
350 
351 
initializeWindowSystem(int * argcp,char ** argv)352 boolean IBMApplication::initializeWindowSystem(int *argcp, char **argv)
353 {
354 
355     if (!this->Application::initializeWindowSystem(argcp, argv))
356         return FALSE;
357 
358 #if defined(DEBUG) && defined(BETA_VERSION)
359     fprintf(stderr,"This is a BETA version. Undef BETA_VERSION"
360 			" (in IBMVersion.h) before shipping\n");
361 #endif
362 
363 
364     XtAppSetTypeConverter (this->applicationContext, XmRString, XmRPixel,
365 	(XtTypeConverter)IBMApplication_String2Pixel, NULL, 0,
366 	XtCacheAll, NULL);
367 
368     // By setting Motif's color calculation proc, we can ensure that
369     // we'll wind up using reasonable shadows when the shadows Motif
370     // would normally use, aren't available.
371     IBMApplication::DefColorProc =
372 	XmSetColorCalculation ((XmColorProc)IBMApplication_ColorProc);
373 
374 
375     return TRUE;
376 }
377 
initialize(int * argcp,char ** argv)378 boolean IBMApplication::initialize(int* argcp,
379 				   char**        argv)
380 {
381     if (!this->Application::initialize(argcp,argv))
382         return FALSE;
383 
384     this->parseCommand(argcp, argv, _IBMOptionList, XtNumber(_IBMOptionList));
385 
386     //
387     // Get application resources.
388     //
389     this->getResources((XtPointer)&IBMApplication::resource,
390 		       _IBMResourceList,
391 		       XtNumber(_IBMResourceList));
392 
393     if (IBMApplication::resource.UIRoot == NULL) {
394 	char *s = getenv("DXROOT");
395 	if (s)
396 	    // POSIX says we better copy the result of getenv(), so...
397 	    // This will show up as a memory leak, not worth worrying about
398 	    IBMApplication::resource.UIRoot = DuplicateString(s);
399 	else
400 	    IBMApplication::resource.UIRoot =  "/usr/local/dx";
401     }
402 
403     this->initIcon();
404 
405     this->parseNoWizardNames();
406 
407     return TRUE;
408 }
409 
newHelpWindow()410 HelpWin *IBMApplication::newHelpWindow()
411 {
412     return new HelpWin();
413 }
helpOn(const char * topic)414 void IBMApplication::helpOn(const char *topic)
415 {
416     if (!this->helpWindow) {
417         this->helpWindow = this->newHelpWindow();
418     }
419     this->helpWindow->helpOn(topic);
420 }
421 
addActions()422 void IBMApplication::addActions()
423 {
424     this->Application::addActions();
425     XtAppAddActions(this->applicationContext, IBMApplication::actions,
426         sizeof(IBMApplication::actions)/sizeof(IBMApplication::actions[0]));
427 }
428 
IBMApplication_IBMButtonHelpAP(Widget widget,XEvent *,String *,Cardinal *)429 extern "C" void IBMApplication_IBMButtonHelpAP(
430     Widget   widget,
431     XEvent*   /* event */,
432     String*   /* params */,
433     Cardinal* /* num_params */)
434 {
435 
436     MainWindowHelpCallbackStruct callData;
437 
438 #if FIXME
439     if (!theDXApplication->appAllowsDXHelp())
440         return;
441 #endif
442 
443     while (widget)
444     {
445         if (XtHasCallbacks(widget, XmNhelpCallback) == XtCallbackHasSome)
446         {
447             callData.reason = DxCR_HELP;
448             callData.event  = NULL;
449             callData.widget = widget;
450             XtCallCallbacks
451                 (widget,
452                  XmNhelpCallback,
453                  (XtPointer)&callData);
454             break;
455         }
456         else
457         {
458             widget = XtParent(widget);
459         }
460     }
461 }
462 
463 
464 //
465 // Get the command string that will start the tutorial.
466 //
getStartTutorialCommandString()467 const char *IBMApplication::getStartTutorialCommandString()
468 {
469     return "dx -tutor";
470 }
471 
472 //
473 // Start the tutorial on behalf of the application.
474 //
startTutorial()475 boolean IBMApplication::startTutorial()
476 {
477     char *url = new char[strlen(getUIRoot()) + 35];
478     strcpy(url, "file://");
479     strcat(url, getUIRoot());
480     strcat(url, "/html/pages/qikgu011.htm");
481     if(!_dxf_StartWebBrowserWithURL(url))
482 	system("dx -tutor");
483     delete[] url;
484 
485     return TRUE;
486 }
handleXtWarning(char * message)487 void IBMApplication::handleXtWarning(char *message)
488 {
489     this->Application::handleXtWarning(message);
490     if(strstr(message, "Could not convert X KEYSYM to a keycode"))
491     {
492 	fprintf(stderr, "XtWarning: %s\n", message);
493 	fprintf(stderr, "Please see the README file for Data Explorer for a work-around.\n\n");
494     }
495 }
496 
497 //
498 // If there is a copyright notice, we create the Logo and Icon data structures
499 // and then call the super class method,  otherwise, we just return.
500 //
postCopyrightNotice()501 void IBMApplication::postCopyrightNotice()
502 {
503     const char *s = this->getCopyrightNotice();
504     if (s)
505 	this->initLogo();
506 
507     this->Application::postCopyrightNotice();
508 }
509 
initLogo()510 void IBMApplication::initLogo()
511 {
512 int		i,k;
513 unsigned long	ndx;
514 int		x,y;
515 Display 	*d;
516 Colormap	cmap;
517 XColor		xcolor2[256];
518 unsigned long	rmult, gmult, bmult;
519 XImage 		*ximage;
520 GC		gc;
521 unsigned char	*logo_data;
522 FILE	*fp;
523 size_t  size;
524 char	s[256];
525 
526 #if defined(HAVE_LIBXPM)
527     Widget w;
528     int err;
529     w = theIBMApplication->getRootWidget();
530 
531     sprintf(s, "%s/ui/logo.xpm", theIBMApplication->getUIRoot());
532     err = XpmReadFileToPixmap(XtDisplay(w),
533         RootWindowOfScreen(XtScreen(w)),
534 	s, &this->logo_pmap, NULL, NULL);
535     if (err != XpmSuccess) {
536 
537 #endif
538     size = LOGO_WIDTH*LOGO_HEIGHT;
539     logo_data = (unsigned char *)XtMalloc(size);
540     sprintf(s,"%s/ui/logo.dat", this->getUIRoot());
541 
542     if((fp = fopen(s, "r")) == NULL)
543     {
544 	WarningMessage("Unable to open logo data");
545 	XtFree((char *)logo_data);
546 	return;
547     }
548     if(fread((char *)logo_data, sizeof(char), size, fp) != size)
549     {
550 	WarningMessage("Unable to read logo data");
551 	XtFree((char *)logo_data);
552 	return;
553     }
554     fclose(fp);
555     d = XtDisplay(this->getRootWidget());
556     XtVaGetValues (this->getRootWidget(),
557 	XmNcolormap, &cmap,
558     NULL);
559 
560     this->logo_pmap =
561 	XCreatePixmap(d, RootWindowOfScreen(XtScreen(this->getRootWidget())),
562 	    LOGO_WIDTH, LOGO_HEIGHT,
563 	    DefaultDepthOfScreen(XtScreen(this->getRootWidget())));
564     ximage = XGetImage(d, this->logo_pmap, 0, 0,
565 	LOGO_WIDTH, LOGO_HEIGHT, AllPlanes, ZPixmap);
566 
567     Visual *xvi = DefaultVisualOfScreen(XtScreen(this->getRootWidget()));
568     XVisualInfo vinfotemplate;
569     vinfotemplate.visualid = XVisualIDFromVisual(xvi);
570     int nReturn;
571     XVisualInfo *xvinfo = XGetVisualInfo(XtDisplay(this->getRootWidget()),
572                               VisualIDMask, &vinfotemplate, &nReturn);
573 
574     if (xvinfo->c_class == PseudoColor || xvinfo->c_class == TrueColor)
575     {
576 	unsigned char *l;
577 	Boolean failed = False;
578 	this->num_colors = 0;
579 	for(i = 0; i < LUT_SIZE; i++)
580 	{
581 	    if(XAllocColor(d, cmap, &logo_lut[1][i]) && !failed)
582 	    {
583 		this->num_colors++;
584 	    }
585 	    else
586 	    {
587 		failed = True;
588 		find_color(this->getRootWidget(), &logo_lut[1][i]);
589 	    }
590 	}
591 	for (i = 0; i < LUT_SIZE; i++)
592 	{
593 	    ndx = logo_lut[0][i].pixel;
594 	    xcolor2[ndx] = logo_lut[1][i];
595 	}
596 	for(y = 0, l = logo_data; y < LOGO_HEIGHT; y++ )
597 	    for(x = 0; x < LOGO_WIDTH; x++ )
598 		XPutPixel(ximage, x, y, xcolor2[*l++].pixel);
599     }
600     else if(xvinfo->c_class == DirectColor)
601     {
602 	Visual *xvi = DefaultVisualOfScreen(XtScreen(this->getRootWidget()));
603 	rmult = xvi->red_mask & (~xvi->red_mask+1);
604 	gmult = xvi->green_mask & (~xvi->green_mask+1);
605 	bmult = xvi->blue_mask & (~xvi->blue_mask+1);
606 
607 	for (i = 0; i < LUT_SIZE; i++)
608 	{
609 	    ndx = logo_lut[0][i].pixel;
610 	    xcolor2[ndx].red =   logo_lut[0][i].red >> 8;
611 	    xcolor2[ndx].green = logo_lut[0][i].green >> 8;
612 	    xcolor2[ndx].blue =  logo_lut[0][i].blue >> 8;
613 	    xcolor2[ndx].pixel =
614 				xcolor2[ndx].red * rmult +
615 				xcolor2[ndx].green * gmult +
616 				xcolor2[ndx].blue * bmult;
617 	}
618 
619 	k = 0;
620 	for(y = 0; y < LOGO_HEIGHT; y++)
621 	{
622 	    for(x = 0; x < LOGO_WIDTH; x++)
623 	    {
624 		ndx = logo_data[k++];
625 		XPutPixel(ximage, x, y, xcolor2[ndx].pixel);
626 	    }
627 	}
628     }
629     gc = XCreateGC(d, this->logo_pmap, 0, NULL);
630 
631     XPutImage(d, this->logo_pmap, gc, ximage, 0, 0, 0, 0,
632 	LOGO_WIDTH, LOGO_HEIGHT);
633 
634     XtFree((char *)logo_data);
635     XFreeGC(d, gc);
636     XDestroyImage(ximage);
637 #if defined(HAVE_LIBXPM)
638     }
639 #endif
640 }
cleanupLogo()641 void IBMApplication::cleanupLogo()
642 {
643     Display *d;
644     Colormap cmap;
645     int     depth, i;
646     unsigned long   pix[256];
647 
648     if (this->logo_pmap == XtUnspecifiedPixmap)
649 	return;
650 
651     d = XtDisplay(this->getRootWidget());
652 
653     XtVaGetValues (this->getRootWidget(),
654 	XmNcolormap, &cmap,
655 	XmNdepth, &depth,
656     NULL);
657     if (depth == 8)
658     {
659 
660         for(i = 0; i < this->num_colors; i++)
661             pix[i] = logo_lut[1][i].pixel;
662 
663         XFreeColors(d, cmap, &(pix[0]), this->num_colors, 0);
664     }
665     XFreePixmap(d, this->logo_pmap);
666 }
667 
initIcon()668 void IBMApplication::initIcon()
669 {
670 Display 	*d;
671 Colormap	cmap;
672 XImage		*ximage;
673 GC		gc;
674 unsigned char	*icon_data;
675 FILE		*fp;
676 size_t 		size;
677 int		k;
678 int		x,y;
679 char		s[256];
680 
681 #if defined(HAVE_LIBXPM)
682     Widget w;
683     int err;
684     w = theIBMApplication->getRootWidget();
685 
686     sprintf(s, "%s/ui/icon50.xpm", theIBMApplication->getUIRoot());
687     err = XpmReadFileToPixmap(XtDisplay(w),
688         RootWindowOfScreen(XtScreen(w)),
689 	s, &this->icon_pmap, NULL, NULL);
690     if (err != XpmSuccess) {
691 
692 #endif
693     size = ICON_WIDTH*ICON_HEIGHT;
694     icon_data = (unsigned char *)XtMalloc(size);
695 
696     sprintf(s,"%s/ui/icon50.dat", theIBMApplication->getUIRoot());
697     if((fp = fopen(s, "r")) == NULL)
698     {
699         WarningMessage("Unable to open icon data\n");
700 	XtFree((char *)icon_data);
701         return;
702     }
703     if(fread((char *)icon_data, sizeof(char), size, fp) != size)
704     {
705         WarningMessage("Unable to read icon data\n");
706 	XtFree((char *)icon_data);
707         return;
708     }
709     fclose(fp);
710 
711     d = XtDisplay(theIBMApplication->getRootWidget());
712     XtVaGetValues (this->getRootWidget(), XmNcolormap, &cmap, NULL);
713 
714     this->icon_pmap =
715 	XCreatePixmap(d, RootWindowOfScreen(XtScreen(this->getRootWidget())),
716 	    ICON_WIDTH, ICON_HEIGHT, 1);
717     ximage =
718 	XGetImage(d, this->icon_pmap, 0, 0,
719 	    ICON_WIDTH, ICON_HEIGHT, AllPlanes, ZPixmap);
720 
721     k = 0;
722     for(y = 0; y < ICON_HEIGHT; y++)
723     {
724 	for(x = 0; x < ICON_WIDTH; x++)
725 	{
726 	    XPutPixel(ximage, x, y, icon_data[k++]);
727 	}
728     }
729 
730     gc = XCreateGC(d, this->icon_pmap, 0, NULL);
731 
732     XPutImage(d, this->icon_pmap, gc, ximage,
733 	      0, 0, 0, 0, ICON_WIDTH, ICON_HEIGHT);
734 
735     XFreeGC(d, gc);
736     XDestroyImage(ximage);
737     XtFree((char *)icon_data);
738 #if defined(HAVE_LIBXPM)
739     }
740 #endif
741 }
getVersionNumbers(int * maj,int * min,int * mic)742 void IBMApplication::getVersionNumbers(int *maj, int *min, int *mic)
743 {
744    *maj = IBM_MAJOR_VERSION;
745    *min = IBM_MINOR_VERSION;
746    *mic = IBM_MICRO_VERSION;
747 }
748 //
749 // Get the 'about' string as reported from 'About...' menu option
750 //
getAboutAppString()751 const char *IBMApplication::getAboutAppString()
752 {
753 
754     if (!this->aboutAppString) {
755 	int a,b,c;
756 	this->getVersionNumbers(&a,&b,&c);
757         this->aboutAppString = new char[1024];
758         sprintf(this->aboutAppString,
759 		"Product : %s \n"
760 #if defined(BETA_VERSION)
761 		"Version : %d.%d.%d Beta\n"
762 #else
763 		"Version : %d.%d.%d\n"
764 #endif
765 		"Dated   : %s",
766                         this->getFormalName(),
767 			a,b,c,
768                         __DATE__);
769     }
770     return this->aboutAppString;
771 }
772 
773 //
774 // Get the 'technical support' string as reported from 'Technical Support...'
775 // menu option
776 //
getTechSupportString()777 const char *IBMApplication::getTechSupportString()
778 {
779     if (!this->techSupportString) {
780 	const char *dxroot = this->getUIRoot();
781 	const char *nosup = "No Technical Support Available";
782 	if (!dxroot) {
783 	    this->techSupportString = DuplicateString(nosup);
784 	    return this->techSupportString;
785 	}
786 
787 	char supfile[1024];
788 	sprintf(supfile,"%s/ui/support.txt",dxroot);
789 	FILE *fp;
790 	int helpsize;
791 
792 	struct STATSTRUCT buf;
793 
794 	if (STATFUNC(supfile, &buf) != 0) {
795 	    this->techSupportString = DuplicateString(nosup);
796 	    return this->techSupportString;
797 	}
798 	helpsize = buf.st_size;
799 
800 	if (!(fp = fopen(supfile,"r"))) {
801 	    this->techSupportString = DuplicateString(nosup);
802 	    return this->techSupportString;
803 	}
804 
805 	this->techSupportString = new char[helpsize + 1];
806 	if (!this->techSupportString) {
807 	    this->techSupportString = DuplicateString(nosup);
808 	    return this->techSupportString;
809 	}
810 	fread(this->techSupportString,1,helpsize,fp);
811 	this->techSupportString[helpsize] = '\0';
812 	fclose(fp);
813     }
814 
815     return this->techSupportString;
816 }
817 
818 //
819 // Get the name of the directoy that contains the help files.
820 // This returns $UIRoot/help
821 //
getHelpDirectory()822 const char *IBMApplication::getHelpDirectory()
823 {
824     static char *helpDir = NULL;
825 
826     if (!helpDir)
827     {
828         const char *root = this->getUIRoot();
829         helpDir = new char[STRLEN(root) + strlen("/help") + 1];
830         sprintf(helpDir, "%s/help", root);
831     }
832     return helpDir;
833 }
getHTMLDirectory()834 const char *IBMApplication::getHTMLDirectory()
835 {
836     static char *htmlDir = NULL;
837 
838     if (!htmlDir)
839     {
840         const char *root = this->getUIRoot();
841         htmlDir = new char[STRLEN(root) + strlen("/html") + 1];
842         sprintf(htmlDir, "%s/html", root);
843     }
844     return htmlDir;
845 }
getTmpDirectory(boolean bList)846 const char *IBMApplication::getTmpDirectory(boolean bList)
847 {
848 #ifndef MAX_DIR_PATH_LIST
849 #define MAX_DIR_PATH_LIST  255
850 #endif
851     static char *tmpDir = NULL, tmpDirList[MAX_DIR_PATH_LIST];
852     static int beingHere = 0;
853     char	*p;
854 
855 #ifdef DXD_OS_NON_UNIX
856     if(!beingHere) {
857 	strcpy(tmpDirList, "./;");
858 	tmpDir = "./";
859 
860 	p = getenv("TEMP");	//	2nd Pref
861 	if(p) {
862 	    tmpDir = p;
863 	    strcat(tmpDirList, p);
864 	    strcat(tmpDirList, ";");
865 	}
866 
867 	p = getenv("TMP");	//	1st Pref.
868 	if(p) {
869 	    tmpDir = p;
870 	    strcat(tmpDirList, p);
871 	    strcat(tmpDirList, ";");
872 	}
873 	beingHere = 1;
874 	DOS2UNIXPATH(tmpDir);
875 	DOS2UNIXPATH(tmpDirList);
876     }
877     if (bList) {
878 	return tmpDirList;
879     }
880     else {
881 	return tmpDir;
882     }
883 #else
884     if(!beingHere) {
885 	strcpy(tmpDirList, "/tmp;");
886 	tmpDir = "/tmp";
887 
888 	p = getenv("TMP");	//	2nd Pref
889 	if(p) {
890 	    tmpDir = p;
891 	    strcat(tmpDirList, p);
892 	    strcat(tmpDirList, ";");
893 	}
894 
895 	p = getenv("TMPDIR");	//	1st Pref
896 	if(p) {
897 	    tmpDir = p;
898 	    strcat(tmpDirList, p);
899 	    strcat(tmpDirList, ";");
900 	}
901 	beingHere = 1;
902     }
903     if (bList)
904 	return tmpDirList;
905     else
906 	return tmpDir;
907 #endif
908 }
909 
910 //
911 // Application Resources
912 //
getApplicationDefaultsFileName(char * res_file,boolean create)913 boolean IBMApplication::getApplicationDefaultsFileName(char* res_file, boolean create)
914 {
915     //
916     // Print the resource database to the file.
917     //
918 #ifdef DXD_OS_NON_UNIX
919 const char* class_name = this->getApplicationClass();
920     char* home = (char*)getenv("XAPPLRESDIR");
921     if (!home || !strlen(home)) {
922 	home = (char*)this->resource.UIRoot;
923 	if (!home || !strlen(home)) {
924 	    sprintf(res_file, "/%s-AD", class_name);
925 	} else {
926 	    sprintf(res_file, "%s/ui/%s-AD", home, class_name);
927 	}
928     } else {
929 	sprintf(res_file, "%s/ui/%s-AD", home, class_name);
930     }
931 
932     return this->isUsableDefaultsFile(res_file, create);
933 #else
934     return this->Application::getApplicationDefaultsFileName(res_file, create);
935 #endif
936 }
937 
938 //
939 // Open $HOME/DX, search for DX*dismissedWizards:.   If found, replace it,
940 // otherwise append the DX*dismissedWizards: and the contents of noWizards.
941 //
printResource(const char * resource,const char * value)942 void IBMApplication::printResource(const char* resource, const char* value)
943 {
944 const char* class_name = this->getApplicationClass();
945 
946     //
947     // Create one line which specifies the new resource setting.
948     //
949     int totlen = 0;
950     char resource_line[4096];
951     sprintf (resource_line, "%s*%s: %s\n", class_name, resource, value);
952 
953     char res_file[256];
954     if (this->getApplicationDefaultsFileName(res_file, TRUE)) {
955 	// Here, it would be nice to use a function like
956 	// XrmRemoveLineResource() but I can't find any
957 	// such beast.  If one were available, then when
958 	// there is no value for a resource, the spec
959 	// could be removed from the file.  This way
960 	// we store a nothing spec in the file.
961 	XrmDatabase db = XrmGetFileDatabase(res_file);
962 	XrmPutLineResource (&db, resource_line);
963 	XrmPutFileDatabase (db, res_file);
964 	XrmDestroyDatabase(db);
965     }
966 }
967 
968 
969 //
970 // W I Z A R D S     W I Z A R D S     W I Z A R D S
971 // W I Z A R D S     W I Z A R D S     W I Z A R D S
972 // W I Z A R D S     W I Z A R D S     W I Z A R D S
973 //
974 #define NAME_SEP ','
975 
976 //
977 // The wizard name list is a colon separated list of names.
978 //
parseNoWizardNames()979 void IBMApplication::parseNoWizardNames()
980 {
981     if (this->resource.noWizardNames == NUL(char*)) return ;
982 
983     this->noWizards = new List;
984 
985     //
986     // Change the separators to \0
987     //
988     char* nwn = DuplicateString(this->resource.noWizardNames);
989     int len = strlen(nwn);
990     int names = 0;
991     int i;
992     boolean trailing_name_sep = FALSE;
993     for (i=0; i<len; i++) {
994 	if (nwn[i] == NAME_SEP) {
995 	    if (i == (len-1))
996 		trailing_name_sep = TRUE;
997 	    nwn[i] = '\0';
998 	    names++;
999 	}
1000     }
1001     if (!trailing_name_sep) names++;
1002 
1003     //
1004     // Append each name in the big string to a list.
1005     //
1006     char *cp = nwn;
1007     for (i=0; i<names; i++) {
1008 	char *name = DuplicateString(cp);
1009 	this->noWizards->appendElement((void*)name);
1010 	cp+= 1+strlen(name);
1011     }
1012 
1013     delete[] nwn;
1014 }
1015 
1016 //
1017 // Add 1 name to the list and update the resource value in $HOME/DX file
1018 // dxui will automatically read the contents of $HOME/DX when it starts up thereby
1019 // setting the list of names which should get no wizard.
1020 //
appendNoWizardName(const char * nowiz)1021 void IBMApplication::appendNoWizardName(const char* nowiz)
1022 {
1023     char* name = DuplicateString(nowiz);
1024     if (!this->noWizards)
1025 	this->noWizards = new List;
1026     this->noWizards->appendElement((void*)name);
1027     this->printNoWizardNames();
1028 }
1029 
1030 
1031 //
1032 // Open $HOME/DX, search for DX*dismissedWizards:.   If found, replace it,
1033 // otherwise append the DX*dismissedWizards: and the contents of noWizards.
1034 //
printNoWizardNames()1035 void IBMApplication::printNoWizardNames()
1036 {
1037 const char* class_name = this->getApplicationClass();
1038 
1039     char res_file[256];
1040     if (!this->getApplicationDefaultsFileName(res_file,TRUE)) {
1041 	//
1042 	// Probably should complain somehow, but the user is not in a position
1043 	// to deal with this sort of complaint.  This happens when the user
1044 	// clicks the 'don't show this help message anymore' button that only
1045 	// appears as a result of running with -wizard or thru startupui.
1046 	//
1047 	return ;
1048     }
1049 
1050     //
1051     // Create one line which specifies the new resource setting.
1052     //
1053     int totlen = 0;
1054     char *resource_fmt = "%s*dismissedWizards: %s";
1055     char* name;
1056     ListIterator it(*this->noWizards);
1057     while ( (name = (char*)it.getNext()) ) {
1058 	totlen+= 1+strlen(name);
1059     }
1060 
1061     totlen+= 32;
1062     char *name_list = new char[totlen];
1063 
1064     totlen+= strlen(resource_fmt);
1065 
1066     char *resource_line = new char[totlen];
1067 
1068     it.setList(*this->noWizards);
1069     int nl_os = 0;
1070     while ( (name = (char*)it.getNext()) ) {
1071 	strcpy (&name_list[nl_os], name);
1072 	nl_os+= strlen(name);
1073 	name_list[nl_os++] = NAME_SEP;
1074 	name_list[nl_os] = '\0';
1075     }
1076     if (name_list[nl_os-1] == NAME_SEP) {
1077 	nl_os--;
1078 	name_list[nl_os] = '\0';
1079     }
1080     sprintf (resource_line, resource_fmt, class_name, name_list);
1081 
1082     //
1083     // Print the resource database to the file.
1084     //
1085 
1086     XrmDatabase db = XrmGetFileDatabase(res_file);
1087     XrmPutLineResource (&db, resource_line);
1088     XrmPutFileDatabase (db, res_file);
1089     XrmDestroyDatabase(db);
1090     delete[] resource_line;
1091 }
1092 
isWizardWindow(const char * name)1093 boolean IBMApplication::isWizardWindow(const char* name)
1094 {
1095     if (this->inWizardMode() == FALSE) return FALSE;
1096 
1097     if (!this->noWizards) return TRUE;
1098 
1099     ListIterator it(*this->noWizards);
1100     char *wiz;
1101     while ( (wiz = (char*)it.getNext()) ) {
1102 	if (EqualString(wiz, name)) return FALSE;
1103     }
1104 
1105     return TRUE;
1106 }
1107 
getLogoPixmap(boolean create_if_necessary)1108 Pixmap IBMApplication::getLogoPixmap(boolean create_if_necessary)
1109 {
1110     if ((this->logo_pmap == XtUnspecifiedPixmap) && (create_if_necessary == TRUE))
1111 	this->initLogo();
1112     return this->logo_pmap;
1113 }
1114