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