diff options
| author | Ian C <ianc@noddybox.co.uk> | 2011-06-09 13:46:28 +0000 | 
|---|---|---|
| committer | Ian C <ianc@noddybox.co.uk> | 2011-06-09 13:46:28 +0000 | 
| commit | a9022b5972dc49d86f617a27940fafe9c4d0e7e7 (patch) | |
| tree | 61405aa4ade91ed1057f863ddf118ceb38e14f8e /djgpp/platgui.c | |
Initial import of (very old) vidoom sources.
Diffstat (limited to 'djgpp/platgui.c')
| -rw-r--r-- | djgpp/platgui.c | 4235 | 
1 files changed, 4235 insertions, 0 deletions
| diff --git a/djgpp/platgui.c b/djgpp/platgui.c new file mode 100644 index 0000000..3f50964 --- /dev/null +++ b/djgpp/platgui.c @@ -0,0 +1,4235 @@ +/* + +    viDOOM - level editor for DOOM + +    Copyright (C) 2000  Ian Cowburn (ianc@noddybox.demon.co.uk) + +    This program is free software; you can redistribute it and/or modify +    it under the terms of the GNU General Public License as published by +    the Free Software Foundation; either version 2 of the License, or +    (at your option) any later version. + +    This program is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +    GNU General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program; if not, write to the Free Software +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + +    ------------------------------------------------------------------------- + +    Platform specific GUI type routines + +*/ +static const char rcs_id[]="$Id$"; + +#include "config.h" + +#include <stdio.h> +#include <allegro.h> +#include <string.h> + +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> +#include <dir.h> +#include <limits.h> +#include <ctype.h> +#include <fcntl.h> + +#include "platgui.h" +#include "gfx.h" +#include "gui.h" +#include "mem.h" +#include "file.h" +#include "util.h" + +#include "debug.h" + +#define COLDEP  16 +#define ACOL(c) (makecol_depth(COLDEP,((c)&0xff0000)>>16, \ +				      ((c)&0xff00)>>8, \ +				      ((c)&0xff))) + +#define DIALOG_STRLEN	16 + +#define SMALL_BEVEL	1	/* Bevels on radio and flag boxes */ +#define BEVEL		2	/* All other bevels */ +#define TICK		2 + +#define PL_COL		0xb0b0ff	/* Col for active picklist */ + +#define BUFF_LEN	1024 + +/* ---------------------------------------- VARS +*/ +static int	SCRW,SCRH; +static int	FW,FH; + +/* Vars for GUI_yesno_all() +*/ +static int	all_pressed=FALSE; +static int	all_result=FALSE; + +/* Global picklist data and the picklist dialog +*/ +#define PL_BORDER	0 +#define PL_TITLE	1 +#define PL_PICKLIST	2 +#define PL_OK		3 +#define PL_CANCEL	4 +#define PL_END		5 + +static DIALOG	picklist[PL_END+1]; +static int	pick_no; +static char	**pick_data; + + +/* Global image picklist data and the image picklist dialog +*/ +#define IPL_BORDER	0 +#define IPL_TITLE	1 +#define IPL_PICKLIST	2 +#define IPL_IMG_BORDER	3 +#define IPL_IMAGE	4 +#define IPL_OK		5 +#define IPL_CANCEL	6 +#define IPL_END		7 + +static DIALOG	img_picklist[IPL_END+1]; +static int	img_pick_no; +static PLAT_IMG_PICKLIST +		*img_pick_data; + + +/* Global data and the file viewer dialog +*/ +#define FV_BORDER	0 +#define FV_TITLE	1 +#define FV_TEXTBOX	2 +#define FV_TEXT		3 +#define FV_VERT_SCROLL	4 +#define FV_HORIZ_SCROLL	5 +#define FV_OK		6 +#define FV_END		7 + +#define FV_SCROLLWIDTH	10 +#define FV_WIDTH	75 +#define FV_HEIGHT	40 + +static DIALOG	fv_dialog[FV_END+1]; + +typedef struct +	{ +	double	one; +	int	size; +	int	pos; +	} ScrollbarData; + + +/* Global data for the text editor dialog +*/ +#define TE_BORDER	0 +#define TE_TITLE	1 +#define TE_TEXTBOX	2 +#define TE_TEXT		3 +#define TE_OK		4 +#define TE_CANCEL	5 +#define TE_END		6 + +#define TE_WIDTH	75 +#define TE_CHUNK	256 +#define TE_HEIGHT	40 + +static DIALOG	te_dialog[TE_END+1]; + +typedef struct +	{ +	char	t[TE_HEIGHT][TE_WIDTH+1]; +	int	top; +	int	x,y; +	int	col; +	int	lines; +	int	start; +	} TextEditData; + +typedef struct +	{ +	int	len; +	char	*p; +	} TextEditLine; + + +/* Types for the menu +*/ +typedef struct +    { +    int		x; +    int		y; +    int		w; +    int		h; +    } BoundBox; + +#define MENU_OK			0 +#define MENU_CANCEL_ESC		1 +#define MENU_CANCEL_CLICK	2 +#define MENU_CHILD_RETURN	3 + +typedef struct +	{ +	int	ret; +	int	mode; +	} MenuControl; + + +static int	MouseInBox(BoundBox *box,int no); + +/* 'Hidden' interfaces to gfx.c +*/ +extern void	GFX_FORCE_REDRAW(void); +extern void	GFX_SETTEXT(void); +extern void	GFX_SETGRAPHICS(void); + + +/* ---------------------------------------- FILE VEIWER SUPPORT FUNCS +*/ +static char *ConvertFileText(char *p) +{ +    static char s[BUFF_LEN+1]; +    int f; + +    f=0; + +    while((*p)&&(f<BUFF_LEN)) +    	{ +	if (isprint(*p)) +	    s[f++]=*p++; +	else if (*p == '\t') +	    { +	    if ((f%8)==0) +	    	s[f++]=' '; + +	    while(((f%8)!=0)&&(f<BUFF_LEN)) +	    	s[f++]=' '; + +	    p++; +	    } +	else +	    p++; +	} + +    s[f]=0; + +    return(s); +} + + +/* ---------------------------------------- GUI OBJECT PROCS SUPPORT FUNCS +*/ +static void Rect3D(int x,int y,int w,int h, int invert,int bevel) +{ +    int f; +    int mid,lo,hi; + +    mid=ACOL(GUI_MID); + +    if (invert) +    	{ +	lo=ACOL(GUI_HI); +	hi=ACOL(GUI_LO); +	} +    else +    	{ +	hi=ACOL(GUI_HI); +	lo=ACOL(GUI_LO); +	} + +    rectfill(screen,x,y,x+w-1,y+h-1,mid); + +    for(f=0;f<bevel;f++) +    	{ +	vline(screen,x+f,y+f,y+h-1-f,hi); +	vline(screen,x+w-1-f,y+f,y+h-1-f,lo); + +	hline(screen,x+f,y+f,x+w-1-f,hi); +	hline(screen,x+f,y+h-1-f,x+w-1-f,lo); +	} +} + + +static void DrawTick(int x,int y,int w,int h) +{ +    int ox,oy,x2,y2,x3,y3; +    int f; + +    x2=x+(w/4); +    y2=y+h-1; + +    x3=x2; +    y3=y2; + +    while(x3<(x+w-1)) +    	{ +	x3++; +	y3--; +	} + +    ox=x; +    oy=y; + +    x=x2; +    y=y2; + +    while(x>ox) +    	{ +	x--; +	y--; +	} + +    for(f=0;f<TICK;f++) +    	{ +	line(screen,x,y,x2,y2,ACOL(BLACK)); +	line(screen,x2,y2,x3,y3,ACOL(BLACK)); + +	y--; +	y2--; +	y3--; +	} +} + + +/* This code is based on _draw_scrollable_frame() from guiproc.c in Allegro +*/ +static void DrawScrollableFrame(DIALOG *d, int listsize, int offset, +				int height, int fg_color, int bg) +{ +    BITMAP *pattern; +    int i, len; +    int xx, yy; + +    /* draw frame +    */ +    rect(screen, d->x, d->y, d->x+d->w, d->y+d->h, fg_color); + +    /* possibly draw scrollbar +    */ +    if (listsize > height) +    	{ +	vline(screen, d->x+d->w-12, d->y+1, d->y+d->h-1, fg_color); + +	/* create and draw the scrollbar +	*/ +	pattern=create_bitmap(2,2); + +	/* +	putpixel(pattern,0,0,d->fg); +	putpixel(pattern,1,1,d->fg); +	putpixel(pattern,1,0,d->bg); +	putpixel(pattern,0,1,d->bg); +	*/ +	putpixel(pattern,0,0,ACOL(GUI_MID)); +	putpixel(pattern,1,1,ACOL(GUI_MID)); +	putpixel(pattern,1,0,ACOL(GUI_LO)); +	putpixel(pattern,0,1,ACOL(GUI_LO)); + +	i = ((d->h-4) * height + listsize/2) / listsize; +	xx = d->x+d->w-11; +	yy = d->y+2; + +	if (offset > 0) +	    { +	    len = (((d->h-4) * offset) + listsize/2) / listsize; +	    drawing_mode(DRAW_MODE_COPY_PATTERN, pattern, 0, 0); +	    rectfill(screen, xx, yy, xx+10, yy+len-1, ACOL(GUI_MID)); +	    solid_mode(); +	    yy += len; +	    } + +	if (yy+i < d->y+d->h-2) +	    { +	    Rect3D(xx, yy, 11, i, FALSE, BEVEL); +	    yy += i; +	    drawing_mode(DRAW_MODE_COPY_PATTERN, pattern, 0, 0); +	    rectfill(screen, xx, yy, xx+10, d->y+d->h-2, ACOL(GUI_MID)); +	    solid_mode(); +	    } +	else +	    Rect3D(xx, yy, 11, i, FALSE, BEVEL); + +	destroy_bitmap(pattern); +	} +} + + +/* This code is copied from _draw_listbox() from guiproc.c in Allegro, so we +   can force it to call DrawScrollableFrame() +*/ +static void DrawListbox(DIALOG *d) +{ +    typedef char *(*getfuncptr)(int, int *); +    int height, listsize, i, len, bar, x, y, w; +    int fg_color, fg, bg; +    char *sel = d->dp2; +    char *s; +    char store; + +    (*(getfuncptr)d->dp)(-1, &listsize); +    height = (d->h-3) / text_height(font); +    bar = (listsize > height); +    w = (bar ? d->w-14 : d->w-2); + +    fg_color = (d->flags & D_DISABLED) ? gui_mg_color : d->fg; + +    /* draw box contents +    */ +    for (i=0; i<height; i++) +    	{ +	if (d->d2+i < listsize) +	    { +	    if (d->d2+i == d->d1) +	    	{ +		fg = d->bg; +		bg = fg_color; +		}  +	    else if ((sel) && (sel[d->d2+i])) +	    	{  +		fg = d->bg; +		bg = gui_mg_color; +		} +	    else +	    	{ +		fg = fg_color; +		bg = d->bg; +		} + +	    s = (*(getfuncptr)d->dp)(i+d->d2, NULL); +	    x = d->x + 2; +	    y = d->y + 2 + i*text_height(font); +	    text_mode(bg); +	    rectfill(screen, x, y, x+7, y+text_height(font)-1, bg);  +	    x += 8; +	    len = strlen(s); +	    store = 0; +	    while (text_length(font, s) >= d->w - (bar ? 22 : 10)) +	    	{ +		s[len] = store; +		len--; +		store = s[len]; +		s[len] = 0; +		} +	    textout(screen, font, s, x, y, fg);  +	    x += text_length(font, s); +	    s[len] = store; +	    if (x <= d->x+w)  +		rectfill(screen, x, y, d->x+w, y+text_height(font)-1, bg); +	    } +	else +	    rectfill(screen, d->x+2,  d->y+2+i*text_height(font),  +			d->x+w, d->y+1+(i+1)*text_height(font), d->bg); +	} + +    if (d->y+2+i*text_height(font) <= d->y+d->h-2) +	rectfill(screen, d->x+2, d->y+2+i*text_height(font),  +				    d->x+w, d->y+d->h-2, d->bg); + +    /* draw frame, maybe with scrollbar +    */ +    DrawScrollableFrame(d, listsize, d->d2, height, fg_color, d->bg); +} + + +/* ---------------------------------------- GUI OBJECT PROCS + +   Note that many of the functions are based on the source available +   in guiproc.c in Allegro +*/ +static int d_3d_box(int msg, DIALOG *d, int c) +{ +    if (msg==MSG_DRAW) +    	Rect3D(d->x,d->y,d->w,d->h,FALSE,BEVEL); + +    return(D_O_K); +} + + +static int d_inv_3d_box(int msg, DIALOG *d, int c) +{ +    if (msg==MSG_DRAW) +    	Rect3D(d->x,d->y,d->w,d->h,TRUE,BEVEL); + +    return(D_O_K); +} + + +static int d_img_bmap_proc(int msg, DIALOG *d, int c) +{ +    RLE_SPRITE *bm; + +    if (msg==MSG_DRAW) +    	{ +	rectfill(screen,d->x,d->y,d->x+d->w-1,d->y+d->h-1,ACOL(BLACK)); +	 +	if ((bm=d->dp)) +	    draw_rle_sprite(screen,bm,d->x,d->y); +	} + +    return(D_O_K); +} + + +static int d_img_list_proc(int msg, DIALOG *d, int c) +{ +    static int my_d_list_proc(int msg, DIALOG *d, int c); +    int d1; +    int ret; + +    d1=img_picklist[IPL_PICKLIST].d1; + +    ret=my_d_list_proc(msg,d,c); + +    if (d1!=img_picklist[IPL_PICKLIST].d1) +	{ +	img_picklist[IPL_IMAGE].dp= +		img_pick_data[img_picklist[IPL_PICKLIST].d1].img; + +    	d_img_bmap_proc(MSG_DRAW,&img_picklist[IPL_IMAGE],0); +	} + +    return(ret); +} + + +int my_d_check_proc(int msg, DIALOG *d, int c) +{ +    int x; +    int fg; + +    if (msg==MSG_DRAW) +	{ +	fg=ACOL(WHITE); +	text_mode(d->bg); + +	gui_textout(screen, d->dp, d->x,  +			d->y+(d->h-(text_height(font)-gui_font_baseline))/2, +					    fg, FALSE); + +	x=d->x+d->w-d->h; + +	Rect3D(x,d->y,d->h,d->h,TRUE,SMALL_BEVEL); +	rectfill(screen,x+SMALL_BEVEL,d->y+SMALL_BEVEL, +			x+d->h-SMALL_BEVEL*2,d->y+d->h-SMALL_BEVEL*2, +			ACOL(WHITE)); + +	if (d->flags & D_SELECTED) +	    if (d->d1) +		rectfill(screen,x+SMALL_BEVEL+2,d->y+SMALL_BEVEL+2, +				x+d->h-SMALL_BEVEL*2-2, +				d->y+d->h-SMALL_BEVEL*2-2, +				ACOL(BLACK)); +	    else +		DrawTick(x+SMALL_BEVEL,d->y+SMALL_BEVEL, +			 d->h-SMALL_BEVEL*2,d->h-SMALL_BEVEL*2); + +	return D_O_K; +	}  + +    /* Group zero is done as a check box, not a radio box +    */ +    if (d->d1) +	return d_radio_proc(msg, d, c); +    else +	return d_button_proc(msg, d, c); +} + + +int my_d_radio_proc(int msg, DIALOG *d, int c) +{ +    int x,fg; + +    switch(msg) +    	{ +	case MSG_DRAW: +	    fg=(d->flags & D_DISABLED) ? gui_mg_color : d->fg; +	    text_mode(d->bg); +	    gui_textout +	    	(screen, +		 d->dp,d->x+d->h+text_height(font), +		 d->y+(d->h-(text_height(font)-gui_font_baseline))/2,fg,FALSE); + +	    x = d->x; + +	    Rect3D(x,d->y,d->h,d->h,TRUE,SMALL_BEVEL); +	    rectfill(screen,x+SMALL_BEVEL,d->y+SMALL_BEVEL, +			    x+d->h-SMALL_BEVEL*2,d->y+d->h-SMALL_BEVEL*2, +			    ACOL(WHITE)); + +	    if (d->flags & D_SELECTED) +		rectfill(screen,x+SMALL_BEVEL+2,d->y+SMALL_BEVEL+2, +				x+d->h-SMALL_BEVEL*2-2, +					d->y+d->h-SMALL_BEVEL*2-2, +				ACOL(BLACK)); + +	    break; + +	default: +	    return(d_radio_proc(msg,d,c)); +	    break; +	} + +    return(D_O_K); +} + + +static int my_d_list_proc(int msg, DIALOG *d, int c) +{ +    switch(msg) +    	{ +	case MSG_DRAW: +	    DrawListbox(d); +	    break; + +	default: +	    return(d_list_proc(msg,d,c)); +	    break; +	} + +    return (D_O_K); +} + + +static int my_d_button_proc(int msg, DIALOG *d, int c) +{ +    int inv; + +    switch(msg) +    	{ +	case MSG_DRAW: +	    if (d->flags&D_GOTFOCUS) +		rect(screen,d->x-1,d->y-1,d->x+d->w,d->y+d->h,ACOL(BLACK)); +	    else +		rect(screen,d->x-1,d->y-1,d->x+d->w,d->y+d->h,ACOL(GUI_MID)); + +	    if (d->flags&D_SELECTED) +	    	inv=TRUE; +	    else +	    	inv=FALSE; + +	    Rect3D(d->x,d->y,d->w,d->h,inv,BEVEL); +	    text_mode(-1); +	    gui_textout(screen,d->dp,d->x+(d->w/2),d->y+d->h/2-FH/2,d->fg,TRUE); + +	    break; + +	default: +	    return(d_button_proc(msg,d,c)); +	    break; +	} + +    return (D_O_K); +} + + +static int d_ro_textbox(int msg, DIALOG *d, int c) +{ +    char **p; +    int x,y; +    int f; + +    p=d->dp; + +    if(msg==MSG_DRAW) +    	{ +	text_mode(-1); + +	y=d->d2; +	x=d->d1; + +	vsync(); + +	rectfill(screen,d->x,d->y,d->x+d->w-1,d->y+d->h-1,ACOL(WHITE)); + +	for(f=0;(f<FV_HEIGHT)&&(p[y]);f++,y++) +	    if (strlen(p[y])>x) +		textprintf(screen,font,d->x,d->y+(f*FH),ACOL(BLACK), +						    "%-.*s",FV_WIDTH,p[y]+x); + +	} + +    return (D_O_K); +} + + +static int d_vert_scrollbar(int msg, DIALOG *d, int c) +{ +    ScrollbarData *sd; +    int *ip; +    DIALOG *dp; +    int last_y; + +    /* Special case for 'zero' length scrollbars - just ignore interactions +       and draw a full length scrollbar +    */ +    if (d->d2==0) +	{ +	if (msg==MSG_DRAW) +	    { +	    rect(screen,d->x,d->y,d->x+d->w,d->y+d->h,ACOL(BLACK)); +	    Rect3D(d->x+1,d->y+1,d->w-1,d->h-1,FALSE,BEVEL); +	    } + +    	return(D_O_K); +	} + +    switch(msg) +    	{ +	case MSG_START: +	    /* Calc box size, etc +	    */ +	    sd=Grab(sizeof(*sd)); +	    d->dp3=sd; + +	    sd->one=(double)d->h/(double)(d->d2+d->d1); +	    sd->size=(int)(sd->one*d->d1); +	    sd->pos=0; +	    ip=d->dp; +	    *ip=0; + +	    break; + +	case MSG_END: +	    Release(d->dp3); +	    break; + +	case MSG_DRAW: +	    { +	    BITMAP *pattern; + +	    sd=d->dp3; + +	    /* draw frame +	    */ +	    rect(screen,d->x,d->y,d->x+d->w,d->y+d->h,ACOL(BLACK)); + +	    /* create and draw the scrollbar +	    */ +	    pattern=create_bitmap(2,2); + +	    putpixel(pattern,0,0,ACOL(GUI_MID)); +	    putpixel(pattern,1,1,ACOL(GUI_MID)); +	    putpixel(pattern,1,0,ACOL(GUI_LO)); +	    putpixel(pattern,0,1,ACOL(GUI_LO)); + +	    drawing_mode(DRAW_MODE_COPY_PATTERN, pattern, 0, 0); +	    rectfill(screen,d->x+1,d->y+1,d->x+d->w-1,d->y+d->h-2,0); +	    solid_mode(); +	    Rect3D(d->x+1,d->y+1+sd->pos,d->w-1,sd->size,FALSE,BEVEL); + +	    destroy_bitmap(pattern); + +	    break; +	    } + +	case MSG_WANTFOCUS: +	    return(D_WANTFOCUS); +	    break; + +	case MSG_CLICK: +	    sd=d->dp3; +	    ip=d->dp; +	    dp=d->dp2; + +	    if (mouse_y<(d->y+sd->pos)) +	    	{ +		while((mouse_b)&&(mouse_y<(d->y+sd->pos))) +		    if (*ip) +			{ +			(*ip)--; + +			sd->pos=(int)((*ip)*sd->one); + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} +		} +	    else if (mouse_y>(d->y+sd->pos+sd->size)) +	    	{ +		while((mouse_b)&&(mouse_y>(d->y+sd->pos+sd->size))) +		    if ((*ip)<d->d2) +			{ +			(*ip)++; + +			sd->pos=(int)((*ip)*sd->one); + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} +		} +	    else +	    	{ +		last_y=mouse_y; + +		/* I'm sure there's a better way of doing this, but I couldn't +		   get the sums to work out... +		*/ +		while(mouse_b) +		    { +		    int my; +		    int diff; +		    int np; + +		    my=mouse_y; +		    diff=my-last_y; +		    np=sd->pos+diff; + +		    if ((diff<0)&&((*ip)>0)) +			{ +			while((sd->pos>np)&&(*ip)) +			    { +			    (*ip)--; +			    sd->pos=(int)((*ip)*sd->one); +			    } + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} +		    else if ((diff>0)&&((*ip)<d->d2)) +			{ +			while((sd->pos<np)&&((*ip)<d->d2)) +			    { +			    (*ip)++; +			    sd->pos=(int)((*ip)*sd->one); +			    } + +			if (sd->pos==(d->h-sd->size)) +			    *ip=d->d2; + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} + +		    last_y=my; +		    } +		} + +	    break; + +	default: +	    break; +	} + +    return(D_O_K); +} + + +static int d_horiz_scrollbar(int msg, DIALOG *d, int c) +{ +    ScrollbarData *sd; +    int *ip; +    DIALOG *dp; +    int last_x; + +    /* Special case for 'zero' length scrollbars - just ignore interactions +       and draw a full length scrollbar +    */ +    if (d->d2==0) +	{ +	if (msg==MSG_DRAW) +	    { +	    rect(screen,d->x,d->y,d->x+d->w,d->y+d->h,ACOL(BLACK)); +	    Rect3D(d->x+1,d->y+1,d->w-1,d->h-1,FALSE,BEVEL); +	    } + +    	return(D_O_K); +	} + +    switch(msg) +    	{ +	case MSG_START: +	    /* Calc box size, etc +	    */ +	    sd=Grab(sizeof(*sd)); +	    d->dp3=sd; + +	    sd->one=(double)d->w/(double)(d->d2+d->d1); +	    sd->size=(int)(sd->one*d->d1); +	    sd->pos=0; +	    ip=d->dp; +	    *ip=0; + +	    break; + +	case MSG_END: +	    Release(d->dp3); +	    break; + +	case MSG_DRAW: +	    { +	    BITMAP *pattern; + +	    sd=d->dp3; + +	    /* draw frame +	    */ +	    rect(screen,d->x,d->y,d->x+d->w,d->y+d->h,ACOL(BLACK)); + +	    /* create and draw the scrollbar +	    */ +	    pattern=create_bitmap(2,2); + +	    putpixel(pattern,0,0,ACOL(GUI_MID)); +	    putpixel(pattern,1,1,ACOL(GUI_MID)); +	    putpixel(pattern,1,0,ACOL(GUI_LO)); +	    putpixel(pattern,0,1,ACOL(GUI_LO)); + +	    drawing_mode(DRAW_MODE_COPY_PATTERN, pattern, 0, 0); +	    rectfill(screen,d->x+1,d->y+1,d->x+d->w-1,d->y+d->h-2,0); +	    solid_mode(); +	    Rect3D(d->x+1+sd->pos,d->y+1,sd->size,d->h-1,FALSE,BEVEL); + +	    destroy_bitmap(pattern); + +	    break; +	    } + +	case MSG_WANTFOCUS: +	    return(D_WANTFOCUS); +	    break; + +	case MSG_CLICK: +	    sd=d->dp3; +	    ip=d->dp; +	    dp=d->dp2; + +	    if (mouse_x<(d->x+sd->pos)) +	    	{ +		while((mouse_b)&&(mouse_x<(d->x+sd->pos))) +		    if (*ip) +			{ +			(*ip)--; + +			sd->pos=(int)((*ip)*sd->one); + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} +		} +	    else if (mouse_x>(d->x+sd->pos+sd->size)) +	    	{ +		while((mouse_b)&&(mouse_x>(d->x+sd->pos+sd->size))) +		    if ((*ip)<d->d2) +			{ +			(*ip)++; + +			sd->pos=(int)((*ip)*sd->one); + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} +		} +	    else +	    	{ +		last_x=mouse_x; + +		/* I'm sure there's a better way of doing this, but I couldn't +		   get the sums to work out... +		*/ +		while(mouse_b) +		    { +		    int mx; +		    int diff; +		    int np; + +		    mx=mouse_x; +		    diff=mx-last_x; +		    np=sd->pos+diff; + +		    if ((diff<0)&&((*ip)>0)) +			{ +			while((sd->pos>np)&&(*ip)) +			    { +			    (*ip)--; +			    sd->pos=(int)((*ip)*sd->one); +			    } + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} +		    else if ((diff>0)&&((*ip)<d->d2)) +			{ +			while((sd->pos<np)&&((*ip)<d->d2)) +			    { +			    (*ip)++; +			    sd->pos=(int)((*ip)*sd->one); +			    } + +			if (sd->pos==(d->h-sd->size)) +			    *ip=d->d2; + +			show_mouse(NULL); +			SEND_MESSAGE(d,MSG_DRAW,0); +			SEND_MESSAGE(dp,MSG_DRAW,0); +			show_mouse(screen); +			} + +		    last_x=mx; +		    } +		} + +	    break; + +	default: +	    break; +	} + +    return(D_O_K); +} + + +static int d_textedit(int msg, DIALOG *d, int c) +{ +    static char out[2]=" "; +    char *tmp; +    TextEditData *te; +    TextEditLine *p; +    int y,sx,sy; +    int f; + +    p=d->dp; + +    switch(msg) +	{ +	case MSG_START: +	    /* Memory for text buffer +	    */ +	    te=Grab(sizeof(*te)); +	    d->dp3=te; +	    te->start=TRUE; +	    te->top=0; +	    te->x=0; +	    te->y=0; +	    te->col=0; + +	    te->lines=0; + +	    while(p[te->lines].p) +	    	te->lines++; + +	    for(sx=0;sx<TE_WIDTH+1;sx++) +		for(sy=0;sy<TE_HEIGHT;sy++) +		    te->t[sy][sx]=0; +	    break; + +	case MSG_END: +	    Release(d->dp3); +	    break; + +	case MSG_WANTFOCUS: +	    return(D_WANTFOCUS); +	    break; + +	case MSG_LOSTFOCUS: +	    return(D_WANTFOCUS); +	    break; + +	case MSG_DRAW: +	    te=d->dp3; + +	    if (te->start) +		{ +		rectfill(screen,d->x,d->y,d->x+d->w-1,d->y+d->h-1,ACOL(WHITE)); +		te->start=FALSE; +		} + +	    text_mode(ACOL(WHITE)); + +	    y=te->top; + +	    rectfill(screen,d->x+d->w-FW,d->y, +			    d->x+d->w-1,d->y+d->h-1,ACOL(WHITE)); + +	    for(sy=0;sy<TE_HEIGHT;sy++,y++) +		if (y<te->lines) +		    { +		    for(sx=0;sx<TE_WIDTH;sx++) +			if ((te->col+sx>=p[y].len)|| +				(te->t[sy][sx]!=p[y].p[te->col+sx])) +			    { +			    if (te->col+sx>=p[y].len) +				te->t[sy][sx]=0; +			    else +				te->t[sy][sx]=p[y].p[te->col+sx]; + +			    if (isprint(te->t[sy][sx])) +				out[0]=te->t[sy][sx]; +			    else +				out[0]=' '; + +			    textout(screen,font,out, +				    d->x+(sx*FW),d->y+(sy*FH),ACOL(BLACK)); +			    } +		    } +		else +		    { +		    memset(te->t[sy],0,TE_WIDTH+1); +		    rectfill(screen,d->x,d->y+(sy*FH), +				    d->x+d->w-1,d->y+(sy*FH)+FH-1,ACOL(WHITE)); +		    } + +	    text_mode(ACOL(BLACK)); +	    out[0]=isprint(te->t[te->y-te->top][te->x-te->col]) ?  +				    te->t[te->y-te->top][te->x-te->col] : ' '; +	    textout(screen,font,out, +		    d->x+((te->x-te->col)*FW), +		    d->y+((te->y-te->top)*FH),ACOL(WHITE)); +	    te->t[te->y-te->top][te->x-te->col]=-1; + +	    break; + +	case MSG_CLICK: +	    te=d->dp3; + +	    te->y=(mouse_y-d->y)/FH; +	    te->x=te->col+(mouse_x-d->x)/FW; + +	    if (te->y>=te->lines) +	    	te->y=te->lines-1; + +	    if (te->x>p[te->y].len) +		te->x=p[te->y].len; + +	    show_mouse(NULL); +	    SEND_MESSAGE(d,MSG_DRAW,0); +	    show_mouse(screen); +	    break; + +	case MSG_CHAR: +	    te=d->dp3; + +	    /* Pressing shift and space seems to generate odd values +	    */ +	    if ((c>>8)==KEY_SPACE) +	    	c=(c&0xff00)|' '; + +	    switch(c>>8) +	    	{ +		case KEY_HOME: +		    te->x=0; +		    te->col=0; +		    break; + +		case KEY_END: +		    te->x=p[te->y].len; +		    te->col=MAX(0,te->x-TE_WIDTH); +		    break; + +		case KEY_LEFT: +		    { +		    int ctrl; + +		    ctrl=key_shifts&(KB_CTRL_FLAG|KB_SHIFT_FLAG); + +		    if (ctrl) +			while((te->x)&&(isspace(p[te->y].p[te->x]))) +			    { +			    if (te->x) +				te->x--; +			    else +				ctrl=FALSE; + +			    if (te->x<te->col) +				te->col--; +			    } + +		    do  { +			if (te->x) +			    te->x--; +			else +			    ctrl=FALSE; + +			if (te->x<te->col) +			    te->col--; + +			if (isspace(p[te->y].p[te->x])) +			    ctrl=FALSE; + +			} while(ctrl); + +		    break; +		    } + +		case KEY_RIGHT: +		    { +		    int ctrl; + +		    ctrl=key_shifts&(KB_CTRL_FLAG|KB_SHIFT_FLAG); + +		    if (ctrl) +			while((te->x<p[te->y].len)&& +					(isspace(p[te->y].p[te->x]))) +			    { +			    te->x++; + +			    if ((te->x-TE_WIDTH)>te->col) +				te->col++; +			    } + +		    do  { +			if (te->x<p[te->y].len) +			    { +			    te->x++; + +			    if ((te->x-TE_WIDTH)>te->col) +				te->col++; +			    } +			else +			    ctrl=FALSE; + +			if (isspace(p[te->y].p[te->x])) +			    ctrl=FALSE; + +			} while(ctrl); + +		    break; +		    } + +		case KEY_UP: +		    if (te->y) +			{ +			te->y--; + +			if (te->y<te->top) +			    te->top--; + +			if (te->x>p[te->y].len) +			    { +			    te->x=p[te->y].len; +			    te->col=MAX(0,te->x-TE_WIDTH); +			    } +			} +		    break; + +		case KEY_PGUP: +		    if (te->y) +			{ +			te->y-=TE_HEIGHT; + +			if (te->y<0) +			    te->y=0; + +			if (te->y<te->top) +			    te->top=te->y; + +			if (te->x>p[te->y].len) +			    { +			    te->x=p[te->y].len; +			    te->col=MAX(0,te->x-TE_WIDTH); +			    } +			} +		    break; + +		case KEY_DOWN: +		    if (p[te->y+1].p) +			{ +			te->y++; + +			if (te->y>=te->top+TE_HEIGHT) +			    te->top=te->y-TE_HEIGHT+1; + +			if (te->x>p[te->y].len) +			    { +			    te->x=p[te->y].len; +			    te->col=MAX(0,te->x-TE_WIDTH); +			    } +			} +		    break; + +		case KEY_PGDN: +		    te->y+=TE_HEIGHT; + +		    if (te->y>=te->lines) +		    	te->y=te->lines-1; + +		    if (te->y>=te->top+TE_HEIGHT) +			te->top=te->y-TE_HEIGHT+1; + +		    if (te->x>p[te->y].len) +			{ +			te->x=p[te->y].len; +			te->col=MAX(0,te->x-TE_WIDTH); +			} + +		    break; + +		case KEY_DEL: +		    if (p[te->y].p[te->x]) +		    	{ +			for(f=te->x;f<p[te->y].len;f++) +			    p[te->y].p[f]=p[te->y].p[f+1]; + +			p[te->y].len--; +			p[te->y].p[p[te->y].len]=0; +			} +		    else if (p[te->y+1].p) +		    	{ +			p[te->y].len+=p[te->y+1].len; + +			p[te->y].p=ReGrab(p[te->y].p, +					 (p[te->y].len/TE_CHUNK+1)*TE_CHUNK+1); + +			strcat(p[te->y].p,p[te->y+1].p); + +			Release(p[te->y+1].p); + +			for(f=te->y+1;f<te->lines;f++) +			    p[f]=p[f+1]; + +			te->lines--; + +			p=d->dp=ReGrab(d->dp, +					sizeof(TextEditLine)*(te->lines+1)); +			p[te->lines].p=NULL; +			} +		    break; + +		case KEY_BACKSPACE: +		    if (te->x) +		    	{ +			for(f=te->x;f<p[te->y].len;f++) +			    p[te->y].p[f-1]=p[te->y].p[f]; + +			p[te->y].len--; +			te->x--; +			p[te->y].p[p[te->y].len]=0; + +			if (te->x<te->col) +			    te->col--; +			} +		    else if (te->y) +		    	{ +			te->x=p[te->y-1].len; +			te->col=MAX(0,te->x-TE_WIDTH); + +			p[te->y-1].len+=p[te->y].len; + +			p[te->y-1].p=ReGrab(p[te->y-1].p, +				     (p[te->y-1].len/TE_CHUNK+1)*TE_CHUNK+1); + +			strcat(p[te->y-1].p,p[te->y].p); + +			Release(p[te->y].p); + +			for(f=te->y;f<te->lines;f++) +			    p[f]=p[f+1]; + +			if (--te->y<te->top) +			    te->top--; + +			te->lines--; +			p=d->dp=ReGrab(d->dp, +					sizeof(TextEditLine)*(te->lines+1)); +			p[te->lines].p=NULL; +			} +		    break; + +		case KEY_ENTER: +		    te->lines++; +		    p=d->dp=ReGrab(d->dp,sizeof(TextEditLine)*(te->lines+1)); + +		    for(f=te->lines;f>te->y;f--) +		    	p[f]=p[f-1]; + +		    tmp=Strdup(p[te->y].p+te->x); +		    tmp=ReGrab(tmp,(strlen(tmp)/TE_CHUNK+1)*TE_CHUNK+1); + +		    p[te->y].p[te->x]=0; +		    p[te->y].len=strlen(p[te->y].p); + +		    te->y++; +		    te->x=0; +		    te->col=0; + +		    p[te->y].p=tmp; +		    p[te->y].len=strlen(tmp); + +		    if (te->y>=te->top+TE_HEIGHT) +			te->top=te->y-TE_HEIGHT+1; + +		    break; + +		case KEY_TAB: +		    for(f=te->x%4+1;f<=4;f++) +		    	simulate_keypress(KEY_SPACE<<8|' '); +		    break; + +		default: +		    if (isprint(c&0xff)) +			{ +			p[te->y].len++; + +			if (!(p[te->y].len%TE_CHUNK)) +			    p[te->y].p=ReGrab(p[te->y].p, +					     (p[te->y].len/TE_CHUNK+1)* +								TE_CHUNK+1); + +			for(f=p[te->y].len;f>te->x;f--) +			    p[te->y].p[f]=p[te->y].p[f-1]; + +			p[te->y].p[te->x]=(c&0xff); + +			te->x++; + +			if ((te->x-TE_WIDTH)>te->col) +			    te->col++; +			} +		    break; +		} + +	    show_mouse(NULL); +	    SEND_MESSAGE(d,MSG_DRAW,0); +	    show_mouse(screen); +	    return(D_USED_CHAR); +	    break; +    	} + +    return (D_O_K); +} + + +static int d_dial_picklist(int msg, DIALOG *d, int c) +{ +    char **text; +    int lx,ly; + +    text=d->dp; + +    switch(msg) +    	{ +	case MSG_START: +	    break; + +	case MSG_END: +	    break; + +	case MSG_DRAW: +	    { +	    int bx1,by1,bx2,by2; + +	    bx1=d->x+d->w-d->h+1; +	    by1=d->y; +	    bx2=d->x+d->w-1; +	    by2=d->y+d->h-1; + +	    text_mode(-1); + +	    if (d->flags&D_GOTFOCUS) +		rectfill(screen,d->x,d->y,d->x+d->w-1,d->y+d->h-1,ACOL(PL_COL)); +	    else +		rectfill(screen,d->x,d->y,d->x+d->w-1,d->y+d->h-1,ACOL(WHITE)); + +	    Rect3D(bx1,by1,d->h,d->h,FALSE,BEVEL); + +	    textout(screen,font,text[d->d1],d->x,d->y,d->fg); +	    break; +	    } + +	case MSG_WANTFOCUS: +	    return(D_WANTFOCUS); +	    break; + +	case MSG_CLICK: +	    { +	    BITMAP *under; +	    int done; +	    BoundBox b; +	    int fg,bg; +	    int f; +	    int draw; +	    int cur; +	    int last; +	    int new; +	    int press; +	    int first; + +	    text_mode(-1); +	    cur=d->d1; +	    press=FALSE; +	    first=TRUE; + +	    done=FALSE; +	    b.h=d->d2*(FH+1)+1; +	    b.w=d->w; +	    b.x=d->x; +	    b.y=d->y; + +	    if ((b.x+b.w)>SCRW) +	    	b.x=SCRW-b.w; + +	    if ((b.y+b.h)>SCRH) +	    	b.y=SCRH-b.h; + +	    if (!(under=create_bitmap(b.w+1,b.h+1))) +		GFX_exit(EXIT_FAILURE,"No more memory to create save under\n"); + +	    show_mouse(NULL); +	    blit(screen,under,b.x,b.y,0,0,b.w+1,b.h+1); +	    show_mouse(screen); + +	    show_mouse(NULL); +	    rectfill(screen,b.x,b.y,b.x+b.w,b.y+b.h,ACOL(WHITE)); +	    rect(screen,b.x,b.y,b.x+b.w,b.y+b.h,ACOL(BLACK)); +	     +	    for(f=0;f<d->d2;f++) +		{ +		if (f==cur) +		    { +		    fg=ACOL(WHITE); +		    bg=ACOL(BLACK); +		    } +		else +		    { +		    fg=ACOL(BLACK); +		    bg=ACOL(WHITE); +		    } + +		rectfill(screen,b.x+1,b.y+1+(FH+1)*f, +				b.x+b.w-1,b.y+b.h-1,bg); +		textout(screen,font,text[f],b.x+1,b.y+1+(FH+1)*f,fg); +		} + +	    show_mouse(screen); + +	    draw=FALSE; +	    last=-1; +	    lx=-1; +	    ly=-1; + +	    while(!done) +	    	{ +		if (draw) +		    { +		    show_mouse(NULL); +		     +		    for(f=0;f<d->d2;f++) +			{ +			if (f==cur) +			    { +			    fg=ACOL(WHITE); +			    bg=ACOL(BLACK); + +			    rectfill(screen,b.x+1,b.y+1+(FH+1)*f, +					    b.x+b.w-1,b.y+(FH+1)*(f+1),bg); +			    textout(screen,font,text[f], +			    			b.x+1,b.y+1+(FH+1)*f,fg); +			    } +			else if (f==last) +			    { +			    fg=ACOL(BLACK); +			    bg=ACOL(WHITE); + +			    rectfill(screen,b.x+1,b.y+1+(FH+1)*f, +					    b.x+b.w-1,b.y+(FH+1)*(f+1),bg); +			    textout(screen,font,text[f], +			    			b.x+1,b.y+1+(FH+1)*f,fg); +			    } +			} + +		    show_mouse(screen); +		    draw=FALSE; +		    } + +		if (first) +		    { +		    while(mouse_b); +		    first=FALSE; +		    } + +		if (keypressed()) +		    { +		    int k; + +		    k=readkey(); + +		    switch(k>>8) +			{ +			case KEY_UP: +			    draw=TRUE; + +			    if (cur==-1) +			    	cur=d->d2-1; +			    else +				if (--cur<0) +				    cur+=d->d2; +			    break; + +			case KEY_DOWN: +			    draw=TRUE; + +			    if (cur==-1) +			    	cur=0; +			    else +				cur=(cur+1)%d->d2; +			    break; + +			case KEY_ESC: +			    cur=-1; +			    done=TRUE; +			    break; + +			case KEY_ENTER: +			    done=TRUE; +			    break; + +			default: +			    break; +			} +		    } +		else +		    { +		    if ((mouse_b)&&(!press)) +			press=TRUE; + +		    if ((!mouse_b)&&(press)) +			{ +			done=TRUE; +			lx=-1; +			ly=-1; +			} + +		    last=cur; + +		    if ((lx!=mouse_x)||(ly!=mouse_y)) +		    	{ +			lx=mouse_x; +			ly=mouse_y; + +			if (MouseInBox(&b,1)!=-1) +			    { +			    new=(mouse_y-b.y)/(FH+1); + +			    if (new>=d->d2) +				new=d->d2-1; + +			    if (new!=cur) +				{ +				cur=new; +				draw=TRUE; +				} +			    } +			else +			    { +			    if (cur!=-1) +				draw=TRUE; + +			    cur=-1; +			    } +			} +		    } +		} + +	    if (cur!=-1) +		d->d1=cur; + +	    show_mouse(NULL); +	    blit(under,screen,0,0,b.x,b.y,b.w+1,b.h+1); +	    SEND_MESSAGE(d,MSG_DRAW,0); +	    show_mouse(screen); + +	    break; +	    } + +	case MSG_CHAR: +	    switch(c>>8) +	    	{ +		case KEY_ENTER: +		    SEND_MESSAGE(d,MSG_CLICK,0); +		    break; + +		default: +		    return(D_O_K); +		    break; +		} + +	    show_mouse(NULL); +	    SEND_MESSAGE(d,MSG_DRAW,0); +	    show_mouse(screen); +	    return(D_USED_CHAR); +	    break; + +	default: +	    break; +	} + +    return(D_O_K); +} + + +static int d_title_proc(int msg, DIALOG *d, int c) +{ +    char *t; +    int x,y; +    int l; + +    if (msg==MSG_DRAW) +    	{ +	t=d->dp; +	l=strlen(t); + +	x=d->x-l*(FW/2); +	y=d->y; + +	text_mode(d->bg); +	textout(screen,font,t,x,y,d->fg); + +	line(screen,active_dialog[0].x+BEVEL+1,d->y+FH+1, +		    active_dialog[0].x+active_dialog[0].w-BEVEL-1, +		    				d->y+FH+1,ACOL(GUI_HI)); + +	line(screen,active_dialog[0].x+BEVEL+1,d->y+FH+2, +		    active_dialog[0].x+active_dialog[0].w-BEVEL-1, +		    				d->y+FH+2,ACOL(GUI_LO)); +	} + +    return(D_O_K); +} + + +static int d_my_ctext_proc(int msg, DIALOG *d, int c) +{ +    char *t; +    int x,y; +    int l; + +    if (msg==MSG_DRAW) +    	{ +	t=d->dp; +	l=strlen(t); + +	x=d->x-l*(FW/2); +	y=d->y; + +	text_mode(d->bg); +	textout(screen,font,t,x,y,d->fg); +	} + +    return(D_O_K); +} + + +static int d_my_text_proc(int msg, DIALOG *d, int c) +{ +    if (msg==MSG_DRAW) +    	{ +	text_mode(d->bg); +	textout(screen,font,d->dp,d->x,d->y,d->fg); +	} + +    return(D_O_K); +} + + +/* ---------------------------------------- FILE SELECTION CODE + +    This code is a copy of the file selector code provided by Shawn Hargreaves +    in his Allegro library (original filename fsel.c).  The only changes are +    to the file_selector[] DIALOG structure and some of the fs_*_proc() +    callbacks to use my 3D buttons, etc. + +    If this code causes problems, blame *ME*, _not_ Shawn! +*/ + + +#ifndef _USE_LFN +#define _USE_LFN  0 +#endif + +static int fs_edit_proc(int, DIALOG *, int ); +static int fs_flist_proc(int, DIALOG *, int ); +static int fs_dlist_proc(int, DIALOG *, int ); +static char *fs_flist_getter(int, int *); +static char *fs_dlist_getter(int, int *); + + +#define FLIST_SIZE      2048 + +typedef struct FLIST +{ +   char dir[80]; +   int size; +   char *name[FLIST_SIZE]; +} FLIST; + +static FLIST *flist = NULL; + +static char *fext = NULL; + + + +static DIALOG file_selector[] = +{ +   /* (dialog proc)     (x)   (y)   (w)   (h)   (fg)  (bg)  (key) (flags)  (d1)  (d2)  (dp) */ +   { d_3d_box, 0,    0,    304,  160,  0,    0,    0,    0,       0,    0,    NULL }, +   { d_inv_3d_box, 14,    26,    276,  12,  0,    0,    0,    0,       0,    0,    NULL }, +   { d_my_ctext_proc,      152,  8,    1,    1,    0,    0,    0,    0,       0,    0,    NULL }, +   { my_d_button_proc,     208,  107,  80,   16,   0,    0,    0,    D_EXIT,  0,    0,    "OK" }, +   { my_d_button_proc,     208,  129,  80,   16,   0,    0,    27,   D_EXIT,  0,    0,    "Cancel" }, +   { fs_edit_proc,      16,   28,   272,  8,    0,    0,    0,    0,       79,   0,    NULL }, +   { fs_flist_proc,     16,   46,   176,  99,   0,    0,    0,    D_EXIT,  0,    0,    fs_flist_getter }, +   { fs_dlist_proc,     208,  46,   80,   51,   0,    0,    0,    D_EXIT,  0,    0,    fs_dlist_getter }, +   { NULL } +}; + +#define FS_MESSAGE   2 +#define FS_OK        3 +#define FS_CANCEL    4 +#define FS_EDIT      5 +#define FS_FILES     6 +#define FS_DISKS     7 + + + +/* fs_dlist_getter: + *  Listbox data getter routine for the file selector disk list. + */ +static char *fs_dlist_getter(int index, int *list_size) +{ +   static char d[] = "A:\\"; + +   if (index < 0) { +      if (list_size) +	 *list_size = 26; +      return NULL; +   } + +   d[0] = 'A' + index; +   return d; +} + + + +/* fs_dlist_proc: + *  Dialog procedure for the file selector disk list. + */ +static int fs_dlist_proc(int msg, DIALOG *d, int c) +{ +   int ret; +   char *s = file_selector[FS_EDIT].dp; + +   if (msg == MSG_START) +      d->d1 = d->d2 = 0; + +   ret = my_d_list_proc(msg, d, c); + +   if (ret == D_CLOSE) { +      *(s++) = 'A' + d->d1; +      *(s++) = ':'; +      *(s++) = '\\'; +      *s = 0; +      show_mouse(NULL); +      SEND_MESSAGE(file_selector+FS_FILES, MSG_START, 0); +      SEND_MESSAGE(file_selector+FS_FILES, MSG_DRAW, 0); +      SEND_MESSAGE(file_selector+FS_EDIT, MSG_START, 0); +      SEND_MESSAGE(file_selector+FS_EDIT, MSG_DRAW, 0); +      show_mouse(screen); +      return D_O_K; +   } + +   return ret; +} + + + +/* fs_edit_proc: + *  Dialog procedure for the file selector editable string. + */ +static int fs_edit_proc(int msg, DIALOG *d, int c) +{ +   char *s = d->dp; +   int ch; +   int attr; +   int x; +   char b[80]; + +   if (msg == MSG_START) { +      if (s[0]) { +	 _fixpath(s, b); +	 errno = 0; + +	 x = s[strlen(s)-1]; +	 if ((x=='/') || (x=='\\')) +	    put_backslash(b); + +	 for (x=0; b[x]; x++) { +	    if (b[x] == '/') +	       s[x] = '\\'; +	    else +	       s[x] = toupper(b[x]); +	 } +	 s[x] = 0; +      } +   } + +   if (msg == MSG_KEY) { +      if (*s) +	 ch = s[strlen(s)-1]; +      else +	 ch = 0; +      if (ch == ':') +	 put_backslash(s); +      else { +	 if ((ch != '/') && (ch != '\\')) { +	    if (file_exists(s, FA_RDONLY | FA_HIDDEN | FA_DIREC, &attr)) { +	       if (attr & FA_DIREC) +		  put_backslash(s); +	       else +		  return D_CLOSE; +	    } +	    else +	       return D_CLOSE; +	 } +      } +      show_mouse(NULL); +      SEND_MESSAGE(file_selector+FS_FILES, MSG_START, 0); +      SEND_MESSAGE(file_selector+FS_FILES, MSG_DRAW, 0); +      SEND_MESSAGE(d, MSG_START, 0); +      SEND_MESSAGE(d, MSG_DRAW, 0); +      show_mouse(screen); +      return D_O_K; +   } + +   if (msg==MSG_CHAR) { +      ch = c & 0xff; +      if ((ch >= 'a') && (ch <= 'z')) +	 c = (c & 0xffffff00L) | (ch - 'a' + 'A'); +      else if (ch == '/') +	 c = (c & 0xffffff00L) | '\\'; +      else if (_USE_LFN) { +	 if ((ch > 127) || ((ch < 32) && (ch != 8) && (ch != 0))) +	    return D_O_K; +      } +      else { +	 if ((ch != '\\') && (ch != '_') && (ch != ':') && (ch != '.') && +	     ((ch < 'A') || (ch > 'Z')) && ((ch < '0') || (ch > '9')) && +	     (ch != 8) && (ch != 127) && (ch != 0)) +	    return D_O_K; +      } +   } + +   return d_edit_proc(msg, d, c);  +} + + + +/* fs_flist_putter: + *  Callback routine for for_each_file() to fill the file selector listbox. + */ +static void fs_flist_putter(char *str, int attrib) +{ +   int c, c2; +   char *s, *ext, *tok; +   char tmp[80]; +   static char ext_tokens[] = " ,;"; + +   s = get_filename(str); +   strupr(s); + +   if ((fext) && (!(attrib & FA_DIREC))) { +      strcpy(tmp, fext); +      ext = get_extension(s); +      tok = strtok(tmp, ext_tokens); +      while (tok) { +	 if (stricmp(ext, tok) == 0) +	    break; +	 tok = strtok(NULL, ext_tokens); +      } +      if (!tok) +	 return; +   } + +   if ((flist->size < FLIST_SIZE) && (strcmp(s,".") != 0)) { +      for (c=0; c<flist->size; c++) { +	 if (flist->name[c][strlen(flist->name[c])-1]=='\\') { +	    if (attrib & FA_DIREC) +	       if (strcmp(s, flist->name[c]) < 0) +		  break; +	 } +	 else { +	    if (attrib & FA_DIREC) +	       break; +	    if (strcmp(s, flist->name[c]) < 0) +	       break; +	 } +      } +      for (c2=flist->size; c2>c; c2--) +	 flist->name[c2] = flist->name[c2-1]; + +      flist->name[c] = malloc(strlen(s) + ((attrib & FA_DIREC) ? 2 : 1)); +      strcpy(flist->name[c], s); +      if (attrib & FA_DIREC) +	 put_backslash(flist->name[c]); +      flist->size++; +   } +} + + + +/* fs_flist_getter: + *  Listbox data getter routine for the file selector list. + */ +static char *fs_flist_getter(int index, int *list_size) +{ +   if (index < 0) { +      if (list_size) +	 *list_size = flist->size; +      return NULL; +   } +   return flist->name[index]; +} + + + +/* fs_flist_proc: + *  Dialog procedure for the file selector list. + */ +static int fs_flist_proc(int msg, DIALOG *d, int c) +{ +   int i, ret; +   int sel = d->d1; +   char *s = file_selector[FS_EDIT].dp; +   static int recurse_flag = 0; + +   if (msg == MSG_START) { +      if (!flist) +	 flist = malloc(sizeof(FLIST)); +      else { +	 for (i=0; i<flist->size; i++) +	    if (flist->name[i]) +	       free(flist->name[i]); +      } +      if (!flist) { +	 errno = ENOMEM; +	 return D_CLOSE;  +      } +      flist->size = 0; +      for (i=0; i<flist->size; i++) +	 flist->name[i] = NULL; +      strcpy(flist->dir, s); +      *get_filename(flist->dir) = 0; +      put_backslash(flist->dir); +      strcat(flist->dir,"*.*"); +      for_each_file(flist->dir, FA_RDONLY | FA_DIREC | FA_ARCH, fs_flist_putter, 0); +      if (errno) +	 alert(NULL, "Disk error", NULL, "OK", NULL, 13, 0); +      *get_filename(flist->dir) = 0; +      d->d1 = d->d2 = 0; +      sel = 0; +   } + +   if (msg == MSG_END) { +      if (flist) { +	 for (i=0; i<flist->size; i++) +	    if (flist->name[i]) +	       free(flist->name[i]); +	 free(flist); +      } +      flist = NULL; +   } + +   recurse_flag++; +   ret = my_d_list_proc(msg,d,c);     /* call the parent procedure */ +   recurse_flag--; + +   if (((sel != d->d1) || (ret == D_CLOSE)) && (recurse_flag == 0)) { +      strcpy(s, flist->dir); +      *get_filename(s) = 0; +      put_backslash(s); +      strcat(s, flist->name[d->d1]); +      show_mouse(NULL); +      SEND_MESSAGE(file_selector+FS_EDIT, MSG_START, 0); +      SEND_MESSAGE(file_selector+FS_EDIT, MSG_DRAW, 0); +      show_mouse(screen); + +      if (ret == D_CLOSE) +	 return SEND_MESSAGE(file_selector+FS_EDIT, MSG_KEY, 0); +   } + +   return ret; +} + + + +/* my_file_select: + *  Displays the Allegro file selector, with the message as caption.  + *  Allows the user to select a file, and stores the selection in path  + *  (which should have room for at least 80 characters). The files are + *  filtered according to the file extensions in ext. Passing NULL + *  includes all files, "PCX;BMP" includes only files with .PCX or .BMP + *  extensions. Returns zero if it was closed with the Cancel button,  + *  non-zero if it was OK'd. + */ +int my_file_select(char *message, char *path, char *ext) +{ +   int ret; +   char *p; +   int f; + +   f=0; +   while(file_selector[f].proc) +	{ +	switch(f) +	    { +	    case FS_EDIT: +   	    case FS_FILES: +   	    case FS_DISKS: +	       file_selector[f].fg=ACOL(BLACK); +	       file_selector[f].bg=ACOL(WHITE); +	       break; + +	    default: +	       file_selector[f].fg=gui_fg_color; +	       file_selector[f].bg=gui_bg_color; +	       break; +	    } + +	f++; +	} + +   file_selector[FS_MESSAGE].dp = message; +   file_selector[FS_EDIT].dp = path; +   fext = ext; + +   if (!path[0]) { +      getcwd(path, 80); +      for (p=path; *p; p++) +	 if (*p=='/') +	    *p = '\\'; +	 else +	    *p = toupper(*p); + +      put_backslash(path); +   } + +   clear_keybuf(); + +   do { +   } while (mouse_b); + +   centre_dialog(file_selector); +   ret = do_dialog(file_selector, FS_EDIT); + +   if ((ret == FS_CANCEL) || (*get_filename(path) == 0)) +      return FALSE; + +   p = get_extension(path); +   if ((*p == 0) && (ext) && (!strpbrk(ext, " ,;"))) { +      *p = '.'; +      strcpy(p+1, ext); +   } + +   return TRUE;  +} + + +/* ---------------------------------------- GUI MENU SUPPORT FUNCS +*/ +static void DrawMenuItem(BoundBox *b,char *txt,int sel,PLAT_MENU *child) +{ +    int h,hy; +    int fg; + +    fg=ACOL(GUI_TEXT); + +    if (sel) +    	Rect3D(b->x,b->y,b->w,b->h,FALSE,SMALL_BEVEL); +    else +    	rectfill(screen,b->x,b->y,b->x+b->w-1,b->y+b->h-1,ACOL(GUI_MID)); + +    text_mode(-1); +    textout(screen,font,txt,b->x+SMALL_BEVEL+2,b->y+b->h/2-FH/2,fg); + +    if (child) +    	{ +	h=b->h-(SMALL_BEVEL*2)-2; +	hy=b->y+SMALL_BEVEL+1; + +	line(screen,b->x+b->w-SMALL_BEVEL-2-h/2,hy, +			b->x+b->w-SMALL_BEVEL-2,hy+h/2,ACOL(GUI_HI)); + +	line(screen,b->x+b->w-SMALL_BEVEL-2-h/2,hy, +			b->x+b->w-SMALL_BEVEL-2-h/2,hy+h,ACOL(GUI_HI)); + +	line(screen,b->x+b->w-SMALL_BEVEL-2-h/2,hy+h, +			b->x+b->w-SMALL_BEVEL-2,hy+h/2,ACOL(GUI_LO)); +	} +} + + +static int MouseInBox(BoundBox *box,int no) +{ +    int f; + +    for(f=0;f<no;f++) +    	if (((mouse_x>=box[f].x)&&(mouse_x<box[f].x+box[f].w))&& +	    ((mouse_y>=box[f].y)&&(mouse_y<box[f].y+box[f].h))) +	    return(f); + +    return(-1); +} + + +/* ---------------------------------------- CALLBACK AND HANDLER FUNCTIONS +*/ +static char *picklist_cb(int index,int *size) +{ +    if (index<0) +	{ +    	*size=pick_no; +	return(NULL); +	} +    else +    	return(pick_data[index]); +} + + +static char *img_picklist_cb(int index,int *size) +{ +    if (index<0) +	{ +    	*size=img_pick_no; +	return(NULL); +	} +    else +    	return(img_pick_data[index].text); +} + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static void init_picklist_dialog(char *title,int width) +{ +    static int done=FALSE; + +    width+=15; + +    picklist[PL_BORDER].x=SCRW/2-width/2-20; +    picklist[PL_BORDER].w=width+40; + +    picklist[PL_TITLE].w=width+30; +    picklist[PL_TITLE].dp=title; + +    picklist[PL_PICKLIST].x=SCRW/2-width/2-10; +    picklist[PL_PICKLIST].w=width+20; +    picklist[PL_PICKLIST].d1=0; +    picklist[PL_PICKLIST].d2=0; + +    picklist[PL_OK].x=picklist[PL_PICKLIST].x; +    picklist[PL_OK].w=FW*8; +    picklist[PL_CANCEL].x=picklist[PL_OK].x+picklist[PL_OK].w+20; +    picklist[PL_CANCEL].w=picklist[PL_OK].w; + +    if (done) +	return; + +    done=TRUE; + +    /* Box +    */ +    picklist[PL_BORDER].proc=d_3d_box; +    picklist[PL_BORDER].y=10; +    picklist[PL_BORDER].h=SCRH-20; +    picklist[PL_BORDER].fg=ACOL(GUI_TEXT); +    picklist[PL_BORDER].bg=ACOL(GUI_MID); +    picklist[PL_BORDER].key=0; +    picklist[PL_BORDER].flags=0; +    picklist[PL_BORDER].d1=picklist[PL_BORDER].d2=0; +    picklist[PL_BORDER].dp=picklist[PL_BORDER].dp2=picklist[PL_BORDER].dp3=NULL; + +    /* Title +    */ +    picklist[PL_TITLE].proc=d_my_ctext_proc; +    picklist[PL_TITLE].x=SCRW/2; +    picklist[PL_TITLE].y=20; +    picklist[PL_TITLE].h=10; +    picklist[PL_TITLE].fg=ACOL(GUI_TEXTBOLD); +    picklist[PL_TITLE].bg=ACOL(GUI_MID); +    picklist[PL_TITLE].key=0; +    picklist[PL_TITLE].flags=0; +    picklist[PL_TITLE].d1=picklist[PL_TITLE].d2=0; +    picklist[PL_TITLE].dp2=picklist[PL_TITLE].dp3=NULL; + +    /* List +    */ +    picklist[PL_PICKLIST].proc=my_d_list_proc; +    picklist[PL_PICKLIST].y=30; +    picklist[PL_PICKLIST].h=SCRH-60-FH*2; +    picklist[PL_PICKLIST].fg=ACOL(BLACK); +    picklist[PL_PICKLIST].bg=ACOL(WHITE); +    picklist[PL_PICKLIST].key=0; +    picklist[PL_PICKLIST].flags=D_EXIT; +    picklist[PL_PICKLIST].dp=picklist_cb; +    picklist[PL_PICKLIST].dp2=picklist[PL_PICKLIST].dp3=NULL; + +    /* OK +    */ +    picklist[PL_OK].proc=my_d_button_proc; +    picklist[PL_OK].y=picklist[PL_PICKLIST].y+picklist[PL_PICKLIST].h+7; +    picklist[PL_OK].h=FH+3+BEVEL; +    picklist[PL_OK].fg=ACOL(GUI_TEXT); +    picklist[PL_OK].bg=ACOL(GUI_MID); +    picklist[PL_OK].key=0; +    picklist[PL_OK].flags=D_EXIT; +    picklist[PL_OK].d1=picklist[PL_OK].d2=0; +    picklist[PL_OK].dp="OK"; +    picklist[PL_OK].dp2=picklist[PL_OK].dp3=NULL; + +    /* Cancel +    */ +    picklist[PL_CANCEL].proc=my_d_button_proc; +    picklist[PL_CANCEL].y=picklist[PL_OK].y; +    picklist[PL_CANCEL].h=FH+3+BEVEL; +    picklist[PL_CANCEL].fg=ACOL(GUI_TEXT); +    picklist[PL_CANCEL].bg=ACOL(GUI_MID); +    picklist[PL_CANCEL].key=0; +    picklist[PL_CANCEL].flags=D_EXIT; +    picklist[PL_CANCEL].d1=picklist[PL_CANCEL].d2=0; +    picklist[PL_CANCEL].dp="Cancel"; +    picklist[PL_CANCEL].dp2=picklist[PL_CANCEL].dp3=NULL; + +    memset(&picklist[PL_END],0,sizeof(DIALOG)); +    picklist[PL_END].proc=NULL; +} + + +static void init_img_picklist_dialog(char *title) +{ +    static int done=FALSE; + +    img_picklist[IPL_TITLE].dp=title; + +    img_picklist[IPL_PICKLIST].d1=0; +    img_picklist[IPL_PICKLIST].d2=0; + +    img_picklist[IPL_IMAGE].dp=img_pick_data[0].img; + +    if (done) +	return; + +    done=TRUE; + +    /* Box +    */ +    img_picklist[IPL_BORDER].proc=d_3d_box; +    img_picklist[IPL_BORDER].y=10; +    img_picklist[IPL_BORDER].h=SCRH-20; +    img_picklist[IPL_BORDER].x=10; +    img_picklist[IPL_BORDER].w=SCRW-20; +    img_picklist[IPL_BORDER].fg=ACOL(GUI_TEXT); +    img_picklist[IPL_BORDER].bg=ACOL(GUI_MID); +    img_picklist[IPL_BORDER].key=0; +    img_picklist[IPL_BORDER].flags=0; +    img_picklist[IPL_BORDER].d1=img_picklist[IPL_BORDER].d2=0; +    img_picklist[IPL_BORDER].dp=img_picklist[IPL_BORDER].dp2= +				    img_picklist[IPL_BORDER].dp3=NULL; + +    /* Title +    */ +    img_picklist[IPL_TITLE].proc=d_my_ctext_proc; +    img_picklist[IPL_TITLE].x=SCRW/2; +    img_picklist[IPL_TITLE].w=SCRW-20; +    img_picklist[IPL_TITLE].y=20; +    img_picklist[IPL_TITLE].h=10; +    img_picklist[IPL_TITLE].fg=ACOL(GUI_TEXTBOLD); +    img_picklist[IPL_TITLE].bg=ACOL(GUI_MID); +    img_picklist[IPL_TITLE].key=0; +    img_picklist[IPL_TITLE].flags=0; +    img_picklist[IPL_TITLE].d1=img_picklist[IPL_TITLE].d2=0; +    img_picklist[IPL_TITLE].dp2=img_picklist[IPL_TITLE].dp3=NULL; + +    /* List +    */ +    img_picklist[IPL_PICKLIST].proc=d_img_list_proc; +    img_picklist[IPL_PICKLIST].y=30; +    img_picklist[IPL_PICKLIST].h=SCRH-60-FH*2; +    img_picklist[IPL_PICKLIST].x=30; +    img_picklist[IPL_PICKLIST].w=SCRW/2; +    img_picklist[IPL_PICKLIST].fg=ACOL(BLACK); +    img_picklist[IPL_PICKLIST].bg=ACOL(WHITE); +    img_picklist[IPL_PICKLIST].key=0; +    img_picklist[IPL_PICKLIST].flags=D_EXIT; +    img_picklist[IPL_PICKLIST].dp=img_picklist_cb; +    img_picklist[IPL_PICKLIST].dp2=img_picklist[IPL_PICKLIST].dp3=NULL; + +    /* Image border +    */ +    img_picklist[IPL_IMG_BORDER].proc=d_inv_3d_box; +    img_picklist[IPL_IMG_BORDER].y=30; +    img_picklist[IPL_IMG_BORDER].h=MAX_GFXBM_H+4; +    img_picklist[IPL_IMG_BORDER].x=SCRW-MAX_GFXBM_W-24; +    img_picklist[IPL_IMG_BORDER].w=MAX_GFXBM_W+4; +    img_picklist[IPL_IMG_BORDER].fg=ACOL(WHITE); +    img_picklist[IPL_IMG_BORDER].bg=ACOL(BLACK); +    img_picklist[IPL_IMG_BORDER].key=0; +    img_picklist[IPL_IMG_BORDER].flags=0; +    img_picklist[IPL_IMG_BORDER].dp=img_picklist[IPL_IMG_BORDER].dp2= +    					img_picklist[IPL_IMG_BORDER].dp3=NULL; +    img_picklist[IPL_IMG_BORDER].d1=img_picklist[IPL_IMG_BORDER].d2=0; + +    /* Image  +    */ +    img_picklist[IPL_IMAGE].proc=d_img_bmap_proc; +    img_picklist[IPL_IMAGE].x=SCRW-MAX_GFXBM_W-22; +    img_picklist[IPL_IMAGE].y=32; +    img_picklist[IPL_IMAGE].w=MAX_GFXBM_W; +    img_picklist[IPL_IMAGE].h=MAX_GFXBM_H; +    img_picklist[IPL_IMAGE].fg=ACOL(0); +    img_picklist[IPL_IMAGE].bg=ACOL(0); +    img_picklist[IPL_IMAGE].key=0; +    img_picklist[IPL_IMAGE].flags=0; +    img_picklist[IPL_IMAGE].dp2=img_picklist[IPL_IMAGE].dp3=NULL; +    img_picklist[IPL_IMAGE].d1=img_picklist[IPL_IMAGE].d2=0; + +    /* OK +    */ +    img_picklist[IPL_OK].proc=my_d_button_proc; +    img_picklist[IPL_OK].x=img_picklist[IPL_PICKLIST].x; +    img_picklist[IPL_OK].y=img_picklist[IPL_PICKLIST].y+ +    				img_picklist[IPL_PICKLIST].h+7; +    img_picklist[IPL_OK].w=FW*8; +    img_picklist[IPL_OK].h=FH+3+BEVEL; +    img_picklist[IPL_OK].fg=ACOL(GUI_TEXT); +    img_picklist[IPL_OK].bg=ACOL(GUI_MID); +    img_picklist[IPL_OK].key=0; +    img_picklist[IPL_OK].flags=D_EXIT; +    img_picklist[IPL_OK].d1=img_picklist[IPL_OK].d2=0; +    img_picklist[IPL_OK].dp="OK"; +    img_picklist[IPL_OK].dp2=img_picklist[IPL_OK].dp3=NULL; + +    /* Cancel +    */ +    img_picklist[IPL_CANCEL].proc=my_d_button_proc; +    img_picklist[IPL_CANCEL].x=img_picklist[IPL_OK].x+img_picklist[IPL_OK].w+20; +    img_picklist[IPL_CANCEL].y=img_picklist[IPL_OK].y; +    img_picklist[IPL_CANCEL].w=img_picklist[IPL_OK].w; +    img_picklist[IPL_CANCEL].h=FH+3+BEVEL; +    img_picklist[IPL_CANCEL].fg=ACOL(GUI_TEXT); +    img_picklist[IPL_CANCEL].bg=ACOL(GUI_MID); +    img_picklist[IPL_CANCEL].key=0; +    img_picklist[IPL_CANCEL].flags=D_EXIT; +    img_picklist[IPL_CANCEL].d1=img_picklist[IPL_CANCEL].d2=0; +    img_picklist[IPL_CANCEL].dp="Cancel"; +    img_picklist[IPL_CANCEL].dp2=img_picklist[IPL_CANCEL].dp3=NULL; + +    memset(&img_picklist[IPL_END],0,sizeof(DIALOG)); +    img_picklist[IPL_END].proc=NULL; +} + + +/* ---------------------------------------- EXPORTED FUNCTIONS +*/ + +void GUI_setscreen(int w,int h) +{ +    gui_fg_color=ACOL(GUI_TEXT); +    gui_bg_color=ACOL(GUI_MID); + +    /* Disabled objects are used for bold text +    */ +    gui_mg_color=ACOL(GUI_TEXTBOLD); + +    SCRW=w; +    SCRH=h; + +    FW=GFX_fw(); +    FH=GFX_fh(); +} + + +int GUI_yesno(char *question) +{ +    DIALOG *d; +    char *t; +    char *p; +    int no; +    char *tl[64];	/* Should be enough... */ +    int ml,l; +    int yl; +    int f; +    int h; +    int x,y; +    int ret; + +    t=Strdup(question); + +    no=0; +    p=t; + +    tl[no++]=p; + +    while(*p) +    	{ +	if (*p=='|') +	    { +	    *p++=0; + +	    if (*p) +		tl[no++]=p; +	    } +	else +	    p++; +	} + +    h=(FH+1)*(no+1)+FH*4; + +    ml=FW*14; + +    for(f=0;f<no;f++) +	{ +	l=(strlen(tl[f])+2)*FW; +    	ml=MAX(ml,l); +	} + +    x=SCRW/2-ml/2; +    y=SCRH/2-h/2; + +    d=Grab(sizeof(DIALOG)*(3+no)); + +    /* Surrounding box +    */ +    d[0].proc=d_3d_box; +    d[0].x=x; +    d[0].y=y; +    d[0].w=ml; +    d[0].h=h; +    d[0].fg=ACOL(GUI_TEXT); +    d[0].bg=ACOL(GUI_MID); +    d[0].key=0; +    d[0].flags=0; +    d[0].d1=d[0].d2=0; +    d[0].dp=d[0].dp2=d[0].dp3=NULL; + +    /* Text +    */ +    yl=d[0].y+FH; + +    for(f=0;f<no;f++) +        { +	d[1+f].proc=d_my_ctext_proc; +	d[1+f].x=SCRW/2; +	d[1+f].w=ml-FW; +	d[1+f].y=yl; +	d[1+f].h=FH; +	d[1+f].fg=ACOL(GUI_TEXT); +	d[1+f].bg=ACOL(GUI_MID); +	d[1+f].key=0; +	d[1+f].flags=0; +	d[1+f].d1=d[1+f].d2=0; +	d[1+f].dp=tl[f]; +	d[1+f].dp2=d[1+f].dp3=NULL; + +	yl+=FH+1; +	} + +    /* Yes +    */ +    d[1+no].proc=my_d_button_proc; +    d[1+no].x=x+10; +    d[1+no].w=(ml/2)-20; +    d[1+no].h=FH+3+BEVEL; +    d[1+no].y=y+h-d[1+no].h-5-BEVEL; +    d[1+no].fg=ACOL(GUI_TEXT); +    d[1+no].bg=ACOL(GUI_MID); +    d[1+no].key='Y'; +    d[1+no].flags=D_EXIT; +    d[1+no].d1=d[1+no].d2=0; +    d[1+no].dp="&Yes"; +    d[1+no].dp2=d[1+no].dp3=NULL; + +    /* No +    */ +    d[2+no].proc=my_d_button_proc; +    d[2+no].x=SCRW/2+10; +    d[2+no].y=d[1+no].y; +    d[2+no].w=(ml/2)-20; +    d[2+no].h=d[1+no].h; +    d[2+no].fg=ACOL(GUI_TEXT); +    d[2+no].bg=ACOL(GUI_MID); +    d[2+no].key='N'; +    d[2+no].flags=D_EXIT; +    d[2+no].d1=d[2+no].d2=0; +    d[2+no].dp="&No"; +    d[2+no].dp2=d[2+no].dp3=NULL; + +    d[3+no].proc=NULL; + +    GFX_bounce(); + +    if(do_dialog(d,-1)==(1+no)) +	ret=TRUE; +    else +    	ret=FALSE; + +    GFX_FORCE_REDRAW(); + +    Release(d); +    Release(t); + +    return(ret); +} + + +void GUI_start_yesno_all(void) +{ +    all_pressed=FALSE; +    all_result=FALSE; +} + + +int GUI_yesno_all(char *question) +{ +    DIALOG *d; +    char *t; +    char *p; +    int no; +    char *tl[64];	/* Should be enough... */ +    int ml,l; +    int yl; +    int f; +    int h; +    int x,y; +    int ret; + +    if (all_pressed) +    	return(all_result); + +    t=Strdup(question); + +    no=0; +    p=t; + +    tl[no++]=p; + +    while(*p) +    	{ +	if (*p=='|') +	    { +	    *p++=0; + +	    if (*p) +		tl[no++]=p; +	    } +	else +	    p++; +	} + +    h=(FH+1)*(no+1)+FH*5; + +    ml=FW*26; + +    for(f=0;f<no;f++) +	{ +	l=(strlen(tl[f])+2)*FW; +    	ml=MAX(ml,l); +	} + +    x=SCRW/2-ml/2; +    y=SCRH/2-h/2; + +    d=Grab(sizeof(DIALOG)*(5+no)); + +    /* Surrounding box +    */ +    d[0].proc=d_3d_box; +    d[0].x=x; +    d[0].y=y; +    d[0].w=ml; +    d[0].h=h; +    d[0].fg=ACOL(GUI_TEXT); +    d[0].bg=ACOL(GUI_MID); +    d[0].key=0; +    d[0].flags=0; +    d[0].d1=d[0].d2=0; +    d[0].dp=d[0].dp2=d[0].dp3=NULL; + +    /* Text +    */ +    yl=d[0].y+FH; + +    for(f=0;f<no;f++) +        { +	d[1+f].proc=d_my_ctext_proc; +	d[1+f].x=SCRW/2; +	d[1+f].w=ml-FW; +	d[1+f].y=yl; +	d[1+f].h=FH; +	d[1+f].fg=ACOL(GUI_TEXT); +	d[1+f].bg=ACOL(GUI_MID); +	d[1+f].key=0; +	d[1+f].flags=0; +	d[1+f].d1=d[1+f].d2=0; +	d[1+f].dp=tl[f]; +	d[1+f].dp2=d[1+f].dp3=NULL; + +	yl+=FH+1; +	} + +    /* Yes +    */ +    d[1+no].proc=my_d_button_proc; +    d[1+no].x=x+10; +    d[1+no].w=(ml/2)-20; +    d[1+no].h=FH+3+BEVEL; +    d[1+no].y=y+h-d[1+no].h-5-BEVEL; +    d[1+no].fg=ACOL(GUI_TEXT); +    d[1+no].bg=ACOL(GUI_MID); +    d[1+no].key='Y'; +    d[1+no].flags=D_EXIT; +    d[1+no].d1=d[1+no].d2=0; +    d[1+no].dp="&Yes"; +    d[1+no].dp2=d[1+no].dp3=NULL; + +    /* No +    */ +    d[2+no].proc=my_d_button_proc; +    d[2+no].x=SCRW/2+10; +    d[2+no].y=d[1+no].y; +    d[2+no].w=(ml/2)-20; +    d[2+no].h=d[1+no].h; +    d[2+no].fg=ACOL(GUI_TEXT); +    d[2+no].bg=ACOL(GUI_MID); +    d[2+no].key='N'; +    d[2+no].flags=D_EXIT; +    d[2+no].d1=d[2+no].d2=0; +    d[2+no].dp="&No"; +    d[2+no].dp2=d[2+no].dp3=NULL; + +    /* Yes to All +    */ +    d[3+no].proc=my_d_button_proc; +    d[3+no].x=x+10; +    d[3+no].w=(ml/2)-20; +    d[3+no].h=FH+3+BEVEL; +    d[3+no].y=y+h-d[1+no].h-5-BEVEL; +    d[3+no].fg=ACOL(GUI_TEXT); +    d[3+no].bg=ACOL(GUI_MID); +    d[3+no].key='A'; +    d[3+no].flags=D_EXIT; +    d[3+no].d1=d[3+no].d2=0; +    d[3+no].dp="Yes to &All"; +    d[3+no].dp2=d[3+no].dp3=NULL; + +    /* Yes to All +    */ +    d[4+no].proc=my_d_button_proc; +    d[4+no].x=SCRW/2+10; +    d[4+no].w=(ml/2)-20; +    d[4+no].h=FH+3+BEVEL; +    d[4+no].y=y+h-d[1+no].h-5-BEVEL; +    d[4+no].fg=ACOL(GUI_TEXT); +    d[4+no].bg=ACOL(GUI_MID); +    d[4+no].key='O'; +    d[4+no].flags=D_EXIT; +    d[4+no].d1=d[4+no].d2=0; +    d[4+no].dp="N&o to All"; +    d[4+no].dp2=d[4+no].dp3=NULL; + +    d[1+no].y=d[3+no].y-FH*2; +    d[2+no].y=d[4+no].y-FH*2; + +    d[5+no].proc=NULL; + +    GFX_bounce(); + +    ret=do_dialog(d,-1); + +    if (ret==(1+no)) +	all_result=TRUE; +    else if (ret==(2+no)) +	all_result=FALSE; +    else if (ret==(3+no)) +	{ +	all_result=TRUE; +	all_pressed=TRUE; +	} +    else if (ret==(4+no)) +	{ +	all_result=FALSE; +	all_pressed=TRUE; +	} + +    GFX_FORCE_REDRAW(); + +    Release(d); +    Release(t); + +    return(all_result); +} + + +void GUI_alert(char *title, char *text, char *button_text) +{ +    DIALOG *d; +    char *t; +    char *p; +    int no; +    char *tl[64];	/* Should be enough... */ +    int ml,l; +    int yl; +    int f; +    int h; +    int x,y; + +    t=Strdup(text); + +    no=0; +    p=t; + +    tl[no++]=p; + +    while(*p) +    	{ +	if (*p=='|') +	    { +	    *p++=0; + +	    if (*p) +		tl[no++]=p; +	    } +	else +	    p++; +	} + +    h=(FH+1)*(no+2)+FH*4; + +    ml=(strlen(button_text)+2)*FW; + +    l=(strlen(title)+2)*FW; +    ml=MAX(ml,l); + +    for(f=0;f<no;f++) +	{ +	l=(strlen(tl[f])+2)*FW; +    	ml=MAX(ml,l); +	} + +    x=SCRW/2-ml/2; +    y=SCRH/2-h/2; + +    d=Grab(sizeof(DIALOG)*(4+no)); + +    /* Surrounding box +    */ +    d[0].proc=d_3d_box; +    d[0].x=x; +    d[0].y=y; +    d[0].w=ml; +    d[0].h=h; +    d[0].fg=ACOL(GUI_TEXT); +    d[0].bg=ACOL(GUI_MID); +    d[0].key=0; +    d[0].flags=0; +    d[0].d1=d[0].d2=0; +    d[0].dp=d[0].dp2=d[0].dp3=NULL; + +    /* Title +    */ +    d[1].proc=d_title_proc; +    d[1].x=SCRW/2; +    d[1].w=ml-FW; +    d[1].y=y+BEVEL+2; +    d[1].h=FH; +    d[1].fg=ACOL(GUI_TEXTBOLD); +    d[1].bg=ACOL(GUI_MID); +    d[1].key=0; +    d[1].flags=0; +    d[1].d1=d[1].d2=0; +    d[1].dp=title; +    d[1].dp2=d[1].dp3=NULL; + +    /* Text +    */ +    yl=d[1].y+FH*2; + +    for(f=0;f<no;f++) +        { +	d[2+f].proc=d_my_ctext_proc; +	d[2+f].x=SCRW/2; +	d[2+f].w=ml-FW; +	d[2+f].y=yl; +	d[2+f].h=FH; +	d[2+f].fg=ACOL(GUI_TEXT); +	d[2+f].bg=ACOL(GUI_MID); +	d[2+f].key=0; +	d[2+f].flags=0; +	d[2+f].d1=d[2+f].d2=0; +	d[2+f].dp=tl[f]; +	d[2+f].dp2=d[2+f].dp3=NULL; + +	yl+=FH+1; +	} + +    /* Button +    */ +    d[2+no].proc=my_d_button_proc; +    d[2+no].w=((strlen(button_text)+1)*FW)+BEVEL*2; +    d[2+no].x=SCRW/2-d[2+no].w/2; +    d[2+no].h=FH+3+BEVEL; +    d[2+no].y=y+h-d[2+no].h-5-BEVEL; +    d[2+no].fg=ACOL(GUI_TEXT); +    d[2+no].bg=ACOL(GUI_MID); +    d[2+no].key='\r'; +    d[2+no].flags=D_EXIT; +    d[2+no].d1=d[2+no].d2=0; +    d[2+no].dp=button_text; +    d[2+no].dp2=d[2+no].dp3=NULL; + +    d[3+no].proc=NULL; + +    GFX_bounce(); + +    do_dialog(d,2+no); + +    GFX_FORCE_REDRAW(); +    Release(d); +    Release(t); +} + + +static MenuControl do_GUI_menu(char *title, int x, int y, +			PLAT_MENU menu[],int defval,int is_child) +{ +    MenuControl ret; +    MenuControl cr; +    int lx,ly; +    int no; +    int f; +    BITMAP *under; +    int cur; +    int last_cur; +    int cx; +    int by; +    int done; +    int quit; +    int child_done; +    BoundBox *box; +    BoundBox menu_box; +    int do_child; + +    /* Calc dimensions +    */ +    no=0; +    menu_box.x=x; +    menu_box.y=y; +    menu_box.w=text_length(font,title); + +    while(menu[no].text) +	{ +	int l; + +	l=text_length(font,menu[no].text)+(menu[no].child ? 12 : 0); +	menu_box.w=MAX(menu_box.w,l); +    	no++; +	} + +    menu_box.h=BEVEL*2+FH+4; +    menu_box.h+=(FH+SMALL_BEVEL*2+2)*no; +    menu_box.h+=2; +    menu_box.w+=BEVEL+SMALL_BEVEL+4; + +    box=Grab(sizeof(BoundBox)*no); + +    if ((menu_box.x+menu_box.w)>SCRW) +    	menu_box.x=SCRW-menu_box.w; + +    if ((menu_box.y+menu_box.h)>SCRH) +    	menu_box.y=SCRH-menu_box.h; + +    if ((menu_box.x<0)||(menu_box.y<0)) +    	{ +	alert("Cannot display menu:",title,"Menu is bigger than display!", +				"OK",NULL,0,0); + +	ret.mode=MENU_CHILD_RETURN; +	ret.ret=defval; + +	return(ret); +	} + +    cx=menu_box.x+menu_box.w/2; + +    /* Save screen contents +    */ +    show_mouse(NULL); + +    if (!(under=create_bitmap(menu_box.w+1,menu_box.h+1))) +    	GFX_exit(EXIT_FAILURE,"No more memory to create MENU save under\n"); + +    blit(screen,under,menu_box.x,menu_box.y,0,0,menu_box.w+1,menu_box.h+1); + +    /* Draw menu border and title +    */ +    Rect3D(menu_box.x,menu_box.y,menu_box.w,menu_box.h,FALSE,BEVEL); +    text_mode(-1); +    textout_centre(screen,font,title,cx,menu_box.y+BEVEL*2,ACOL(GUI_TEXTBOLD)); + +    /* Draw menu items +    */ +    cur=0; +    last_cur=-1; + +    by=menu_box.y+BEVEL*2+FH+4; + +    for(f=0;f<no;f++) +	{ +	box[f].x=menu_box.x+BEVEL; +	box[f].y=by; +	box[f].w=menu_box.w-BEVEL*2; +	box[f].h=FH+SMALL_BEVEL*2+2; +	by+=box[f].h; + +	DrawMenuItem(&box[f],menu[f].text,(f==cur),menu[f].child); +	} + +    show_mouse(screen); +    GFX_bounce(); + +    /* Main loop +    */ +    quit=FALSE; +    done=FALSE; +    child_done=FALSE; +    lx=mouse_x; +    ly=mouse_y; +    do_child=FALSE; + +    while((!done)&&(!quit)&&(!child_done)) +    	{ +	/* Handle input +	*/ +	if (!do_child) +	    { +	    if (mouse_b) +		{ +		int new; + +		new=MouseInBox(box,no); + +		if (new==-1) +		    { +		    if (MouseInBox(&menu_box,1)==-1) +		    	{ +			quit=TRUE; +			ret.mode=MENU_CANCEL_CLICK; + +			while(mouse_b); +			} +		    } +		else +		    { +		    if (menu[new].child) +			{ +			cur=new; +			while(mouse_b); +			do_child=TRUE; +			} +		    else +			{ +			done=TRUE; +			cur=new; +			ret.mode=MENU_OK; +			while(mouse_b); +			} +		    } +		} +	    else if (keypressed()) +		switch(readkey()>>8) +		    { +		    case KEY_ESC: +			quit=TRUE; +			ret.mode=MENU_CANCEL_ESC; +			break; + +		    case KEY_ENTER: +			ret.mode=MENU_OK; +			done=TRUE; +			break; + +		    case KEY_DOWN: +			show_mouse(NULL); +			DrawMenuItem(&box[cur],menu[cur].text,FALSE, +							menu[cur].child); + +			cur=(cur+1)%no; + +			DrawMenuItem(&box[cur],menu[cur].text,TRUE, +							menu[cur].child); +			show_mouse(screen); +			break; + +		    case KEY_UP: +			show_mouse(NULL); +			DrawMenuItem(&box[cur],menu[cur].text,FALSE, +							menu[cur].child); + +			if (cur) +			    cur--; +			else +			    cur=no-1; + +			DrawMenuItem(&box[cur],menu[cur].text,TRUE, +							menu[cur].child); +			show_mouse(screen); +			break; + +		    case KEY_RIGHT: +			if (menu[cur].child) +			    do_child=TRUE; + +			break; + +		    case KEY_LEFT: +			if (is_child) +			    { +			    quit=TRUE; +			    ret.mode=MENU_CHILD_RETURN; +			    } +			break; +		    } +	    else if ((lx!=mouse_x)||(ly!=mouse_y)) +		{ +		int new; + +		lx=mouse_x; +		ly=mouse_y; + +		new=MouseInBox(box,no); + +		if (new!=-1) +		    cur=new; +		} +	    } + + +	/* Draw menu selection if changed +	*/ +	if (cur!=last_cur) +	    { +	    show_mouse(NULL); + +	    if (last_cur!=-1) +		DrawMenuItem(&box[last_cur],menu[last_cur].text,FALSE, +						    menu[last_cur].child); + +	    DrawMenuItem(&box[cur],menu[cur].text,TRUE, +					    menu[cur].child); +	    show_mouse(screen); +	    } + +	last_cur=cur; + +	/* Handle child menus +	*/ +	if (do_child) +	    { +	    do_child=FALSE; + +	    cr=do_GUI_menu(menu[cur].text, +			   box[cur].x+box[cur].w,box[cur].y, +			   menu[cur].child,defval,TRUE); + +	    switch(cr.mode) +		{ +		case MENU_OK: +		    child_done=TRUE; +		    break; + +		case MENU_CANCEL_ESC: +		    quit=TRUE; +		    ret.mode=MENU_CANCEL_ESC; +		    break; + +		case MENU_CANCEL_CLICK: +		    if (MouseInBox(&menu_box,1)==-1) +			{ +			quit=TRUE; +			ret.mode=MENU_CANCEL_CLICK; +			} +		    else +		    	{ +			if ((cur=MouseInBox(box,no))==-1) +			    cur=0; +			else if (menu[cur].child) +			    do_child=TRUE; +			} + +		    break; + +		case MENU_CHILD_RETURN: +		    break; +		} +	    } +	} + +    show_mouse(NULL); +    blit(under,screen,0,0,menu_box.x,menu_box.y,menu_box.w+1,menu_box.h+1); +    show_mouse(screen); +    destroy_bitmap(under); +    Release(box); + +    if (child_done) +    	ret=cr; +    else +    	{ +	if (!quit) +	    ret.ret=menu[cur].client_index; +	else +	    ret.ret=defval; +	} + +    return(ret); +} + + +int GUI_menu(char *title, int x, int y, PLAT_MENU menu[],int defval) +{ +    return(do_GUI_menu(title,x,y,menu,defval,FALSE).ret); +} + + +char *GUI_fsel(char *title, char *default_path, char *filter) +{ +    int ret; +    char path[PATH_MAX+1]; + +    if ((filter)&&(*filter=='.')) +    	filter++; + +    strcpy(path,default_path); + +    GFX_bounce(); + +    ret=my_file_select(title,path,filter); + +    GFX_FORCE_REDRAW(); + +    if (ret) +    	return(Strdup(path)); + +    return(NULL); +} + + +int GUI_picklist(char *title,char *opt[]) +{ +    int ml; +    int ret; + +    pick_no=0; + +    /* Enough room for the OK/CANCEL +    */ +    ml=(FW*16)+30; +    ml=MAX(ml,gui_strlen(title)); + +    while(opt[pick_no]) +	{ +        if (gui_strlen(opt[pick_no])>ml) +	    ml=gui_strlen(opt[pick_no]); +    	pick_no++; +	} + +    pick_data=opt; + +    init_picklist_dialog(title,ml); + +    GFX_bounce(); +    ret=do_dialog(picklist,-1); +    GFX_FORCE_REDRAW(); + +    switch(ret) +    	{ +	case PL_OK: +	case PL_PICKLIST: +	    return(picklist[IPL_PICKLIST].d1); +	    break; + +	default: +	    return(-1); +	    break; +	} +} + + +int GUI_client_picklist(char *title,PLAT_PICKLIST opt[],int defval) +{ +    int ml; +    int ret; +    char **c_opt; +    int f; + +    pick_no=0; + +    /* Enough room for the OK/CANCEL +    */ +    ml=(FW*16)+30; +    ml=MAX(ml,gui_strlen(title)); + +    while(opt[pick_no].text) +	{ +        if (gui_strlen(opt[pick_no].text)>ml) +	    ml=gui_strlen(opt[pick_no].text); +    	pick_no++; +	} + +    c_opt=Grab(sizeof(char *)*(pick_no+1)); + +    for(f=0;f<pick_no;f++) +    	c_opt[f]=opt[f].text; + +    c_opt[f]=NULL; + +    pick_data=c_opt; + +    init_picklist_dialog(title,ml); + +    GFX_bounce(); +    ret=do_dialog(picklist,-1); +    GFX_FORCE_REDRAW(); +    Release(c_opt); + +    switch(ret) +    	{ +	case PL_OK: +	case PL_PICKLIST: +	    return(opt[picklist[PL_PICKLIST].d1].client_index); +	    break; + +	default: +	    return(defval); +	    break; +	} +} + + +int GUI_image_picklist(char *title,PLAT_IMG_PICKLIST opt[],int defval) +{ +    int ret; + +    img_pick_no=0; +    while(opt[img_pick_no].text) +    	img_pick_no++; + +    img_pick_data=opt; + +    init_img_picklist_dialog(title); + +    GFX_bounce(); +    ret=do_dialog(img_picklist,-1); +    GFX_FORCE_REDRAW(); + +    if (ret==-1) +    	return(defval); + +    switch(ret) +    	{ +	case IPL_OK: +	case IPL_PICKLIST: +	    return(opt[img_picklist[IPL_PICKLIST].d1].client_index); +	    break; + +	default: +	    return(defval); +	    break; +	} +} + + +int GUI_radio_box(char *title,PLAT_RADIO opt[],int current,int defval) +{ +    int no; +    DIALOG *d; +    int ml,l; +    int h; +    int f; +    int ret; +    int x,y; + +    no=0; +    while(opt[no].text) +    	no++; + +    d=Grab(sizeof(DIALOG)*(no+6)); + +    h=(FH+5)*no; +    ml=text_length(font,"CANCEL  CANCEL"); + +    for(f=0;f<no;f++) +        if ((l=text_length(font,opt[f].text))>ml) +	    ml=l; + +    h+=FH*4; +    ml+=FW*4; +    x=SCRW/2-ml/2; +    y=SCRH/2-h/2; + +    /* Surrounding box +    */ +    d[0].proc=d_3d_box; +    d[0].x=x; +    d[0].y=y; +    d[0].w=ml; +    d[0].h=h; +    d[0].fg=ACOL(GUI_TEXT); +    d[0].bg=ACOL(GUI_MID); +    d[0].key=0; +    d[0].flags=0; +    d[0].d1=d[0].d2=0; +    d[0].dp=d[0].dp2=d[0].dp3=NULL; + +    /* Title +    */ +    d[1].proc=d_my_ctext_proc; +    d[1].x=SCRW/2; +    d[1].w=ml-20; +    d[1].y=y+10; +    d[1].h=10; +    d[1].fg=ACOL(GUI_TEXTBOLD); +    d[1].bg=ACOL(GUI_MID); +    d[1].key=0; +    d[1].flags=0; +    d[1].d1=d[1].d2=0; +    d[1].dp=title; +    d[1].dp2=d[1].dp3=NULL; + +    /* OK +    */ +    d[2].proc=my_d_button_proc; +    d[2].x=x+10; +    d[2].y=y+h-15; +    d[2].w=(ml/2)-20; +    d[2].h=10+BEVEL; +    d[2].fg=ACOL(GUI_TEXT); +    d[2].bg=ACOL(GUI_MID); +    d[2].key=0; +    d[2].flags=D_EXIT; +    d[2].d1=d[2].d2=0; +    d[2].dp="OK"; +    d[2].dp2=d[2].dp3=NULL; + +    /* CANCEL +    */ +    d[3].proc=my_d_button_proc; +    d[3].x=SCRW/2+10; +    d[3].y=y+h-15; +    d[3].w=(ml/2)-20; +    d[3].h=10+BEVEL; +    d[3].fg=ACOL(GUI_TEXT); +    d[3].bg=ACOL(GUI_MID); +    d[3].key=0; +    d[3].flags=D_EXIT; +    d[3].d1=d[3].d2=0; +    d[3].dp="Cancel"; +    d[3].dp2=d[3].dp3=NULL; + +    /* Buttons +    */ +    for(f=0;f<no;f++) +    	{ +	d[4+f].proc=my_d_radio_proc; +	d[4+f].x=x+10; +	d[4+f].y=y+20+f*10; +	d[4+f].w=ml-20; +	d[4+f].h=10; +	d[4+f].fg=ACOL(GUI_TEXT); +	d[4+f].bg=ACOL(GUI_MID); +	d[4+f].key=0; +	d[4+f].flags=(f==0 ? D_SELECTED : 0); +	d[4+f].d1=d[4+f].d2=0; +	d[4+f].dp=opt[f].text; +	d[4+f].dp2=d[4+f].dp3=NULL; +	} + +    d[4+no].proc=NULL; + +    for(f=0;f<no;f++) +    	if (opt[f].client_index==current) +	    { +	    d[4].flags=0; +	    d[4+f].flags=D_SELECTED; +	    } + +    ret=defval; + +    GFX_bounce(); +    if(do_dialog(d,-1)==2) +	for(f=0;f<no;f++) +	    if (d[4+f].flags&D_SELECTED) +		ret=opt[f].client_index; + +    Release(d); + +    return(ret); +} + + +int GUI_multi_box(char *title,PLAT_MULTI p[]) +{ +    int no; +    DIALOG *d; +    int ml,l; +    int h; +    int f; +    int ret; +    int x,y; + +    no=0; +    while(p[no].text) +    	no++; + +    d=Grab(sizeof(DIALOG)*(no+6)); + +    h=(FH+5)*no; +    ml=text_length(font,"CANCEL  CANCEL"); + +    for(f=0;f<no;f++) +        if ((l=text_length(font,p[f].text))>ml) +	    ml=l; + +    h+=FH*4; +    ml+=FW*4; +    x=SCRW/2-ml/2; +    y=SCRH/2-h/2; + +    /* Surrounding box +    */ +    d[0].proc=d_3d_box; +    d[0].x=x; +    d[0].y=y; +    d[0].w=ml; +    d[0].h=h; +    d[0].fg=ACOL(GUI_TEXT); +    d[0].bg=ACOL(GUI_MID); +    d[0].key=0; +    d[0].flags=0; +    d[0].d1=d[0].d2=0; +    d[0].dp=d[0].dp2=d[0].dp3=NULL; + +    /* Title +    */ +    d[1].proc=d_my_ctext_proc; +    d[1].x=SCRW/2; +    d[1].w=ml-20; +    d[1].y=y+10; +    d[1].h=10; +    d[1].fg=ACOL(GUI_TEXTBOLD); +    d[1].bg=ACOL(GUI_MID); +    d[1].key=0; +    d[1].flags=0; +    d[1].d1=d[1].d2=0; +    d[1].dp=title; +    d[1].dp2=d[1].dp3=NULL; + +    /* OK +    */ +    d[2].proc=my_d_button_proc; +    d[2].x=x+10; +    d[2].y=y+h-15; +    d[2].w=(ml/2)-20; +    d[2].h=10+BEVEL; +    d[2].fg=ACOL(GUI_TEXT); +    d[2].bg=ACOL(GUI_MID); +    d[2].key=0; +    d[2].flags=D_EXIT; +    d[2].d1=d[2].d2=0; +    d[2].dp="OK"; +    d[2].dp2=d[2].dp3=NULL; + +    /* CANCEL +    */ +    d[3].proc=my_d_button_proc; +    d[3].x=SCRW/2+10; +    d[3].y=y+h-15; +    d[3].w=(ml/2)-20; +    d[3].h=10+BEVEL; +    d[3].fg=ACOL(GUI_TEXT); +    d[3].bg=ACOL(GUI_MID); +    d[3].key=0; +    d[3].flags=D_EXIT; +    d[3].d1=d[3].d2=0; +    d[3].dp="Cancel"; +    d[3].dp2=d[3].dp3=NULL; + +    /* Buttons  +    */ +    for(f=0;f<no;f++) +    	{ +	d[4+f].proc=my_d_check_proc; +	d[4+f].x=x+10; +	d[4+f].y=y+20+f*10; +	d[4+f].w=ml-20; +	d[4+f].h=10; +	d[4+f].fg=ACOL(GUI_TEXT); +	d[4+f].bg=ACOL(GUI_MID); +	d[4+f].key=0; + +	if (p[f].val) +	    d[4+f].flags=D_SELECTED; +	else +	    d[4+f].flags=0; + +	d[4+f].d1=p[f].group; +	d[4+f].d2=0; +	d[4+f].dp=p[f].text; +	d[4+f].dp2=d[4+f].dp3=NULL; +	} + +    d[4+no].proc=NULL; + +    GFX_bounce(); + +    if(do_dialog(d,-1)==2) +	{ +	for(f=0;f<no;f++) +	    if (d[4+f].flags&D_SELECTED) +		p[f].val=TRUE; +	    else +		p[f].val=FALSE; + +	ret=TRUE; +	} +    else +    	ret=FALSE; + +    GFX_FORCE_REDRAW(); +    Release(d); + +    return(ret); +} + + +int GUI_dialog(char *title, int no, PLAT_DIALOG pd[]) +{ +    DIALOG *d; +    int tl,ml,pl,l; +    int h; +    int f,r; +    int ret; +    int x,y; +    char *p; +    int tmp; +    double d_tmp; + +    d=Grab(sizeof(DIALOG)*(no*3+6)); + +    h=(FH+10)*no; +    tl=0; + +    for(f=0;f<no;f++) +        if ((pd[f].text)&&((l=text_length(font,pd[f].text))>tl)) +	    tl=l; + +    pl=DIALOG_STRLEN*FW; + +    for(f=0;f<no;f++) +    	if (pd[f].type==PLAT_DIAL_PICKLIST) +	    for(r=0;r<pd[f].data.pl.no;r++) +		if ((l=text_length(font,pd[f].data.pl.text[r])+10)>pl) +		    pl=l; + +    ml=tl+pl+(FW*4); + +    if (ml<(text_length(font,title)+FW*4)) +	ml=text_length(font,title)+FW*4; + +    h+=FH*5; +    x=SCRW/2-ml/2; +    y=SCRH/2-h/2; + +    /* Surrounding box +    */ +    d[0].proc=d_3d_box; +    d[0].x=x; +    d[0].y=y; +    d[0].w=ml; +    d[0].h=h; +    d[0].fg=ACOL(GUI_TEXT); +    d[0].bg=ACOL(GUI_MID); +    d[0].key=0; +    d[0].flags=0; +    d[0].d1=d[0].d2=0; +    d[0].dp=d[0].dp2=d[0].dp3=NULL; + +    /* Title +    */ +    d[1].proc=d_my_ctext_proc; +    d[1].x=SCRW/2; +    d[1].w=ml-20; +    d[1].y=y+3; +    d[1].h=10; +    d[1].fg=ACOL(GUI_TEXTBOLD); +    d[1].bg=ACOL(GUI_MID); +    d[1].key=0; +    d[1].flags=0; +    d[1].d1=d[1].d2=0; +    d[1].dp=title; +    d[1].dp2=d[1].dp3=NULL; + +    /* OK +    */ +    d[2].proc=my_d_button_proc; +    d[2].x=x+10; +    d[2].w=(ml/2)-20; +    d[2].h=FH+3+BEVEL; +    d[2].y=y+h-d[2].h-5-BEVEL; +    d[2].fg=ACOL(GUI_TEXT); +    d[2].bg=ACOL(GUI_MID); +    d[2].key=0; +    d[2].flags=D_EXIT; +    d[2].d1=d[2].d2=0; +    d[2].dp="OK"; +    d[2].dp2=d[2].dp3=NULL; + +    /* CANCEL +    */ +    d[3].proc=my_d_button_proc; +    d[3].x=SCRW/2+10; +    d[3].y=d[2].y; +    d[3].w=(ml/2)-20; +    d[3].h=d[2].h; +    d[3].fg=ACOL(GUI_TEXT); +    d[3].bg=ACOL(GUI_MID); +    d[3].key=0; +    d[3].flags=D_EXIT; +    d[3].d1=d[3].d2=0; +    d[3].dp="Cancel"; +    d[3].dp2=d[3].dp3=NULL; + +    /* Labels and text entries +    */ +    for(f=0;f<no;f++) +    	{ +	if (pd[f].text) +	    p=pd[f].text; +	else +	    p=""; + +	d[4+(f*3)].proc=d_my_text_proc; +	d[4+(f*3)].x=x+FW; +	d[4+(f*3)].y=y+23+f*15; +	d[4+(f*3)].w=text_length(font,p); +	d[4+(f*3)].h=10; +	d[4+(f*3)].fg=ACOL(GUI_TEXT); +	d[4+(f*3)].bg=ACOL(GUI_MID); +	d[4+(f*3)].key=0; +	d[4+(f*3)].flags=0; +	d[4+(f*3)].d1=0; +	d[4+(f*3)].d2=0; +	d[4+(f*3)].dp=p; +	d[4+(f*3)].dp2=d[4+(f*3)].dp3=NULL; + +	if (pd[f].type==PLAT_DIAL_PICKLIST) +	    { +	    d[5+(f*3)].proc=d_inv_3d_box; +	    d[5+(f*3)].x=d[4+(f*3)].x+tl+FW; +	    d[5+(f*3)].y=y+21+f*15; +	    d[5+(f*3)].h=FH+BEVEL*2; +	    d[5+(f*3)].fg=ACOL(GUI_LO); +	    d[5+(f*3)].bg=ACOL(GUI_MID); +	    d[5+(f*3)].key=0; +	    d[5+(f*3)].flags=0; +	    d[5+(f*3)].d1=d[5+(f*3)].d2=0; +	    d[5+(f*3)].dp=d[5+(f*3)].dp2=d[5+(f*3)].dp3=NULL; + +	    d[6+(f*3)].w=0; + +	    for(r=0;r<pd[f].data.pl.no;r++) +		if ((l=text_length(font,pd[f].data.pl.text[r])+10)>d[6+(f*3)].w) +		    d[6+(f*3)].w=l; + +	    d[5+(f*3)].w=d[6+(f*3)].w+BEVEL*2; + +	    d[6+(f*3)].proc=d_dial_picklist; +	    d[6+(f*3)].x=d[5+(f*3)].x+BEVEL; +	    d[6+(f*3)].y=y+20+BEVEL+1+f*15; +	    d[6+(f*3)].h=FH; +	    d[6+(f*3)].fg=ACOL(BLACK); +	    d[6+(f*3)].bg=ACOL(WHITE); +	    d[6+(f*3)].key=0; +	    d[6+(f*3)].flags=0; +	    d[6+(f*3)].d1=pd[f].data.pl.current; +	    d[6+(f*3)].d2=pd[f].data.pl.no; +	    d[6+(f*3)].dp=pd[f].data.pl.text; +	    d[6+(f*3)].dp2=d[6+(f*3)].dp3=NULL; +	    } +	else +	    { +	    if (pd[f].type==PLAT_DIAL_INTEGER) +		{ +		tmp=pd[f].data.i; +		sprintf(pd[f].data.s,"%d",tmp); +		} + +	    if (pd[f].type==PLAT_DIAL_DOUBLE) +		{ +		d_tmp=pd[f].data.d; +		sprintf(pd[f].data.s,"%G",d_tmp); +		} + +	    d[5+(f*3)].proc=d_inv_3d_box; +	    d[5+(f*3)].x=d[4+(f*3)].x+tl+FW; +	    d[5+(f*3)].y=y+21+f*15; +	    d[5+(f*3)].w=text_length(font," ")*DIALOG_STRLEN+2*BEVEL; +	    d[5+(f*3)].h=8+BEVEL*2; +	    d[5+(f*3)].fg=ACOL(GUI_LO); +	    d[5+(f*3)].bg=ACOL(GUI_MID); +	    d[5+(f*3)].key=0; +	    d[5+(f*3)].flags=0; +	    d[5+(f*3)].d1=d[5+(f*3)].d2=0; +	    d[5+(f*3)].dp=d[5+(f*3)].dp2=d[5+(f*3)].dp3=NULL; + +	    d[6+(f*3)].proc=d_edit_proc; +	    d[6+(f*3)].x=d[5+(f*3)].x+BEVEL; +	    d[6+(f*3)].y=y+20+BEVEL+1+f*15; +	    d[6+(f*3)].w=text_length(font," ")*DIALOG_STRLEN; +	    d[6+(f*3)].h=10; +	    /* +	    d[6+(f*3)].fg=ACOL(GUI_TEXT); +	    d[6+(f*3)].bg=ACOL(GUI_MID); +	    */ +	    d[6+(f*3)].fg=ACOL(BLACK); +	    d[6+(f*3)].bg=ACOL(WHITE); +	    d[6+(f*3)].key=0; +	    d[6+(f*3)].flags=0; +	    d[6+(f*3)].d1=PLAT_DIAL_MAXSTRLEN; +	    d[6+(f*3)].d2=strlen(pd[f].data.s); +	    d[6+(f*3)].dp=pd[f].data.s; +	    d[6+(f*3)].dp2=d[6+(f*3)].dp3=NULL; +	    } +	} + +    d[4+(no*3)].proc=NULL; + +    GFX_bounce(); +    if(do_dialog(d,-1)==2) +	{ +	for(f=0;f<no;f++) +	    { +	    if (pd[f].type==PLAT_DIAL_INTEGER) +		{ +		tmp=(int)strtol(pd[f].data.s,NULL,0); +	        pd[f].data.i=tmp; +		} +	    else if (pd[f].type==PLAT_DIAL_DOUBLE) +		{ +		d_tmp=strtod(pd[f].data.s,NULL); +	        pd[f].data.d=d_tmp; +		} +	    else if (pd[f].type==PLAT_DIAL_PICKLIST) +	    	pd[f].data.pl.current=d[6+(f*3)].d1; +	    } + +	ret=TRUE; +	} +    else +    	ret=FALSE; + +    GFX_FORCE_REDRAW(); +    Release(d); + +    return(ret); +} + + +void GUI_view_file (char *title, char *path) +{ +    FILE *fp; +    int no; +    char s[BUFF_LEN]; +    char **line; +    int f; +    int ml; +    int bw; +    int bh; + +    if ((fp=fopen(path,"r"))) +    	{ +	no=0; +	fgets(s,BUFF_LEN,fp); + +	while(!feof(fp)) +	    { +	    no++; +	    fgets(s,BUFF_LEN,fp); +	    } + +	fclose(fp); + +	line=Grab(sizeof(char *)*(no+1)); + +	f=0; +	fp=fopen(path,"r"); + +	fgets(s,BUFF_LEN,fp); + +	ml=0; + +	while(!feof(fp)) +	    { +	    line[f]=Strdup(ConvertFileText(s)); +	    ml=MAX(ml,strlen(line[f])); +	    f++; +	    fgets(s,BUFF_LEN,fp); +	    } + +	fclose(fp); + +	line[f]=NULL; +	} +    else +	{ +	no=2; +	ml=0; +	line=Grab(sizeof(char *)*3); +	line[0]=Strdup("File not found:"); +	line[1]=Strdup(path); +	line[2]=NULL; +	} + +    bw=FV_WIDTH*FW+20+FV_SCROLLWIDTH; +    bh=FV_HEIGHT*FH+20+FV_SCROLLWIDTH+20+FH*2; + +    /* Box +    */ +    fv_dialog[FV_BORDER].proc=d_3d_box; +    fv_dialog[FV_BORDER].y=0; +    fv_dialog[FV_BORDER].h=bh; +    fv_dialog[FV_BORDER].x=0; +    fv_dialog[FV_BORDER].w=bw; +    fv_dialog[FV_BORDER].fg=ACOL(GUI_TEXT); +    fv_dialog[FV_BORDER].bg=ACOL(GUI_MID); +    fv_dialog[FV_BORDER].key=0; +    fv_dialog[FV_BORDER].flags=0; +    fv_dialog[FV_BORDER].d1=fv_dialog[FV_BORDER].d2=0; +    fv_dialog[FV_BORDER].dp=fv_dialog[FV_BORDER].dp2= +				    fv_dialog[FV_BORDER].dp3=NULL; + +    /* Title +    */ +    fv_dialog[FV_TITLE].proc=d_my_ctext_proc; +    fv_dialog[FV_TITLE].x=bw/2; +    fv_dialog[FV_TITLE].w=bw-20; +    fv_dialog[FV_TITLE].y=BEVEL+5; +    fv_dialog[FV_TITLE].h=FH; +    fv_dialog[FV_TITLE].fg=ACOL(GUI_TEXTBOLD); +    fv_dialog[FV_TITLE].bg=ACOL(GUI_MID); +    fv_dialog[FV_TITLE].key=0; +    fv_dialog[FV_TITLE].flags=0; +    fv_dialog[FV_TITLE].d1=fv_dialog[FV_TITLE].d2=0; +    fv_dialog[FV_TITLE].dp2=fv_dialog[FV_TITLE].dp3=NULL; +    fv_dialog[FV_TITLE].dp=title; + +    /* Text Box Pt 1 +    */ +    fv_dialog[FV_TEXTBOX].proc=d_inv_3d_box; +    fv_dialog[FV_TEXTBOX].y=BEVEL+5+FH+5; +    fv_dialog[FV_TEXTBOX].x=BEVEL+5; +    fv_dialog[FV_TEXTBOX].fg=ACOL(GUI_TEXT); +    fv_dialog[FV_TEXTBOX].bg=ACOL(GUI_MID); +    fv_dialog[FV_TEXTBOX].key=0; +    fv_dialog[FV_TEXTBOX].flags=0; +    fv_dialog[FV_TEXTBOX].d1=fv_dialog[FV_TEXTBOX].d2=0; +    fv_dialog[FV_TEXTBOX].dp=fv_dialog[FV_TEXTBOX].dp2= +				    fv_dialog[FV_TEXTBOX].dp3=NULL; + +    /* Text +    */ +    fv_dialog[FV_TEXT].proc=d_ro_textbox; +    fv_dialog[FV_TEXT].y=fv_dialog[FV_TEXTBOX].y+BEVEL; +    fv_dialog[FV_TEXT].h=FH*FV_HEIGHT; +    fv_dialog[FV_TEXT].x=fv_dialog[FV_TEXTBOX].x+BEVEL; +    fv_dialog[FV_TEXT].w=FW*FV_WIDTH; +    fv_dialog[FV_TEXT].fg=ACOL(BLACK); +    fv_dialog[FV_TEXT].bg=ACOL(WHITE); +    fv_dialog[FV_TEXT].key=0; +    fv_dialog[FV_TEXT].flags=0; +    fv_dialog[FV_TEXT].d1=0; +    fv_dialog[FV_TEXT].d2=0; +    fv_dialog[FV_TEXT].dp=line; +    fv_dialog[FV_TEXT].dp2=fv_dialog[FV_TEXT].dp3=NULL; + +    /* Text Box Pt 2 +    */ +    fv_dialog[FV_TEXTBOX].w=fv_dialog[FV_TEXT].w+BEVEL*2; +    fv_dialog[FV_TEXTBOX].h=fv_dialog[FV_TEXT].h+BEVEL*2; + +    /* Vertical scrollbar +    */ +    fv_dialog[FV_VERT_SCROLL].proc=d_vert_scrollbar; +    fv_dialog[FV_VERT_SCROLL].x=fv_dialog[FV_TEXTBOX].x+ +    					fv_dialog[FV_TEXTBOX].w+3; +    fv_dialog[FV_VERT_SCROLL].y=fv_dialog[FV_TEXTBOX].y; +    fv_dialog[FV_VERT_SCROLL].w=FV_SCROLLWIDTH; +    fv_dialog[FV_VERT_SCROLL].h=fv_dialog[FV_TEXTBOX].h; +    fv_dialog[FV_VERT_SCROLL].fg=ACOL(GUI_TEXT); +    fv_dialog[FV_VERT_SCROLL].bg=ACOL(GUI_MID); +    fv_dialog[FV_VERT_SCROLL].key=0; +    fv_dialog[FV_VERT_SCROLL].flags=0; +    fv_dialog[FV_VERT_SCROLL].d1=FV_HEIGHT; +    fv_dialog[FV_VERT_SCROLL].d2=MAX(0,no-FV_HEIGHT); +    fv_dialog[FV_VERT_SCROLL].dp=&fv_dialog[FV_TEXT].d2; +    fv_dialog[FV_VERT_SCROLL].dp2=&fv_dialog[FV_TEXT]; +    fv_dialog[FV_VERT_SCROLL].dp3=NULL; + +    /* Horizontal scrollbar +    */ +    fv_dialog[FV_HORIZ_SCROLL].proc=d_horiz_scrollbar; +    fv_dialog[FV_HORIZ_SCROLL].x=fv_dialog[FV_TEXTBOX].x; +    fv_dialog[FV_HORIZ_SCROLL].y=fv_dialog[FV_TEXTBOX].y+ +    					fv_dialog[FV_TEXTBOX].h+3; +    fv_dialog[FV_HORIZ_SCROLL].w=fv_dialog[FV_TEXTBOX].w; +    fv_dialog[FV_HORIZ_SCROLL].h=FV_SCROLLWIDTH; +    fv_dialog[FV_HORIZ_SCROLL].fg=ACOL(GUI_TEXT); +    fv_dialog[FV_HORIZ_SCROLL].bg=ACOL(GUI_MID); +    fv_dialog[FV_HORIZ_SCROLL].key=0; +    fv_dialog[FV_HORIZ_SCROLL].flags=0; +    fv_dialog[FV_HORIZ_SCROLL].d1=FV_WIDTH; +    fv_dialog[FV_HORIZ_SCROLL].d2=MAX(0,ml-FV_WIDTH); +    fv_dialog[FV_HORIZ_SCROLL].dp=&fv_dialog[FV_TEXT].d1; +    fv_dialog[FV_HORIZ_SCROLL].dp2=&fv_dialog[FV_TEXT]; +    fv_dialog[FV_HORIZ_SCROLL].dp3=NULL; + +    /* OK +    */ +    fv_dialog[FV_OK].proc=my_d_button_proc; +    fv_dialog[FV_OK].x=fv_dialog[FV_TEXTBOX].x; +    fv_dialog[FV_OK].y=fv_dialog[FV_HORIZ_SCROLL].y+ +    				fv_dialog[FV_HORIZ_SCROLL].h+5; +    fv_dialog[FV_OK].w=FW*5; +    fv_dialog[FV_OK].h=FH+3+BEVEL; +    fv_dialog[FV_OK].fg=ACOL(GUI_TEXT); +    fv_dialog[FV_OK].bg=ACOL(GUI_MID); +    fv_dialog[FV_OK].key=0; +    fv_dialog[FV_OK].flags=D_EXIT; +    fv_dialog[FV_OK].d1=fv_dialog[FV_OK].d2=0; +    fv_dialog[FV_OK].dp="OK"; +    fv_dialog[FV_OK].dp2=fv_dialog[FV_OK].dp3=NULL; + +    fv_dialog[FV_END].proc=NULL; + +    do_dialog(fv_dialog,-1); + +    for(f=0;f<no;f++) +	Release(line[f]); + +    Release(line); + +    GFX_FORCE_REDRAW(); +} + + +char *GUI_text_edit (char *title, char *text) +{ +    char *cp_text; +    char *p; +    TextEditLine *line; +    char *ret; +    int f; +    int size; +    int no; +    int bw; +    int bh; + +    p=text; + +    if (*(p+strlen(p)-1)=='\n') +    	no=0; +    else +	no=1; + +    while(*p) +	if (*p++=='\n') +	    no++; + +    line=Grab(sizeof(TextEditLine)*(no+1)); +    cp_text=Strdup(text); +    p=cp_text; + +    for(f=0;f<no;f++) +    	{ +	char *e; + +	e=p; + +	while((*e)&&(*e!='\n')) +	    e++; + +	*e=0; + +	/* We rely on the fact that Grab() zeroes data... +	*/ +	line[f].len=strlen(p); +	line[f].p=Grab((line[f].len/TE_CHUNK+1)*TE_CHUNK+1); +	strcpy(line[f].p,p); +	p=e+1; +	} + +    line[f].p=NULL; +    line[f].len=0; +    Release(cp_text); + +    bw=(TE_WIDTH+1)*FW+20; +    bh=TE_HEIGHT*FH+40+FH*2; + +    /* Box +    */ +    te_dialog[TE_BORDER].proc=d_3d_box; +    te_dialog[TE_BORDER].y=0; +    te_dialog[TE_BORDER].h=bh; +    te_dialog[TE_BORDER].x=0; +    te_dialog[TE_BORDER].w=bw; +    te_dialog[TE_BORDER].fg=ACOL(GUI_TEXT); +    te_dialog[TE_BORDER].bg=ACOL(GUI_MID); +    te_dialog[TE_BORDER].key=0; +    te_dialog[TE_BORDER].flags=0; +    te_dialog[TE_BORDER].d1=te_dialog[TE_BORDER].d2=0; +    te_dialog[TE_BORDER].dp=te_dialog[TE_BORDER].dp2= +				    te_dialog[TE_BORDER].dp3=NULL; + +    /* Title +    */ +    te_dialog[TE_TITLE].proc=d_my_ctext_proc; +    te_dialog[TE_TITLE].x=bw/2; +    te_dialog[TE_TITLE].w=bw-20; +    te_dialog[TE_TITLE].y=BEVEL+5; +    te_dialog[TE_TITLE].h=FH; +    te_dialog[TE_TITLE].fg=ACOL(GUI_TEXTBOLD); +    te_dialog[TE_TITLE].bg=ACOL(GUI_MID); +    te_dialog[TE_TITLE].key=0; +    te_dialog[TE_TITLE].flags=0; +    te_dialog[TE_TITLE].d1=te_dialog[TE_TITLE].d2=0; +    te_dialog[TE_TITLE].dp2=te_dialog[TE_TITLE].dp3=NULL; +    te_dialog[TE_TITLE].dp=title; + +    /* Text Box Pt 1 +    */ +    te_dialog[TE_TEXTBOX].proc=d_inv_3d_box; +    te_dialog[TE_TEXTBOX].y=BEVEL+5+FH+5; +    te_dialog[TE_TEXTBOX].x=BEVEL+5; +    te_dialog[TE_TEXTBOX].fg=ACOL(GUI_TEXT); +    te_dialog[TE_TEXTBOX].bg=ACOL(GUI_MID); +    te_dialog[TE_TEXTBOX].key=0; +    te_dialog[TE_TEXTBOX].flags=0; +    te_dialog[TE_TEXTBOX].d1=te_dialog[TE_TEXTBOX].d2=0; +    te_dialog[TE_TEXTBOX].dp=te_dialog[TE_TEXTBOX].dp2= +				    te_dialog[TE_TEXTBOX].dp3=NULL; + +    /* Text +    */ +    te_dialog[TE_TEXT].proc=d_textedit; +    te_dialog[TE_TEXT].y=te_dialog[TE_TEXTBOX].y+BEVEL; +    te_dialog[TE_TEXT].h=FH*TE_HEIGHT; +    te_dialog[TE_TEXT].x=te_dialog[TE_TEXTBOX].x+BEVEL; +    te_dialog[TE_TEXT].w=FW*(TE_WIDTH+1); +    te_dialog[TE_TEXT].fg=ACOL(BLACK); +    te_dialog[TE_TEXT].bg=ACOL(WHITE); +    te_dialog[TE_TEXT].key=0; +    te_dialog[TE_TEXT].flags=0; +    te_dialog[TE_TEXT].d1=0; +    te_dialog[TE_TEXT].d2=0; +    te_dialog[TE_TEXT].dp=line; +    te_dialog[TE_TEXT].dp2=te_dialog[TE_TEXT].dp3=NULL; + +    /* Text Box Pt 2 +    */ +    te_dialog[TE_TEXTBOX].w=te_dialog[TE_TEXT].w+BEVEL*2; +    te_dialog[TE_TEXTBOX].h=te_dialog[TE_TEXT].h+BEVEL*2; + +    /* OK +    */ +    te_dialog[TE_OK].proc=my_d_button_proc; +    te_dialog[TE_OK].x=te_dialog[TE_TEXTBOX].x; +    te_dialog[TE_OK].y=te_dialog[TE_TEXTBOX].y+te_dialog[TE_TEXTBOX].h+7; +    te_dialog[TE_OK].w=FW*8; +    te_dialog[TE_OK].h=FH+3+BEVEL; +    te_dialog[TE_OK].fg=ACOL(GUI_TEXT); +    te_dialog[TE_OK].bg=ACOL(GUI_MID); +    te_dialog[TE_OK].key=0; +    te_dialog[TE_OK].flags=D_EXIT; +    te_dialog[TE_OK].d1=te_dialog[TE_OK].d2=0; +    te_dialog[TE_OK].dp="OK"; +    te_dialog[TE_OK].dp2=te_dialog[TE_OK].dp3=NULL; + +    /* CANCEL +    */ +    te_dialog[TE_CANCEL].proc=my_d_button_proc; +    te_dialog[TE_CANCEL].x=te_dialog[TE_OK].x+te_dialog[TE_OK].w+20; +    te_dialog[TE_CANCEL].y=te_dialog[TE_TEXTBOX].y+te_dialog[TE_TEXTBOX].h+7; +    te_dialog[TE_CANCEL].w=FW*8; +    te_dialog[TE_CANCEL].h=FH+3+BEVEL; +    te_dialog[TE_CANCEL].fg=ACOL(GUI_TEXT); +    te_dialog[TE_CANCEL].bg=ACOL(GUI_MID); +    te_dialog[TE_CANCEL].key=0; +    te_dialog[TE_CANCEL].flags=D_EXIT; +    te_dialog[TE_CANCEL].d1=te_dialog[TE_CANCEL].d2=0; +    te_dialog[TE_CANCEL].dp="Cancel"; +    te_dialog[TE_CANCEL].dp2=te_dialog[TE_CANCEL].dp3=NULL; + +    te_dialog[TE_END].proc=NULL; + +    no=do_dialog(te_dialog,TE_TEXT); +    line=te_dialog[TE_TEXT].dp; + +    if (no==TE_OK) +	{ +	f=0; +	size=0; + +	while(line[f].p) +	    size+=line[f++].len+1; + +	size++; + +	ret=Grab(size); +	*ret=0; + +	f=0; + +	while(line[f].p) +	    { +	    strcat(ret,line[f++].p); + +	    if (line[f].p) +		strcat(ret,"\n"); +	    } +	} +    else +    	ret=NULL; + +    f=0; +    while(line[f].p) +	Release(line[f++].p); + +    Release(line); + +    GFX_FORCE_REDRAW(); + +    return(ret); +} + + +/* END OF FILE */ | 
