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/************************************************************************/ 24/* THIS SOURCE CODE IS MODIFIED FOR TKO BY T.MURAI 1997 25/************************************************************************/ 26 27 28#if !defined(lint) && !defined(__CODECENTER__) 29static char rcs_id[] = "@(#) 102.1 $Id: uiutil.c 14875 2005-11-12 21:25:31Z bonefish $"; 30#endif 31 32#include "canna.h" 33#include "patchlevel.h" 34 35#ifndef NO_EXTEND_MENU 36 37typedef struct { 38 char *title; 39 int func; 40 int funcd; 41} e_menuitem; 42 43#define MENU_NEXT_MENU 0 /* ������������������������������������������������ */ 44#define MENU_FUNC_NUM 1 /* ������������������������������������������������������������������������ */ 45 46#ifdef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */ 47#define MT_HELP 0 48#define MT_SONOTA 1 49#define MT_KIGO 2 50#define MT_TANGO 3 51#define MT_HENKAN 4 52#define MT_FILE 5 53#else 54#define MT_HELP 0 55#define MT_SONOTA 1 56#define MT_KIGO 2 57#define MT_SERV 3 58#define MT_TANGO 4 59#define MT_HENKAN 5 60#define MT_FILE 6 61#endif 62 63static e_menuitem e_helptable[] = { 64 /* ���������������� */ 65 {"\265\255\271\346\306\376\316\317", MENU_NEXT_MENU, MT_KIGO}, 66 /* �������������������� */ 67 {"\245\263\241\274\245\311\306\376\316\317", MENU_FUNC_NUM, CANNA_FN_HexMode}, 68 /* ���������������� */ 69 {"\311\364\274\363\306\376\316\317", MENU_FUNC_NUM, CANNA_FN_BushuMode}, 70 /* ���������������� */ 71 {"\303\261\270\354\305\320\317\277", MENU_NEXT_MENU, MT_TANGO}, 72 /* ���������������� */ 73 {"\264\304\266\255\300\337\304\352", MENU_NEXT_MENU, MT_SONOTA}, 74}; 75 76static e_menuitem e_uusonotatable[] = { 77#ifdef WIN 78 {"����������������", MENU_NEXT_MENU, MT_HENKAN}, 79#ifndef STANDALONE // This is not used in Windows environment 80 {"��������������������", MENU_NEXT_MENU, MT_SERV}, 81#endif 82 {"����������������������������������������������������", MENU_FUNC_NUM, CANNA_FN_DicMountMode}, 83 {"������������������������", MENU_FUNC_NUM, CANNA_FN_ShowGakushu}, 84 {"����������������������������", MENU_FUNC_NUM, CANNA_FN_ShowVersion}, 85 {"������������������������", MENU_NEXT_MENU, MT_FILE}, 86#else 87 /* ���������������� */ 88 {"\312\321\264\271\312\375\274\260", MENU_NEXT_MENU, MT_HENKAN}, 89#ifndef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */ 90 /* �������������������� */ 91 {"\245\265\241\274\245\320\301\340\272\356", MENU_NEXT_MENU, MT_SERV}, 92#endif 93 /* ���������������������������������������������������� */ 94 {"\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}, 95 /* ������������������������ */ 96 {"\263\330\275\254\276\365\302\326\311\275\274\250", MENU_FUNC_NUM, CANNA_FN_ShowGakushu}, 97 /* ���������������������������� */ 98 {"\245\320\241\274\245\270\245\347\245\363\311\275\274\250", MENU_FUNC_NUM, CANNA_FN_ShowVersion}, 99 /* ������������������������ */ 100 {"\245\325\245\241\245\244\245\353\311\275\274\250", MENU_NEXT_MENU, MT_FILE}, 101#endif /* WIN */ 102}; 103 104static e_menuitem e_uukigotable[] = { 105 /* ���������������� */ 106 {"\265\255\271\346\301\264\310\314", MENU_FUNC_NUM, CANNA_FN_KigouMode}, 107 /* �������������������� */ 108 {"\245\355\245\267\245\242\312\270\273\372", MENU_FUNC_NUM, CANNA_FN_RussianMode}, 109 /* ������������������������ */ 110 {"\245\256\245\352\245\267\245\343\312\270\273\372", MENU_FUNC_NUM, CANNA_FN_GreekMode}, 111 /* �������� */ 112 {"\267\323\300\376", MENU_FUNC_NUM, CANNA_FN_LineMode}, 113}; 114 115#ifndef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */ 116static e_menuitem e_uuservertable[] = { 117 /* �������������������������������� */ 118 {"\245\265\241\274\245\320\244\316\300\332\244\352\316\245\244\267", MENU_FUNC_NUM, CANNA_FN_DisconnectServer}, 119 /* �������������������������������� */ 120 {"\245\265\241\274\245\320\244\316\300\332\244\352\302\330\244\250", MENU_FUNC_NUM, CANNA_FN_ChangeServerMode}, 121 /* ������������������������ */ 122 {"\245\265\241\274\245\320\244\316\311\275\274\250", MENU_FUNC_NUM, CANNA_FN_ShowServer}, 123}; 124#endif /* STANDALONE */ 125 126static e_menuitem e_uutangotable[] = { 127 /* ���������������� */ 128 {"\303\261\270\354\305\320\317\277", MENU_FUNC_NUM, CANNA_FN_DefineDicMode}, 129 /* ���������������� */ 130 {"\303\261\270\354\272\357\275\374", MENU_FUNC_NUM, CANNA_FN_DeleteDicMode}, 131 /* ���������������������������������������������������� */ 132 {"\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}, 133 }; 134 135static e_menuitem e_uuhenkantable[] = { 136 /* �������������������� */ 137 {"\317\242\312\270\300\341\312\321\264\271", MENU_FUNC_NUM, CANNA_FN_EnterRenbunMode}, 138 /* ������������������������ */ 139 {"\303\340\274\241\274\253\306\260\312\321\264\271", MENU_FUNC_NUM, CANNA_FN_EnterChikujiMode}, 140}; 141 142static e_menuitem e_uufiletable[] = { 143 /* ������������������������������������������������ */ 144 {"\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}, 145 /* ���������������������������������������� */ 146 {"\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}, 147}; 148 149 150#define numitems(x) ((sizeof(x)) / sizeof(e_menuitem)) 151 152static struct _e_menu { 153 e_menuitem *mi; 154 int ni; 155} e_me[] = { /* MT_ ������������������������������������ */ 156 {e_helptable, numitems(e_helptable)}, /* MT_HELP */ 157 {e_uusonotatable, numitems(e_uusonotatable)}, /* MT_SONOTA */ 158 {e_uukigotable, numitems(e_uukigotable)}, /* MT_KIGO */ 159#ifndef STANDALONE /* This is not used in Windows environment 1996.7.30 kon */ 160 {e_uuservertable, numitems(e_uuservertable)}, /* MT_SERV */ 161#endif /* STANDALONE */ 162 {e_uutangotable, numitems(e_uutangotable)}, /* MT_TANGO */ 163 {e_uuhenkantable, numitems(e_uuhenkantable)}, /* MT_HENKAN */ 164 {e_uufiletable, numitems(e_uufiletable)}, /* MT_FILE */ 165}; 166 167#define N_BUILTIN_MENU (sizeof(e_me) / sizeof(struct _e_menu)) 168 169static menustruct *me[N_BUILTIN_MENU]; 170 171#define MBUFSIZE 512 172 173static menustruct *copystruct(struct _e_menu *eucmenu); 174static int makeUiUtilEchoStr(uiContext d); 175static void pushmenu(uiContext d, menustruct *tab); 176static int uuflExitCatch(uiContext d, int retval, mode_context env); 177static int uuflQuitCatch(uiContext d, int retval, mode_context env); 178static menuinfo *newMenuInfo(menustruct *tab); 179static menuinfo *findMenuInfo(menuinfo *p, menustruct *ms); 180 181void 182freeMenu(menustruct *m) 183{ 184 free(m->titles); 185 free(m->titledata); 186 free(m->body); 187 free(m); 188} 189 190menustruct * 191allocMenu(int n, int nc) 192{ 193 WCHAR_T *wctab, **wcs; 194 menuitem *menubody; 195 menustruct *res; 196 197 res = (menustruct *)malloc(sizeof(menustruct)); 198 if (res) { 199 wctab = (WCHAR_T *)malloc(sizeof(WCHAR_T) * nc); 200 if (wctab) { 201 wcs = (WCHAR_T **)malloc(sizeof(WCHAR_T *) * n); 202 if (wcs) { 203 menubody = (menuitem *)malloc(sizeof(menuitem) * n); 204 if (menubody) { 205 res->titles = wcs; 206 res->titledata = wctab; 207 res->body = menubody; 208 return res; 209 } 210 free(wcs); 211 } 212 free(wctab); 213 } 214 free(res); 215 } 216 return (menustruct *)0; 217} 218 219static menustruct * 220copystruct(struct _e_menu *eucmenu) 221{ 222 int i, nc, len, n = eucmenu->ni; 223 e_menuitem *euctable = eucmenu->mi; 224 menuitem *menubody; 225 WCHAR_T *wp, **wpp; 226 menustruct *res = (menustruct *)0; 227#ifndef WIN 228 WCHAR_T buf[MBUFSIZE]; 229#else 230 WCHAR_T *buf = (WCHAR_T *)malloc(sizeof(WCHAR_T) * MBUFSIZE); 231 if (!buf) { 232 return res; 233 } 234#endif 235 236 /* ���������������������������������������������������� */ 237 for (i = 0, nc = 0 ; i < n ; i++) { 238 len = MBstowcs(buf, euctable[i].title, MBUFSIZE); 239 nc += len + 1; 240 } 241 242 res = allocMenu(n, nc); 243 if (res) { 244 menubody = res->body; 245 /* ������������������������������������������������������������������������ */ 246 for (i = 0, wp = res->titledata, wpp = res->titles ; i < n ; i++) { 247 len = MBstowcs(wp, euctable[i].title, MBUFSIZE); 248 *wpp++ = wp; 249 wp += len + 1; 250 251 /* ������������������������������������ */ 252 switch (euctable[i].func) { 253 case MENU_NEXT_MENU: 254 menubody[i].flag = MENU_MENU; 255 menubody[i].u.fnum = euctable[i].funcd; 256 break; 257 case MENU_FUNC_NUM: 258 menubody[i].flag = MENU_FUNC; 259 menubody[i].u.fnum = euctable[i].funcd; 260 break; 261 } 262 } 263 res->nentries = n; 264 res->modeid = CANNA_MODE_ExtendMode; 265 } 266#ifdef WIN 267 free(buf); 268#endif 269 return res; 270} 271 272/* 273 * menuitem������������������������������������"unsigned char"��������"WCHAR_T"�������������������� 274 */ 275int 276initExtMenu(void) 277{ 278 int i, j; 279 280 for (i = 0 ; i < N_BUILTIN_MENU ; i++) { 281 me[i] = copystruct(e_me + i); 282 if (!me[i]) { 283 for (j = 0 ; j < i ; j++) { 284 freeMenu(me[j]); 285 } 286 return -1; 287 } 288 } 289 for (i = 0 ; i < N_BUILTIN_MENU ; i++) { 290 menustruct *m = me[i]; 291 for (j = 0 ; j < m->nentries ; j++) { 292 if (m->body[j].flag == MENU_MENU) { 293 m->body[j].u.menu_next = me[m->body[j].u.fnum]; 294 } 295 } 296 } 297 298 return 0; 299} 300 301#undef numitems 302 303void 304finExtMenu(void) 305{ 306 int i; 307 for (i = 0 ; i < N_BUILTIN_MENU ; i++) { 308 freeMenu(me[i]); 309 } 310} 311#endif /* NO_EXTEND_MENU */ 312 313static 314int makeUiUtilEchoStr(uiContext d) 315{ 316 ichiranContext ic = (ichiranContext)d->modec; 317 318 d->kanji_status_return->echoStr = ic->allkouho[*(ic->curIkouho)]; 319 d->kanji_status_return->length = WStrlen(ic->allkouho[*(ic->curIkouho)]); 320 d->kanji_status_return->revPos = 0; 321 d->kanji_status_return->revLen = 0; 322 323 return(0); 324} 325 326int 327uiUtilIchiranTooSmall(uiContext d, int retval, mode_context env) 328/* ARGSUSED */ 329{ 330 makeUiUtilEchoStr(d); 331 return 0; 332} 333 334#ifndef NO_EXTEND_MENU 335static void 336pushmenu(uiContext d, menustruct *tab) 337{ 338 tab->prev = d->prevMenu; 339 d->prevMenu = tab; 340} 341 342/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 343 * UI������������������������������������������������(FirstLine) * 344 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 345 346static 347int uuflExitCatch(uiContext d, int retval, mode_context env) 348/* ARGSUSED */ 349{ 350 forichiranContext fc; 351 menustruct *mtab, *ptab; 352 menuitem *men; 353 int cur; 354 355 d->nbytes = 0; 356 357 popCallback(d); /* ������������ pop */ 358 359 fc = (forichiranContext)d->modec; 360 cur = fc->curIkouho; 361 if (fc->prevcurp) { 362 *(fc->prevcurp) = cur; 363 } 364 men = fc->table->body + cur; 365 ptab = fc->table; 366 367 popForIchiranMode(d); 368 popCallback(d); 369 370 pushmenu(d, ptab); 371 switch (men->flag) { 372 case MENU_MENU: 373 for (mtab = d->prevMenu ; mtab ; mtab = mtab->prev) { 374 if (mtab == men->u.menu_next) { 375 killmenu(d); 376 jrKanjiError = "\244\263\244\316\271\340\314\334\244\316\245\341" 377 "\245\313\245\345\241\274\244\317\272\306\265\242\305\252\244\313" 378 "\301\252\302\362\244\265\244\354\244\306\244\244\244\336\244\271"; 379 /* ���������������������������������������������������������������������������������������� */ 380 makeGLineMessageFromString(d, jrKanjiError); 381 currentModeInfo(d); 382 return 0; 383 } 384 } 385 return showmenu(d, men->u.menu_next); 386 case MENU_FUNC: 387 if (men->u.fnum < 0) { 388 jrKanjiError = "\244\263\244\316\271\340\314\334\244\317\300\265\244\267" 389 "\244\257\304\352\265\301\244\265\244\354\244\306\244\244\244\336" 390 "\244\273\244\363"; 391 /* �������������������������������������������������������������������� */ 392 killmenu(d); 393 makeGLineMessageFromString(d, jrKanjiError); 394 currentModeInfo(d); 395 return 0; 396 } 397 else { 398 d->more.todo = 1; 399 d->more.fnum = men->u.fnum; 400 /* ���������������������������������������������������������������������������� */ 401 GlineClear(d); 402 echostrClear(d); 403 return 0; 404 } 405 } 406 return NothingChangedWithBeep(d); /* ������������������������������������ */ 407} 408 409int prevMenuIfExist(uiContext d) 410{ 411 menustruct *m = d->prevMenu; 412 413 if (m) { 414 d->prevMenu = m->prev; 415 d->kanji_status_return->info &= ~KanjiEmptyInfo; 416 417 return showmenu(d, m); 418 } 419 else { 420 return 0; 421 } 422} 423 424static 425int uuflQuitCatch(uiContext d, int retval, mode_context env) 426/* ARGSUSED */ 427{ 428 popCallback(d); /* ������������ pop */ 429 430 popForIchiranMode(d); 431 popCallback(d); 432 currentModeInfo(d); 433 434 return prevMenuIfExist(d); 435} 436#endif /* NO_EXTEND_MENU */ 437 438/* cfuncdef 439 440 UiUtilMode -- UI������������������������������������������������������������������������������������ 441 442 */ 443int UiUtilMode(uiContext d) 444{ 445#ifdef NO_EXTEND_MENU 446 d->kanji_status_return->info |= KanjiExtendInfo; 447 return 0; 448#else 449 return showmenu(d, me[MT_HELP]); 450#endif 451} 452 453#ifndef NO_EXTEND_MENU 454/* 455 * newMenuInfo() -- ������������������������������������������������ 456 */ 457 458inline menuinfo * 459newMenuInfo(menustruct *tab) 460{ 461 menuinfo *res; 462 463 res = (menuinfo *)malloc(sizeof(menuinfo)); 464 if (res) { 465 res->mstruct = tab; 466 res->curnum = 0; 467 } 468 return res; 469} 470 471void 472freeAllMenuInfo(menuinfo *p) 473{ 474 menuinfo *q; 475 476 while (p) { 477 q = p->next; 478 free(p); 479 p = q; 480 } 481} 482 483inline menuinfo * 484findMenuInfo(menuinfo *p, menustruct *ms) 485{ 486 while (p) { 487 if (p->mstruct == ms) { 488 return p; 489 } 490 p = p->next; 491 } 492 return (menuinfo *)0; 493} 494 495/* 496 * showmenu -- ���������������������������� 497 * 498 * �������� 499 * d : uiContext 500 * table : ������������������������(menustruct ������������������������) 501 */ 502 503int 504showmenu(uiContext d, menustruct *table) 505{ 506 yomiContext yc = (yomiContext)d->modec; 507 forichiranContext fc; 508 ichiranContext ic; 509 unsigned inhibit = 0; 510 int retval = 0; 511 menuinfo *minfo; 512 int *prevcurp = (int *)0; 513 514 if (yc->generalFlags & CANNA_YOMI_CHGMODE_INHIBITTED) { 515 return NothingChangedWithBeep(d); 516 } 517 518 minfo = findMenuInfo(d->minfo, table); 519 if (!minfo) { 520 minfo = newMenuInfo(table); 521 if (minfo) { 522 minfo->next = d->minfo; 523 d->minfo = minfo; 524 } 525 } 526 527 if (minfo) { 528 prevcurp = &(minfo->curnum); 529 } 530 531 d->status = 0; 532 533 if((retval = getForIchiranContext(d)) == NG) 534 return(GLineNGReturn(d)); 535 fc = (forichiranContext)d->modec; 536 537 fc->prevcurp = prevcurp; 538 fc->table = table; 539 540 /* selectOne �������������������������������� */ 541 fc->allkouho = table->titles; 542 fc->curIkouho = 0; 543 if (!cannaconf.HexkeySelect) 544 inhibit |= ((unsigned char)NUMBERING | (unsigned char)CHARINSERT); 545 else 546 inhibit |= (unsigned char)CHARINSERT; 547 if((retval = selectOne(d, fc->allkouho, &fc->curIkouho, table->nentries, 548 BANGOMAX, inhibit, 0, WITHOUT_LIST_CALLBACK, 549 NO_CALLBACK, uuflExitCatch, 550 uuflQuitCatch, uiUtilIchiranTooSmall)) == NG) { 551 return(GLineNGReturnFI(d)); 552 } 553 554 ic = (ichiranContext)d->modec; 555 ic->majorMode = CANNA_MODE_ExtendMode; 556 ic->minorMode = table->modeid; 557 currentModeInfo(d); 558 559 if (prevcurp) { 560 *(ic->curIkouho) = *prevcurp; 561 } 562 else { 563 *(ic->curIkouho) = 0; 564 } 565 566 /* ������������������������������������������������������������������������ */ 567 if(ic->tooSmall) { 568 d->status = AUX_CALLBACK; 569 return(retval); 570 } 571 572 makeGlineStatus(d); 573 /* d->status = ICHIRAN_EVERYTIME; */ 574 575 return(retval); 576} 577#endif /* NO_EXTEND_MENU */ 578