1 /*----------------------------------------------------------------------------
2                            topaz.cc (main routine of topaz)
3                        This file is a part of topaz systems
4                   Copyright: Hisao Kawaura, All rights reserved
5                                    1997 - 99
6 
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 
22 ----------------------------------------------------------------------------*/
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string>
27 #include "topazcurses.h"
28 #include <string.h>
29 #include <unistd.h>
30 #include <dirent.h>
31 #include <sys/stat.h>
32 #include <signal.h>
33 //#include <getopt.h>
34 //char *optarg;
35 #include "script.h"
36 #include "frame.h"
37 #include "menudef.h"
38 #if defined(TOPAZ_SJIS)
39 #include "jmenudef_sjis.h"
40 #else
41 #include "jmenudef_euc.h"
42 #endif
43 #include "cui.h"
44 #include "msgbuff.h"
45 #include "filepoint.h"
46 
47 extern char *toshortfilename(char *in);
48 extern int linelength(char *str, int offset, int displength);
49 extern bool getmacroname(std::string *file, std::string *out);
50 
51 // sub-window pointer
52 WINDOW  *menuwin = 0, *msgwin = 0, *sepwin = 0;
53 // mainwindow size
54 int mainwinlines, mainwincols;
55 // window lines
56 # define MINMENUWINLINES 17
57 int menuwinlines = MINMENUWINLINES;
58 int sepwinlines =1;
59 int tabnumber = 5;
60 // menuitem
61 int itemwidth = 11;
62 int itemspace = 2;
63 // maxrow
64 int maxrow;
65 int leftmargin = 1;
66 int topmargin = 1;
67 // buffersize
68 int msgbuffsize = 100;
69 
70 
71 // pointer to graph object
72 graph* gra = 0;
73 
74 // pointer to msgbuff
75 msgbuff* msgb = 0;
76 
77 // path
78 char confpath[1000];
79 char tmppath[1000];
80 char pid[100];
81 
82 // filehandle buff
83 FileHandleArray* fhvuff = 0;
84 
85 // exist cuimenu
86 bool isexistcuimenu = false;
87 
88 // pointer to environment variables
89 char **envp;
90 
91 // japanesecuimenu
92 bool japanesecui = false;
93 
94 #if defined(TOPAZ_PDCURSES)
95 #define TABSIZE  0
96 #endif
97 
98 #define MENU_HOTKEY_FORECOLOR 11
99 #define MENU_HOTKEY_BACKCOLOR 12
100 #define MENU_HOTKEY_COLORPAIR 1
101 bool has_color = true;
102 int hotkeyattr;
103 
104 void updatemenu();
105 int mainmenuitempos(int i);
106 void updatepop();
107 
108 
topazgetch(WINDOW * win)109 int topazgetch(WINDOW *win)
110 {
111   return wgetch(win);
112 }
113 
clearmenuwin()114 void clearmenuwin()
115 {
116   for (int i = 0; i < mainwinlines; i++)
117     {
118       for (int j = 0; j < mainwincols; j++)
119 	{
120 	  wmove(menuwin, i, j); wprintw(menuwin, " ");
121 	}
122     }
123   wmove(menuwin, 0, 0);
124   wprintw(menuwin, " ");
125   wmove(menuwin, 0, 0);
126   wrefresh(menuwin);
127 }
128 
129 
exitcuimenu()130 void exitcuimenu()
131 {
132   if (msgb != 0)
133     {
134       def_prog_mode();
135       endwin();
136     }
137 }
138 
restorecuimenu()139 void restorecuimenu()
140 {
141   if (msgb != 0)
142     {
143       wnoutrefresh(menuwin); wnoutrefresh(msgwin);
144       wnoutrefresh(sepwin);
145       wnoutrefresh(stdscr);
146       doupdate();
147     }
148 }
149 
abs_wtov_x(int wx)150 int abs_wtov_x(int wx)
151 {
152   return wx;
153 }
154 
abs_wtov_y(int wy)155 int abs_wtov_y(int wy)
156 {
157   return wy;
158 }
159 
abs_scale(int x)160 int abs_scale(int x)
161 {
162   return x;
163 }
164 
fileexist(char * file)165 bool fileexist(char *file)
166 {
167   FILE *h;
168   if ((h = fopen(file, "r")) != NULL)
169     {
170       fclose(h);
171       return true;
172     }
173   return false;
174 }
175 
message(const char * msg)176 void message(const char *msg)
177 {
178   if (msgb == 0)
179     fprintf(stdout, (char *)msg);
180   else
181     msgb->print(msg);
182 }
183 
emessage(int lineno,char * mes,const char * com,char * scrname)184 int emessage(int lineno, char *mes, const char *com, char *scrname)
185 {
186   std::string tempstr;
187   char stemp[100];
188 
189   tempstr = std::string(scrname);
190   tempstr += std::string(":");
191   sprintf(stemp, "%d: ", lineno);
192   tempstr += std::string(stemp);
193   tempstr += std::string("Error!: ");
194   tempstr += std::string(mes);
195   tempstr += std::string(" '");
196   tempstr += std::string(com);
197   tempstr += std::string("'\n");
198 
199   if (msgb == 0)
200     fprintf(stderr, (char *)tempstr.c_str());
201   else
202     msgb->print(tempstr.c_str());
203 
204   return false;
205 }
206 
207 
showsepwin()208 void showsepwin()
209 {
210   char stemp[1000], stemp1[1000];
211   char dest[] = " Topaz | ";
212   int len = strlen(dest);
213   strcpy(stemp, dest);
214   strncpy(stemp1, toshortfilename(gra->graphname), 75 - len);
215   stemp[sizeof(stemp1) - 1] = 0;
216   strcat(stemp, stemp1);
217 
218   if (sepwin == 0)
219     return;
220 
221   wattron(sepwin, A_REVERSE);
222   for (int i = 0; i < mainwincols; i++)
223     {
224       wmove(sepwin, 0, i);
225       if (i < (int)strlen(stemp))
226           wprintw(sepwin, "%c", stemp[i]);
227       else
228           wprintw(sepwin, " ");
229     }
230   wattroff(sepwin, A_REVERSE);
231   wrefresh(sepwin);
232 
233 }
234 
truetitlelength(const char * s)235 int truetitlelength(const char *s)
236 {
237   int count = 0;
238   char *p = (char *)s;
239   while (*p != 0)
240     {
241       if (*p != '&')
242 	count++;
243       p++;
244     }
245   return count;
246 }
247 
itemshowcurrentmenu(CUIMENU * menu,int maxitem,int addoffset)248 void itemshowcurrentmenu(CUIMENU *menu, int maxitem, int addoffset)
249 {
250   char mask[100];
251   int x, y;
252   int width = 3 * itemwidth + 3 * itemspace;
253   int oset, count = 0;
254   char stemp[20];
255   char *p;
256   bool keyflag = false;
257   script *scr;
258   std::string str1, str2;
259   int casoffsety = 2;
260   char menuline1[] = "-----------------------------------------------------------------------------";
261   char menuline2[] = "=============================================================================";
262   int labelwidth = itemwidth * 3 / 2;
263 
264   if (menuwin == 0)
265     return;
266 
267   strcpy(mask, "");
268   for (int i = 0; i < itemwidth; i++)
269     strcat(mask, " ");
270 
271   oset = 0;
272 
273   clearmenuwin();
274   //wclear(menuwin);
275   for (int i = 1; i <= maxitem; i++)
276     {
277       keyflag = false;
278       y = (i - 1) / (maxrow / 3);
279       x = (i - 1) - (maxrow / 3) * y;
280 
281       wmove(menuwin, y + topmargin + addoffset + casoffsety,
282 	    x * width + leftmargin);
283       wprintw(menuwin, mask);
284 
285       p = (char *)menu[i].item;
286       count = 0;
287 
288       while (*p != 0)
289 	{
290 	  if (*p != '&')
291 	    {
292 	      stemp[0] = *p; stemp[1] = 0;
293 	      wmove(menuwin, y + topmargin + addoffset + casoffsety,
294 		    x * width + leftmargin + oset + count++);
295 	      wprintw(menuwin, stemp);
296 
297 	      if (keyflag)
298 		{
299 		  wattroff(menuwin, hotkeyattr);
300 		  keyflag = false;
301 		}
302 	    }
303 	  else
304 	    {
305 	      wattron(menuwin, hotkeyattr);
306 	      keyflag = true;
307 	    }
308 	  p++;
309 	}
310 
311       // display value
312       str1 = std::string ("");
313       scr = new script(gra);
314       str2 = std::string(menu[i].getvalue);
315       scr->execscript(&str2, &str1, 0);
316       delete scr;
317       strncpy(stemp, str1.c_str(), sizeof(stemp));
318       stemp[linelength(stemp, 0, sizeof(stemp))] = 0;
319 
320       wattron(menuwin, A_BOLD);
321       wmove(menuwin, y + topmargin + addoffset + casoffsety,
322 	    x * width + oset + (labelwidth + 1) + leftmargin + oset);
323       printtext(menuwin, stemp);
324       wattroff(menuwin, A_BOLD);
325 
326     }
327 
328   wattron(menuwin, A_BOLD);
329   wmove(menuwin, 1, leftmargin);
330   wprintw(menuwin, menu[0].item);
331   wattroff(menuwin, A_BOLD);
332   wmove(menuwin, 0, leftmargin);
333   wprintw(menuwin, menuline1);
334   wmove(menuwin, 2, leftmargin);
335   wprintw(menuwin, menuline2);
336 
337   wrefresh(menuwin);
338 }
339 
340 
itemshowcursor(CUIMENU * menu,int itemno,bool flag,int addoffset)341 void itemshowcursor(CUIMENU *menu, int itemno, bool flag, int addoffset)
342 {
343   char mask[100];
344   int x, y;
345   int width = itemwidth * 3 + itemspace * 3;
346   int oset, count = 0;
347   char stemp[10];
348   char *p;
349   bool keyflag = false;
350   int casoffsety = 2;
351   int labelwidth = itemwidth * 3 / 2;
352 
353   if (menuwin == 0)
354     return;
355 
356   y = (itemno - 1) / (maxrow / 3);
357   x = (itemno - 1) - (maxrow / 3) * y;
358 
359   strcpy(mask, "");
360   for (int i = 0; i < labelwidth; i++)
361     strcat(mask, " ");
362 
363   oset = 0;
364 
365   if (flag)
366       wattron(menuwin, A_REVERSE);
367 
368   wmove(menuwin, y + topmargin + addoffset + casoffsety,
369 	x * width + oset + leftmargin);
370   wprintw(menuwin, mask);
371 
372   p = (char *)menu[itemno].item;
373   count = 0;
374   while (*p != 0)
375     {
376       if (*p != '&')
377 	{
378 	  stemp[0] = *p; stemp[1] = 0;
379 	  wmove(menuwin, y + topmargin + addoffset + casoffsety,
380 		x * width + leftmargin + oset + count++);
381 	  wprintw(menuwin, stemp);
382 
383 	  if (keyflag)
384 	    {
385 	      if (!flag)
386 		wattroff(menuwin, hotkeyattr);
387 	      keyflag = false;
388 	    }
389 	}
390       else
391 	{
392 	  if (!flag)
393 	    wattron(menuwin, hotkeyattr);
394 	  keyflag = true;
395 	}
396       p++;
397     }
398 
399   wmove(menuwin, 0, 0);
400   wprintw(menuwin, " ");
401   wmove(menuwin, 0, 0);
402 
403   if (flag)
404       wattroff(menuwin, A_REVERSE);
405 
406   wrefresh(menuwin);
407 
408 }
409 
410 
itemcursormove(CUIMENU * menu,int * itemno,int maxitem,int addoffset)411 int itemcursormove (CUIMENU *menu, int *itemno, int maxitem, int addoffset)
412 {
413   int key, y;
414   char *p;
415   script *scr;
416   std::string str;
417 
418   if (menuwin == 0)
419     return LOCAL_ESCAPE_KEY;
420 
421   cbreak();
422   noecho();
423   if (*itemno < 0 || *itemno > maxitem)
424     *itemno = 0;
425 
426   while (1)
427     {
428 
429       y = *itemno;
430       itemshowcursor(menu, y, true, addoffset);
431       key = topazgetch(menuwin);
432       itemshowcursor(menu, y, false, addoffset);
433 
434       switch (key)
435 	{
436 	case KEY_LEFT:
437 	case CTRL('b'):
438 	  *itemno = (*itemno > 1) ? *itemno - 1: maxitem;
439 	  break;
440 	case KEY_RIGHT:
441 	case CTRL('f'):
442 	  *itemno = (*itemno < maxitem) ? *itemno + 1: 1;
443 	  break;
444 	case KEY_DOWN:
445 	case CTRL('n'):
446 	  *itemno = (*itemno + maxrow / 3 <= maxitem) ? *itemno + maxrow / 3: 1;
447 	  break;
448 	case KEY_UP:
449 	case CTRL('p'):
450 	  *itemno = (*itemno - maxrow / 3 >= 1) ? *itemno - maxrow / 3: maxitem;
451 	  break;
452 	case CTRL('a'):
453 	  *itemno = 1;
454 	  break;
455 	case CTRL('e'):
456 	  *itemno = maxitem;
457 	  break;
458 	  //select
459 	case ' ':
460 	  //paint
461 	case CTRL('v'):
462 	  scr = new script(gra);
463 	  str = std::string("$graph->paintall(V0);");
464 	  scr->execscript(&str, 0, 0);
465 	  delete scr;
466 	  break;
467 	  // return to top menu
468 	case CTRL('t'):
469 	  *itemno = -1;
470 	  return LOCAL_LF_KEY;
471 	  // scrolldown messagewindow
472  	case '[':
473 	  msgb->previous(1);
474 	  break;
475 	  // scrollup messagewindow
476 	case ']':
477 	  msgb->next(1);
478 	  break;
479 	  // return to previous menu
480 	case CTRL('g'):
481 	case '.':
482 	  return LOCAL_ESCAPE_KEY;
483 	}
484 
485       if ( 'a' < key < 'z')
486 	{
487 	  for (int i = 1; i <= maxitem; i++)
488 	    {
489 	      p = (char *)menu[i].item;
490 	      while (*p != 0)
491 		{
492 		  if (*p == '&')
493 		    {
494 		      p++;
495 		      if ((*p == key) || ((*p - 'A' + 'a') == key))
496 			{
497 			  *itemno = i;
498 			  return (LOCAL_LF_KEY);
499 			}
500 		    }
501 		  p++;
502 		}
503 	    }
504 	}
505 
506       if (key == LOCAL_ESCAPE_KEY || key == LOCAL_LF_KEY)
507 	break;
508     }
509   itemshowcursor(menu, y, true, addoffset);
510 
511   return (key);
512 }
513 
514 
515 
516 
517 
518 /*                                            */
519 /*   base of various menus for selecting item */
520 /*                                            */
521 
itemmenuexec(CUIMENU * menu,int * selectno)522 int itemmenuexec(CUIMENU *menu, int *selectno)
523 {
524   CUIMENU *m;
525   int itemlength = 0;
526   int itemno;
527   int flag1;
528   int selectedkey = 1;
529 
530   if (menuwin == 0)
531     return false;
532 
533   m = menu;
534   for (; m->item; m++)
535     {
536       if (itemlength < (int)strlen(m->item))
537 	itemlength = strlen(m->item);
538     }
539   itemno = m - menu - 1;
540   if (itemno < 1)
541     return false;
542 
543   do
544     {
545 
546       itemshowcurrentmenu(menu, itemno, 0);
547       flag1 = itemcursormove (menu, &selectedkey, itemno, 0);
548 
549 
550       //return to top menu
551       if (selectedkey == -1)
552 	{
553 	    *selectno = M_MAIN;
554 	    return LOCAL_LF_KEY;
555 	}
556       else if (flag1 == LOCAL_LF_KEY && !menu[selectedkey].submenu)
557 	{
558 	  execitem(menu, &selectedkey);
559 
560 	  if (menu[selectedkey].id == M_QUIT)
561 	  {
562 	    *selectno = M_QUIT;
563 	    return LOCAL_LF_KEY;
564 	  }
565 	}
566       *selectno = menu[selectedkey].id;
567 
568     }while (flag1 != LOCAL_ESCAPE_KEY);
569   return flag1;
570 }
571 
framemenu()572 int framemenu()
573 {
574   int selectno;
575   if (japanesecui)
576     return itemmenuexec(JFrame, &selectno);
577   else
578     return itemmenuexec(Frame, &selectno);
579 }
580 
xbasemenu()581 int xbasemenu()
582 {
583   int selectno;
584   if (japanesecui)
585     return itemmenuexec(JXBase, &selectno);
586   else
587     return itemmenuexec(XBase, &selectno);
588 }
xrangemenu()589 int xrangemenu()
590 {
591   int selectno;
592   if (japanesecui)
593     return itemmenuexec(JXRange, &selectno);
594   else
595     return itemmenuexec(XRange, &selectno);
596 }
xtickmenu()597 int xtickmenu()
598 {
599   int selectno;
600   if (japanesecui)
601     return itemmenuexec(JXMajortick, &selectno);
602   else
603     return itemmenuexec(XMajortick, &selectno);
604 }
xsubtickmenu()605 int xsubtickmenu()
606 {
607   int selectno;
608   if (japanesecui)
609     return itemmenuexec(JXMinortick, &selectno);
610   else
611     return itemmenuexec(XMinortick, &selectno);
612 }
xlabelmenu()613 int xlabelmenu()
614 {
615   int selectno;
616   if (japanesecui)
617     return itemmenuexec(JXLabel, &selectno);
618   else
619     return itemmenuexec(XLabel, &selectno);
620 }
621 
ybasemenu()622 int ybasemenu()
623 {
624   int selectno;
625   if (japanesecui)
626     return itemmenuexec(JYBase, &selectno);
627   else
628     return itemmenuexec(YBase, &selectno);
629 }
yrangemenu()630 int yrangemenu()
631 {
632   int selectno;
633   if (japanesecui)
634     return itemmenuexec(JYRange, &selectno);
635   else
636     return itemmenuexec(YRange, &selectno);
637 }
ytickmenu()638 int ytickmenu()
639 {
640   int selectno;
641   if (japanesecui)
642     return itemmenuexec(JYMajortick, &selectno);
643   else
644     return itemmenuexec(YMajortick, &selectno);
645 }
ysubtickmenu()646 int ysubtickmenu()
647 {
648   int selectno;
649   if (japanesecui)
650     return itemmenuexec(JYMinortick, &selectno);
651   else
652     return itemmenuexec(YMinortick, &selectno);
653 }
ylabelmenu()654 int ylabelmenu()
655 {
656   int selectno;
657   if (japanesecui)
658     return itemmenuexec(JYLabel, &selectno);
659   else
660     return itemmenuexec(YLabel, &selectno);
661 }
662 
tbasemenu()663 int tbasemenu()
664 {
665   int selectno;
666   if (japanesecui)
667     return itemmenuexec(JTBase, &selectno);
668   else
669     return itemmenuexec(TBase, &selectno);
670 }
trangemenu()671 int trangemenu()
672 {
673   int selectno;
674   if (japanesecui)
675     return itemmenuexec(JTRange, &selectno);
676   else
677     return itemmenuexec(TRange, &selectno);
678 }
ttickmenu()679 int ttickmenu()
680 {
681   int selectno;
682   if (japanesecui)
683     return itemmenuexec(JTMajortick, &selectno);
684   else
685     return itemmenuexec(TMajortick, &selectno);
686 }
tsubtickmenu()687 int tsubtickmenu()
688 {
689   int selectno;
690   if (japanesecui)
691     return itemmenuexec(JTMinortick, &selectno);
692   else
693     return itemmenuexec(TMinortick, &selectno);
694 }
tlabelmenu()695 int tlabelmenu()
696 {
697   int selectno;
698   if (japanesecui)
699     return itemmenuexec(JTLabel, &selectno);
700   else
701     return itemmenuexec(TLabel, &selectno);
702 }
703 
rbasemenu()704 int rbasemenu()
705 {
706   int selectno;
707   if (japanesecui)
708     return itemmenuexec(JRBase, &selectno);
709   else
710     return itemmenuexec(RBase, &selectno);
711 }
rrangemenu()712 int rrangemenu()
713 {
714   int selectno;
715   if (japanesecui)
716     return itemmenuexec(JRRange, &selectno);
717   else
718     return itemmenuexec(RRange, &selectno);
719 }
rtickmenu()720 int rtickmenu()
721 {
722   int selectno;
723   if (japanesecui)
724     return itemmenuexec(JRMajortick, &selectno);
725   else
726     return itemmenuexec(RMajortick, &selectno);
727 }
rsubtickmenu()728 int rsubtickmenu()
729 {
730   int selectno;
731   if (japanesecui)
732     return itemmenuexec(JRMinortick, &selectno);
733   else
734     return itemmenuexec(RMinortick, &selectno);
735 }
rlabelmenu()736 int rlabelmenu()
737 {
738   int selectno;
739   if (japanesecui)
740     return itemmenuexec(JRLabel, &selectno);
741   else
742     return itemmenuexec(RLabel, &selectno);
743 }
744 
plotmappingmenu()745 int plotmappingmenu()
746 {
747   int selectno;
748   if (japanesecui)
749     return itemmenuexec(JMapping, &selectno);
750   else
751     return itemmenuexec(Mapping, &selectno);
752 }
plotlinemenu()753 int plotlinemenu()
754 {
755   int selectno;
756   if (japanesecui)
757     return itemmenuexec(JPlotline, &selectno);
758   else
759     return itemmenuexec(Plotline, &selectno);
760 }
plotmarkermenu()761 int plotmarkermenu()
762 {
763   int selectno;
764   if (japanesecui)
765     return itemmenuexec(JPlotmarker, &selectno);
766   else
767     return itemmenuexec(Plotmarker, &selectno);
768 }
plotmemdatamenu()769 int plotmemdatamenu()
770 {
771   int selectno;
772   if (japanesecui)
773     return itemmenuexec(JMemdata, &selectno);
774   else
775     return itemmenuexec(Memdata, &selectno);
776 }
loaddatamenu()777 int loaddatamenu()
778 {
779   int selectno;
780   if (japanesecui)
781     return itemmenuexec(JLoaddata, &selectno);
782   else
783     return itemmenuexec(Loaddata, &selectno);
784 }
785 
partsstylemenu()786 int partsstylemenu()
787 {
788   int selectno;
789   if (japanesecui)
790     return itemmenuexec(JPartsstyle, &selectno);
791   else
792     return itemmenuexec(Partsstyle, &selectno);
793 }
794 
textstylemenu()795 int textstylemenu()
796 {
797   int selectno;
798   if (japanesecui)
799     return itemmenuexec(JTextstyle, &selectno);
800   else
801     return itemmenuexec(Textstyle, &selectno);
802 }
803 
functionmenu()804 int functionmenu()
805 {
806   int selectno;
807   if (japanesecui)
808     return itemmenuexec(JFunction, &selectno);
809   else
810     return itemmenuexec(Function, &selectno);
811 }
812 
linearfitmenu()813 int linearfitmenu()
814 {
815   int selectno;
816   if (japanesecui)
817     return itemmenuexec(JLinear, &selectno);
818   else
819     return itemmenuexec(Linear, &selectno);
820 }
821 
nonlinearfitmenu()822 int nonlinearfitmenu()
823 {
824   int selectno;
825   if (japanesecui)
826     return itemmenuexec(JNonlinear, &selectno);
827   else
828     return itemmenuexec(Nonlinear, &selectno);
829 }
830 
831 
832 
833 /********************************************************************/
834 /**************** popup menu ****************************************/
835 /********************************************************************/
836 
837 typedef struct popstack
838 {
839   CUIMENU *menu;
840   int item;
841   int maxitem;
842 }POPSTACK;
843 
844 POPSTACK pop[20];
845 int popstackno = -1;
846 
getmaxpopupitem(CUIMENU * menu,int maxitem)847 int getmaxpopupitem(CUIMENU *menu, int maxitem)
848 {
849   int length;
850   int maxlength = 0;
851   char *p;
852 
853   for (int i = 1; i <= maxitem; i++)
854     {
855       p = (char *)menu[i].item;
856       length = 0;
857       while (*p != 0)
858 	{
859 	  if (*p != '&')
860 	    length++;
861 	  p++;
862 	}
863       if (length > maxlength)
864 	maxlength = length;
865     }
866   return maxlength;
867 }
868 
869 
showpopcurrentmenu(CUIMENU * menu,int pos,int maxitem,int poplevel,int addoffset)870 void showpopcurrentmenu(CUIMENU *menu, int pos, int maxitem, int poplevel, int addoffset)
871 {
872   char mask[100];
873   int x, y;
874   int oset, count = 0;
875   char stemp[10];
876   char *p;
877   bool keyflag = false;
878   int maxlength;
879   char itemback[100], nextitemback[100], endback[100], sepback[100], startback[100];
880   int casoffsetx, casoffsety;
881 
882   if (menuwin == 0)
883     return;
884 
885   maxlength = getmaxpopupitem(menu, maxitem);
886   casoffsetx = 1;
887   for(int i = 1; i < poplevel; i++)
888     casoffsetx += getmaxpopupitem(pop[i].menu, pop[i].maxitem) + 5 - 2;
889 
890   // itemback
891   strcpy(itemback, "| ");
892   for (int i = 0; i < maxlength; i++)
893     strcat(itemback, " ");
894   strcat(itemback, "  |");
895 
896   // nextitemback
897   strcpy(nextitemback, "| ");
898   for (int i = 0; i < maxlength; i++)
899     strcat(nextitemback, " ");
900   strcat(nextitemback, " >|");
901 
902   // sepback
903   strcpy(sepback, "|-");
904   for (int i = 0; i < maxlength; i++)
905     strcat(sepback, "-");
906   strcat(sepback, "--|");
907 
908   // startback
909   strcpy(startback, "+-");
910   for (int i = 0; i < maxlength; i++)
911     strcat(startback, "-");
912   strcat(startback, "--+");
913 
914   // endback
915   strcpy(endback, "+-");
916   for (int i = 0; i < maxlength; i++)
917     strcat(endback, "-");
918   strcat(endback, "--+");
919 
920   strcpy(mask, "");
921   for (int i = 0; i < itemwidth; i++)
922     strcat(mask, " ");
923 
924   if (poplevel > 1)
925     {
926       if (pop[poplevel - 1].item + maxitem + topmargin + addoffset + 2 <=  menuwinlines)
927 	casoffsety = pop[poplevel - 1].item - 1;
928       else
929 	casoffsety = menuwinlines - maxitem - topmargin - addoffset - 3;
930     }
931   else
932     casoffsety = 0;
933 
934   //  wclear(menuwin);
935 
936   wmove(menuwin, 1 + topmargin + addoffset + casoffsety,
937 	mainmenuitempos(pos) + leftmargin + casoffsetx);
938   wprintw(menuwin, startback);
939 
940   for (int i = 1; i <= maxitem; i++)
941     {
942       keyflag = false;
943       y = i + 1;
944       x = mainmenuitempos(pos);
945 
946       wmove(menuwin, y + topmargin + addoffset + casoffsety,
947 	    x + leftmargin + casoffsetx);
948 
949       if (menu[i].id != M_SEP)
950 	{
951 	  if (menu[i].submenu)
952 	    wprintw(menuwin, nextitemback);
953 	  else
954 	    wprintw(menuwin, itemback);
955 	}
956       else
957 	wprintw(menuwin, sepback);
958 
959       oset = 2;
960       p = (char *)menu[i].item;
961       count = 0;
962 
963       if (menu[i].id != M_SEP)
964 	{
965 	  while (*p != 0)
966 	    {
967 	      if (*p != '&')
968 		{
969 		  stemp[0] = *p; stemp[1] = 0;
970 		  wmove(menuwin, y + topmargin + addoffset + casoffsety,
971 			x + leftmargin + oset + count++ + casoffsetx);
972 		  wprintw(menuwin, stemp);
973 
974 		  if (keyflag)
975 		    {
976 		      wattroff(menuwin, hotkeyattr);
977 		      keyflag = false;
978 		    }
979 		}
980 	      else
981 		{
982 		  wattron(menuwin, hotkeyattr);
983 		  keyflag = true;
984 		}
985 	      p++;
986 	    }
987 
988 	}
989     }
990 
991   y = maxitem + 2;
992   x = mainmenuitempos(pos);
993   wmove(menuwin, y + topmargin + addoffset + casoffsety,
994 	x + leftmargin + casoffsetx);
995   wprintw(menuwin, endback);
996 
997   //  wrefresh(menuwin);
998 }
999 
showpopcursor(CUIMENU * menu,int pos,int maxitem,int poplevel,int itemno,bool flag,int addoffset)1000 void showpopcursor(CUIMENU *menu, int pos, int maxitem, int poplevel, int itemno, bool flag, int addoffset)
1001 {
1002   char mask[100];
1003   int x, y;
1004   int oset, count = 0;
1005   char stemp[10];
1006   char *p;
1007   bool keyflag = false;
1008   int maxlength;
1009   int casoffsetx, casoffsety;
1010 
1011   if (menuwin == 0)
1012     return;
1013 
1014   maxlength = getmaxpopupitem(menu, maxitem);
1015   casoffsetx = 1;
1016   for(int i = 1; i < poplevel; i++)
1017     casoffsetx += getmaxpopupitem(pop[i].menu, pop[i].maxitem) + 5 - 2;
1018 
1019   y = itemno + 1;
1020   x = mainmenuitempos(pos);
1021 
1022   if (poplevel > 1)
1023     {
1024       if (pop[poplevel - 1].item + maxitem + topmargin + addoffset + 2 <=  menuwinlines)
1025 	casoffsety = pop[poplevel - 1].item - 1;
1026       else
1027 	casoffsety = menuwinlines - maxitem - topmargin - addoffset - 3;
1028     }
1029   else
1030     casoffsety = 0;
1031 
1032   strcpy(mask, "");
1033   for (int i = 0; i < maxlength + 1; i++)
1034     strcat(mask, " ");
1035 
1036   if (flag)
1037     wattron(menuwin, A_REVERSE);
1038 
1039   oset = 2;
1040 
1041   wmove(menuwin, y + topmargin + addoffset + casoffsety
1042 	, x + leftmargin + oset + casoffsetx);
1043   wprintw(menuwin, mask);
1044 
1045   p = (char *)menu[itemno].item;
1046   count = 0;
1047   while (*p != 0)
1048   {
1049     if (*p != '&')
1050       {
1051 	stemp[0] = *p; stemp[1] = 0;
1052 	wmove(menuwin, y + topmargin + addoffset + casoffsety
1053 	      , x + leftmargin + oset + count++ + casoffsetx);
1054 	wprintw(menuwin, stemp);
1055 
1056 	if (keyflag)
1057 	  {
1058 	    if (!flag)
1059 	      wattroff(menuwin, hotkeyattr);
1060 	    keyflag = false;
1061 	  }
1062       }
1063     else
1064       {
1065 	  if (!flag)
1066 	    wattron(menuwin, hotkeyattr);
1067 	  keyflag = true;
1068       }
1069     p++;
1070   }
1071 
1072   wmove(menuwin, 0, 0);
1073   wprintw(menuwin, " ");
1074   wmove(menuwin, 0, 0);
1075 
1076   if (flag)
1077       wattroff(menuwin, A_REVERSE);
1078 
1079   //  wrefresh(menuwin);
1080 
1081 }
1082 
1083 
popcursormove(CUIMENU * menu,int pos,int * itemno,int maxitem,int addoffset)1084 int popcursormove (CUIMENU *menu, int pos, int *itemno, int maxitem, int addoffset)
1085 {
1086   int key, y;
1087   char *p;
1088   script *scr;
1089   std::string str;
1090 
1091   if (menuwin == 0)
1092     return LOCAL_ESCAPE_KEY;
1093 
1094   cbreak();
1095   noecho();
1096   if (*itemno < 0 || *itemno > maxitem)
1097     *itemno = 0;
1098 
1099   while (1)
1100     {
1101 
1102       y = *itemno;
1103       showpopcursor(menu, pos, maxitem, popstackno, y, true, addoffset);
1104       key = topazgetch(menuwin);
1105       showpopcursor(menu, pos, maxitem, popstackno, y, false, addoffset);
1106 
1107       switch (key)
1108 	{
1109 	case KEY_LEFT:
1110 	case CTRL('b'):
1111 	  key = MENU_LEFT;
1112 	  break;
1113 	case KEY_RIGHT:
1114 	case CTRL('f'):
1115 	  key = MENU_RIGHT;
1116 	  break;
1117 	case KEY_DOWN:
1118 	case CTRL('n'):
1119 	  if (*itemno < maxitem)
1120 	    {
1121 	      if (menu[*itemno + 1].id != M_SEP)
1122 		*itemno = *itemno + 1;
1123 	      else
1124 		{
1125 		  if (*itemno + 1 < maxitem && menu[*itemno + 2].id != M_SEP)
1126 		    *itemno = *itemno + 2;
1127 		  else
1128 		    *itemno = 1;
1129 		}
1130 	    }
1131 	  else
1132 	    *itemno = 1;
1133 	  break;
1134 	case KEY_UP:
1135 	case CTRL('p'):
1136 	  if (*itemno > 1)
1137 	    {
1138 	      if (menu[*itemno - 1].id != M_SEP)
1139 		*itemno = *itemno - 1;
1140 	      else
1141 		{
1142 		  if (*itemno - 1 > 1 && menu[*itemno - 2].id != M_SEP)
1143 		    *itemno = *itemno - 2;
1144 		  else
1145 		    *itemno = maxitem;
1146 		}
1147 	    }
1148 	  else
1149 	    *itemno = maxitem;
1150 	  break;
1151 	case CTRL('a'):
1152 	  *itemno = 1;
1153 	  break;
1154 	case CTRL('e'):
1155 	  *itemno = maxitem;
1156 	  break;
1157 	  //paint
1158 	case CTRL('v'):
1159 	case ' ':
1160 	  scr = new script(gra);
1161 	  str = std::string("$graph->paintall(V0);");
1162 	  scr->execscript(&str, 0, 0);
1163 	  delete scr;
1164 	  break;
1165 	  // return to top menu
1166 	case CTRL('t'):
1167 	case '/':
1168 	  *itemno = -1;
1169 	  return LOCAL_LF_KEY;
1170 	  // scrolldown messagewindow
1171  	case '[':
1172 	  msgb->previous(1);
1173 	  break;
1174 	  // scrollup messagewindow
1175 	case ']':
1176 	  msgb->next(1);
1177 	  break;
1178 	  // return to previous menu
1179 	case CTRL('g'):
1180 	case '.':
1181 	  return LOCAL_ESCAPE_KEY;
1182 	}
1183 
1184       if ( 'a' < key < 'z')
1185 	{
1186 	  for (int i = 1; i <= maxitem; i++)
1187 	    {
1188 	      p = (char *)menu[i].item;
1189 	      while (*p != 0)
1190 		{
1191 		  if (*p == '&')
1192 		    {
1193 		      p++;
1194 		      if ((*p == key) || ((*p - 'A' + 'a') == key))
1195 			{
1196 			  *itemno = i;
1197 			  return (LOCAL_LF_KEY);
1198 			}
1199 		    }
1200 		  p++;
1201 		}
1202 	    }
1203 	}
1204 
1205       if (key == LOCAL_ESCAPE_KEY || key == LOCAL_LF_KEY
1206 	  || key == MENU_RIGHT || key == MENU_LEFT)
1207 	break;
1208     }
1209   showpopcursor(menu, pos, maxitem, popstackno, y, true, addoffset);
1210 
1211   return (key);
1212 }
1213 
1214 /********************************************************************/
1215 /**************** main  menu ****************************************/
1216 /********************************************************************/
1217 
mainmenuitempos(int i)1218 int mainmenuitempos(int i)
1219 {
1220   int pos = 0;
1221   if (i == 1)
1222     return 3;
1223   else
1224     {
1225       pos = 3;
1226       for(int j = 1; j < i; j++)
1227 	{
1228 	  if (japanesecui)
1229 	    pos += truetitlelength(JMain[j].item) + 6;
1230 	  else
1231 	    pos += truetitlelength(Main[j].item) + 6;
1232 	}
1233     }
1234   return pos;
1235 }
1236 
showmaincurrentmenu(CUIMENU * menu,int maxitem,int addoffset)1237 void showmaincurrentmenu(CUIMENU *menu, int maxitem, int addoffset)
1238 {
1239   char mask[20];
1240   int x, y;
1241   int oset, count = 0;
1242   char stemp[10];
1243   char *p;
1244   bool keyflag = false;
1245   int maxlength;
1246   char menuline1[] = "-----------------------------------------------------------------------------";
1247   char menuline2[] = "=============================================================================";
1248 
1249   if (menuwin == 0)
1250     return;
1251 
1252   maxlength = getmaxpopupitem(menu, maxitem);
1253 
1254   strcpy(mask, "   ");
1255   for (int i = 0; i < maxlength; i++)
1256     strcat(mask, " ");
1257   strcat(mask, "   ");
1258 
1259   wmove(menuwin, 0, leftmargin);
1260   wprintw(menuwin, menuline1);
1261   wmove(menuwin, 2, leftmargin);
1262   wprintw(menuwin, menuline2);
1263 
1264   for (int i = 1; i <= maxitem; i++)
1265     {
1266       keyflag = false;
1267       y = 0;
1268       x = mainmenuitempos(i);
1269 
1270       wmove(menuwin, y + topmargin + addoffset, x + leftmargin);
1271       wprintw(menuwin, mask);
1272 
1273       oset = 3;
1274       p = (char *)menu[i].item;
1275       count = 0;
1276 
1277       while (*p != 0)
1278 	{
1279 	  if (*p != '&')
1280 	    {
1281 	      stemp[0] = *p; stemp[1] = 0;
1282 	      wmove(menuwin, y + topmargin + addoffset, x + leftmargin + oset + count++);
1283 	      wprintw(menuwin, stemp);
1284 
1285 	      if (keyflag)
1286 		{
1287 		  wattroff(menuwin, hotkeyattr);
1288 		  keyflag = false;
1289 		}
1290 	    }
1291 	  else
1292 	    {
1293 	      wattron(menuwin, hotkeyattr);
1294 	      keyflag = true;
1295 	    }
1296 	  p++;
1297 	}
1298 
1299     }
1300 
1301   //  wrefresh(menuwin);
1302 }
1303 
1304 
showmaincursor(CUIMENU * menu,int itemno,bool flag,int addoffset)1305 void showmaincursor(CUIMENU *menu, int itemno, bool flag, int addoffset)
1306 {
1307   char mask[20];
1308   int x, y;
1309   int oset, count = 0;
1310   char stemp[10];
1311   char *p;
1312   bool keyflag = false;
1313 
1314   if (menuwin == 0)
1315     return;
1316 
1317   strcpy(mask, "   ");
1318   for (int i = 0; i < truetitlelength(menu[itemno].item); i++)
1319     strcat(mask, " ");
1320   strcat(mask, "   ");
1321 
1322   y = 0;
1323   x = mainmenuitempos(itemno);
1324 
1325   if (flag)
1326     wattron(menuwin, A_REVERSE);
1327 
1328   wmove(menuwin, y + topmargin + addoffset, x + leftmargin);
1329   wprintw(menuwin, mask);
1330 
1331   oset = 3;
1332   p = (char *)menu[itemno].item;
1333   count = 0;
1334   while (*p != 0)
1335   {
1336     if (*p != '&')
1337       {
1338 	stemp[0] = *p; stemp[1] = 0;
1339 	wmove(menuwin, y + topmargin + addoffset, x + leftmargin + oset + count++);
1340 	wprintw(menuwin, stemp);
1341 
1342 	if (keyflag)
1343 	  {
1344 	    if (!flag)
1345 	      wattroff(menuwin, hotkeyattr);
1346 	    keyflag = false;
1347 	  }
1348       }
1349     else
1350       {
1351 	  if (!flag)
1352 	    wattron(menuwin, hotkeyattr);
1353 	  keyflag = true;
1354       }
1355     p++;
1356   }
1357 
1358   wmove(menuwin, 0, 0);
1359   wprintw(menuwin, " ");
1360   wmove(menuwin, 0, 0);
1361 
1362   if (flag)
1363       wattroff(menuwin, A_REVERSE);
1364 
1365   //  wrefresh(menuwin);
1366 
1367 }
1368 
1369 
maincursormove(CUIMENU * menu,int * itemno,int maxitem,int addoffset)1370 int maincursormove (CUIMENU *menu, int *itemno, int maxitem, int addoffset)
1371 {
1372   int key, y;
1373   char *p;
1374   script *scr;
1375   std::string str;
1376 
1377   if (menuwin == 0)
1378     return LOCAL_ESCAPE_KEY;
1379 
1380   cbreak();
1381   noecho();
1382   if (*itemno < 0 || *itemno > maxitem)
1383     *itemno = 0;
1384 
1385   while (1)
1386     {
1387 
1388       y = *itemno;
1389       showmaincursor(menu, y, true, addoffset);
1390       key = topazgetch(menuwin);
1391       showmaincursor(menu, y, false, addoffset);
1392 
1393       switch (key)
1394 	{
1395 	case KEY_LEFT:
1396 	case CTRL('b'):
1397 	  *itemno = (*itemno > 1) ? *itemno - 1: maxitem;
1398 	  break;
1399 	case KEY_RIGHT:
1400 	case CTRL('f'):
1401 	  *itemno = (*itemno < maxitem) ? *itemno + 1: 1;
1402 	  break;
1403 	case KEY_DOWN:
1404 	case CTRL('n'):
1405 	  *itemno = (*itemno + maxrow <= maxitem) ? *itemno + maxrow: 1;
1406 	  break;
1407 	case KEY_UP:
1408 	case CTRL('p'):
1409 	  *itemno = (*itemno - maxrow >= 1) ? *itemno - maxrow: maxitem;
1410 	  break;
1411 	case CTRL('a'):
1412 	  *itemno = 1;
1413 	  break;
1414 	case CTRL('e'):
1415 	  *itemno = maxitem;
1416 	  break;
1417 	  //paint
1418 	case CTRL('v'):
1419 	case ' ':
1420 	  scr = new script(gra);
1421 	  str = std::string("$graph->paintall(V0);");
1422 	  scr->execscript(&str, 0, 0);
1423 	  delete scr;
1424 	  break;
1425 	  // scrolldown messagewindow
1426  	case '[':
1427 	  msgb->previous(1);
1428 	  break;
1429 	  // scrollup messagewindow
1430 	case ']':
1431 	  msgb->next(1);
1432 	  break;
1433 	  // return to previous menu
1434 	case CTRL('g'):
1435 	  return LOCAL_ESCAPE_KEY;
1436 	}
1437 
1438       if ( 'a' < key < 'z')
1439 	{
1440 	  for (int i = 1; i <= maxitem; i++)
1441 	    {
1442 	      p = (char *)menu[i].item;
1443 	      while (*p != 0)
1444 		{
1445 		  if (*p == '&')
1446 		    {
1447 		      p++;
1448 		      if ((*p == key) || ((*p - 'A' + 'a') == key))
1449 			{
1450 			  *itemno = i;
1451 			  return (LOCAL_LF_KEY);
1452 			}
1453 		    }
1454 		  p++;
1455 		}
1456 	    }
1457 	}
1458 
1459       if (key == LOCAL_ESCAPE_KEY || key == LOCAL_LF_KEY)
1460 	break;
1461     }
1462   showmaincursor(menu, y, true, addoffset);
1463 
1464   return (key);
1465 }
1466 
1467 
1468 /********************************************************************/
1469 /**************** common menu ***************************************/
1470 /********************************************************************/
1471 
showcurrentmenu(CUIMENU * menu,int maxitem,int addoffset)1472 void showcurrentmenu(CUIMENU *menu, int maxitem, int addoffset)
1473 {
1474   char mask[20];
1475   int x, y;
1476   int width = itemwidth + itemspace;
1477   int oset, count = 0;
1478   char stemp[10];
1479   char *p;
1480   bool keyflag = false;
1481 
1482   if (menuwin == 0)
1483     return;
1484 
1485   strcpy(mask, "");
1486   for (int i = 0; i < itemwidth; i++)
1487     strcat(mask, " ");
1488 
1489 
1490   clearmenuwin();
1491   //wclear(menuwin);
1492   for (int i = 1; i <= maxitem; i++)
1493     {
1494       keyflag = false;
1495       y = (i - 1) / maxrow;
1496       x = (i - 1) - maxrow * y;
1497 
1498       wmove(menuwin, y + topmargin + addoffset, x * width + leftmargin);
1499       wprintw(menuwin, mask);
1500 
1501       oset = (itemwidth - truetitlelength(menu[i].item)) / 2;
1502       p = (char *)menu[i].item;
1503       count = 0;
1504 
1505       while (*p != 0)
1506 	{
1507 	  if (*p != '&')
1508 	    {
1509 	      stemp[0] = *p; stemp[1] = 0;
1510 	      wmove(menuwin, y + topmargin + addoffset, x * width + leftmargin + oset + count++);
1511 	      wprintw(menuwin, stemp);
1512 
1513 	      if (keyflag)
1514 		{
1515 		  wattroff(menuwin, hotkeyattr);
1516 		  keyflag = false;
1517 		}
1518 	    }
1519 	  else
1520 	    {
1521 	      wattron(menuwin, hotkeyattr);
1522 	      keyflag = true;
1523 	    }
1524 	  p++;
1525 	}
1526 
1527     }
1528 
1529   wrefresh(menuwin);
1530 }
1531 
1532 
showcursor(CUIMENU * menu,int itemno,bool flag,int addoffset)1533 void showcursor(CUIMENU *menu, int itemno, bool flag, int addoffset)
1534 {
1535   char mask[20];
1536   int x, y;
1537   int width = itemwidth + itemspace;
1538   int oset, count = 0;
1539   char stemp[10];
1540   char *p;
1541   bool keyflag = false;
1542 
1543   if (menuwin == 0)
1544     return;
1545 
1546   y = (itemno - 1) / maxrow;
1547   x = (itemno - 1) - maxrow * y;
1548 
1549   strcpy(mask, "");
1550   for (int i = 0; i < itemwidth; i++)
1551     strcat(mask, " ");
1552 
1553 
1554   if (flag)
1555     wattron(menuwin, A_REVERSE);
1556 
1557 
1558   wmove(menuwin, y + topmargin + addoffset, x * width + leftmargin);
1559   wprintw(menuwin, mask);
1560 
1561   oset = (itemwidth - truetitlelength(menu[itemno].item)) / 2;
1562   p = (char *)menu[itemno].item;
1563   count = 0;
1564   while (*p != 0)
1565   {
1566     if (*p != '&')
1567       {
1568 	stemp[0] = *p; stemp[1] = 0;
1569 	wmove(menuwin, y + topmargin + addoffset, x * width + leftmargin + oset + count++);
1570 	wprintw(menuwin, stemp);
1571 
1572 	if (keyflag)
1573 	  {
1574 	    if (!flag)
1575 	      wattroff(menuwin, hotkeyattr);
1576 	    keyflag = false;
1577 	  }
1578       }
1579     else
1580       {
1581 	  if (!flag)
1582 	    wattron(menuwin, hotkeyattr);
1583 	  keyflag = true;
1584       }
1585     p++;
1586   }
1587 
1588   wmove(menuwin, 0, 0);
1589   wprintw(menuwin, " ");
1590   wmove(menuwin, 0, 0);
1591 
1592   if (flag)
1593       wattroff(menuwin, A_REVERSE);
1594 
1595   wrefresh(menuwin);
1596 
1597 }
1598 
1599 
cursormove(CUIMENU * menu,int * itemno,int maxitem,int addoffset)1600 int cursormove (CUIMENU *menu, int *itemno, int maxitem, int addoffset)
1601 {
1602   int key, y;
1603   char *p;
1604   script *scr;
1605   std::string str;
1606 
1607   if (menuwin == 0)
1608     return LOCAL_ESCAPE_KEY;
1609 
1610   cbreak();
1611   noecho();
1612   if (*itemno < 0 || *itemno > maxitem)
1613     *itemno = 0;
1614 
1615   while (1)
1616     {
1617 
1618       y = *itemno;
1619       showcursor(menu, y, true, addoffset);
1620       key = topazgetch(menuwin);
1621       showcursor(menu, y, false, addoffset);
1622 
1623       switch (key)
1624 	{
1625 	case KEY_LEFT:
1626 	case CTRL('b'):
1627 	  *itemno = (*itemno > 1) ? *itemno - 1: maxitem;
1628 	  break;
1629 	case KEY_RIGHT:
1630 	case CTRL('f'):
1631 	  *itemno = (*itemno < maxitem) ? *itemno + 1: 1;
1632 	  break;
1633 	case KEY_DOWN:
1634 	case CTRL('n'):
1635 	  *itemno = (*itemno + maxrow <= maxitem) ? *itemno + maxrow: 1;
1636 	  break;
1637 	case KEY_UP:
1638 	case CTRL('p'):
1639 	  *itemno = (*itemno - maxrow >= 1) ? *itemno - maxrow: maxitem;
1640 	  break;
1641 	case CTRL('a'):
1642 	  *itemno = 1;
1643 	  break;
1644 	case CTRL('e'):
1645 	  *itemno = maxitem;
1646 	  break;
1647 	  //paint
1648 	case CTRL('v'):
1649 	case ' ':
1650 	  scr = new script(gra);
1651 	  str = std::string("$graph->paintall(V0);");
1652 	  scr->execscript(&str, 0, 0);
1653 	  delete scr;
1654 	  break;
1655 	  // return to top menu
1656 	case CTRL('t'):
1657 	  *itemno = -1;
1658 	  return LOCAL_LF_KEY;
1659 	  // scrolldown messagewindow
1660  	case '[':
1661 	  msgb->previous(1);
1662 	  break;
1663 	  // scrollup messagewindow
1664 	case ']':
1665 	  msgb->next(1);
1666 	  break;
1667 	  // return to previous menu
1668 	case CTRL('g'):
1669 	  return LOCAL_ESCAPE_KEY;
1670 	}
1671 
1672       if ( 'a' < key < 'z')
1673 	{
1674 	  for (int i = 1; i <= maxitem; i++)
1675 	    {
1676 	      p = (char *)menu[i].item;
1677 	      while (*p != 0)
1678 		{
1679 		  if (*p == '&')
1680 		    {
1681 		      p++;
1682 		      if ((*p == key) || ((*p - 'A' + 'a') == key))
1683 			{
1684 			  *itemno = i;
1685 			  return (LOCAL_LF_KEY);
1686 			}
1687 		    }
1688 		  p++;
1689 		}
1690 	    }
1691 	}
1692 
1693       if (key == LOCAL_ESCAPE_KEY || key == LOCAL_LF_KEY)
1694 	break;
1695     }
1696   showcursor(menu, y, true, addoffset);
1697 
1698   return (key);
1699 }
1700 
getwininfo()1701 void getwininfo()
1702 {
1703   mainwinlines = LINES;
1704   mainwincols  = COLS;
1705   tabnumber    = TABSIZE;
1706 }
1707 
menuexec(CUIMENU * menu,int * selectno,int item)1708 int menuexec(CUIMENU *menu, int *selectno, int item)
1709 {
1710   CUIMENU *m;
1711   int itemlength = 0;
1712   int itemno;
1713   int flag1 , flag2;
1714   int selectedkey = 1;
1715 
1716   if (menuwin == 0)
1717     return false;
1718 
1719   popstackno++;
1720   pop[popstackno].menu = menu;
1721 
1722   m = menu;
1723   for (; m->item; m++)
1724     {
1725       if (itemlength < (int)strlen(m->item))
1726 	itemlength = strlen(m->item);
1727     }
1728   itemno = m - menu - 1;
1729   if (itemno < 1)
1730     return false;
1731 
1732   pop[popstackno].maxitem = itemno;
1733   pop[popstackno].item = selectedkey;
1734 
1735   do
1736     {
1737       if (menu[*selectno].submenu)
1738 	{
1739 	  updatepop();
1740 	  flag1 = popcursormove (menu, item, &selectedkey, itemno, 0);
1741 	}
1742       else
1743 	{
1744 	  updatepop();
1745 	  flag1 = popcursormove (menu, item, &selectedkey, itemno, 0);
1746 	}
1747 
1748       pop[popstackno].item = selectedkey;
1749 
1750       //return to top menu
1751       if (selectedkey == -1)
1752 	{
1753 	  popstackno = 0;
1754 	  pop[popstackno].item = 1;
1755 	  *selectno = M_MAIN;
1756 	  return LOCAL_LF_KEY;
1757 	}
1758       else if ((flag1 == LOCAL_LF_KEY)
1759 	       && menu[selectedkey].submenu)
1760 	{
1761 	  flag2 = menuexec(menu[selectedkey].submenu, selectno, item);
1762 	  if ((*selectno == M_QUIT || *selectno == M_MAIN)
1763 	      && flag2 == LOCAL_LF_KEY)
1764 	    {
1765 	      popstackno = 0;
1766 	      pop[popstackno].item = 1;
1767 	      return LOCAL_LF_KEY;
1768 	    }
1769 	}
1770       else if ((flag1 == LOCAL_LF_KEY)
1771 	       && !menu[selectedkey].submenu)
1772 	{
1773 	  execitem(menu, &selectedkey);
1774 
1775 	  if (menu[selectedkey].id == M_QUIT)
1776 	  {
1777 	    popstackno = 0;
1778 	    pop[popstackno].item = 1;
1779 	    *selectno = M_QUIT;
1780 	    return LOCAL_LF_KEY;
1781 	  }
1782 	}
1783 
1784       *selectno = menu[selectedkey].id;
1785 
1786     }while(!(flag1 == LOCAL_ESCAPE_KEY ||
1787 	     ((flag1 == MENU_LEFT || flag1 == MENU_RIGHT)
1788 	      && popstackno == 1)));
1789 
1790   popstackno--;
1791   return flag1;
1792 
1793 }
1794 
1795 
1796 
mainmenuexec(CUIMENU * menu,int * selectno)1797 int mainmenuexec(CUIMENU *menu, int *selectno)
1798 {
1799   CUIMENU *m;
1800   int itemlength = 0;
1801   int itemno;
1802   int flag1 , flag2;
1803   int selectedkey = 1;
1804   std::string str, str1;
1805   bool bufferflashflag = true;
1806 
1807   if (menuwin == 0)
1808     return false;
1809 
1810   popstackno++;
1811   m = menu;
1812   for (; m->item; m++)
1813     {
1814       if (itemlength < (int)strlen(m->item))
1815 	itemlength = strlen(m->item);
1816     }
1817   itemno = m - menu - 1;
1818   if (itemno < 1)
1819     return false;
1820 
1821   pop[popstackno].menu = menu;
1822   pop[popstackno].maxitem = itemno;
1823   pop[popstackno].item = selectedkey;
1824 
1825   updatemenu();
1826   do
1827     {
1828       updatepop();
1829       flag1 = maincursormove (menu, &selectedkey, itemno, 0);
1830       pop[popstackno].item = selectedkey;
1831 
1832       //message area flush. only one time
1833       if (bufferflashflag)
1834 	{
1835 	  msgb->flush();
1836 	  bufferflashflag = false;
1837 	}
1838 
1839       //return to top menu
1840       if (selectedkey == -1)
1841 	{
1842 	    *selectno = M_MAIN;
1843 	    selectedkey = 1;
1844 	}
1845       else if (flag1 == LOCAL_LF_KEY  && menu[selectedkey].submenu)
1846 	{
1847 	  do
1848 	    {
1849 	      flag2 = menuexec(menu[selectedkey].submenu, selectno, selectedkey);
1850 	      if (*selectno == M_QUIT && flag2 == LOCAL_LF_KEY)
1851 		{
1852 		  if (gra->updated)
1853 		    {
1854 		      str = std::string("0");
1855 		      str1 = std::string("The graph is updated. Exit Topaz?");
1856 		      exec_yesno_select(&str, &str1);
1857 		      if (str == std::string("1"))
1858 			return LOCAL_LF_KEY;
1859 		    }
1860 		  else
1861 		    {
1862 		      str = std::string("0");
1863 		      str1 = std::string("Exit Topaz?");
1864 		      exec_yesno_select(&str, &str1);
1865 		      if (str == std::string("1"))
1866 			return LOCAL_LF_KEY;
1867 		    }
1868 		}
1869 	      else if (*selectno == M_MAIN && flag2 == LOCAL_LF_KEY)
1870 		{
1871 		  *selectno = M_MAIN;
1872 		  selectedkey = 1;
1873 		}
1874 	      else
1875 		*selectno = menu[selectedkey].id;
1876 
1877 	      switch (flag2)
1878 		{
1879 		case MENU_LEFT:
1880 		  if (selectedkey > 1)
1881 		    selectedkey--;
1882 		  break;
1883 		case MENU_RIGHT:
1884 		  if (selectedkey < itemno)
1885 		    selectedkey++;
1886 		  break;
1887 		}
1888 	      pop[popstackno].item = selectedkey;
1889 	      //	      showmaincursor(menu, *selectno, true, 0);
1890 	    }
1891 	  while(flag2 == MENU_LEFT || flag2 == MENU_RIGHT);
1892 
1893 	}
1894       else if (flag1 == LOCAL_LF_KEY && !menu[selectedkey].submenu)
1895 	{
1896 	  execitem(menu, &selectedkey);
1897 
1898 	  if (menu[selectedkey].id == M_QUIT)
1899 	  {
1900 	    *selectno = M_QUIT;
1901 	    return LOCAL_LF_KEY;
1902 	  }
1903 	  *selectno = menu[selectedkey].id;
1904 	}
1905     }while (1);
1906   return flag1;
1907 
1908 }
1909 
updatemenu()1910 void updatemenu()
1911 {
1912   wclear(menuwin);
1913   showmaincurrentmenu(pop[0].menu, pop[0].maxitem, 0);
1914   showmaincursor(pop[0].menu, pop[0].item, true, 0);
1915   for (int i = 1; i <= popstackno; i++)
1916     {
1917       showpopcurrentmenu(pop[i].menu, pop[0].item, pop[i].maxitem, i, 0);
1918       showpopcursor(pop[i].menu, pop[0].item, pop[i].maxitem, i, pop[i].item, true, 0);
1919     }
1920   wmove(menuwin, 0, 0);
1921   wprintw(menuwin, " ");
1922   wmove(menuwin, 0, 0);
1923   wrefresh(menuwin);
1924 }
1925 
updatepop()1926 void updatepop()
1927 {
1928   for (int i = 0; i < mainwinlines; i++)
1929     {
1930       for (int j = 0; j < mainwincols; j++)
1931 	{
1932 	  wmove(menuwin, i, j); wprintw(menuwin, " ");
1933 	}
1934     }
1935   showmaincurrentmenu(pop[0].menu, pop[0].maxitem, 0);
1936   showmaincursor(pop[0].menu, pop[0].item, true, 0);
1937   for (int i = 1; i <= popstackno; i++)
1938     {
1939       showpopcurrentmenu(pop[i].menu, pop[0].item, pop[i].maxitem, i, 0);
1940       showpopcursor(pop[i].menu, pop[0].item, pop[i].maxitem, i, pop[i].item, true, 0);
1941     }
1942   wmove(menuwin, 0, 0);
1943   wprintw(menuwin, " ");
1944   wmove(menuwin, 0, 0);
1945   wrefresh(menuwin);
1946 }
1947 
iscommentline(const char * s)1948 bool iscommentline(const char *s)
1949 {
1950   char *p;
1951 
1952   p = (char *)s;
1953   while (*p != 0)
1954     {
1955       if ((*p != ' ') && (*p != '\t'))
1956         {
1957 	  if (*p == '#')
1958 	    return true;
1959 	  else
1960 	    return false;
1961         }
1962       else
1963 	p++;
1964     }
1965   return false;
1966 }
1967 
separatercitem(char * line)1968 bool separatercitem(char *line)
1969 {
1970   char *p = line;
1971   char tmpline[1024], item[1000], value[1000], stemp[3];
1972   int count = 0;
1973   bool flag = false;
1974   int fcolor, bcolor, itemp;
1975 
1976   //remove space, tab, '\r' and '\n'
1977   strcpy(tmpline, "");
1978   while(*p != 0)
1979     {
1980       if (*p != ' ' && *p != '\t' && *p != '\r' && *p != '\n')
1981 	{
1982 	  stemp[0] = *p;
1983 	  stemp[1] = 0;
1984 	  strcat(tmpline, stemp);
1985 	}
1986       p++;
1987     }
1988 
1989   // commentline
1990   if (iscommentline(tmpline))
1991     return true;
1992 
1993   // null line
1994   if (strcmp(tmpline, "") == 0)
1995     return true;
1996 
1997   // count number of '='
1998   count = 0;
1999   p = tmpline;
2000   while(*p != 0)
2001     {
2002       if (*p == '=')
2003 	count++;
2004       p++;
2005     }
2006 
2007   if (count != 1)
2008     return false;
2009 
2010   //separate tmpline into item and value
2011   strcpy(item, ""); strcpy(value, "");
2012   p = tmpline;
2013   while(*p != 0)
2014     {
2015       if (*p == '=')
2016 	  flag = true;
2017       else
2018 	{
2019 	  stemp[0] = *p;
2020 	  stemp[1] = 0;
2021 	  if (flag)
2022 	    strcat(value, stemp);
2023 	  else
2024 	    strcat(item, stemp);
2025 	}
2026       p++;
2027     }
2028 
2029   if (strcmp(item, "menu_hotkey_color") == 0)
2030     {
2031       if (sscanf(value, "%d/%d",
2032 		 &fcolor, &bcolor) != 2)
2033 	return false;
2034       init_pair(MENU_HOTKEY_COLORPAIR, fcolor, bcolor);
2035     }
2036   else if (strcmp(item, "menu_color_enable") == 0)
2037     {
2038       if (sscanf(value, "%d",
2039 		 &itemp) != 1)
2040 	return false;
2041 
2042       switch(itemp)
2043 	{
2044 	case 1:
2045 	  if (has_color)
2046 	    has_color = true;
2047 	  break;
2048 	default:
2049 	    has_color = false;
2050 	  break;
2051 	}
2052     }
2053   else if (strcmp(item, "menuarea_height") == 0)
2054     {
2055       if (sscanf(value, "%d",
2056 		 &itemp) != 1)
2057 	return false;
2058 
2059       if (17 <= itemp && itemp <= 20)
2060 	menuwinlines = itemp;
2061       else
2062 	menuwinlines    = 17;
2063     }
2064   else if (strcmp(item, "messagebuffer_size") == 0)
2065     {
2066       if (sscanf(value, "%d",
2067 		 &itemp) != 1)
2068 	return false;
2069 
2070       if (100 <= itemp && itemp <= 10000)
2071 	msgbuffsize = itemp;
2072       else
2073 	msgbuffsize = 100;
2074     }
2075   else if (strcmp(item, "kanjimenu") == 0)
2076     {
2077       if (sscanf(value, "%d",
2078 		 &itemp) != 1)
2079 	return false;
2080 
2081       if (itemp == 1)
2082 	japanesecui = true;
2083       else
2084 	japanesecui = false;
2085     }
2086   return true;
2087 }
2088 
loadrc()2089 bool loadrc()
2090 {
2091   char buffer[1024];
2092   FILE *f;
2093   std::string out, str;
2094 
2095   str = std::string("cui.rc");
2096   if (!getmacroname(&str, &out))
2097     return false;
2098 
2099   if ((f = fopen((char *)out.c_str(), "r")) == NULL)
2100     return false;
2101 
2102   while(fgets(buffer, sizeof(buffer), f) != NULL)
2103     {
2104       if (!separatercitem(buffer))
2105 	{
2106 	  fclose(f);
2107 	  return false;
2108 	}
2109     }
2110 
2111   fclose (f);
2112   return true;
2113 }
2114 
cuimenu()2115 void cuimenu()
2116 {
2117   int selectno = 0;
2118   char stemp1[200], stemp2[200];
2119   FILE *ttyin = NULL, *ttyout = NULL;
2120 
2121   ttyin = fopen("/dev/tty", "r");
2122   ttyout = fopen("/dev/tty", "w");
2123 
2124 #if !defined(TOPAZ_PDCURSES)
2125   set_term(newterm(NULL, ttyout, ttyin));
2126 #else
2127   initscr();
2128 #endif
2129 
2130   if (has_colors())
2131     has_color = true;
2132   else
2133     has_color = false;
2134 
2135 
2136   if (has_color)
2137     {
2138       if (start_color() != OK)
2139 	{
2140 	  endwin();
2141 	  fclose(ttyin); fclose(ttyout);
2142 	  fprintf(stderr, "Error!!: could not initialize colors!!\n");
2143 	  return;
2144 	}
2145     }
2146 
2147   if (!loadrc())
2148     {
2149       endwin();
2150       fclose(ttyin); fclose(ttyout);
2151       fprintf(stderr, "Error!!: could not load resource file!!\n");
2152       return;
2153     }
2154 
2155   if (has_color)
2156     hotkeyattr = COLOR_PAIR(MENU_HOTKEY_COLORPAIR);
2157   else
2158     hotkeyattr = A_UNDERLINE;
2159 
2160   getwininfo();
2161   if (mainwincols < WINDOWCOL)
2162     {
2163       endwin();
2164       fclose(ttyin); fclose(ttyout);
2165       fprintf(stderr, "Error!!: Terminal width must be 78 characters or more.\naborted!!\n");
2166       return;
2167     }
2168   else
2169     mainwincols = WINDOWCOL;
2170 
2171   if (mainwinlines < 24)
2172     {
2173       endwin();
2174       fclose(ttyin); fclose(ttyout);
2175       fprintf(stderr, "Error!!: Terminal height must be 25 lines or more.\naborted!!\n");
2176       return;
2177     }
2178 
2179   maxrow = mainwincols / (itemwidth + itemspace);
2180   crmode();
2181 
2182 #if !defined(TOPAZ_PDCURSES)
2183   ESCDELAY = 0;
2184 #endif
2185 
2186   //for displaying sjis-kanji
2187   use_legacy_coding(2);
2188 
2189   menuwin = newwin(menuwinlines, mainwincols, 0, 0);
2190   sepwin = newwin(sepwinlines, mainwincols, menuwinlines, 0);
2191   msgwin = newwin(mainwinlines - menuwinlines - sepwinlines, mainwincols
2192 		    , menuwinlines + sepwinlines, 0);
2193   msgb = new msgbuff(msgwin, mainwinlines - menuwinlines - sepwinlines, msgbuffsize);
2194 
2195   scrollok(msgwin, true);
2196   cbreak();
2197   noecho();
2198   showsepwin();
2199 
2200   keypad(menuwin, TRUE);
2201   keypad(stdscr, TRUE);
2202 
2203   gra->versionstring(stemp1);
2204   sprintf(stemp2, "Welcome to the Topaz system version %s!!\n", stemp1);
2205   strcat(stemp2, "Topaz comes with ABSOLUTELY NO WARRANTY.\n");
2206   if (japanesecui)
2207     strcat(stemp2, "Kanji cuimenu is ready.\n");
2208   msgb->print(stemp2);
2209 
2210   if (japanesecui)
2211     mainmenuexec(JMain, &selectno);
2212   else
2213     mainmenuexec(Main, &selectno);
2214 
2215   delete msgb;
2216   msgb = 0;
2217 
2218   delwin(msgwin);
2219   msgwin = 0;
2220 
2221   delwin(sepwin);
2222   sepwin = 0;
2223 
2224   delwin(menuwin);
2225   menuwin = 0;
2226 
2227   endwin();
2228   fclose(ttyin); fclose(ttyout);
2229 
2230   popstackno = -1;
2231 
2232 }
2233 
2234 int intrflag = false;
2235 
setintrflag(int sig)2236 void setintrflag(int sig)
2237 {
2238   signal(sig, SIG_IGN);
2239   message("User interruption\n");
2240   intrflag = true;
2241   (void) signal(sig, setintrflag);
2242 }
2243 
floatingerror(int sig)2244 void floatingerror(int sig)
2245 {
2246   signal(sig, SIG_IGN);
2247   (void) signal(sig, floatingerror);
2248 }
2249 
pipeerror(int sig)2250 void pipeerror(int sig)
2251 {
2252   signal(sig, SIG_IGN);
2253   message("Error: cannot create pipe\n");
2254   (void) signal(sig, pipeerror);
2255 }
2256 
isabort()2257 bool isabort()
2258 {
2259   return intrflag;
2260 }
2261 
resetabort()2262 void resetabort()
2263 {
2264   intrflag = false;
2265 }
2266 
2267 
main(int argc,char * argv[],char * env[])2268 int main (int argc, char *argv[], char *env[])
2269 {
2270   int c;
2271   extern int optind;
2272   std::string out, initscript, argscript = std::string(""), str1;
2273   buffarray tempbuffarray;
2274   DIR *dp;
2275 
2276 
2277   //check environ
2278   if (getenv("TOPAZINIDIR") == NULL)
2279     {
2280       fprintf(stderr, "Error: 'TOPAZINIDIR' is not defined.");
2281       exit(1);
2282     }
2283   if (getenv("TOPAZDIR") == NULL)
2284     {
2285       fprintf(stderr, "Error: 'TOPAZDIR' is not defined.");
2286       exit(1);
2287     }
2288 
2289   // initialization
2290   strcpy(confpath, getenv("TOPAZINIDIR"));
2291   strcpy(tmppath, confpath);
2292   strcat(tmppath, "/tmp");
2293   sprintf(pid, "%u_", (unsigned int)getpid());
2294 
2295   //check directories
2296   if ((dp = opendir(confpath)) == NULL)
2297     {
2298       mkdir(confpath, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH);
2299     }
2300   else
2301     closedir (dp);
2302 
2303   if ((dp = opendir(tmppath)) == NULL)
2304     {
2305       mkdir(tmppath, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH);
2306     }
2307   else
2308     closedir (dp);
2309 
2310 
2311 
2312   // options
2313   while ((c = getopt(argc, argv, "vh:b:")) != -1)
2314     {
2315       switch(c)
2316 	{
2317 	  // show version and exit;
2318 	case 'v':
2319 	  fprintf(stderr, "\n");
2320 	  fprintf(stderr, "    Topaz Version 3.41 /  Copyright: Hisao Kawaura\n");
2321 	  fprintf(stderr, "\n");
2322 	  fprintf(stderr, "    Options:\n");
2323 	  fprintf(stderr, "       -v:    show current version and options\n");
2324 	  fprintf(stderr, "\n");
2325 	  exit(0);
2326 	  break;
2327 	}
2328     }
2329 
2330   // script exists
2331   if (optind < argc)
2332     {
2333       argscript = std::string(argv[optind++]);
2334       tempbuffarray.setbuff(0);
2335       for (; optind < argc; optind++)
2336 	tempbuffarray.add(argv[optind]);
2337     }
2338 
2339   // environment variables
2340   envp = env;
2341 
2342   // interrupt
2343   (void) signal(SIGINT, setintrflag);
2344   // floating point error
2345   (void) signal(SIGFPE, floatingerror);
2346   // write on a pipe with no reader
2347   (void) signal(SIGPIPE, pipeerror);
2348 
2349   // creaete filehandle buffer
2350   fhvuff  = new FileHandleArray;
2351 
2352   // create graph
2353   gra = new graph;
2354 
2355   script *scr = new script(gra);
2356 
2357   // initialize objects
2358   if (argscript == std::string(""))
2359     {
2360       initscript = std::string("inittopaz");
2361       switch (scr->execscriptfile(&initscript, &out, 0))
2362 	{
2363 	case false:
2364 	case NOTEXISTSCRIPT:
2365 	  str1 = std::string("Error!!: cannot execute '");
2366 	  str1 += initscript;
2367 	  str1 += std::string("'\n");
2368 	  message((char *)str1.c_str());
2369 	  break;
2370 	}
2371     }
2372   // execute loaded script
2373   else
2374     {
2375       switch (scr->execscriptfile(&argscript, &out, &tempbuffarray))
2376 	{
2377 	case NOTEXISTSCRIPT:
2378 	case false:
2379 	  str1 = std::string("Error!!: cannot execute '");
2380 	  str1 += argscript;
2381 	  str1 += std::string("'\n");
2382 	  message((char *)str1.c_str());
2383 	  break;
2384 	}
2385     }
2386 
2387   delete scr;
2388 
2389   // flush tmp files in '$HOME/.topaz/tmp'
2390   gra->flushtmpfiles();
2391   delete gra;
2392   delete fhvuff;
2393 
2394   exit (0);
2395 }
2396 
2397 
2398 
2399 
2400 
2401