/****************************************************************************/
/* TEXT MENU SYSTEM for X68000 V1.9 Copyright (C) 1991-94 by AIG-SOFT       */
/****************************************************************************/
/* '94/02/21 V1.90 キー設定機能削除／スクロールシンボル内蔵 */
/* '94/07/18 V1.91 細部改良 */
/* '94/08/03 V1.92 スクロールシンボルが壊れるバグを修正 */
/* '94/09/26 V1.93 オフスクリーン処理削除 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <iocslib.h>
#include "defines.h"
#include "menu.h"
#include "aigtext.h"
#include "ascreen.h"
#include "akey.h"
#include "skey.h"

#define UPKEY	(SKdown|SKopt1)	/* １ラインアップキー */
#define DNKEY	(SKup|SKopt1)	/* １ラインダウンキー */

/****************************************************************************/

static	unchar	mnone[DISPX+1];	/* 項目が無いところに表示するパターン */
static	unsint	k2,k4,k6,k8;	/* テンキー移動モード */
static	unsint	Cno[9],Csep[9],Cmn[9];	/* 色コードバッファー */
static	unsint	fscroll;	/* スクロールモード */
/* スクロールシンボル */
static _FNTBUF fb1,fb2,fb0={8,16,{0x00,0x00,0x18,0x18,0x24,0x24,0x42,0x42
				    ,0x81,0xe7,0x24,0x24,0x24,0x24,0x3c,0x00}};

/****************************************************************************/

static void SSsub(int fud,int ex,int y)
/* スクロールシンボル表示 */
{
short i;
	for (i=0;i<16;i++) fb2.buffer[i]=fb1.buffer[fud? 15-i:i];
	B_LOCATE(ex,y);
	FONTPUT2(&fb2);
}

/****************************************************************************/

static int line_no(n,all1,lt,sp,wp,clm)
int n,all1,*lt,sp,*wp,clm;
{
	if (*lt<0 || *wp<0) {(*lt)=(*wp)=0;}
	*lt=sp-1;
	*wp=(*lt)%clm;
	sp=(*lt)/clm+1;
	if (*lt+n>all1) {
		*lt=all1-n;
		return(sp-*lt);
	}
	return(1);
}

/****************************************************************************/

static void LastPoint(int lt,int sp,int clm,int *wp,int all)
/* 一番最後のポイント修正 */
{
	if ((lt+sp-1)*clm+*wp+1>all) *wp=all-1-(lt+sp-1)*clm;
}

/****************************************************************************/

static int key_play(ky,n,all,all1,lt,sp,wp,clm,md)
int ky,n,all,all1,clm,*lt,*sp,*wp;
_MENU_DATA *md;
/* return : 0 = nothing happen (not use key)
   	    1 = nothing happen (operation disable)
	    2 = point move in active window
	    3 = scroll up   (sp not move)
	    4 = scroll down (sp not move)
	    5 = all window remake
	    7 = scroll up   (sp move)
	    8 = scroll down (sp move)
	    9 = scroll up   (sp move , at sp=1)
	   10 = scroll down (sp move , at sp=n)
	   11 = point move in this line
	10001 = exit by top
	10002 = exit by last
*/
{
int ltsp,mwp;
	ltsp=*lt+*sp;
	mwp=all-1-(ltsp-1)*clm;
	
	/* テンキーオペレーション */
	if (ky==k4) ky=SKleft;	/* cursor left */
	if (ky==k8) ky=SKup;	/* cursor up */
	if (ky==k6) ky=SKright;	/* cursor right */
	if (ky==k2) ky=SKdown;	/* cursor down */
	
	switch (ky) {
	    case SKright: /* cursor right */
		if (ltsp==all1) {
			if (*wp==mwp) { /* 一番右下にいる時 */
				if (clm>=2 && md->ex_last) return(10002);
				return(1);
			}
		}
		(*wp)++;
		if (*wp<clm) return(11);
		*wp=0;
	    case SKdown: /* cursor down */
		while (!md->ms_mode) {
			if (*sp==n) {
				if (*lt==all1-n) return(1); /* cursor at end */
				if (ltsp*clm+*wp+1>all) break;
				(*lt)++;
				return(3); /* scroll up */
			}
			if (ltsp*clm+*wp+1>all) {
				if (md->ex_last) return(10002);
				return(1); /* 移動不可 */
			}
			(*sp)++;
			return(2); /* point move */
		} /* メッセージモードの時は1line upとなる */
	    case UPKEY:
	    case SKdown|SKopt2: /* 1line up */
		if (fscroll && *lt<all1-n) {
			(*lt)++;
			if (*sp==1) return(9);
			(*sp)--;
			return(7); /* scroll up */
		}
		return(1);
	
	    case SKleft: /* cursor left */
		if (*lt==0 && *sp==1 && *wp==0) { /* 一番左上にいる時 */
			if (clm>=2 && md->ex_top) return(10001);
			return(1);
		}
		(*wp)--;
		if (*wp>=0) return(11);
		*wp=clm-1;
	    case SKup: /* cursor up */
		if (!md->ms_mode) {
			if (*sp==1) {
				if (*lt==0) { /* cursor at top */
					if (md->ex_top) return(10001);
					return(1);
				}
				(*lt)--;
				return(4); /* scroll down */
			}
			(*sp)--;
			return(2); /* point move */
		} /* メッセージモードの時は1line downになる */
	    case DNKEY:
	    case SKup|SKopt2: /* 1line down */
		if (fscroll && *lt>0) {
			(*lt)--;
			if (*sp==n) return(10);
			(*sp)++;
			return(8);
		}
		return(1);
	
	    case SKrdown: /* page down */
		if (fscroll) {
			if (*lt==0) return(1);
			*lt-=n;
			if (*lt<0) *lt=0;
			return(5); /* window remake */
		}
		return(1);
	
	    case SKrup: /* page up */
		if (fscroll) {
			if (*lt==all1-n) return(1);
			*lt+=n;
			if (*lt+n>all1) *lt=all1-n;
			LastPoint(*lt,*sp,clm,wp,all);
			return(5);
		}
		return(1);
	
	    case SKhome: /* active window top */
		*sp=1;
		*wp=0;
		return(2);
	
	    case SKdel: /* active window end */
		*sp=n;
		*wp=clm-1;
		LastPoint(*lt,*sp,clm,wp,all);
		return(2);
	
	    case SKhome|SKopt1:
	    case SKhome|SKopt2: /* cursor top：lt+sp=1 & wp=0 */
		*wp=0;
		if (ltsp==1) return(11);
		*sp=1;
		if (fscroll && *lt>0) {
			*lt=0;
			return(5);
		}
		return(2);
	
	    case SKdel|SKopt1:
	    case SKdel|SKopt2: /* cursor end：lt+sp=all1 & wp=end */
		*wp=clm-1;
		if (ltsp==all1) { /* 最下行にいるとき */
			*wp=mwp;
			return(11);
		}
		*sp=n;
		if (fscroll && *lt<all1-n) {
			*lt=all1-n;
			LastPoint(*lt,*sp,clm,wp,all);
			return(5);
		}
		LastPoint(*lt,*sp,clm,wp,all);
		return(2);
	}
	return(0); /* not use key */
}

/****************************************************************************/

static int jump_key(ky,n,all,all1,lt,sp,wp,clm,msatr,fdirect,num,num0)
int ky,n,all,all1,*lt,*sp,*wp,clm,msatr[],fdirect,num,num0;
/* リターン値はkey_play()と同じ */
{
int i;
	ky=toupper(ky&0xff);
	
	if (fdirect) { /* ダイレクトキージャンプモード */
		for(i=1;i<=all;i++) {
			if ((msatr[i]&0xff)==ky) {
				ky=i;
				goto DJUMP;
			}
		}
		return(0); /* not use key */
	}
	
	switch (num) {
		default: /* それ以外の番号モードの時 */
			return(0);
		case 1: /* A-Z mode */
			if (!isupper(ky)) return(1); /* 'A'-'Z'以外 */
			ky-=('A'-1);
			break;
		case 2: /* 1-9/A-Z */
			if (!isalnum(ky)) return(0); /* '0'-'9','A'-'Z'以外のとき */
			if (isdigit(ky)) ky-='0'; /* '0'-'9' */
			else ky-=('A'-10); /* 'A'-'Z' */
			if (num0==0) { /* 1からモード */
				if (ky==0) return(1); /* 1からのときに0が押された */
			} else ky++; /* ０からモード */
	}
	if (ky>all) return(1); /* この番号はない */
	
    DJUMP: /* 実際のジャンプ */
	if (ky>=((*lt)*clm+1) && ky<=((*lt+n)*clm)) {
		/* 現在表示している範囲内で移動できる */
		#if 0
		ky-=((*lt)*clm);
		*wp=(ky-1)%clm;
		*sp=(ky-1)/clm+1;
		#endif
		ky-=((*lt)*clm);
		*wp=(ky-1)%clm;
		*sp=(ky-1)/clm+1;
		return(2);
	}
	/* 範囲外のとき */
	*sp=line_no(n,all1,lt,ky,wp,clm);
	return(5);
}

/****************************************************************************/

static void set1(no,sel,ms,msatr,mlen,md,col)
/* １項目表示ルーチン */
int no,sel,msatr,mlen;
unchar *ms;
_MENU_DATA *md;
MCOLORS *col;
{
int c,l,l2;
unchar a[DISPX+1],b[DISPX*2+1];
static unchar *NUMS[]={
	 "%02d","%2d"
	,"%03d","%3d"
	,"%02x","%02X"
};
	/* sel */
	/* 入力 */
	/* 0=normal , 1=select , 2=決定 */
	
	/* 内部変換 */
	/* 3=特殊色１ , 4=特殊色２ , 5=特殊色２select , 6=特殊色２決定 */
	/* 7=non select normal , 8=non select select */
	
	if ((md->md_non)&&(msatr&BIT8)) { /* non select */
		sel+=7;
	} else {
		if (md->md_spcol) { /* 特殊色有効モード */
			if (msatr&BIT10) sel+=4;
			if ((msatr&BIT9) && sel==0) sel=3;
		}
	}
	if (md->md_scnc) sel=0; /* select color -> normal color */
	
	if (md->num) { /* 番号あり */
		a[1]=0;
		if (md->direct) { /* ダイレクトキージャンプモード */
			a[0]=toupper(msatr&0xff);
			if (a[0]<' ') a[0]+=('a'-1); /* CTRL-key */
		} else { /* 通常番号モード */
			if (md->num>=2 && md->num0) no--; /* ０から */
			c=(md->nums? 'a':'A');
			switch (md->num) {
			    case 1: /* A-Z */
				a[0]=c+no-1;
				break;
			    case 2: /* 1-9/A-Z */
				if (no>=0 && no<=9) a[0]='0'+no;
				else a[0]=c+no-10;
				break;
			    case 3:
			    case 4:
			    case 5:
				sprintf2(a,NUMS[(md->num-3)*2+md->nums],no);
				break;
			}
		}
		EX_COLOR(Cno[sel]); /* 番号色選択 */
		EX_PRINT2(8,a);
	}
	
	if (md->sep[0]!=0) {	/* ":" */
		EX_COLOR(Csep[sel]); /* ":"色選択 */
		EX_PRINT2(8,md->sep);
	}
	
	/* メニュー項目 */
	if (md->md_wxcut) {jnstrcpy(b,ms,mlen); ms=b;} /* 固定枠幅モード */
	c=Cmn[sel]; /* 項目色選択 */
	
	l=mlen-klen2(ms); /* 見た目の長さの差 */
	if (md->md_mes) { /* center/right */
		if (md->md_mes==1) {l2=l; l/=2; l2-=l;} /* center */
		/* メッセージ長がmlenに満たないときの処理 */
		if (l>0) { /* 前にスペースを表示する */
			string(a,' ',l);
			EX_COLOR(md->md_revlen==0? col->back:c);
			EX_PRINT2(8,a);
		}
		l=(md->md_mes==1? l2:0);
	} /* leftの時は何もしない */
	
	EX_COLOR(c);
	EX_PRINT2(8,ms);
	
	/* メッセージ長がmlenに満たないときの処理 */
	if (l>0) { /* 後ろにスペースを表示する */
		string(a,' ',l);
		if (md->md_revlen==0) EX_COLOR(col->back);
		EX_PRINT2(8,a);
	}
}

/****************************************************************************/

static void set1w(x,y,all,clm,ltsp,wsp,ms,msatr,mlen,nlen,md,col,sel)
/* メニュー項目：横１行表示 */
/* x,y = in active window */
int x,y,all,clm,ltsp,wsp,msatr[],mlen,nlen,sel;
unchar *ms[];
_MENU_DATA *md;
MCOLORS *col;
{
int i,c;
	for (i=0;i<clm;i++) {
		/* カーソル位置 */
		B_LOCATE(x+i*(mlen+nlen+md->wcol),y);
		
		/* その項目は全体では何番目か */
		c=(ltsp-1)*clm+i+1;
		
		if (c>all) { /* ここは空きメニューである */
			/* 項目が存在しないところは空白を表示する */
			EX_COLOR((sel>0 && i==wsp)? col->nsl_menues:col->non_menues);
			EX_PRINT2(8,mnone);
		} else { /* ここは通常表示 */
			set1(c,(sel>0 && i==wsp)? sel:0 /* この行中に選択中項目がある */
				,ms[c]
				,(md->direct||md->md_spcol||md->md_non)? msatr[c]:0
				,mlen,md,col);
		}
	}
}

/****************************************************************************/
/*	x,y	: メニュー左上座標（テキスト）
	sp 	: 初期セレクトポイント：何行目か（１〜ｎ）
	   	  sp<0のときは-sp=ポイント、rcode[0]=第一入力キー
	wsp	: 初期セレクトポイント：何段目か（０〜ｃｏｌｕｍ−１）
	llt	: 画面上一番左の段の１番目の項目の番号（０〜ａｌｌ−ｎ）
	n  	: １段当たりの画面上での項目数
	all	: 全項目数
	colum	: メニュー横段数
 	ms[]	: メニュー項目
		  ms[0]="" : タイトルはmd.title
		  ms[0]<>"": ms[0]がタイトル
		  メニュー項目は横展開される
	msatr[]	: メニュー項目属性
		  bit0-7 : ダイレクトセレクトキー
		  bit8   : non select
		  bit9   : 特殊色１を使う
		  bit10  : 特殊色２を使う
		  bit11  : nwmenu()にて使用
	md	: メニューデータ
	col	: 色情報
		  mdとcolは本体をｽﾀｯｸに積まないようにするためｱﾄﾞﾚｽ渡しにする
		  ｽﾀｯｸに本体を積むとｽﾀｯｸを多く消費し,ｽﾋﾟｰﾄﾞも低下するのでこれを防ぐためである
	wget	: メニューの下のﾃｷｽﾄ画面を待避するﾜｰｸｴﾘｱ変数のｱﾄﾞﾚｽ
	rcode[MRCODE]: リターン時のメニュー状態情報
		  [0]=return key , [1]=ex , [2]=ey , [3]=ltsp , [4]=sp
		  [5]=cx , [6]=cy , [7]=mouse-x , [8]=mouse-y
		  またsp<0のときは[0]は第一入力キーコードになる
		  選択番号=(ltsp-1)*clm+wp+1
*/
/****************************************************************************/

int wmenu(x,y,sp,wsp,llt,n,all,colum,ms,msatr,md,col,wget,rcode)
int *x,*y,sp,*wsp,*llt,n,all,*colum,msatr[],rcode[MRCODE];
unchar *ms[],*(*wget);
_MENU_DATA *md;
MCOLORS *col;
{
int sx,sy,ex,ey,mlen,nlen,clm,wp,lt,all1,fkey=0,fcur=1,ltsp,ssp;
int asx,asy,aex,aey;
int code[15];
int btn=0,lx,ly,cur,ret,i,ky,c,cx,cy,msc,mcx,mcy,fmouse;
int fwakuonly=0,bline;
int scl,sf=1,fud=0;
unchar *title,*pms,*wbuff;
	/* 枠だけモード */
	if (n==0 || all==0) {
		if (md->wy>0) {
			n=1;
			all=1;
			bline=md->bline; /* blineで枠のみを描くから */
			pms=ms[1];
			ms[1]=" "; /* dummy */
			fwakuonly=1;
		} else return(-10006);
	}
	
	/* 設定 */
	c=EX_COLOR(-1);
	cur=curmode(md->cursor);
	cursor(&lx,&ly); /* cursor save */
	
	/* メモリー節約のため */
	lt=*llt;
	wp=*wsp;
	fmouse=md->mouse&(~BIT7); /* BIT7を消しておく */
	
	/* 色コード記録 */
	Cno[0]=col->no;
	Cno[1]=col->sel_no;
	Cno[2]=col->cr_no;
	Cno[3]=col->no1;
	Cno[4]=col->no2;
	Cno[5]=col->sel_no2;
	Cno[6]=col->cr_no2;
	Cno[7]=col->non_no;
	Cno[8]=col->nsl_no;
	
	Csep[0]=col->sep;
	Csep[1]=col->sel_sep;
	Csep[2]=col->cr_sep;
	Csep[3]=col->sep1;
	Csep[4]=col->sep2;
	Csep[5]=col->sel_sep2;
	Csep[6]=col->cr_sep2;
	Csep[7]=col->non_sep;
	Csep[8]=col->nsl_sep;
	
	Cmn[0]=col->menues;
	Cmn[1]=col->sel_menues;
	Cmn[2]=col->cr_menues;
	Cmn[3]=col->menues1;
	Cmn[4]=col->menues2;
	Cmn[5]=col->sel_menues2;
	Cmn[6]=col->cr_menues2;
	Cmn[7]=col->non_menues;
	Cmn[8]=col->nsl_menues;
	
	/* タイトル置き換え */
	if (ms[0][0]!=0) md->title=ms[0];
	title=md->title;
	
	/* メニュー情報GET */
	mlen=wmenu_width(*x,*y,n,all,*colum,ms,md,code);
	if (mlen<0) { /* parameter error */
		ret=mlen-10000; /* -10001/-10002 */
		goto WEND3;
	}
	sx  =code[0];	sy  =code[1];
	ex  =code[4];	ey  =code[5];
	asx =code[6];	asy =code[7];
	aex =code[8];	aey =code[9];
	n   =code[10];	all =code[11];
	clm =code[12];	all1=code[13];
	nlen=code[14];
	
	/* 項目が無いところに表示する空きパターン */
	string(mnone,' ',mlen+nlen);
	
	/* テンキー移動モード */
	k2=SKt2;
	k4=SKt4;
	k6=SKt6;
	k8=SKt8;
	if (md->num==2) { /* 番号が１〜９でないときはテンキーで操作可能 */
		k2=k4=k6=k8=0;
	}
	
	/* セレクトポイント修正 */
	if (wp>clm-1) wp=clm-1;
	if (sp==0) sp=1;
	if (sp<0) {sp=-sp; fkey=rcode[0];}
	if (lt<0 || wp<0) sp=line_no(n,all1,&lt,sp,&wp,clm);
	
	if (md->remake==0) { /* make menu */
		/* ウインドウ用ワークエリア確保 */
		*wget=gettext2(sx,sy,ex,ey);
		if (*wget==NULL) { /* memory can't get error */
			ret=-10003;
			goto WEND2;
		}
		
		/* ポップアップメニュー */
		if (md->popup) popup3s(sx,sy,ex,ey,col->waku,md->pwait,md->udmode);
		
		/* 枠描画 */
		make_waku(sx,sy,ex,ey,md,col);
		
		if (fwakuonly==1) { /* 枠だけモード */
			md->bline=bline;
			ms[1]=pms;
			ret=0;
			goto WEND2;
		}
		
		/* メッセージモードにおけるカーソル点滅位置 */
		if (md->ms_mode && md->cursor) {
			cx=ex;
			cy=ey;
			if (*md->tale) cursor(&cx,&cy);
		}
		if (fmouse) { /* マウス前回座標初期化 */
			rcode[7]=rcode[8]=-1;
		}
	} else { /* 再表示の時 */
		if (md->ms_mode && md->cursor) {
			/* かつ、メッセージモードでカーソルＯＮのとき */
			cx=rcode[5];
			cy=rcode[6];
		}
	}
	
	/* 項目表示 */
	if (md->remake!=1) { /* 最初または項目再表示モードの時のみ */
		for (i=1;i<=n;i++) {
			set1w(asx,asy+i-1,all,clm,lt+i,wp,ms,msatr,mlen,nlen
					,md,col,md->ms_mode? 0:i==sp);
		}
		kflush(); /* キーボードバッファークリア */
	}
	
	if (fmouse) { /* マウス初期化 */
		if (fmouse==3) { /* マウスカーソル初期設定なし */
		    mcx=MS_CURGT();
		    mcy=mcx&0xffff;
		    mcx>>=16;
		    msc=MS_STAT();
		} else {
		  int cx,cy;
		    if (md->remake==0) {
			cx=(sx+1)*8+4;
			cy=(sy+1)*16+8;
		    } else {
			cx=(asx+(rcode[7]>>16))*8+4;
			cy=(asy+rcode[8])*16+8;
		    }
		    msc=ms_set(&mcx,&mcy,cx,cy,1);
		}
	}
	
	/* スクロール上下記号表示準備 */
	fscroll=0;
	if (all1>n) { /* スクロールあり */
		if (sy+1==ey-1) sf=0; /* n=1のとき */
		wbuff=gettext2(ex,sy+1+sf,ex,sy+1+sf);
		if (wbuff==NULL) {
			ret=-10004;
			free(*wget);
			goto WEND;
		}
		scl=col->scroll;
		if (md->cwaku==5) scl|=REVERSE;
		scl&=(~UDREV); /* 但し上下反転は無効にする */
		/* フォント作成（ベース）*/
		fb1=fb0;
		for (i=0;i<16;i++) fb1.buffer[i]=fb0.buffer[i];
		fontset2(&fb1,scl);
		fb2=fb1; /* これではフォント内容はコピーされない */
		fscroll=1;
	}
	
	/* メイン */
	while (1) { /* 項目選択 */
		/* スクロール上下記号表示 */
		if (all1>n) {
		    int x,y,c;
			cursor(&x,&y);
			c=EX_COLOR(scl);
			if (lt>0) { /* 上向き */
				if (!(fud&BIT0)) {
					SSsub(0,ex,sy+sf);
					fud|=BIT0;
				} /* すでに表示中の時は何もしない */
			} else {
				if (fud&BIT0) { /* 表示していたら消す */
					puttext(ex,sy+sf,wbuff);
					fud&=(~BIT0);
				}
			}
			if (lt<all1-n) { /* 下向き */
				if (!(fud&BIT1)) {
					SSsub(1,ex,ey-sf);
					fud|=BIT1;
				} /* すでに表示中の時は何もしない */
			} else {
				if (fud&BIT1) { /* 表示していたら消す */
					puttext(ex,ey-sf,wbuff);
					fud&=(~BIT1);
				}
			}
			EX_COLOR(c);
			B_LOCATE(x,y);
		}
		
		ltsp=lt+sp;
		ssp=sp;
		
		/* 選択中項目反転表示 */
		if (fcur && !md->ms_mode) {
			set1w(asx,asy+sp-1,all,clm,ltsp,wp,ms,msatr,mlen,nlen,md,col,1);
		}
		if (fcur==2) fkey=SKcr; /* セレクト＆リターン */
		fcur=0;
		
		/* メッセージモード時のカーソル処理 */
		if (md->ms_mode && md->cursor) B_LOCATE(cx,cy);
		
		/* キー入力 */
		if (fkey) {ky=fkey; fkey=0;} /* 第１入力キー */
		else {
		    do {
			if (fmouse) btn=mson();
			ky=inkey2(1,btn);
			if (ky==0 && fmouse) { /* マウス */
				ky=menu_mouse(btn,&sp,&wp,sx,sy,ex,ey,lt,all,mlen+nlen
						,clm,lt>0,lt<all1-n,md,&rcode[7]);
				switch (ky) { /* 特殊操作 */
					case -1: /* move */
						goto WM_MOVE;
					case -2: /* up-scroll */
						ky=DNKEY;
						break;
					case -3: /* down-scroll */
						ky=UPKEY;
						break;
					case 2: /* point move */
						goto OPERATION;
				}
				/* ESC/CRも帰って来る */
			}
		    } while (ky==0);
		}
		
		/* キーごとの処理 */
		for (i=0;i<md->exits;i++) { /* 緊急脱出キー */
			if (keycmp(ky,md->exit[i])) {
				ret=-((ltsp-1)*clm+wp+1); /* リターン値 */
				goto WRETURN;
			}
		}
		
		if ((ky&0xff)==ESC||ky==SKbrk) { /* ESC/BREAK */
			ret=0; /* リターン値 */
			break;
		}
		
		if ((ky&0xff)==CR) { /* 決定 */
			ret=(ltsp-1)*clm+wp+1; /* リターン値 */
			if (ret>all || (md->md_non&&(msatr[ret]&BIT8))) {
				/* 空きメニューのところかnon select menu */
				beep();
				continue;
			}
			/* 決定色に変える */
			if (!md->ms_mode) {
				set1w(asx,asy+ssp-1,all,clm,ltsp,wp,ms,msatr
						,mlen,nlen,md,col,2);
			}
			break;
		}
		
		if (ky==SKtou && CheckMESXY()) { /* 登録：メニュー移動 */
		  int osx,osy,oex,oey,ocx,ocy;
		    WM_MOVE:; /* メニュー移動 */
			osx=asx-sx; osy=asy-sy;
			oex=ex-aex; oey=ey-aey;
			ocx=cx-sx;  ocy=cy-sy;
			ky=move_area(&sx,&sy,&ex,&ey
				,wget,fmouse
				,md->startx,md->starty,md->endx,md->endy);
			if (ky!=-1) { /* move ok => active window area */
				asx=sx+osx; asy=sy+osy;
				aex=ex-oex; aey=ey-oey;
				cx =sx+ocx; cy =sy+ocy;
			} else beep(); /* can't move */
			continue;
		}
		
		/* cursor key move */
		ret=key_play(ky,n,all,all1,&lt,&sp,&wp,clm,md);
		if (ret>10000) break; /* exit at top/last */
		
		if (ret==0 && !md->ms_mode) {
			/* direct key move */
			ret=jump_key(ky,n,all,all1,&lt,&sp,&wp,clm,msatr
					,md->direct,md->num,md->num0);
			if (ret && md->direct==2) fcur=2; /* direct select & return */
		}
		
		switch (ret) { /* opepation */
			case 2:/* point move in active window */
			    OPERATION:;
				/* 元のところをselect中でないにする */
				set1w(asx,asy+ssp-1,all,clm,ltsp,0,ms,msatr,mlen,nlen
						,md,col,0);
			case 11:/* point move in this line */
				if (fcur==0) fcur=1;
			case 1:/* operation disable */
				continue;
				
			case 3:/* scroll up   (sp not move) */
			case 4:/* scroll down (sp not move) */
				if (fcur==0) fcur=1;
				if (n>1) { /* nが1のときは何もしない */
					/* 元のところをselect中でないにする */
					set1w(asx,asy+ssp-1,all,clm,ltsp,0,ms,msatr,mlen,nlen
							,md,col,0);
					EX_COLOR(col->back);
					text_scroll(asx,asy,aex,aey,1,(ret==4)+md->scroll);
				}
				continue;
				
			case  7:/* scroll up   (sp move) */
			case  8:/* scroll down (sp move) */
			case  9:/* scroll up   (sp move at sp=1) */
			case 10:/* scroll down (sp move at sp=n) */
				if (n==1) { /* nが1のときは何もしない */
					if (fcur==0) fcur=1;
					continue;
				}
				EX_COLOR(col->back);
				i=(ret==8||ret==10);
				text_scroll(asx,asy,aex,aey,1,i+md->scroll);
				/* 一番上下の行を入れる */
				ltsp=lt+(i? 1:n);
				set1w(asx,asy+(i? 0:n-1),all,clm,ltsp,0,ms,msatr,mlen,nlen
							,md,col,0);
				if (ret==9 || ret==10) {
				    	if (fcur==0) fcur=1;
				}
				continue;
				
			case 5:/* all window remake */
				for (i=1;i<=n;i++) {
					set1w(asx,asy+i-1,all,clm,lt+i,wp,ms,msatr,mlen,nlen
						,md,col,md->ms_mode? 0:i==sp);
				}
				continue;
		}
	}
	
    WRETURN: /* リターン */
	if (ret<=10000 && md->popdown) { /* menu close */
		if (!(md->popdown==1 && ret!=0)) {
			/* ESC onlyのときにESCでなかった場合を除く */
			popdown3s(sx,sy,ex,ey,col->waku,md->pwait,md->udmode);
			/* under window put */
			puttext(sx,sy,*wget);
		}
	} /* exit at top/lastの時はクローズしない */
	if (all1>n) free(wbuff);
	
    WEND:; /* 後処理 */
	if (fmouse==1) ms_reset(msc,mcx,mcy); /* マウス後処理 */
    WEND2:;
	/* 座標渡し */
	*x=sx;
	*y=sy;
	*llt=lt;
	*wsp=wp;
	*colum=clm;
	
	/* status */
	rcode[0]=ky;
	rcode[1]=ex;	rcode[2]=ey;
	rcode[3]=ltsp;
	rcode[4]=sp;
	rcode[5]=cx;	rcode[6]=cy;
	
    WEND3:;
	md->title=title;
	EX_COLOR(c);
	B_LOCATE(lx,ly);
	curmode(cur);
	return(ret);
}

/****************************************************************************/
