/*
    Wind Consol
*/
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    <mos.h>
#include    "defs.h"
#include    "event.h"
#include    "graphic.h"
#include    "msg.h"
#include    "buff.h"
#include    "coldef.h"
#include    "wind.h"

#define	unlink(f) remove(f)

#define	FONT_SIZ	16
#define	TAB		8
#define	CUR_COL		8

/********
#define	TERM		0
*********/

#define	W_NAME_X	4
#define	W_UP_X		50
#define	W_DOWN_X	(W_UP_X+24)
#define	W_UPLOAD_X	(W_DOWN_X+32)
#define	W_MENU_X	(W_UPLOAD_X+64)
#define	W_DIAL_X	(W_MENU_X+44)
#define	W_DOWNLD_X	(W_DIAL_X+44)
#define	W_CHILD_X	400
#define	W_SECRET_X	520
#define	W_MOVE_X	600

void	WIN_resize(void);
void	WIN_open(int no);
void	WIN_act_cheng(int no);
char	*read_line(char tmp[],FILE *fp);
char	*strdup(char *str);
void	WIN_upload(int no);
char	*secret_file();
int	iskan(char *str);
void	DSP_xline();
int	secret_chk(char *file);
void	RSB_putc(int ch);
int	RSB_chk(void);
int	RSB_getc(void);
void	cputstr();
int	kbhit();
int	getkey(unsigned *ec);
int	macval(char *mac);
void	macvalset(char *mac,int val);
void	macset(char *mac,char *str);
void	KAN_touroku(int len,char *tango);
void	MEMO_insrt(int no,int ch);
int	EDIT_KEY_chk(int code);
int	EDIT_KEY_exec(int code,int no);
int	TERM_KEY_exec(int code);
int	LIN_buf_pos(void);
void	LIN_buf_dsp(void);
void	LIN_buf_flush(void);
void	LIN_input(int ch);
void	eof_chk(FILE *fp);
void	KEY_line_top(void);

extern int	key_flg;

       int	TERM=0;
       int	lin_new_flg=FALSE;
       int	act_wind=0;
       WIND	win[MAX_WIND];
static int	bak_ins_mode=TRUE;
static int	cur_dsp_flg=FALSE;
static int	cur_dsp_ptn=0;
static int	cur_dsp_col=15;
static int	cur_wind=ERR;
static int	wind_count=0;
static int	up_memo=ERR;
static int	up_wind=ERR;
static int	up_child=ERR;
static FILE	*down_fp=NULL;
static int	log_max=1000;
static int	scl_flg=FALSE;
static int	lin_flg=FALSE;
static char     *memo_buf=NULL;
static int	memo_ptr=ERR;
static char	undo[120];

static char	*win_name[]={ "MIKE","JOHN","KENT" };
static char *child_name[]={
	"\x1B\xE8","\x1B\xE9","\x1B\xEA","\x1B\xEB","\x1B\xEC" };
static int      wind_col[MAX_WIND]={ COL_MIKE,COL_JOHN,COL_KENT };
static int      wind_col2[MAX_WIND]={ COL_MIKE2,COL_JOHN2,COL_KENT2 };
static struct {
    struct {
	short	top,siz;
    } w[MAX_WIND];
} win_tbl[MAX_WIND+1];

int	kan_pos(char *p,int n)
{
    int     i;

    for ( i = n ; i > 0 ; ) {
	if ( *p == '\0' ) {
	    return (n - i);

	} else if ( iskan(p) ) {
	    i -= 2;
	    p += 2;

	} else {
	    i--;
	    p++;
	}
    }
    return (n + i);
}
void	WIN_cursol(int no,int x,int y)
{
    int     sz;
    static int bak_x=0,bak_y=0,bak_sz=0;
    static char cur_ptn[][16]={
	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,
        0x00,0x08,0x08,0x1c,0x3e,0x7f,0x7f,0x7f,
        0x7f,0x2a,0x08,0x1c,0x3e,0x00,0x00,0x00,
        0x00,0x22,0x22,0x77,0x7f,0x7f,0x7f,0x7f,
        0x3e,0x3e,0x1c,0x1c,0x08,0x00,0x00,0x00,
        0x00,0x08,0x1c,0x1c,0x3e,0x3e,0x7f,0x7f,
        0x3e,0x3e,0x1c,0x1c,0x08,0x00,0x00,0x00,
        0x00,0x08,0x1c,0x1c,0x1c,0x08,0x6b,0x7f,
        0x7f,0x6b,0x08,0x1c,0x3e,0x00,0x00,0x00,
        0x00,0x00,0x18,0x3c,0x3c,0x7e,0x7e,0x7e,
        0x7e,0x7e,0x3c,0x3c,0x18,0x00,0x00,0x00,
        0x00,0x00,0x18,0x24,0x24,0x42,0x42,0x42,
        0x42,0x42,0x24,0x24,0x18,0x00,0x00,0x00 };

    sz = cur_dsp_ptn + (win[no].ins_mode == FALSE ? 0:1);
    if ( cur_wind != ERR ) {
	if ( x == bak_x && y == bak_y && sz == bak_sz )
	    return;
        MOS_disp(FALSE);
	DSP_putptn(cur_ptn[bak_sz],bak_x,bak_y,cur_dsp_col,4);
	MOS_disp(TRUE);
    }

    if ( cur_dsp_flg == FALSE ) {
	bak_sz = sz;
	bak_x = x;
	bak_y = y;
        MOS_disp(FALSE);
	DSP_putptn(cur_ptn[bak_sz],bak_x,bak_y,cur_dsp_col,4);
	cur_wind = no;
	MOS_disp(TRUE);
    }
}
void	WIN_dsp_pause(int no,int sw)
{
    DSP_string( no == TERM ? "PAUSE":"UPLOAD",
		W_UPLOAD_X+2,win[no].wind_y+4,
		sw == FALSE ? wind_col2[no]:COL_RED,win[no].color);
}
void	WIN_dsp_down(int sw)
{
    DSP_string( "DOWN",W_DOWNLD_X+2,win[TERM].wind_y+4,
		sw == FALSE ? wind_col2[TERM]:COL_RED,win[TERM].color);
}
void	WIN_dsp_secret(int no,int sw)
{
    DSP_string("SECRET",
		W_SECRET_X+2,win[no].wind_y+4,
		sw == FALSE ? wind_col2[no]:COL_RED,win[no].color);
}
void	WIN_dsp_buf(int no)
{
    int     i,n,y,fg=FALSE;
    WIND    *wp;
    register CHI_PTR *cp;
    register LIN_PTR *lp;
    char    *p,bch;
    char    tmp[92];

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    wp->wrt_mode = 0;

    if ( cp->cur_y >= wp->max_y )
	cp->cur_y = wp->max_y - 1;

    if ( (n = cp->now_ptr) != ERR ) {
	lp = get_lin(n);
	if ( lp->left == ERR )
	    cp->cur_y = wp->max_y - 1;
    }

    for ( i = cp->cur_y ; i > 0 && n != ERR ; i-- ) {
	lp = get_lin(n);
	if ( lp->right == ERR )
	    break;
	n = lp->right;
    }

    p = strcpy(tmp,"[EOF]");
    y = wp->wind_y + 16;
    for ( i = 0 ; i < wp->max_y ; i++ ) {
	if ( n != ERR ) {
	    if ( n == cp->now_ptr )
		cp->cur_y = i;
	    lp = get_lin(n);
	    if ( no != TERM && 
		 lp->left == ERR && strchr(lp->lin,'\n') == NULL ) {
		strcpy(tmp,lp->lin);
		strcat(tmp,"[EOF]");
		if ( strlen(tmp) > 80 ) {
		    bch = tmp[80];
		    tmp[80] = '\0';
	            putstr(y*512,tmp);
		    tmp[80] = bch;
		    p = &(tmp[80]);
		} else {
		    fg = TRUE;
	            putstr(y*512,tmp);
		}
	    } else
	        putstr(y*512,lp->lin);
	    n = lp->left;
	} else if ( no != TERM && fg == FALSE ) {
	    fg = TRUE;
	    putstr(y*512,p);
	} else
	    putstr(y*512,"");
	y += FONT_SIZ;
    }

    if ( no == cur_wind )
        cur_wind = ERR;
}

void	WIN_dsp_now(int no)
{
    int     y;
    WIND    *wp;
    register CHI_PTR *cp;
    register LIN_PTR *lp;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    wp->wrt_mode = 0;

    if ( cp->cur_y >= wp->max_y ) {
	cp->cur_y = wp->max_y - 1;
	WIN_dsp_buf(no);
	return;
    }

    if ( cp->now_ptr == ERR )
	return;

    lp = get_lin(cp->now_ptr);

    if ( lp->left == ERR ) {
	WIN_dsp_buf(no);
	return;
    }

    y = wp->wind_y + 16 + cp->cur_y * FONT_SIZ;
    putstr(y*512,lp->lin);

    if ( cur_wind == no )
	cur_wind = ERR;
}

int	WIN_down_scrool(int no,int count)
{
    int     fg=ERR;
    WIND    *wp;
    register CHI_PTR *cp;
    register LIN_PTR *lp;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return ERR;
    lp = get_lin(cp->now_ptr);
    if ( lp->left == ERR )
	return ERR;

    while ( count-- > 0 ) {
	cp->now_ptr = lp->left;
	cp->lin_pos++;
	if ( ++cp->cur_y >= wp->max_y ) {
	    cp->cur_y = wp->max_y - 1;
	    fg = FALSE;
	}
	lp = get_lin(cp->now_ptr);
	if ( lp->left == ERR ) {
	    if ( no == TERM && cp->pas_flg != FALSE ) {
		MOS_disp(FALSE);
		WIN_dsp_pause(no,FALSE);
		MOS_disp(TRUE);
		cp->pas_flg = FALSE;
	    }
	    break;
	}
    }
    return fg;
}

int	WIN_up_scrool(int no,int count)
{
    int     fg=ERR;
    WIND    *wp;
    register CHI_PTR *cp;
    register LIN_PTR *lp;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);

    if ( cp->now_ptr == ERR )
	return ERR;

    lp = get_lin(cp->now_ptr);
    if ( lp->right == ERR )
	return ERR;

    if ( no == TERM && cp->pas_flg == FALSE ) {
	MOS_disp(FALSE);
	WIN_dsp_pause(no,TRUE);
	MOS_disp(TRUE);
	cp->pas_flg = TRUE;
    }

    while ( count-- > 0 ) {
	cp->now_ptr = lp->right;
	cp->lin_pos--;
	if ( --cp->cur_y < 0 ) {
	    cp->cur_y = 0;
	    fg = FALSE;
	}
	lp = get_lin(cp->now_ptr);
	if ( lp->right == ERR )
	    break;
    }
    return fg;
}

int	WIN_read_file(int no,int ch,char *org_file,int sw)
{
    int     i,n,ct;
    int     sec_flg=FALSE;
    FILE    *fp;
    CHI_PTR *cp;
    register LIN_PTR *lp;
    LIN_PTR tp;
    char    *file;

    file = org_file;

    if ( secret_chk(file) ) {
	if ( sw == FALSE )
	    return TRUE;
	if ( (file = secret_file(org_file)) == NULL )
	    return ERR;
	sec_flg = TRUE;
    }

    if ( (fp = fopen(file,"r")) == NULL )
	return ERR;

    lp = &tp;
    n = lp->left = ERR;
    ct = 0;
    while ( read_line(tp.lin,fp) != NULL ) {
	i = lp->left = xalloc();
	lp = get_lin(lp->left);
	lp->right = n;
	n = i;
	strcpy(lp->lin,tp.lin);
	ct++;
    }
    fclose(fp);

    if ( sec_flg != FALSE )
	unlink(file);

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;
    cp = &(win[no].child[ch]);

    if ( cp->file_name == NULL ) {
	cp->file_name = strdup(org_file);
        cp->sec_flg = sec_flg;
    }

    if ( tp.left == ERR )
	return FALSE;

    if ( cp->now_ptr == ERR ) {
	cp->wrt_flg = FALSE;
	cp->now_ptr = lp->left = xalloc();
	cp->top_ptr = ERR;
	lp = get_lin(cp->now_ptr);
	lp->right = n;
	lp->lin[0] = '\0';
	ct++;

    } else {
	cp->wrt_flg = TRUE;
	lp = get_lin(cp->now_ptr);
	if ( (i = lp->right) != ERR ) {
	    lp = get_lin(i);
	    lp->left = tp.left;
	    lp = get_lin(tp.left);
	    lp->right = i;
	} else
	    cp->top_ptr = ERR;

	lp = get_lin(n);
	lp->left = cp->now_ptr;
	lp = get_lin(cp->now_ptr);
	lp->right = n;
    }

    cp->lin_max += ct;
    cp->lin_pos += ct;

    if ( ct > win[no].max_y )
	cp->cur_y = win[no].max_y / 2;
    else
	cp->cur_y = ct - 1;

    return FALSE;
}
int	WIN_type(int no,int ch)
{
    int     i,j,n,y;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    char    tmp[120];
    static BLOCK *save=NULL;

    if ( no == 999 ) {
	DSP_pop_vram(save);
	save = NULL;
	return FALSE;
    }

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;
    wp = &(win[no]);
    cp = &(wp->child[ch]);

    if ( cp->now_ptr == ERR )
	return ERR;

    if ( cp->top_ptr == ERR ) {
	n = cp->now_ptr;
	while ( n != ERR ) {
	    cp->top_ptr = n;
	    lp = get_lin(n);
	    n = lp->right;
	}
    }

    if ( (j = macval("TYPELINE")) <= 0 )
	j = 8;
    y = 28 - j;

    if ( save == NULL )
        save = DSP_push_vram(0,y*16,639,463);

    sprintf(tmp,"%s %s %s",win_name[no],child_name[ch],
	cp->file_name == NULL ? "":cp->file_name);

    i = 320 - strlen(tmp) * 4;
    DSP_box(0,y*16,639,y*16+15,COL_LINE,wind_col[no]);
    DSP_string(tmp,i,y*16+4,wind_col2[no],wind_col[no]);

    n = cp->top_ptr;

    for ( i = 0 ; i < j && n != ERR ; i++ ) {
	lp = get_lin(n);
	putstr((i+y+1)*16*512,lp->lin);
	n = lp->left;
    }
    for ( ; i < j ; i++ )
	putstr((i+y+1)*16*512,"");

    return FALSE;
}
char	*WIN_file_chk(int no,int ch)
{
    CHI_PTR *cp;

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;

    cp = &(win[no].child[ch]);
    return cp->file_name;
}
char	*WIN_get_line(int no,int ch)
{
    CHI_PTR *cp;
    LIN_PTR *lp;

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;

    cp = &(win[no].child[ch]);
    if ( cp->now_ptr == ERR )
	return "";
    lp = get_lin(cp->now_ptr);
    return lp->lin;
}
int	WIN_secret_chk(int no,int ch)
{
    CHI_PTR *cp;

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;

    cp = &(win[no].child[ch]);
    return cp->sec_flg;
}
int	WIN_write_chk(int no,int ch)
{
    CHI_PTR *cp;

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;

    cp = &(win[no].child[ch]);
    return cp->wrt_flg;
}
int	WIN_write_file(int no,int ch,char *file,int sw)
{
    int     n,fg=FALSE;
    FILE    *fp;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    char    *p;

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;

    wp = &(win[no]);
    cp = &(wp->child[ch]);

    if ( cp->now_ptr == ERR )
	return ERR;

    if ( sw != 0 ) {
	if ( secret_chk(file) ) {
	    if ( sw == 1 )
		return TRUE;
	    if ( (p = secret_file(file)) == NULL )
		return ERR;
	    fg = TRUE;
	} else
	    p = file;
	if ( (fp = fopen(p,"r+")) == NULL )
	    return ERR;
	eof_chk(fp);

    } else if ( (fp = fopen(file,"w")) == NULL )
	return ERR;

    n = cp->now_ptr;
    while ( n != ERR ) {
	cp->top_ptr = n;
	lp = get_lin(n);
	n = lp->right;
    }

    for ( n = cp->top_ptr ; n != ERR ; ) {
	lp = get_lin(n);
	fputs(lp->lin,fp);
	n = lp->left;
    }
    fclose(fp);

    if ( fg != FALSE ) {
	unlink(file);
	rename(p,file);
    }

    cp->wrt_flg = FALSE;
    return FALSE;
}
int	WIN_top_ptr(int no)
{
    int     i,n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);

    if ( cp->top_ptr != ERR )
	return cp->top_ptr;

    i = 0;
    n = cp->now_ptr;
    while ( n != ERR ) {
	cp->top_ptr = n;
	lp = get_lin(n);
	n = lp->right;
	i++;
    }
    cp->lin_pos = i;
    return cp->top_ptr;
}
void    WIN_puts(no,str)
int     no;
char    *str;
{
    int     i,j,n,fg;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    LIN_PTR *tp;
    char    *p,*s;
    char    tmp[162];

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    cp->wrt_flg = TRUE;
    if ( cp->now_ptr == ERR ) {
        cp->now_ptr = xalloc();
        lp = get_lin(cp->now_ptr);
        lp->lin[0] = '\0';
	cp->lin_max++;
	wp->wrt_mode = 3;
	cp->top_ptr = ERR;
    }
    lp = get_lin(cp->now_ptr);

    s = lp->lin;
    p = tmp;

    n = cp->cur_x;
    while ( n-- > 0 ) {
        if ( *s == '\n' || *s == '\0' )
            *(p++) = ' ';
        else if ( iskan(s) ) {
            if ( n > 0 ) {
                *(p++) = *(s++);
                *(p++) = *(s++);
                n--;
            } else if ( !wp->ins_mode ) {
		*(s++) = ' ';
		*s = ' ';
                *(p++) = ' ';
            } else
                cp->cur_x--;
         } else
            *(p++) = *(s++);
    }

    while ( *str != '\0' ) {
        *(p++) = *(str++);
        cp->cur_x++;
        if ( !wp->ins_mode ) {
            if ( iskan(s) ) {
                *(s++) = ' ';
                *s = ' ';
            } else if ( *s != '\n' && *s != '\0' )
                *(s++) = ' ';
        }
    }

    while ( *s != '\0' )
        *(p++) = *(s++);

    *p = '\0';

    if ( strlen(tmp) >= 80 ) {
        n = 0;
        s = tmp;
        p = lp->lin;
        while ( n < 80 && *s != '\0' ) {
            if ( iskan(s) ) {
                if ( n == 79 )
                    break;
                *(p++) = *(s++);
                *(p++) = *(s++);
                n += 2;
            } else {
                *(p++) = *(s++);
                n++;
            }
        }
        *p = '\0';

        if ( cp->cur_x >= n ) {
            cp->cur_x -= n;
            if ( ++cp->cur_y >= wp->max_y )
                cp->cur_y = wp->max_y - 1;
            fg = TRUE;
        } else
            fg = FALSE;

        if ( (p = strchr(s,'\n')) != NULL || lp->left == ERR ) {
            n = xalloc();
            tp = get_lin(n);
            tp->right = cp->now_ptr;
            tp->left = lp->left;
            lp->left = n;
            if ( tp->left != ERR ) {
                lp = get_lin(tp->left);
                lp->right = n;
                lp = get_lin(cp->now_ptr);
            }
            strcpy(tp->lin,s);
	    cp->lin_max++;

        } else {
	    i = cp->now_ptr;
            cp->now_ptr = lp->left;
            n = cp->cur_x;
            cp->cur_x = 0;
	    j = cp->lin_pos;
            WIN_puts(no,s);
	    cp->now_ptr = i;
            cp->cur_x = n;
	    cp->lin_pos = j;
        }

        if ( fg ) {
            cp->now_ptr = lp->left;
	    cp->lin_pos++;
	}

        if ( wp->wrt_mode < 3 )
            wp->wrt_mode = 3;

    } else {
        strcpy(lp->lin,tmp);

        if ( wp->wrt_mode < 2 )
            wp->wrt_mode = 2;
    }
}

void    WIN_ins_line(no)
int     no;
{
    int     n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    LIN_PTR *tp;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    cp->wrt_flg = TRUE;
    if ( cp->now_ptr == ERR ) {
        cp->now_ptr = xalloc();
        lp = get_lin(cp->now_ptr);
        lp->lin[0] = '\0';
	cp->lin_max++;
	wp->wrt_mode = 3;
	cp->top_ptr = ERR;
    }

    lp = get_lin(cp->now_ptr);
    n = xalloc();
    tp = get_lin(n);
    tp->lin[0] = '\0';

    tp->right = cp->now_ptr;
    tp->left = lp->left;
    lp->left = n;
    if ( tp->left != ERR ) {
	strcpy(tp->lin,"\n");
        lp = get_lin(tp->left);
        lp->right = n;
    } else if ( strchr(lp->lin,'\n') == NULL )
	strcat(lp->lin,"\n");

    cp->lin_max++;
    wp->wrt_mode = 3;
}
void	WIN_putc(int no,int ch)
{
    int     i,n;
    WIND    *wp;
    register CHI_PTR *cp;
    register LIN_PTR *lp;
    char    tmp[TAB+1];

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr != ERR )
	lp = get_lin(cp->now_ptr);

    if ( cp->bak_cod != '\0' ) {
	tmp[0] = cp->bak_cod;
	cp->bak_cod = '\0';
	if ( iskanji2(ch) ) {
	    tmp[1] = ch;
	    tmp[2] = '\0';
	    WIN_puts(no,tmp);
	    return;
	} else {
	    tmp[1] = '\0';
	    WIN_puts(no,tmp);
	}
    }

    switch(ch) {
    case '\x0D':
	cp->cur_x = 0;
	break;

    case '\x0A':
	if ( cp->now_ptr != ERR ) {
	    macset("PARA",lp->lin);
	    MSG_wind("line_chk");
	}
	if ( cp->now_ptr == ERR || lp->left == ERR || wp->ins_mode )
	    WIN_ins_line(no);
	if ( down_fp != NULL )
	    fputs(lp->lin,down_fp);
	if ( WIN_down_scrool(no,1) != ERR )
	    wp->wrt_mode = 3;

	if ( log_max > 5000 )
	    break;

	WIN_top_ptr(no);
	while ( cp->lin_max >= log_max ) {
	    if ( cp->top_ptr == ERR || cp->top_ptr == cp->now_ptr )
		break;
	    lp = get_lin(cp->top_ptr);
	    if ( (n = lp->left) == ERR )
		break;
	    xfree(cp->top_ptr);
	    cp->top_ptr = n;
	    cp->lin_max--;
	}
	if ( cp->top_ptr != ERR ) {
	    lp = get_lin(cp->top_ptr);
	    lp->right = ERR;
	}
	break;

    case '\x09':
	n = TAB - (cp->cur_x % TAB);
	for ( i = 0 ; i < n ; i++ )
	    tmp[i] = ' ';
	tmp[i] = '\0';
	WIN_puts(no,tmp);
	break;

    case '\x08':
	if ( cp->cur_x > 0 )
	    cp->cur_x--;
	else {
	    cp->cur_x = 79;
	    if ( cur_y > 0 )
		cp->cur_y--;
	    if ( cp->now_ptr != ERR && lp->right != ERR ) {
		cp->now_ptr = lp->right;
		cp->lin_pos--;
	    }
	}
	break;

    case '\x07':
	MSG_wind("beep");
	break;

    default:
	if ( iskanji(ch) )
	    cp->bak_cod = ch;
	else if ( ch != '\0' ) {
	    tmp[0] = ch;
	    tmp[1] = '\0';
	    WIN_puts(no,tmp);
	}
	break;
    }
}
int	WIN_flush(int no)
{
    WIND    *wp;

    wp = &(win[no]);
    if ( wp->open_flg == FALSE )
	return FALSE;

    switch(wp->wrt_mode) {
    case 0:
    case 1:
	return FALSE;

    case 2:
	MOS_disp(FALSE);
	WIN_dsp_now(no);
	MOS_disp(TRUE);
	break;

    case 3:
	MOS_disp(FALSE);
	WIN_dsp_buf(no);
	MOS_disp(TRUE);
	break;
    }

    return TRUE;
}
void	TERM_pause_abort(void)
{
    register WIND    *wp;
    register CHI_PTR *cp;
    LIN_PTR  *lp;

    wp = &(win[TERM]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr != ERR ) {
	do {
	    WIN_down_scrool(TERM,9999);
	    wp->wrt_mode = 3;
	    lp = get_lin(cp->now_ptr);
	} while ( lp->left != ERR );
    }
}
void	DEL_line(void)
{
    int     n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    LIN_PTR *tp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( (n = cp->now_ptr) == ERR )
	return;
    cp->wrt_flg = TRUE;
    lp = get_lin(cp->now_ptr);

    if ( lp->left != ERR ) {
	strcpy(undo,lp->lin);
	tp = get_lin(lp->left);
	tp->right = lp->right;
	if ( lp->right != ERR ) {
	    tp = get_lin(lp->right);
	    tp->left = lp->left;
	} else
	    cp->top_ptr = ERR;
	cp->now_ptr = lp->left;
	xfree(n);
	cp->lin_max--;
	wp->wrt_mode = 3;

    } else if ( lp->right != ERR ) {
	lp->lin[0] = '\0';
	wp->wrt_mode = 3;
	
    } else {
	xfree(cp->now_ptr);
	cp->top_ptr = cp->now_ptr = ERR;
	cp->lin_max = 0;
	cp->lin_pos = 0;
	wp->wrt_mode = 3;
    }
}

void	WIN_merge(void)
{
    int     n,now,nxt;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    LIN_PTR *tp;
    char    *p,*s;
    char    tmp[162];

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( (now = cp->now_ptr) == ERR )
	return;

LOOP:
    lp = get_lin(now);
    if ( (nxt = lp->left) == ERR )
	return;

    tp = get_lin(nxt);
    strcpy(tmp,lp->lin);
    for ( p = tmp ; *p != '\n' && *p != '\0' ; p++ );
    strcpy(p,tp->lin);

    if ( strlen(tmp) < 80 ) {
	strcpy(lp->lin,tmp);
	lp->left = tp->left;
	if ( tp->left != ERR ) {
	    tp = get_lin(tp->left);
	    tp->right = now;
	}
	xfree(nxt);
	cp->lin_max--;

    } else {
        n = 0;
        s = tmp;
        p = lp->lin;
        while ( n < 80 && *s != '\0' ) {
            if ( iskan(s) ) {
                if ( n == 79 )
                    break;
                *(p++) = *(s++);
                *(p++) = *(s++);
                n += 2;
            } else {
                *(p++) = *(s++);
                n++;
            }
        }
        *p = '\0';
	strcpy(tp->lin,s);
	lp = tp;
	now = nxt;
    }

    wp->wrt_mode = 3;

    if ( strchr(lp->lin,'\n') == NULL )
	goto LOOP;
}

void	KEY_cr(void)
{
    int     n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    LIN_PTR *tp;
    char    *p;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    cp->wrt_flg = TRUE;
    if ( cp->now_ptr == ERR ) {
        cp->now_ptr = xalloc();
        lp = get_lin(cp->now_ptr);
        lp->lin[0] = '\0';
	cp->lin_max++;
	wp->wrt_mode = 3;
    }

    if ( wp->ins_mode == FALSE ) {
	cp->cur_x = 0;
	lp = get_lin(cp->now_ptr);
	if ( lp->left == ERR )
	    WIN_ins_line(act_wind);
	if ( WIN_down_scrool(act_wind,1) != ERR )
	    wp->wrt_mode = 3;
	return;
    }

    WIN_ins_line(act_wind);
    lp = get_lin(cp->now_ptr);
    tp = get_lin(lp->left);

    p = lp->lin;
    for ( n = 0 ; n < cp->cur_x ; ) {
	if ( *p == '\n' || *p == '\0' )
	    break;
	else if ( iskan(p) ) {
	    if ( (n += 2) > cp->cur_x )
		break;
	    p += 2;
	} else {
	    p++;
	    n++;
	}
    }

    if ( *p != '\n' ) {
	strcpy(tp->lin,p);
	strcpy(p,"\n");
    }

    cp->cur_x = 0;
    WIN_down_scrool(act_wind,1);
    lp = get_lin(cp->now_ptr);
    if ( strchr(lp->lin,'\n') == NULL )
	WIN_merge();
}
void	KEY_del(void)
{
    int     n,fg=FALSE;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    char    *p,*s;
    char    tmp[82];

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;

    cp->wrt_flg = TRUE;
    lp = get_lin(cp->now_ptr);

    s = lp->lin;
    p = tmp;
    n = cp->cur_x;

    while ( n-- > 0 ) {
        if ( *s == '\n' || *s == '\0' )
            *(p++) = ' ';
        else if ( iskan(s) ) {
            if ( n > 0 ) {
                *(p++) = *(s++);
                *(p++) = *(s++);
                n--;
            } else
                cp->cur_x--;
         } else
            *(p++) = *(s++);
    }

    if ( iskan(s) )
	s += 2;
    else if ( *s != '\n' && *s != '\0' )
	s++;
    else
	fg = TRUE;

    while ( *s != '\0' )
        *(p++) = *(s++);

    *p = '\0';

    strcpy(lp->lin,tmp);

    if ( tmp[0] == '\n' && lp->left == ERR && lp->right == ERR )
	DEL_line();

    else if ( fg != FALSE || strchr(lp->lin,'\n') == NULL )
	WIN_merge();

    if ( wp->wrt_mode < 2 )
	wp->wrt_mode = 2;
}
void	KEY_del_left(void)
{
    int     n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;

    lp = get_lin(cp->now_ptr);
    if ( cp->cur_x >= strlen(lp->lin) )
	return;

    cp->wrt_flg = TRUE;
    n = kan_pos(lp->lin,cp->cur_x);
    if ( strchr(lp->lin,'\n') == NULL ) {
	lp->lin[n] = '\0';
	WIN_merge();
	wp->wrt_mode = 3;

    } else {
	lp->lin[n++] = '\n';
	lp->lin[n] = '\0';
        if ( wp->wrt_mode < 2 )
	    wp->wrt_mode = 2;
    }
}
void	KEY_del_right(void)
{
    int     n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;

    lp = get_lin(cp->now_ptr);
    if ( cp->cur_x == 0 )
	return;

    cp->wrt_flg = TRUE;
    for ( n = 0 ; n < cp->cur_x ; ) {
	if ( lp->lin[n] == '\n' || lp->lin[n] == '\0' )
	    break;
	else if ( iskan(&(lp->lin[n])) )
	    n += 2;
	else
	    n++;
    }

    cp->cur_x = 0;
    strcpy(lp->lin,&(lp->lin[n]));
    if ( strchr(lp->lin,'\n') == NULL ) {
	WIN_merge();
	wp->wrt_mode = 3;
    } else if ( wp->wrt_mode < 2 )
	wp->wrt_mode = 2;
}
void	INS_line(void)
{
    WIN_ins_line(act_wind);
    WIN_down_scrool(act_wind,1);
    KEY_line_top();
}
void	KEY_undo(void)
{
    int     n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    LIN_PTR *tp;
    LIN_PTR *bp;

    if ( undo[0] == '\0' )
	return;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);

    if ( cp->now_ptr == ERR ) {
        cp->now_ptr = xalloc();
        lp = get_lin(cp->now_ptr);
        lp->lin[0] = '\0';
	cp->lin_max = 1;
	cp->lin_pos = 0;
	cp->top_ptr = ERR;
    }

    n = xalloc();
    tp = get_lin(n);
    strcpy(tp->lin,undo);

    lp = get_lin(cp->now_ptr);
    if ( (tp->right = lp->right) != ERR ) {
	bp = get_lin(tp->right);
	bp->left = n;
    } else
	cp->top_ptr = ERR;

    lp->right = n;
    tp->left = cp->now_ptr;
    cp->now_ptr = n;

    wp->wrt_mode = 3;
    cp->lin_max++;
    cp->wrt_flg = FALSE;
}
void	KEY_tab(void)
{
    WIN_putc(act_wind,0x09);
}
void	KEY_up(void)
{
    if ( WIN_up_scrool(act_wind,1) != ERR )
	win[act_wind].wrt_mode = 3;
}
void	KEY_down(void)
{
    if ( WIN_down_scrool(act_wind,1) != ERR )
	win[act_wind].wrt_mode = 3;
}
void	KEY_scr_up(void)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;
    lp = get_lin(cp->now_ptr);
    if ( lp->left == ERR )
	return;
    cp->now_ptr = lp->left;
    cp->lin_pos++;
    wp->wrt_mode = 3;
}
void	KEY_scr_down(void)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;
    lp = get_lin(cp->now_ptr);
    if ( lp->right == ERR )
	return;
    cp->now_ptr = lp->right;
    cp->lin_pos--;
    wp->wrt_mode = 3;
}
void	KEY_page_up(void)
{
    if ( WIN_up_scrool(act_wind,10) != ERR )
	win[act_wind].wrt_mode = 3;
}
void	KEY_page_down(void)
{
    if ( WIN_down_scrool(act_wind,10) != ERR )
	win[act_wind].wrt_mode = 3;
}
void	KEY_left(void)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    char    *p;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( --cp->cur_x < 0 ) {
	KEY_up();
	if ( cp->now_ptr != ERR ) {
	    lp = get_lin(cp->now_ptr);
	    cp->cur_x = 0;
	    for ( p = lp->lin ; *p != '\n' && *p != '\0' ; p++ )
	        cp->cur_x++;
	    if ( cp->cur_x >= 80 )
		cp->cur_x = 79;
	} else
	    cp->cur_x = 79;

    } else if ( cp->now_ptr != ERR ) {
	lp = get_lin(cp->now_ptr);
	if ( cp->cur_x < strlen(lp->lin) )
	    cp->cur_x = kan_pos(lp->lin,cp->cur_x);
    }
}
void	KEY_right(void)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( ++cp->cur_x >= 80 ) {
	cp->cur_x = 0;
	KEY_down();
    } else if ( cp->now_ptr != ERR ) {
	lp = get_lin(cp->now_ptr);
	if ( cp->cur_x < strlen(lp->lin) && 
	     cp->cur_x != kan_pos(lp->lin,cp->cur_x) )
	    cp->cur_x++;
    }
}
void	KEY_line_top(void)
{
    WIND    *wp;
    CHI_PTR *cp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    cp->cur_x = 0;
}
void	KEY_line_btm(void)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    char    *p;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr != ERR ) {
	lp = get_lin(cp->now_ptr);
	cp->cur_x = 0;
	for ( p = lp->lin ; *p != '\n' && *p != '\0' ; p++ )
	    cp->cur_x++;
	if ( cp->cur_x >= 80 )
	    cp->cur_x = 79;
    } else
	cp->cur_x = 79;
}
void	KEY_word_right(void)
{
    int     n,len,fg;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;

    lp = get_lin(cp->now_ptr);
    len = strlen(lp->lin);
    fg = (cp->cur_x >= len ? 1:0);

    for ( ; ; ) {
	while ( cp->cur_x >= len ) {
	    if ( lp->left == ERR )
		return;
	    cp->cur_x = 0;
	    if ( ++cp->cur_y >= wp->max_y ) {
		cp->cur_y = wp->max_y - 1;
		wp->wrt_mode = 3;
	    }
	    cp->now_ptr = lp->left;
	    cp->lin_pos++;
	    lp = get_lin(cp->now_ptr);
	    len = strlen(lp->lin);
	}
	n = kan_pos(lp->lin,cp->cur_x);
	if ( fg == 0 && lp->lin[n] < '0' )
	    fg = 1;
	if ( fg != 0 && lp->lin[n] >= '0' )
	    break;
	cp->cur_x = n + (iskan(&(lp->lin[n])) ? 2:1);
    }
}
void	KEY_word_left(void)
{
    int     n,len,fg;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;

    lp = get_lin(cp->now_ptr);
    len = strlen(lp->lin);

    for ( fg = 0 ; ; ) {
	while ( cp->cur_x < 0 ) {
	    cp->cur_x = 0;
	    if ( lp->right == ERR )
		return;
	    if ( cp->cur_y > 0 )
		cp->cur_y--;
	    else
		wp->wrt_mode = 3;
	    cp->now_ptr = lp->right;
	    cp->lin_pos--;
	    lp = get_lin(cp->now_ptr);
	    len = strlen(lp->lin);
	    cp->cur_x = len - 1;
	}
	n = kan_pos(lp->lin,cp->cur_x);
	if ( fg == 0 && lp->lin[n] < '0' )
	    fg = 1;
	if ( fg == 1 && lp->lin[n] >= '0' )
	    fg = 2;
	if ( fg == 2 && lp->lin[n] < '0' ) {
	    if ( ++cp->cur_x >= len )
	        KEY_word_right();
	    break;
	}
	cp->cur_x = n-1;
    }
}
void	KEY_bs(void)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    char    *p;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;

    if ( --cp->cur_x < 0 ) {
	KEY_up();
	lp = get_lin(cp->now_ptr);
	cp->cur_x = 0;
	for ( p = lp->lin ; *p != '\n' && *p != '\0' ; p++ )
	    cp->cur_x++;
	if ( cp->cur_x >= 80 )
	    cp->cur_x = 79;
	wp->wrt_mode = 3;
    }
    KEY_del();
}
void	KEY_ins_sw(void)
{
    WIND    *wp;

    wp = &(win[act_wind]);
    wp->ins_mode = (wp->ins_mode == FALSE ? TRUE:FALSE);
}
void	KEY_act_cheng(void)
{
     int     i,n;

    if ( wind_count <= 1 )
	return;

    n = act_wind;
    for ( i = 0 ; i < (MAX_WIND - 1) ; i++ ) {
	if ( ++n >= MAX_WIND )
	    n = 0;
	if ( win[n].open_flg != FALSE )
	    break;
    }
    WIN_act_cheng(n);
}
void	KEY_mike_open(void)
{
    WIN_open(0);
}
void	KEY_john_open(void)
{
    WIN_open(1);
}
void	KEY_kent_open(void)
{
    WIN_open(2);
}
void	KEY_jack_open(void)
{
    extern int top_event;

    top_event = 4;		/* looking for whisper.c */
}
void	TERM_cheng(int no)
{
    win[TERM].ins_mode = bak_ins_mode;
    bak_ins_mode = win[no].ins_mode;
    TERM = no;
    macvalset("TERM",no);
    TERM_pause_abort();
    win[no].ins_mode = FALSE;
    if ( up_wind == no )
	up_wind = ERR;
    WIN_resize();
}
void	KEY_term_mike(void)
{
    TERM_cheng(0);
}
void	KEY_term_john(void)
{
    TERM_cheng(1);
}
void	KEY_term_kent(void)
{
    TERM_cheng(2);
}
void	KEY_scl_dsp(void)
{
    scl_flg = (scl_flg == 0 ? 1:0);
    WIN_resize();
}
void	TANGO_set(void)
{
    if ( MSG_wind("tango_touroku") != FALSE )
	return;
    key_flg = TRUE;
    if ( memo_buf != NULL && *memo_buf != '\0' )
	KAN_touroku(strlen(memo_buf),memo_buf);
}
void	KEY_memo(void)
{
    MEMO_insrt(99,99);
}
void	KEY_for_scrool(void)
{
    int    n;
    register WIND    *wp;
    register CHI_PTR *cp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    n = wp->max_y - cp->cur_y + 5;

    if ( WIN_down_scrool(TERM,n) != ERR ) {
	MOS_disp(FALSE);
	WIN_dsp_buf(TERM);
	MOS_disp(TRUE);
   }
}
void	KEY_bak_scrool(void)
{
    int    n;
    register WIND    *wp;
    register CHI_PTR *cp;

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);
    n = cp->cur_y + 1 + 5;

    if ( WIN_up_scrool(TERM,n) != ERR ) {
	MOS_disp(FALSE);
	WIN_dsp_buf(TERM);
	MOS_disp(TRUE);
   }
}
void	WIN_up_line(void)
{
    int     n,y;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    char    *p;
    static int soft_wait=0;

    if ( up_wind == ERR && up_memo == ERR )
	return;

    if ( soft_wait > 0 ) {
	soft_wait--;
	return;
    }

    if ( up_memo != ERR ) {
	lp = get_lin(up_memo);
	for ( p = lp->lin ; *p != '\0' ; p++ ) {
	    if ( *p == '\n' ) {
		RSB_putc(0x0D);
		soft_wait = macval("_CRWAIT");
	    } else
		RSB_putc(*p);
	}
	up_memo = lp->left;
	return;
    }

    wp = &(win[up_wind]);
    n = wp->now;
    wp->now = up_child;
    cp = &(wp->child[wp->now]);
    lp = get_lin(cp->now_ptr);

    for ( p = lp->lin ; *p != '\0' ; p++ ) {
	if ( *p == '\n' ) {
	    RSB_putc(0x0D);
	    soft_wait = macval("_CRWAIT");
	} else
	    RSB_putc(*p);
    }

    WIN_down_scrool(up_wind,1);
    wp->now = n;

    if ( lp->left == ERR ) {
	if ( wp->open_flg != FALSE && wp->now == up_child ) {
	    MOS_disp(FALSE);
	    WIN_dsp_buf(up_wind);
	    WIN_dsp_pause(up_wind,FALSE);
	    MOS_disp(TRUE);
	}
	up_wind = ERR;
	cp->pas_flg = FALSE;

    } else if ( wp->open_flg != FALSE && wp->now == up_child ) {
	MOS_disp(FALSE);
	WIN_dsp_buf(up_wind);
	y = cp->cur_y * FONT_SIZ + wp->wind_y + 31;
	DSP_line(0,y,639,y,COL_RED,4);
	MOS_disp(TRUE);
    }
}

void	WIN_term_loop(void)
{
    int     len,ch;
    CHI_PTR *cp;

    cp = &(win[TERM].child[win[TERM].now]);
    if ( cp->pas_flg )
	return;

    len = RSB_chk();
    while ( len-- > 0 ) {
	ch = RSB_getc();
	WIN_putc(TERM,ch);
    }
    WIN_flush(TERM);
}
void	LIN_onoff(void)
{
    if ( lin_flg == FALSE ) {
	lin_flg = TRUE;
	win[TERM].max_y = (win[TERM].size_y - 32) / FONT_SIZ;
    } else {
	lin_flg = FALSE;
	win[TERM].max_y = (win[TERM].size_y - 16) / FONT_SIZ;
	LIN_buf_flush();
    }

    MOS_disp(FALSE);
    if ( lin_flg != FALSE ) {
	DSP_xline(0,win[TERM].wind_y+16,
		639,win[TERM].wind_y+win[TERM].size_y-1,COL_BAK,0);
	LIN_buf_dsp();
    } else
	putstr((win[TERM].wind_y + win[TERM].size_y - 16)*512,"");

    WIN_dsp_buf(TERM);
    MOS_disp(TRUE);
}
void	WIN_loop(void)
{
    int     i,x,y,ch,n=0;
    unsigned ec;
    WIND    *wp;
    CHI_PTR *cp;
    char    tmp[84];

    wp = &(win[act_wind]);
    cp = &(wp->child[wp->now]);

    x = cur_x = cp->cur_x * 8;
    y = cur_y = cp->cur_y * FONT_SIZ + wp->wind_y + 16;
    
    if ( cp->pas_flg == FALSE )
        WIN_cursol(act_wind,x,y);
    else if ( act_wind != TERM ) {
	MSG_wind("now_upload");
	goto ENDOF;
    }

    if ( act_wind == TERM && lin_flg != FALSE ) {
	cur_x = LIN_buf_pos() * 8;
	cur_y = win[TERM].wind_y + win[TERM].size_y - 16;
    }

    while ( kbhit() ) {
	ch = getkey(&ec);
	ec &= 0xFF14;

	if ( act_wind == TERM ) {
	    if ( TERM_KEY_exec(ec) == FALSE && ch != 0xFFFF ) {
		if ( lin_flg != FALSE )
		    LIN_input(ch);
		else {
		    if ( cp->pas_flg != FALSE )
		        TERM_pause_abort();
		    RSB_putc(ch);
		}
	    }
	    continue;
	}

	if ( (i = EDIT_KEY_chk(ec)) != ERR ) {
	    if ( n > 0 ) {
	        tmp[n] = '\0';
	        WIN_puts(act_wind,tmp);
		WIN_flush(act_wind);
		n = 0;
	    }
	    EDIT_KEY_exec(ec,i);

	} else if ( ch != 0xFFFF && ch >= ' ' ) {
	    tmp[n++] = ch;
	    if ( n >= 80 ) {
	        tmp[n] = '\0';
	        WIN_puts(act_wind,tmp);
		WIN_flush(act_wind);
		n = 0;
	    }
	}
    }

    if ( n > 0 ) {
        tmp[n] = '\0';
        WIN_puts(act_wind,tmp);
    }

ENDOF:
    if ( lin_flg != FALSE && lin_new_flg != FALSE && 
			     win[TERM].open_flg != FALSE ) {
	MOS_disp(FALSE);
	LIN_buf_dsp();
	MOS_disp(TRUE);
	lin_new_flg = FALSE;
    }

    WIN_flush(act_wind);
    WIN_up_line();
    WIN_term_loop();
}
int	WIN_down_start(char *file)
{
    if ( down_fp != NULL ) {
	fclose(down_fp);
	down_fp = NULL;
	WIN_dsp_down(FALSE);
	return TRUE;
    }

    if ( (down_fp = fopen(file,"r+")) == NULL ) {
	if ( (down_fp = fopen(file,"w")) == NULL )
	    return ERR;
    } else
	eof_chk(down_fp);

    WIN_dsp_down(TRUE);
    return FALSE;
}
void	WIN_upload(int no)
{
    int     n,y;
    WIND    *wp;
    CHI_PTR *cp;

    if ( no >= MAX_WIND )
	no = act_wind;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    if ( cp->now_ptr == ERR )
	return;

    if ( up_wind == no && cp->pas_flg != FALSE ) {
	up_wind = ERR;
	cp->pas_flg = FALSE;
	MOS_disp(FALSE);
	WIN_dsp_pause(no,FALSE);
	MOS_disp(TRUE);
	return;

    } else if ( up_wind != ERR )
	return;

    cp->pas_flg = TRUE;
    n = cp->now_ptr = WIN_top_ptr(no);
    cp->cur_y = cp->cur_x = 0;
    up_wind = no;
    up_child = wp->now;
    y = cp->cur_y * FONT_SIZ + wp->wind_y + 31;

    MOS_disp(FALSE);
    WIN_dsp_buf(no);
    WIN_dsp_pause(no,TRUE);
    DSP_line(0,y,639,y,COL_RED,4);
    MOS_disp(TRUE);

    TERM_pause_abort();
}

void	WIN_act_man(int no)
{
    DSP_string(win_name[no],WIND_X+no*40+2,4,
	(win[no].open_flg == FALSE ? COL_WHIS2:
		   (no == act_wind ? COL_RED:
		       (no == TERM ? COL_LOVE:COL_CHR))),COL_WHIS);
}

void	WIN_act_cheng(int no)
{
    int     i;

    macvalset("ACTWIND",no);
    macvalset("OLDWIND",act_wind);
    MSG_wind("wind_act_cheng");

    MOS_disp(FALSE);
    DSP_string(win_name[act_wind],
		W_NAME_X+2,win[act_wind].wind_y+4,
		COL_CHR,win[act_wind].color);
    DSP_string(win_name[no],
		W_NAME_X+2,win[no].wind_y+4,
		COL_RED,win[no].color);
    i = act_wind;
    act_wind = no;
    WIN_act_man(i);
    WIN_act_man(no);
    MOS_disp(TRUE);
}

void	WIN_child_dsp(int no)
{
    int     i;
    register WIND *wp;

    wp = &win[no];
    for ( i = 0 ; i < CHILD_MAX ; i++ ) {
	DSP_string(child_name[i],W_CHILD_X+i*24+6,wp->wind_y+4,
		wp->now == i ? COL_CHR:wind_col2[no],wp->color);
    }
}

void	WIN_move_event(register EVENT *ep,int x,int y)
{
    static int ofy=0,ty=0;
    static int topy=0,btmy=0;
    int     i,n;

    switch(ep->now) {

    case EVT_CLIP_MOS:
	DSP_mos(1);
	EVT_clip_on(ep);
	ofy = y - ep->y1 + 2;
	ep->now = EVT_DOLACK_MOS;
	topy = 16;
	btmy = win[ep->no].wind_y + win[ep->no].size_y - 48;
	for ( i = 0 ; i < ep->no ; i++ ) {
	    if ( win[i].open_flg != FALSE )
		topy = win[i].wind_y + 48;
	}

    case EVT_DOLACK_MOS:
	if ( (ty = y - ofy) < topy ) {
	    ty = topy;
	    MOS_setpos(x,ty + ofy);
	} else if ( ty >= btmy ) {
	    ty = btmy;
	    MOS_setpos(x,ty + ofy);
	}
	MOS_disp(FALSE);
	DSP_line(0,ty,639,ty+15,15,4);
	DSP_line(0,ty,639,ty+15,15,4);
	MOS_disp(TRUE);
	break;

    case EVT_MOVE_MOS:
    case EVT_SELECT_MOS:
    case EVT_DLSEL_MOS:
	EVT_clip_off(ep);
	DSP_mos(0);
	for ( i = n = 0 ; i < ep->no ; i++ ) {
	    if ( win[i].open_flg != FALSE )
		n++;
	}
	i = win_tbl[wind_count].w[n].top + win_tbl[wind_count].w[n].siz;
	win_tbl[wind_count].w[n].top = ty;
	win_tbl[wind_count].w[n].siz = i - ty;
	if ( --n >= 0 ) {
	    i = ty - win_tbl[wind_count].w[n].top;
	    win_tbl[wind_count].w[n].siz = i;
	}
	WIN_resize();
	break;

    case EVT_ON_MOS:
	DSP_mos(1);
	break;

    case EVT_OFF_MOS:
	DSP_mos(0);
	break;
    }
}

void	WIN_col_buf(int no,int pos,int len)
{
    int     i,n,y,ln,col,fg=FALSE;
    WIND    *wp;
    register CHI_PTR *cp;
    register LIN_PTR *lp;
    char    *p,bch;
    char    tmp[92];

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    wp->wrt_mode = 0;

    n = cp->now_ptr;
    ln = cp->lin_pos;

    for ( i = cp->cur_y ; i > 0 && n != ERR ; i-- ) {
	lp = get_lin(n);
	ln--;
	if ( lp->right == ERR )
	    break;
	n = lp->right;
    }

    p = strcpy(tmp,"[EOF]");
    y = wp->wind_y + 16;
    for ( i = 0 ; i < wp->max_y ; i++ ) {
	if ( ln >= pos && ln <= len )
	    col = COL_LINE;
	else
	    col = COL_BAK;

	if ( n != ERR ) {
	    lp = get_lin(n);
	    if ( no != TERM &&
		 lp->left == ERR && strchr(lp->lin,'\n') == NULL ) {
		strcpy(tmp,lp->lin);
		strcat(tmp,"[EOF]");
		if ( strlen(tmp) > 80 ) {
		    bch = tmp[80];
		    tmp[80] = '\0';
		    cputstr(y*512,tmp,col_cnv[COL_CHR],col_cnv[col]);
		    tmp[80] = bch;
		    p = &(tmp[80]);
		} else {
		    fg = TRUE;
		    cputstr(y*512,tmp,col_cnv[COL_CHR],col_cnv[col]);
		}
	    } else
	        cputstr(y*512,lp->lin,col_cnv[COL_CHR],col_cnv[col]);
	    n = lp->left;
	} else if ( no != TERM && fg == FALSE ) {
	    fg = TRUE;
	    cputstr(y*512,p,col_cnv[COL_CHR],col_cnv[col]);
	} else
	    cputstr(y*512,"",col_cnv[COL_CHR],col_cnv[col]);

	y += FONT_SIZ;
	ln++;
    }

    if ( no == cur_wind )
        cur_wind = ERR;
}
int	get_lin_pos(int no,int pos)
{
    int     n,i;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);
    n = cp->lin_pos;
    i = cp->now_ptr;

    while ( n > pos && i != ERR ) {
	lp = get_lin(i);
	if ( lp->right == ERR )
	    break;
	i = lp->right;
	n--;
    }
    while ( n < pos && i != ERR ) {
	lp = get_lin(i);
	if ( lp->left == ERR )
	    break;
	i = lp->left;
	n++;
    }
    return i;
}
void	WIN_ins_ptr(int no,int ch,int ptr)
{
    int     n;
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    LIN_PTR *tp;
    LIN_PTR *bp;

    wp = &(win[no]);
    cp = &(wp->child[ch]);

    if ( cp->now_ptr == ERR ) {
        cp->now_ptr = xalloc();
        lp = get_lin(cp->now_ptr);
        lp->lin[0] = '\0';
	wp->wrt_mode = 3;
	cp->lin_max = 1;
	cp->lin_pos = 0;
	cp->top_ptr = ERR;
	cp->wrt_flg = TRUE;
    }

    while ( ptr != ERR ) {
	n = xalloc();
	tp = get_lin(n);
	bp = get_lin(ptr);
	strcpy(tp->lin,bp->lin);
	ptr = bp->left;

	lp = get_lin(cp->now_ptr);
	if ( (tp->right = lp->right) != ERR ) {
	    bp = get_lin(tp->right);
	    bp->left = n;
	} else
	    cp->top_ptr = ERR;
	lp->right = n;
	tp->left = cp->now_ptr;

	wp->wrt_mode = 3;
	cp->lin_max++;
	cp->lin_pos++;
	cp->wrt_flg = TRUE;
	if ( cp->cur_y < (wp->max_y - 2) )
	    cp->cur_y++;
    }
}
char	*MEMO_get_buf(void)
{
    if ( memo_buf != NULL )
	return memo_buf;
    return "";
}
void	MEMO_set_word(char *str)
{
    if ( memo_buf != NULL )
	free(memo_buf);
    memo_buf = strdup(str);
}
void	MEMO_insrt(int no,int ch)
{
    int     old;
    char    *p;

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;

    if ( no == TERM ) {
	if ( memo_buf != NULL ) {
	    p = memo_buf;
	    while ( *p != '\0' ) {
		if ( lin_flg != FALSE )
		    LIN_input(*(p++));
		else
		    RSB_putc(*(p++));
	    }
	} else if ( memo_ptr != ERR ) {
	    if ( up_memo != ERR )
		up_memo = ERR;
	    else
		up_memo = memo_ptr;
	}

    } else {
	if ( memo_buf != NULL )
	    if ( win[no].now != ch ) {
		old = win[no].now;
		win[no].now = ch;
		WIN_puts(no,memo_buf);
		win[no].now = old;
	    } else
		WIN_puts(no,memo_buf);
	else if ( memo_ptr != ERR )
	    WIN_ins_ptr(no,ch,memo_ptr);
    }
}

void	MEMO_event(register EVENT *ep)
{
    switch(ep->now) {
    case EVT_CLIP_MOS:
	EVT_clip_on(ep);
    case EVT_ON_MOS:
	DSP_mos(1);
	break;

    case EVT_SELECT_MOS:
	EVT_clip_off(ep);
	DSP_mos(0);
	MSG_wind("memo_up");
	break;

    case EVT_DOLACK_MOS:
	ep->now = EVT_NON;
    case EVT_MOVE_MOS:
	EVT_clip_off(ep);
    case EVT_OFF_MOS:
	DSP_mos(0);
	break;
    }
}

void	MEMO_chk(void)
{
    static int memo_flg=FALSE;

    if ( memo_buf == NULL && memo_ptr == ERR && memo_flg != FALSE ) {
	EVT_level_free(290);
	memo_flg = FALSE;
	DSP_xline(MEMO_X,2,MEMO_X+36,13,COL_WHIS,0);

    } else if ( (memo_buf != NULL || memo_ptr != ERR) && memo_flg == FALSE ) {
	EVT_sw(MEMO_X,2,"MEMO",COL_DIA,COL_WHIS,290,MEMO_event,0);
	memo_flg = TRUE;
    }
}
void	MEMO_word_cut(int no,int pos,int x,int len)
{
    int     n;
    LIN_PTR *lp;
    char    *p,*s;
    char    tmp[82];

    if ( (n = get_lin_pos(no,pos)) != ERR ) {
	lp = get_lin(n);
	x = kan_pos(lp->lin,x);
	p = &(lp->lin[x]);
	s = tmp;
	while ( len > 0 ) {
	    if ( iskan(p) ) {
		*(s++) = *(p++);
		*(s++) = *(p++);
		len -= 2;
	    } else if ( *p == '\0' || *p == '\n' ) {
		*(s++) = ' ';
		len--;
	    } else {
		*(s++) = *(p++);
		len--;
	    }
	}
	*s = '\0';
    } else {
	memset(tmp,' ',len);
        tmp[len] = '\0';
    }

    if ( memo_buf != NULL )
	free(memo_buf);
    memo_buf = strdup(tmp);

    MEMO_chk();
}
void	MEMO_lin_set(int sptr,int eptr)
{
    int     i,n,old;
    LIN_PTR *lp,*tp;

    if ( memo_buf != NULL )
	free(memo_buf);
    memo_buf = NULL;

    while ( memo_ptr != ERR ) {
	lp = get_lin(memo_ptr);
	n = lp->left;
	xfree(memo_ptr);
	memo_ptr = n;
    }

    n = sptr;
    tp = NULL;
    old = ERR;
    while ( n != ERR && n != eptr ) {
	i = xalloc();
	if ( tp != NULL )
	    tp->left = i;
	else
	    memo_ptr = i;

	tp = get_lin(i);
	tp->right = old;
	old = i;

	lp = get_lin(n);
	strcpy(tp->lin,lp->lin);
	n = lp->left;
    }
}
void	MEMO_line_cut(int no,int pos,int len)
{
    int     i,n,old;
    LIN_PTR *lp,*tp;

    if ( memo_buf != NULL )
	free(memo_buf);
    memo_buf = NULL;

    while ( memo_ptr != ERR ) {
	lp = get_lin(memo_ptr);
	n = lp->left;
	xfree(memo_ptr);
	memo_ptr = n;
    }

    n = get_lin_pos(no,pos);
    tp = NULL;
    old = ERR;
    while ( n != ERR && pos <= len ) {
	i = xalloc();
	if ( tp != NULL )
	    tp->left = i;
	else
	    memo_ptr = i;

	tp = get_lin(i);
	tp->right = old;
	old = i;

	lp = get_lin(n);
	strcpy(tp->lin,lp->lin);
	n = lp->left;
	pos++;
    }

    MEMO_chk();
}
void	WIN_move_cur(int no,int x,int y)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;

    wp = &(win[no]);
    cp = &(wp->child[wp->now]);

    cp->cur_x = x;

    if (  y < cp->cur_y )
	WIN_up_scrool(no,cp->cur_y - y);

    while ( y > cp->cur_y ) {
	if ( cp->now_ptr == ERR )
	    WIN_ins_line(no);
	lp = get_lin(cp->now_ptr);
	if ( lp->left == ERR )
	    WIN_ins_line(no);
	WIN_down_scrool(no,1);
    }
}
void	WIN_scrn_event(register EVENT *ep,int x,int y,int sw)
{
    WIND    *wp;
    CHI_PTR *cp;
    LIN_PTR *lp;
    int     i,n,xx,yy;
    static int mode,hit_x,hit_y;
    static int old_x,old_y,old_sw,old_len,old_cur_y;
    static int dsp_x1=0,dsp_y1=0,dsp_x2=0,dsp_y2=0;
    static int pos,len,old_ptr,old_pos,rep_cnt=0,rep_tick=0;

    wp = &(win[ep->no]);
    cp = &(wp->child[wp->now]);

    switch(ep->now) {
    case EVT_CLIP_MOS:
	DSP_mos(1);
	ep->now = EVT_DOLACK_MOS;
	mode = 0;
	hit_x = x;
	hit_y = y;
	old_x = x / 8;
	old_y = (y - wp->wind_y - 16) / 16;
	old_sw = sw;
	old_len = ERR;
	pos = cp->lin_pos - cp->cur_y + old_y;
	old_ptr = cp->now_ptr;
	old_pos = cp->lin_pos;
	old_cur_y = cp->cur_y;
	dsp_x1 = ERR;
	rep_cnt = 1;
	rep_tick = 0;
	break;

    case EVT_DOLACK_MOS:
	old_sw = sw;
	xx = x / 8;
	yy = (y - wp->wind_y - 16) / 16;
	switch(mode) {
	case 0: 
	    if ( old_y >= wp->max_y )
		break;
	    if ( y >= (hit_y + 8) || y <= (hit_y - 8) )
		mode = 2;
	    else if ( x >= (hit_x + 8) || x <= (hit_x - 8) )
		mode = 1;
	    break;

	case 1:
	    yy = old_y * 16 + wp->wind_y + 16;

	    if ( y < yy )
		MOS_setpos(x,yy);
	    else if ( y > (yy+15) )
		MOS_setpos(x,yy+15);

	    len = xx;

	    if ( old_len == len )
		break;

	    old_len = len;

	    MOS_disp(FALSE);
	    if ( dsp_x1 != ERR )
		DSP_xline(dsp_x1,dsp_y1,dsp_x2,dsp_y2,7,4);

	    dsp_x1 = old_x * 8 + (len >= old_x ? 0:7);
	    dsp_x2 = len * 8 + (len >= old_x ? 7:0);
	    dsp_y1 = yy;
	    dsp_y2 = yy + 15;

	    DSP_xline(dsp_x1,dsp_y1,dsp_x2,dsp_y2,7,4);
	    MOS_disp(TRUE);
	    break;

	case 2:
	    cur_dsp_flg = TRUE;
	    if ( y <= (wp->wind_y + 16) ) {
		if ( ++rep_tick > 20 ) {
		     rep_cnt++;
		     rep_tick = 0;
		}
		i = wp->wind_y + 16;
		if ( y < i )
		    MOS_setpos(x,i);
		y = i;
		if ( cp->now_ptr != ERR ) {
		    lp = get_lin(cp->now_ptr);
		    for ( n = rep_cnt ; n > 0 && lp->right != ERR ; n-- ) {
			cp->now_ptr = lp->right;
			cp->lin_pos--;
			if ( --cp->cur_y <= 0 )
			    cp->cur_y = 0;
			lp = get_lin(cp->now_ptr);
		    }
		}

	    } else if ( y >= (wp->wind_y + wp->size_y) ) {
		if ( ++rep_tick > 20 ) {
		     rep_cnt++;
		     rep_tick = 0;
		}
		i = wp->wind_y + wp->size_y;
		if ( y > i )
		    MOS_setpos(x,i);
		y = i;
		if ( cp->now_ptr != ERR ) {
		    lp = get_lin(cp->now_ptr);
		    for ( n = rep_cnt ; n > 0 && lp->left != ERR ; n-- ) {
			cp->now_ptr = lp->left;
			cp->lin_pos++;
			if ( ++cp->cur_y >= wp->max_y )
			    cp->cur_y = wp->max_y - 1;
			lp = get_lin(cp->now_ptr);
		    }
		}
	    } else {
		rep_tick = 0;
		rep_cnt = 1;
	    }

	    yy = (y - wp->wind_y - 16) / 16;
	    len = cp->lin_pos - cp->cur_y + yy;
	    if ( old_len == len )
		break;
	    old_len = len;

	    if ( pos > len ) {
		i = len;
		n = pos;
	    } else {
		i = pos;
		n = len;
	    }
	    MOS_disp(FALSE);
	    WIN_col_buf(ep->no,i,n);
	    MOS_disp(TRUE);
	    break;
	}
	break;

    case EVT_DLSEL_MOS:
	DSP_mos(0);
	switch(mode) {
	case 0:
	    if ( act_wind != ep->no )
		WIN_act_cheng(ep->no);

	    if ( (old_sw & 2) != 0 ) {
		if ( cp->cur_x == old_x && cp->cur_y == old_y )
		    MEMO_insrt(ep->no,wp->now);
		else if ( ep->no != TERM )
		    WIN_move_cur(ep->no,old_x,old_y);
	    }
	    break;

	case 1:
	    if ( dsp_x1 != ERR ) {
	        MOS_disp(FALSE);
		DSP_xline(dsp_x1,dsp_y1,dsp_x2,dsp_y2,7,4);
	        MOS_disp(TRUE);
	    }
	    if ( len >= old_x )
		len = len - old_x + 1;
	    else {
		i = old_x - len;
		old_x = len;
		len = i;
	    }
	    MEMO_word_cut(ep->no,pos,old_x,len);
	    break;

	case 2:
	    cur_dsp_flg = FALSE;
	    cp->now_ptr = old_ptr;
	    cp->lin_pos = old_pos;
	    cp->cur_y = old_cur_y;
	    MOS_disp(FALSE);
	    WIN_dsp_buf(ep->no);
	    MOS_disp(TRUE);
	    if ( pos > len ) {
		i = pos;
		pos = len;
		len = i;
	    }
	    MEMO_line_cut(ep->no,pos,len);
	    break;
	}
	break;
    }
}

void	WIN_event(register EVENT *ep)
{
    int     i;
    static int tik=0;
    static int cnt=1;

    switch(ep->now) {
    case EVT_CLIP_MOS:
	EVT_clip_on(ep);
	if ( ep->no == 1 || ep->no == 2 ) {
	    ep->now = EVT_REP_MOS;
	    tik = 0;
	    cnt = 1;
	    break;
	}

    case EVT_ON_MOS:
	DSP_mos(1);
	break;

    case EVT_SELECT_MOS:
	EVT_clip_off(ep);
	DSP_mos(0);
	if ( ep->no == 0 && act_wind != (ep->level - 200) )
	    WIN_act_cheng(ep->level-200);
	break;

    case EVT_REP_MOS:
	if ( ++tik >= 50 ) {
	    tik = 0;
	    cnt++;
	}

	if ( ep->no == 1 )
	    i = WIN_down_scrool(ep->level - 200,cnt);
	else
	    i = WIN_up_scrool(ep->level - 200,cnt);

	if ( i != ERR ) {
	    MOS_disp(FALSE);
	    WIN_dsp_buf(ep->level - 200);
	    MOS_disp(TRUE);
	}
	break;

    case EVT_DOLACK_MOS:
	ep->now = EVT_NON;
    case EVT_MOVE_MOS:
	EVT_clip_off(ep);
    case EVT_OFF_MOS:
	DSP_mos(0);
	break;
    }
}

void	WIN_cmd_event(register EVENT *ep)
{
    WIND    *wp;
    CHI_PTR *cp;

    switch(ep->now) {
    case EVT_CLIP_MOS:
	EVT_clip_on(ep);
    case EVT_ON_MOS:
	DSP_mos(1);
	break;

    case EVT_SELECT_MOS:
	EVT_clip_off(ep);
	DSP_mos(0);
	switch(ep->no) {
	case 0:
	    if ( ep->level == (200 + TERM) ) {
		TERM_pause_abort();
	    } else {
		macvalset("WIND",ep->level - 200);
		MSG_wind("wind_upload");
	    }
	    break;
	case 1:
	    macvalset("WIND",ep->level - 200);
	    MSG_wind("wind_menu");
	    break;
	case 2:
	    MSG_wind("login");
	    break;
	case 3:
	    MSG_wind("down_load");
	    break;
	case 4:
	    macvalset("WIND",ep->level - 200);
	    MSG_wind("wind_secret");
	    wp = &(win[ep->level-200]);
	    cp = &(wp->child[wp->now]);
	    cp->sec_flg = (cp->sec_flg == FALSE ? TRUE:FALSE);
	    MOS_disp(FALSE);
	    WIN_dsp_secret(ep->level-200,cp->sec_flg);
	    MOS_disp(TRUE);
	    break;
	}
	break;

    case EVT_DOLACK_MOS:
	ep->now = EVT_NON;
    case EVT_MOVE_MOS:
	EVT_clip_off(ep);
    case EVT_OFF_MOS:
	DSP_mos(0);
	break;
    }
}
void	CHILD_set(int no,int ch)
{
    WIND    *wp;
    CHI_PTR *cp;

    if ( no >= MAX_WIND || no < 0 )
	no = act_wind;
    if ( ch >= CHILD_MAX || ch < 0 )
	ch = win[no].now;

    wp = &(win[no]);
    if ( ch == wp->now )
	return;
    wp->now = ch;
    cp = &(wp->child[ch]);
    WIN_child_dsp(no);
    WIN_dsp_pause(no,cp->pas_flg);
    WIN_dsp_secret(no,cp->sec_flg);
    WIN_dsp_buf(no);
}
void	WIN_child_event(register EVENT *ep)
{
    WIND    *wp;
    CHI_PTR *cp;

    switch(ep->now) {
    case EVT_CLIP_MOS:
	EVT_clip_on(ep);
    case EVT_ON_MOS:
	DSP_mos(1);
	break;

    case EVT_SELECT_MOS:
	EVT_clip_off(ep);
	DSP_mos(0);
	wp = &win[ep->level-200];
	if ( wp->now == ep->no )
	    break;

	macvalset("WIND",ep->level - 200);
	macvalset("OCH",wp->now);
	macvalset("CH",ep->no);
	MSG_wind("wind_child");
	break;

    case EVT_DOLACK_MOS:
	ep->now = EVT_NON;
    case EVT_MOVE_MOS:
	EVT_clip_off(ep);
    case EVT_OFF_MOS:
	DSP_mos(0);
	break;
    }
}

void	WIN_redisp(int no)
{
    int     i,n,c;
    register WIND *wp;

    wp = &win[no];
    DSP_box(0,wp->wind_y,639,wp->wind_y+15,COL_LINE,wp->color);

    EVT_level_free(200+no);
    EVT_sw(W_NAME_X,wp->wind_y+2,win_name[no],
		no == act_wind ? COL_RED:COL_CHR,wp->color,
		200+no,WIN_event,0);

    EVT_sw(W_UPLOAD_X,wp->wind_y+2,
		no == TERM ? "PAUSE":"UPLOAD",
		wind_col2[no],wp->color,200+no,WIN_cmd_event,0);

    EVT_sw(W_MENU_X,wp->wind_y+2,"MENU",wind_col2[no],wp->color,
		200+no,WIN_cmd_event,1);

    if ( no == TERM ) {
	EVT_sw(W_DIAL_X,wp->wind_y+2,"DIAL",wind_col2[no],wp->color,
		200+no,WIN_cmd_event,2);
	EVT_sw(W_DOWNLD_X,wp->wind_y+2,"DOWN",wind_col2[no],wp->color,
		200+no,WIN_cmd_event,3);
    }

    EVT_sw(W_SECRET_X,wp->wind_y+2,"SECRET",
		wind_col2[no],wp->color,200+no,WIN_cmd_event,4);

    for ( i = 0 ; i < CHILD_MAX ; i++ ) {
	EVT_sw(W_CHILD_X+i*24,wp->wind_y+2,"  ",wind_col2[no],wp->color,
		200+no,WIN_child_event,i);
    }
    WIN_child_dsp(no);

    EVT_sw(W_UP_X,wp->wind_y+2,"",wind_col2[no],wp->color,
		200+no,WIN_event,2);
    EVT_sw(W_DOWN_X,wp->wind_y+2,"",wind_col2[no],wp->color,
		200+no,WIN_event,1);

    EVT_sw(W_MOVE_X,wp->wind_y+2,"ȁ",wind_col2[no],wp->color,
		200+no,WIN_move_event,no);

    EVT_set_node(0,wp->wind_y+16,639,wp->wind_y+wp->size_y-1,
		200+no,WIN_scrn_event,no);

    WIN_act_man(no);
    WIN_dsp_buf(no);
    WIN_dsp_pause(no,win[no].child[win[no].now].pas_flg);
    WIN_dsp_secret(no,win[no].child[win[no].now].sec_flg);

    if ( no == TERM && lin_flg != FALSE )
	LIN_buf_dsp();

    if ( no == TERM ) {
	WIN_dsp_down(down_fp != NULL ? TRUE:FALSE);
        if ( (log_max = macval("_LOGMAX")) <= 0 )
	    log_max = 1000;

    } else if ( scl_flg != FALSE ) {
	for ( i = 0 ; i < 80 ; i++ ) {
	    n = i * 8 + 4;
	    c = ((i+1) % 10) == 0 ? COL_RED:
		(((i+1) % 5) == 0 ? COL_DIA:COL_CHR);
	    DSP_line(n,wp->wind_y+15,n,wp->wind_y+15,c,0);
	}
    }
}

void	WIN_resize(void)
{
    int     i,n;
    register WIND    *wp;

    MOS_disp(FALSE);
    DSP_xline(0,16,639,463,0,0);
    cur_wind = ERR;
    cur_dsp_ptn = macval("_CUR_PTN") * 2;
    if ( (cur_dsp_col = macval("_CUR_COL")) == 0 )
	cur_dsp_col = 15;

    for ( n = i = 0 ; i < MAX_WIND ; i++ ) {
	wp = &win[i];
	if ( wp->open_flg != FALSE ) {
	    wp->wind_y = win_tbl[wind_count].w[n].top;
	    wp->size_y = win_tbl[wind_count].w[n].siz;
	    if ( i == TERM && lin_flg != FALSE )
	        wp->max_y = (wp->size_y - 32) / FONT_SIZ;
	    else
	        wp->max_y = (wp->size_y - 16) / FONT_SIZ;
	    WIN_redisp(i);
	    n++;
	} else {
	    EVT_level_free(200+i);
	    WIN_act_man(i);
	}
    }
    MOS_disp(TRUE);
}

void	WIN_open(int no)
{
    int     i;
    register WIND    *wp;

    wp = &win[no];

    if ( wind_count == 1 && wp->open_flg != FALSE )
	return;

    wp->open_flg = (wp->open_flg != FALSE ? FALSE:TRUE);

    macset("MODE",wp->open_flg != FALSE ? "OPEN":"CLOSE");
    macvalset("WIND",no);
    MSG_wind(WIND_MSG);

    if ( no == act_wind && wp->open_flg == FALSE ) {
	for ( i = 0 ; i < MAX_WIND ; i++ ) {
	    if ( win[i].open_flg != FALSE ) {
		act_wind = i;
		macvalset("ACTWIND",act_wind);
		break;
	    }
	}
    }

    if ( wp->open_flg != FALSE )
	wind_count++;
    else
	wind_count--;

    WIN_resize();
}
void	WIN_init(void)
{
    int     i,j,top,siz;
    register WIND    *wp;
    register CHI_PTR  *cp;

    for ( i = 1 ; i <= MAX_WIND ; i++ ) {
	top = 16;
	siz = 448 / i;
	for ( j = 0 ; j < i ; j++ ) {
	    win_tbl[i].w[j].top = top;
	    win_tbl[i].w[j].siz = siz;
	    top += siz;
	}
    }

    for ( i = 0 ; i < MAX_WIND ; i++ ) {
	wp = &win[i];
	wp->open_flg = FALSE;
	wp->ins_mode = (i == 0 ? FALSE:TRUE);
	wp->wrt_mode = 0;
	wp->color = wind_col[i];
	wp->now = 0;
	for ( j = 0 ; j < CHILD_MAX ; j++ ) {
	    cp = &(wp->child[j]);
	    cp->lin_max = cp->lin_pos = 0;
	    cp->cur_x = cp->cur_y = 0;
	    cp->top_ptr = cp->now_ptr = ERR;
	    cp->bak_cod = '\0';
	    cp->pas_flg = cp->sec_flg = cp->wrt_flg = FALSE;
	    cp->file_name = NULL;
	}
	WIN_act_man(i);
    }

    WIN_open(TERM);
    macvalset("ACTWIND",act_wind);
}
