1 /* Copyright 1992 NEC Corporation, Tokyo, Japan.
2  *
3  * Permission to use, copy, modify, distribute and sell this software
4  * and its documentation for any purpose is hereby granted without
5  * fee, provided that the above copyright notice appear in all copies
6  * and that both that copyright notice and this permission notice
7  * appear in supporting documentation, and that the name of NEC
8  * Corporation not be used in advertising or publicity pertaining to
9  * distribution of the software without specific, written prior
10  * permission.  NEC Corporation makes no representations about the
11  * suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
16  * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19  * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #if !defined(lint) && !defined(__CODECENTER__)
24 static char rcs_id[] = "@(#) 102.1 $Id: uiutil.c,v 1.3 2003/09/17 08:50:53 aida_s Exp $";
25 #endif
26 
27 #include "canna.h"
28 #include "patchlevel.h"
29 
30 /*********************************************************************
31  *                      wchar_t replace begin                        *
32  *********************************************************************/
33 #ifdef wchar_t
34 # error "wchar_t is already defined"
35 #endif
36 #define wchar_t cannawc
37 
38 #ifndef NO_EXTEND_MENU
39 
40 typedef struct {
41   char *title;
42   int func;
43   int funcd;
44 } e_menuitem;
45 
46 #define MENU_NEXT_MENU 0 /* ����ȥ�ϥ�˥塼�Ǥ��� */
47 #define MENU_FUNC_NUM  1 /* ����ȥ�ϡؤ���ʡ٤ε�ǽ�ֹ�Ǥ��� */
48 
49 #ifdef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */
50 #define MT_HELP   0
51 #define MT_SONOTA 1
52 #define MT_KIGO   2
53 #define MT_TANGO  3
54 #define MT_HENKAN 4
55 #define MT_FILE   5
56 #else
57 #define MT_HELP   0
58 #define MT_SONOTA 1
59 #define MT_KIGO   2
60 #define MT_SERV   3
61 #define MT_TANGO  4
62 #define MT_HENKAN 5
63 #define MT_FILE   6
64 #endif
65 
66 static e_menuitem e_helptable[] = {
67   /* �������� */
68   {"\265\255\271\346\306\376\316\317",   MENU_NEXT_MENU, MT_KIGO},
69   /* ���������� */
70   {"\245\263\241\274\245\311\306\376\316\317", MENU_FUNC_NUM,  CANNA_FN_HexMode},
71   /* �������� */
72   {"\311\364\274\363\306\376\316\317",   MENU_FUNC_NUM,  CANNA_FN_BushuMode},
73   /* ñ����Ͽ */
74   {"\303\261\270\354\305\320\317\277",   MENU_NEXT_MENU, MT_TANGO},
75   /* �Ķ����� */
76   {"\264\304\266\255\300\337\304\352",   MENU_NEXT_MENU, MT_SONOTA},
77 };
78 
79 static e_menuitem e_uusonotatable[] = {
80 #ifndef CODED_MESSAGE
81   {"�Ѵ�����",       MENU_NEXT_MENU, MT_HENKAN},
82 #ifndef STANDALONE /* This is not used in Windows environment */
83   {"���������",     MENU_NEXT_MENU, MT_SERV},
84 #endif
85   {"����ޥ���ȡ�����ޥ����", MENU_FUNC_NUM, CANNA_FN_DicMountMode},
86   {"�ؽ�����ɽ��",   MENU_FUNC_NUM,  CANNA_FN_ShowGakushu},
87   {"�С������ɽ��", MENU_FUNC_NUM,  CANNA_FN_ShowVersion},
88   {"�ե�����ɽ��",   MENU_NEXT_MENU, MT_FILE},
89 #else
90   /* �Ѵ����� */
91   {"\312\321\264\271\312\375\274\260",       MENU_NEXT_MENU, MT_HENKAN},
92 #ifndef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */
93   /* ��������� */
94   {"\245\265\241\274\245\320\301\340\272\356",     MENU_NEXT_MENU, MT_SERV},
95 #endif
96   /* ����ޥ���ȡ�����ޥ���� */
97   {"\274\255\275\361\245\336\245\246\245\363\245\310\241\277\245\242\245\363\245\336\245\246\245\363\245\310", MENU_FUNC_NUM, CANNA_FN_DicMountMode},
98   /* �ؽ�����ɽ�� */
99   {"\263\330\275\254\276\365\302\326\311\275\274\250",   MENU_FUNC_NUM,  CANNA_FN_ShowGakushu},
100   /* �С������ɽ�� */
101   {"\245\320\241\274\245\270\245\347\245\363\311\275\274\250", MENU_FUNC_NUM,  CANNA_FN_ShowVersion},
102   /* �ե�����ɽ�� */
103   {"\245\325\245\241\245\244\245\353\311\275\274\250",   MENU_NEXT_MENU, MT_FILE},
104 #endif
105 };
106 
107 static e_menuitem e_uukigotable[] = {
108   /* �������� */
109   {"\265\255\271\346\301\264\310\314",     MENU_FUNC_NUM, CANNA_FN_KigouMode},
110   /* ����ʸ�� */
111   {"\245\355\245\267\245\242\312\270\273\372",   MENU_FUNC_NUM, CANNA_FN_RussianMode},
112   /* ���ꥷ��ʸ�� */
113   {"\245\256\245\352\245\267\245\343\312\270\273\372", MENU_FUNC_NUM, CANNA_FN_GreekMode},
114   /* ���� */
115   {"\267\323\300\376",         MENU_FUNC_NUM, CANNA_FN_LineMode},
116 };
117 
118 #ifndef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */
119 static e_menuitem e_uuservertable[] = {
120   /* �����Ф��ڤ�Υ�� */
121   {"\245\265\241\274\245\320\244\316\300\332\244\352\316\245\244\267", MENU_FUNC_NUM, CANNA_FN_DisconnectServer},
122   /* �����Ф��ڤ��ؤ� */
123   {"\245\265\241\274\245\320\244\316\300\332\244\352\302\330\244\250", MENU_FUNC_NUM, CANNA_FN_ChangeServerMode},
124   /* �����Ф�ɽ�� */
125   {"\245\265\241\274\245\320\244\316\311\275\274\250",     MENU_FUNC_NUM, CANNA_FN_ShowServer},
126 };
127 #endif /* STANDALONE */
128 
129 static e_menuitem e_uutangotable[] = {
130   /* ñ����Ͽ */
131   {"\303\261\270\354\305\320\317\277", MENU_FUNC_NUM, CANNA_FN_DefineDicMode},
132   /* ñ���� */
133   {"\303\261\270\354\272\357\275\374", MENU_FUNC_NUM, CANNA_FN_DeleteDicMode},
134   /* ����ޥ���ȡ�����ޥ���� */
135   {"\274\255\275\361\245\336\245\246\245\363\245\310\241\277\245\242\245\363\245\336\245\246\245\363\245\310", MENU_FUNC_NUM, CANNA_FN_DicMountMode},
136   };
137 
138 static e_menuitem e_uuhenkantable[] = {
139   /* Ϣʸ���Ѵ� */
140   {"\317\242\312\270\300\341\312\321\264\271",   MENU_FUNC_NUM, CANNA_FN_EnterRenbunMode},
141   /* �༡��ư�Ѵ� */
142   {"\303\340\274\241\274\253\306\260\312\321\264\271", MENU_FUNC_NUM, CANNA_FN_EnterChikujiMode},
143 };
144 
145 static e_menuitem e_uufiletable[] = {
146   /* ���޻������Ѵ��ơ��֥� */
147   {"\245\355\241\274\245\336\273\372\244\253\244\312\312\321\264\271\245\306\241\274\245\326\245\353", MENU_FUNC_NUM, CANNA_FN_ShowPhonogramFile},
148   /* �������ޥ����ե����� */
149   {"\245\253\245\271\245\277\245\336\245\244\245\272\245\325\245\241\245\244\245\353", MENU_FUNC_NUM, CANNA_FN_ShowCannaFile},
150 };
151 
152 
153 #define numitems(x) ((sizeof(x)) / sizeof(e_menuitem))
154 
155 static struct _e_menu {
156   e_menuitem *mi;
157   int ni;
158 } e_me[] = {                                    /* MT_ �ν�ȹ�碌�뤳�� */
159   {e_helptable,     numitems(e_helptable)},     /* MT_HELP */
160   {e_uusonotatable, numitems(e_uusonotatable)}, /* MT_SONOTA */
161   {e_uukigotable,   numitems(e_uukigotable)},   /* MT_KIGO */
162 #ifndef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */
163   {e_uuservertable, numitems(e_uuservertable)}, /* MT_SERV */
164 #endif /* STANDALONE */
165   {e_uutangotable,  numitems(e_uutangotable)},  /* MT_TANGO */
166   {e_uuhenkantable, numitems(e_uuhenkantable)}, /* MT_HENKAN */
167   {e_uufiletable,   numitems(e_uufiletable)},   /* MT_FILE */
168 };
169 
170 #define N_BUILTIN_MENU (sizeof(e_me) / sizeof(struct _e_menu))
171 
172 static menustruct *me[N_BUILTIN_MENU];
173 
174 #define MBUFSIZE 512
175 
176 void
freeMenu(m)177 freeMenu(m)
178 menustruct *m;
179 {
180   free((char *)m->titles);
181   free((char *)m->titledata);
182   free((char *)m->body);
183   free((char *)m);
184 }
185 
186 menustruct *
allocMenu(n,nc)187 allocMenu(n, nc)
188 int n, nc;
189 {
190   wchar_t *wctab, **wcs;
191   menuitem *menubody;
192   menustruct *res;
193 
194   res = (menustruct *)malloc(sizeof(menustruct));
195   if (res) {
196     wctab = (wchar_t *)malloc(sizeof(wchar_t) * nc);
197     if (wctab) {
198       wcs = (wchar_t **)malloc(sizeof(wchar_t *) * n);
199       if (wcs) {
200 	menubody = (menuitem *)malloc(sizeof(menuitem) * n);
201 	if (menubody) {
202 	  res->titles = wcs;
203 	  res->titledata = wctab;
204 	  res->body = menubody;
205 	  return res;
206 	}
207 	free((char *)wcs);
208       }
209       free((char *)wctab);
210     }
211     free((char *)res);
212   }
213   return (menustruct *)0;
214 }
215 
216 static menustruct *
copystruct(eucmenu)217 copystruct(eucmenu)
218 struct _e_menu *eucmenu;
219 {
220   int i, nc, len, n = eucmenu->ni;
221   e_menuitem *euctable = eucmenu->mi;
222   menuitem *menubody;
223   wchar_t *wp, **wpp;
224   menustruct *res = (menustruct *)0;
225 #ifndef USE_MALLOC_FOR_BIG_ARRAY
226   wchar_t buf[MBUFSIZE];
227 #else
228   wchar_t *buf = (wchar_t *)malloc(sizeof(wchar_t) * MBUFSIZE);
229   if (!buf) {
230     return res;
231   }
232 #endif
233 
234   /* �����ȥ��ʸ����������� */
235   for (i = 0, nc = 0 ; i < n ; i++) {
236     len = MBstowcs(buf, euctable[i].title, MBUFSIZE);
237     nc += len + 1;
238   }
239 
240   res = allocMenu(n, nc);
241   if (res) {
242     menubody = res->body;
243     /* �����ȥ�ʸ����ǡ����Хåե��˥��ԡ� */
244     for (i = 0, wp = res->titledata, wpp = res->titles ; i < n ; i++) {
245       len = MBstowcs(wp, euctable[i].title, MBUFSIZE);
246       *wpp++ = wp;
247       wp += len + 1;
248 
249       /* ��¤�Τ��ԡ����� */
250       switch (euctable[i].func) {
251       case MENU_NEXT_MENU:
252 	menubody[i].flag = MENU_MENU;
253 	menubody[i].u.fnum = euctable[i].funcd;
254 	break;
255       case MENU_FUNC_NUM:
256 	menubody[i].flag = MENU_FUNC;
257 	menubody[i].u.fnum = euctable[i].funcd;
258 	break;
259       }
260     }
261     res->nentries = n;
262     res->modeid = CANNA_MODE_ExtendMode;
263   }
264 #ifdef USE_MALLOC_FOR_BIG_ARRAY
265   (void)free((char *)buf);
266 #endif
267   return res;
268 }
269 
270 /*
271  * menuitem�������Ƥι�¤�Τ�"unsigned char"����"wchar_t"���Ѵ�����
272  */
273 int
initExtMenu()274 initExtMenu()
275 {
276   int i, j;
277 
278   for (i = 0 ; i < N_BUILTIN_MENU ; i++) {
279     me[i] = copystruct(e_me + i);
280     if (!me[i]) {
281       for (j = 0 ; j < i ; j++) {
282 	freeMenu(me[j]);
283       }
284       return -1;
285     }
286   }
287   for (i = 0 ; i < N_BUILTIN_MENU ; i++) {
288     menustruct *m = me[i];
289     for (j = 0 ; j < m->nentries ; j++) {
290       if (m->body[j].flag == MENU_MENU) {
291 	m->body[j].u.menu_next = me[m->body[j].u.fnum];
292       }
293     }
294   }
295 
296   return 0;
297 }
298 
299 #undef numitems
300 
301 void
finExtMenu()302 finExtMenu()
303 {
304   int i;
305   for (i = 0 ; i < N_BUILTIN_MENU ; i++) {
306     freeMenu(me[i]);
307   }
308 }
309 #endif /* NO_EXTEND_MENU */
310 
311 static
makeUiUtilEchoStr(d)312 makeUiUtilEchoStr(d)
313 uiContext d;
314 {
315   ichiranContext ic = (ichiranContext)d->modec;
316 
317   d->kanji_status_return->echoStr = ic->allkouho[*(ic->curIkouho)];
318   d->kanji_status_return->length = WStrlen(ic->allkouho[*(ic->curIkouho)]);
319   d->kanji_status_return->revPos = 0;
320   d->kanji_status_return->revLen = 0;
321 
322   return(0);
323 }
324 
325 int
uiUtilIchiranTooSmall(d,retval,env)326 uiUtilIchiranTooSmall(d, retval, env)
327 uiContext d;
328 int retval;
329 mode_context env;
330 /* ARGSUSED */
331 {
332   makeUiUtilEchoStr(d);
333   return 0;
334 }
335 
336 #ifndef NO_EXTEND_MENU
337 static void
pushmenu(d,tab)338 pushmenu(d, tab)
339 uiContext d;
340 menustruct *tab;
341 {
342   tab->prev = d->prevMenu;
343   d->prevMenu = tab;
344 }
345 
346 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
347  * UI�桼�ƥ���ƥ��ΰ���ɽ��(FirstLine)                                     *
348  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
349 
350 static
uuflExitCatch(d,retval,env)351 uuflExitCatch(d, retval, env)
352 uiContext d;
353 int retval;
354 mode_context env;
355 /* ARGSUSED */
356 {
357   forichiranContext fc;
358   menustruct *mtab, *ptab;
359   menuitem *men;
360   int cur;
361 
362   d->nbytes = 0;
363 
364   popCallback(d); /* ������ pop */
365 
366   fc = (forichiranContext)d->modec;
367   cur = fc->curIkouho;
368   if (fc->prevcurp) {
369     *(fc->prevcurp) = cur;
370   }
371   men = fc->table->body + cur;
372   ptab = fc->table;
373 
374   popForIchiranMode(d);
375   popCallback(d);
376 
377   pushmenu(d, ptab);
378   switch (men->flag) {
379   case MENU_MENU:
380     for (mtab = d->prevMenu ; mtab ; mtab = mtab->prev) {
381       if (mtab == men->u.menu_next) {
382 	killmenu(d);
383 	jrKanjiError = "\244\263\244\316\271\340\314\334\244\316\245\341"
384 	"\245\313\245\345\241\274\244\317\272\306\265\242\305\252\244\313"
385 	"\301\252\302\362\244\265\244\354\244\306\244\244\244\336\244\271";
386                      /* ���ι��ܤΥ�˥塼�ϺƵ�Ū��������Ƥ��ޤ� */
387 	makeGLineMessageFromString(d, jrKanjiError);
388 	currentModeInfo(d);
389 	return 0;
390       }
391     }
392     return showmenu(d, men->u.menu_next);
393   case MENU_FUNC:
394     if (men->u.fnum < 0) {
395       jrKanjiError = "\244\263\244\316\271\340\314\334\244\317\300\265\244\267"
396 	"\244\257\304\352\265\301\244\265\244\354\244\306\244\244\244\336"
397 	"\244\273\244\363";
398 	    /* ���ι��ܤ��������������Ƥ��ޤ��� */
399       killmenu(d);
400       makeGLineMessageFromString(d, jrKanjiError);
401       currentModeInfo(d);
402       return 0;
403     }
404     else {
405       d->more.todo = 1;
406       d->more.fnum = men->u.fnum;
407       /* �ʲ��Σ��Ĥ�ɬ�פ��ɤ����ɤ�ʬ����ʤ� */
408       GlineClear(d);
409       echostrClear(d);
410       return 0;
411     }
412   }
413   return NothingChangedWithBeep(d); /* �����ˤ���ʤ��Ϥ� */
414 }
415 
prevMenuIfExist(d)416 prevMenuIfExist(d)
417 uiContext d;
418 {
419   menustruct *m = d->prevMenu;
420 
421   if (m) {
422     d->prevMenu = m->prev;
423     d->kanji_status_return->info &= ~KanjiEmptyInfo;
424 
425     return showmenu(d, m);
426   }
427   else {
428     return 0;
429   }
430 }
431 
432 static
uuflQuitCatch(d,retval,env)433 uuflQuitCatch(d, retval, env)
434 uiContext d;
435 int retval;
436 mode_context env;
437 /* ARGSUSED */
438 {
439   popCallback(d); /* ������ pop */
440 
441   popForIchiranMode(d);
442   popCallback(d);
443   currentModeInfo(d);
444 
445   return prevMenuIfExist(d);
446 }
447 #endif /* NO_EXTEND_MENU */
448 
449 /* cfuncdef
450 
451   UiUtilMode -- UI�桼�ƥ���ƥ��⡼�ɤˤʤ�Ȥ��˸ƤФ�롣
452 
453  */
UiUtilMode(d)454 UiUtilMode(d)
455 uiContext d;
456 {
457 #ifdef NO_EXTEND_MENU
458   d->kanji_status_return->info |= KanjiExtendInfo;
459   return 0;
460 #else
461   return showmenu(d, me[MT_HELP]);
462 #endif
463 }
464 
465 #ifndef NO_EXTEND_MENU
466 /*
467  * newMenuInfo() -- ��������˥塼����μ���
468  */
469 
470 static menuinfo *
newMenuInfo(tab)471 newMenuInfo(tab)
472 menustruct *tab;
473 {
474   menuinfo *res;
475 
476   res = (menuinfo *)malloc(sizeof(menuinfo));
477   if (res) {
478     res->mstruct = tab;
479     res->curnum = 0;
480   }
481   return res;
482 }
483 
484 void
freeAllMenuInfo(p)485 freeAllMenuInfo(p)
486 menuinfo *p;
487 {
488   menuinfo *q;
489 
490   while (p) {
491     q = p->next;
492     free((char *)p);
493     p = q;
494   }
495 }
496 
497 static menuinfo *
findMenuInfo(p,ms)498 findMenuInfo(p, ms)
499 menuinfo *p;
500 menustruct *ms;
501 {
502   while (p) {
503     if (p->mstruct == ms) {
504       return p;
505     }
506     p = p->next;
507   }
508   return (menuinfo *)0;
509 }
510 
511 /*
512  * showmenu -- ��˥塼��ɽ��
513  *
514  * ����
515  *   d         : uiContext
516  *   table     : ��˥塼����(menustruct �ؤΥݥ���)
517  */
518 
519 int
showmenu(d,table)520 showmenu(d, table)
521 uiContext d;
522 menustruct *table;
523 {
524   yomiContext yc = (yomiContext)d->modec;
525   forichiranContext fc;
526   ichiranContext ic;
527   unsigned inhibit = 0;
528   int retval = 0;
529   menuinfo *minfo;
530   int *prevcurp = (int *)0;
531 
532   if (yc->generalFlags & CANNA_YOMI_CHGMODE_INHIBITTED) {
533     return NothingChangedWithBeep(d);
534   }
535 
536   minfo = findMenuInfo(d->minfo, table);
537   if (!minfo) {
538     minfo = newMenuInfo(table);
539     if (minfo) {
540       minfo->next = d->minfo;
541       d->minfo = minfo;
542     }
543   }
544 
545   if (minfo) {
546     prevcurp = &(minfo->curnum);
547   }
548 
549   d->status = 0;
550 
551   if((retval = getForIchiranContext(d)) == NG)
552      return(GLineNGReturn(d));
553   fc = (forichiranContext)d->modec;
554 
555   fc->prevcurp = prevcurp;
556   fc->table = table;
557 
558   /* selectOne ��Ƥ֤���ν��� */
559   fc->allkouho = table->titles;
560   fc->curIkouho = 0;
561   if (!cannaconf.HexkeySelect)
562     inhibit |= ((unsigned char)NUMBERING | (unsigned char)CHARINSERT);
563   else
564     inhibit |= (unsigned char)CHARINSERT;
565   if((retval = selectOne(d, fc->allkouho, &fc->curIkouho, table->nentries,
566 			 BANGOMAX, inhibit, 0, WITHOUT_LIST_CALLBACK,
567 			 NO_CALLBACK, uuflExitCatch,
568 			 uuflQuitCatch, uiUtilIchiranTooSmall)) == NG) {
569     return(GLineNGReturnFI(d));
570   }
571 
572   ic = (ichiranContext)d->modec;
573   ic->majorMode = CANNA_MODE_ExtendMode;
574   ic->minorMode = table->modeid;
575   currentModeInfo(d);
576 
577   if (prevcurp) {
578     *(ic->curIkouho) = *prevcurp;
579   }
580   else {
581     *(ic->curIkouho) = 0;
582   }
583 
584   /* ��������Ԥ������Ƹ���������Ф��ʤ� */
585   if(ic->tooSmall) {
586     d->status = AUX_CALLBACK;
587     return(retval);
588   }
589 
590   makeGlineStatus(d);
591   /* d->status = ICHIRAN_EVERYTIME; */
592 
593   return(retval);
594 }
595 #endif /* NO_EXTEND_MENU */
596 
597 #ifndef wchar_t
598 # error "wchar_t is already undefined"
599 #endif
600 #undef wchar_t
601 /*********************************************************************
602  *                       wchar_t replace end                         *
603  *********************************************************************/
604