home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
191.lha
/
ARequester
/
req1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-04-28
|
19KB
|
872 lines
#include <intuition/intuition.h>
#include <libraries/dosextens.h>
#include <exec/memory.h>
#include "reqdir.h"
#include "req.h"
typedef struct
{
short x0, y0, x1, y1;
} Rect;
typedef struct
{
char *line;
long len, x, y, color;
} Txt;
typedef struct
{
struct TextFont *font;
struct Window *window;
struct RastPort *rp;
struct MsgPort *port;
PFV func;
struct Gadget *gad;
short countdown;
short gfx_open;
short intui_open;
short finished;
UWORD top;
UWORD left;
UWORD width;
UWORD most;
UBYTE ubuf[512];
UBYTE pbuf[512];
UBYTE fbuf[512];
char scr_buf[6][28];
UBYTE *buffer;
Entry **ent;
long bufsize;
long max_entries;
long num_entries;
FileReq *req;
} Base;
extern void shadow_area(), render_text(), border_area(), center_title();
extern void write_screen(), init_dir(), pathgad(), close_libs();
extern void cancel(), vert_scroll(), scrollh(), right_htik(), left_htik();
extern void down_vtik(), up_vtik(), filegad(), okay_pressed();
extern void *strcpy(), *strncpy(), *AllocMem(), *trim();
extern short init();
extern long reqdir(), TextLength(), Wait(), process_message();
extern struct Library *OpenLibrary();
extern struct ViewPort *ViewPortAddress();
extern struct Window *OpenWindow();
extern struct TextFont *OpenFont();
extern struct Message *GetMsg();
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
static UWORD NaturalColors[NUM_COLORS] =
{
0x2,
0xeee,
0x44f,
0xd00,
};
static struct TextAttr _ta =
{
(STRPTR) "topaz.font",
8,
FS_NORMAL,
FPF_ROMFONT,
};
#define HV GADGHCOMP
#define HI (GADGIMAGE|GADGHNONE)
#define HC (GADGIMAGE|GADGHCOMP)
#define RELV RELVERIFY
#define BOOLG BOOLGADGET
#define BACT (RELVERIFY|GADGIMMEDIATE)
#define PGAD PROPGADGET
#define PACT (RELVERIFY|GADGIMMEDIATE|FOLLOWMOUSE)
#define SGAD STRGADGET
extern struct Image UpImg, DownImg, LeftImg, RightImg, vi, hi;
static struct PropInfo p[] =
{
{FREEVERT|PROPBORDERLESS,0,0,0xffff,0x0fff,0,0,0,0,0,0,},
{FREEVERT|PROPBORDERLESS,0,0,0xffff,0xfff,0,0,0,0,0,0,},
{FREEHORIZ|PROPBORDERLESS,0,0,0xfff,0xffff,0,0,0,0,0,0,},
};
static struct StringInfo sin[] =
{
{NULL,NULL,0,512,0,0,0,0,0,0,0L,0L,0L},
{NULL,NULL,0,512,0,0,0,0,0,0,0L,0L,0L},
};
static struct Gadget g[] =
{
{&g[1],6,11,17,7,HC,BACT,BOOLG,(APTR)&UpImg,0L,0L,0L,0L,1,(APTR)up_vtik,},
{&g[2],254,11,17,7,HC,BACT,BOOLG,(APTR)&UpImg,0L,0L,0L,0L,2,(APTR)up_vtik,},
{&g[3],6,68,17,7,HC,BACT,BOOLG,(APTR)&DownImg,0L,0L,0L,0L,5,(APTR)down_vtik,},
{&g[4],254,68,17,7,HC,BACT,BOOLG,(APTR)&DownImg,0L,0L,0L,0L,6,(APTR)down_vtik,},
{&g[5],29,77,15,9,HC,BACT,BOOLG,(APTR)&LeftImg,0L,0L,0L,0L,7,(APTR)left_htik,},
{&g[6],232,77,15,9,HC,BACT,BOOLG,(APTR)&RightImg,0L,0L,0L,0L,9,(APTR)right_htik,},
{&g[7],218,90,53,11,HV,RELV,BOOLG,0L,0L,0L,0L,0L,12,(APTR)okay_pressed,},
{&g[8],218,104,53,11,HV,RELV,BOOLG,0L,0L,0L,0L,0L,13,(APTR)cancel,},
{&g[9],7,21,15,44,HI,PACT,PGAD,(APTR)&vi,0L,0L,0L,(APTR)&p[0],3,(APTR)vert_scroll,},
{&g[10],255,21,15,44,HI,PACT,PGAD,(APTR)&vi,0L,0L,0L,(APTR)&p[1],4,(APTR)vert_scroll,},
{&g[11],48,78,180,7,HI,PACT,PGAD,(APTR)&hi,0L,0L,0L,(APTR)&p[2],8,(APTR)scrollh,},
{&g[12],55,94,140,10,HV,RELV,SGAD,0L,0L,0L,0L,(APTR)&sin[0],10,(APTR)pathgad,},
{&g[13],55,104,140,10,HV,RELV,SGAD,0L,0L,0L,0L,(APTR)&sin[1],11,NULL,},
{&g[14],30,12,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,0,(APTR)filegad,},
{&g[15],30,22,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,1,(APTR)filegad,},
{&g[16],30,32,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,2,(APTR)filegad,},
{&g[17],30,42,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,3,(APTR)filegad,},
{&g[18],30,52,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,4,(APTR)filegad,},
{NULL,30,62,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,5,(APTR)filegad,},
};
static struct NewWindow _nw =
{
20, 20, 282, 122,
(UBYTE) 1,
(UBYTE) 1,
MOUSEMOVE | GADGETDOWN | GADGETUP | RAWKEY | ACTIVEWINDOW |
INTUITICKS | REFRESHWINDOW,
BORDERLESS | ACTIVATE | SIMPLE_REFRESH | WINDOWDRAG,
NULL, /* gadgets */
0L, /* check mark */
0L, /* title */
0L, /* screen */
0L,
282, 122,
282, 122,
WBENCHSCREEN,
};
long file_requester(r)
REGS FileReq *r;
{
REGS struct IntuiMessage *imsg;
REGS ULONG signals, mysig;
Base *base;
long alloc_size = 0L, rv = FILEREQ_ERROR;
struct IntuiMessage I;
/* Allocate temporary data storage */
if( !(base = AllocMem((long)sizeof(Base),(long)MEMF_CLEAR)) )
return(rv);
/* If no buffer is provided attempt to allocate memory for it. */
if( !r->buf )
{
if( !(r->buf = AllocMem(r->bufsize,(long)MEMF_CLEAR)) )
{
FreeMem(base,(long)sizeof(Base));
return(rv);
}
alloc_size = r->bufsize;
}
base->ent = (Entry **)r->buf;
base->buffer = r->buf + (r->n_entries * sizeof(Entry *));
base->bufsize = r->bufsize - (r->n_entries * sizeof(Entry *));
base->max_entries = r->n_entries;
base->req = r;
strcpy(base->pbuf,r->path);
strcpy(base->fbuf,r->file);
if( _nw.Screen = r->screen )
_nw.Type = CUSTOMSCREEN;
else
_nw.Type = WBENCHSCREEN;
/* The requested number of entries has to fit in the
* buffer or it is an error. */
if( base->bufsize >= (r->n_entries * sizeof(Entry)) )
{
if( init(base) )
{
/*** The main IO loop ***/
for(rv = CANCEL, mysig = (1L<<base->port->mp_SigBit);!base->finished;)
{
signals = Wait( mysig | r->user_signals );
if( signals & mysig )
{
while( imsg = (struct IntuiMessage *)GetMsg(base->port) )
{
I = *imsg;
ReplyMsg(imsg);
process_message(base,&I);
}
}
if( signals & r->user_signals )
if( r->user_func )
(*r->user_func)(signals);
}
}
}
/* close up some stuff */
if( base->window )
CloseWindow(base->window);
if( base->font )
CloseFont(base->font);
close_libs(base);
if( base->finished == OKAY )
rv = OKAY;
if( alloc_size )
{
FreeMem(r->buf,alloc_size);
r->buf = 0L;
}
FreeMem(base,(long)sizeof(Base));
return(rv);
}
static void draw_all(base,flg)
REGS Base *base;
long flg;
{
static Rect file_area = {31,12,246,73};
static Rect left_area = {7,20,21,65};
static Rect right_area = {255,20,269,65};
static Rect bottom_area = {46,78,229,84};
static Rect path_area = {7,90,200,114};
static Rect ok_area = {219,91,268,99};
static Rect can_area = {219,105,268,113};
static Rect area_path = {52,92,194,102};
static Rect area_file = {52,102,194,112};
static Txt path_txt = {"Path:",5L,11L,100L,1L};
static Txt file_txt = {"File:",5L,11L,110L,1L};
static Txt okay_txt = {"Okay",4L,229L,98L,1L};
static Txt can_txt = {"Cancel",6L,221L,112L,0L};
REGS struct RastPort *rp = base->rp;
if( flg )
BeginRefresh(base->window);
SetRast(rp,1L);
center_title(base);
shadow_area(rp,file_area,1L,0L);
shadow_area(rp,left_area,1L,0L);
shadow_area(rp,right_area,1L,0L);
shadow_area(rp,bottom_area,1L,0L);
shadow_area(rp,path_area,2L,0L);
shadow_area(rp,ok_area,2L,0L);
shadow_area(rp,can_area,3L,0L);
render_text(rp,&path_txt);
render_text(rp,&file_txt);
render_text(rp,&okay_txt);
render_text(rp,&can_txt);
border_area(rp,area_path,0L,1L);
border_area(rp,area_file,0L,1L);
if( flg )
{
write_screen(base);
RefreshGList(g,base->window,0L,-1);
EndRefresh(base->window,1L);
}
}
static void close_libs(base)
REGS Base *base;
{
if( !base->intui_open && IntuitionBase )
CloseLibrary(IntuitionBase);
if( !base->gfx_open && GfxBase )
CloseLibrary(GfxBase);
}
static long open_libs(base)
REGS Base *base;
{
if( !GfxBase )
{
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",33L);
base->gfx_open = 0;
}
else base->gfx_open = 1;
if( !GfxBase )
return(0L);
if( !IntuitionBase )
{
IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library",33L);
base->intui_open = 0;
}
else base->intui_open = 0;
if( !IntuitionBase )
return(0L);
return(1L);
}
static void end(base,code)
REGS Base *base;
short code;
{
base->finished = code;
if( code == OKAY )
{
strcpy(base->req->path,base->pbuf);
strcpy(base->req->file,base->fbuf);
}
}
static short init(base)
REGS Base *base;
{
if( open_libs(base) )
{
if( base->font = OpenFont(&_ta) )
{
if( base->window = OpenWindow(&_nw) )
{
if( base->req->flags & NATURAL_COLOR_BIT ) /* use the natural colors */
{
REGS struct ViewPort *vp = ViewPortAddress(base->window);
LoadRGB4(vp,NaturalColors,NUM_COLORS);
}
/* Attach the buffers to the gadgets */
sin[0].Buffer = base->pbuf;
sin[1].Buffer = base->fbuf;
sin[0].UndoBuffer = sin[1].UndoBuffer = base->ubuf;
base->rp = base->window->RPort;
base->port = base->window->UserPort;
SetFont(base->rp,base->font);
draw_all(base,0L);
if( !base->pbuf[0] )
init_dir(base->pbuf,(UWORD)(base->req->flags & CLI_BIT));
AddGList(base->window,g,0,-1,0L);
RefreshGList(g,base->window,0L,-1);
pathgad(base,NULL);
}
else return(0);
}
else return(0);
}
else return(0);
return(1);
}
static long process_message(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
REGS long rv = 0L;
switch( i->Class )
{
case MOUSEMOVE:
if( base->func )
(*base->func)(base,i);
break;
case INTUITICKS:
if( base->func )
{
if( base->gad->Flags & SELECTED )
{
if( !base->countdown )
(*base->func)(base,i);
else base->countdown--;
}
}
break;
case RAWKEY:
break;
case GADGETDOWN:
base->gad = (struct Gadget *)i->IAddress;
if( base->func = (PFV) base->gad->UserData )
(*base->func)(base,i);
base->countdown = 4;
break;
case GADGETUP:
base->gad = (struct Gadget *)i->IAddress;
if( base->func = (PFV) base->gad->UserData )
(*base->func)(base,i);
base->func = 0L;
base->gad = 0L;
base->countdown = 0;
break;
case ACTIVEWINDOW:
center_title(base);
break;
case REFRESHWINDOW:
draw_all(base,1L);
break;
default: break;
}
return(rv);
}
static void center_title(base)
REGS Base *base;
{
REGS struct RastPort *rp = base->rp;
REGS short text_width, text_length, x;
if( text_length = strlen(base->req->heading) )
{
text_width = TextLength(rp,base->req->heading,(long)text_length);
x = (base->window->Width - text_width) >> 1;
SetAPen(rp,2L);
SetBPen(rp,1L);
Move(rp,(long)x,8L);
Text(rp,base->req->heading,(long)text_length);
}
}
static void cancel(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
end(base,CANCEL);
}
static UWORD write_entry(base,e,buf)
REGS Base *base;
REGS Entry *e;
REGS char *buf;
{
REGS char *pr;
REGS UWORD len;
char tmp_buf[130];
char spc[6];
if( e->dir )
pr = "-Dir-";
else
{
spc[0] = e->archive ? 'a' : '.';
spc[1] = e->read ? 'r' : '.';
spc[2] = e->write ? 'w' : '.';
spc[3] = e->execute ? 'e' : '.';
spc[4] = e->delete ? 'd' : '.';
spc[5] = '\0';
pr = spc;
}
len = sprintf(tmp_buf,"%-10s %-5s %02d-%02d-%02d",
EntryName(e),pr,
e->month,e->day,e->year+78);
if( len > base->width ) base->width = len;
if( (len = len-base->left) > 27 ) len = 27;
strncpy(buf,&tmp_buf[base->left],len);
return(len);
}
static void entries_write(base,lens)
REGS Base *base;
UWORD lens[];
{
REGS UWORD i, j;
for( i = base->top, j = 0, base->width = 27;
j < 6 && i < base->num_entries; i++, j++)
lens[j] = write_entry(base,base->ent[i],base->scr_buf[j]);
base->most = base->width - 27;
}
static void write_screen(base)
REGS Base *base;
{
static Rect wipe_area = {31L,12L,246L,72L};
REGS UWORD i, j;
UWORD lens[6];
entries_write(base,lens);
if( base->left > base->most )
{
base->left = base->most;
entries_write(base,lens);
}
SetAPen(base->rp,1L);
RectFill(base->rp,(long)wipe_area.x0,(long)wipe_area.y0,
(long)wipe_area.x1,(long)wipe_area.y1);
SetAPen(base->rp,2L);
SetBPen(base->rp,1L);
for( i = 0, j = 19; i < 6 && i < base->num_entries; i++, j+=10)
{
Move(base->rp,31L,(long)j);
Text(base->rp,base->scr_buf[i],(long)lens[i]);
}
}
static void calc_vpot(base)
REGS Base *base;
{
REGS struct PropInfo *pa, *pb;
REGS UWORD most = base->num_entries - 6;
REGS ULONG pot, body;
REGS UWORD old_pot;
pa = (struct PropInfo *)g[8].SpecialInfo;
pb = (struct PropInfo *)g[9].SpecialInfo;
old_pot = pa->VertPot;
if( most <= 0 )
{
pa->VertPot = 0;
pa->VertBody = 0xFFFF;
}
else
{
pot = base->top;
pot *= 0xFFFF;
pot /= most;
body = 6 * 0xFFFF;
body /= base->num_entries;
pa->VertPot = pot;
pa->VertBody = body;
}
pb->VertBody = pa->VertBody;
pb->VertPot = pa->VertPot;
if( pot != old_pot )
RefreshGList(&g[8],base->window,0L,2);
}
static void calc_hpot(base)
REGS Base *base;
{
REGS ULONG pot;
REGS struct PropInfo *pi = (struct PropInfo *)g[10].SpecialInfo;
REGS UWORD old_pot;
old_pot = pi->HorizPot;
if( base->most )
{
pot = base->left;
pot *= 0xFFFF;
pot /= base->most;
pi->HorizPot = pot;
pi->HorizBody = 0xFFFF/base->width;
pi->HorizBody *= 27;
}
else pi->HorizPot = 0;
if( old_pot != pi->HorizPot )
RefreshGList(&g[10],base->window,0L,1);
}
static void vert_scroll(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
REGS struct Gadget *a, *b;
REGS long top, range;
if( i->Class == GADGETUP )
ModifyIDCMP(base->window,base->window->IDCMPFlags | INTUITICKS);
else if( i->Class == GADGETDOWN )
ModifyIDCMP(base->window,base->window->IDCMPFlags & ~INTUITICKS);
a = base->gad;
b = (a == &g[8]) ? &g[9] : &g[8];
if( ((struct PropInfo *)b->SpecialInfo)->VertPot !=
((struct PropInfo *)a->SpecialInfo)->VertPot )
{
((struct PropInfo *)b->SpecialInfo)->VertPot =
((struct PropInfo *)a->SpecialInfo)->VertPot;
RefreshGList(b,base->window,0L,1);
top = ((struct PropInfo *)b->SpecialInfo)->VertPot;
range = base->num_entries - 6;
if( range <= 0 )
return;
top *= range;
top /= 0xFFFF;
if( top != base->top )
{
base->top = top;
write_screen(base);
calc_hpot(base);
}
}
}
static void up_vtik(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
if( base->top > 0 && i->Class != GADGETDOWN )
{
base->top--;
write_screen(base);
calc_vpot(base);
}
}
static void down_vtik(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
if( base->top < (base->num_entries - 6) && i->Class != GADGETDOWN )
{
base->top++;
write_screen(base);
calc_vpot(base);
}
}
static void up_one_dir(base,path,len)
REGS Base *base;
UBYTE *path;
REGS UWORD len;
{
REGS UBYTE *end;
if( len )
{
end = path+(len-1);
while( end >= path )
{
if( *end == '/' )
{
*end = '\0';
return;
}
else if( *end == ':' )
{
*(end+1) = '\0';
return;
}
end--;
}
*path = '\0';
}
}
static void pathgad(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
long num_entries;
if( (num_entries = reqdir(trim(base->pbuf),base->buffer,
(ULONG)base->bufsize,base->ent,(ULONG)base->max_entries)) > 0L )
{
base->num_entries = num_entries;
base->top = base->left = 0;
write_screen(base);
calc_hpot(base);
calc_vpot(base);
}
else if( num_entries < 0L )
{
strcpy(base->pbuf,base->ubuf);
RefreshGList(&g[11],base->window,0L,1);
}
}
static void filegad(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
REGS Entry *e;
REGS UWORD len;
REGS struct StringInfo *si;
e = base->ent[base->top + base->gad->GadgetID];
if( e->dir )
{
len = strlen(trim(base->pbuf));
if( strcmp("/",EntryName(e)) )
{
if( len )
{
if( base->pbuf[len-1] != ':' )
strcat(base->pbuf,"/");
}
strcat(base->pbuf,EntryName(e));
}
else
{
si = (struct StringInfo *)g[11].SpecialInfo;
si->DispPos = 0;
up_one_dir(base,base->pbuf,len);
}
RefreshGList(&g[11],base->window,0L,1);
pathgad(base,NULL);
}
else
{
strcpy(base->fbuf,EntryName(e));
RefreshGList(&g[12],base->window,0L,1);
}
}
static void scrollh(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
REGS struct PropInfo *pi;
REGS ULONG pos;
pi = (struct PropInfo *)base->gad->SpecialInfo;
if( i->Class == GADGETUP )
ModifyIDCMP(base->window,base->window->IDCMPFlags | INTUITICKS);
else if( i->Class == GADGETDOWN )
ModifyIDCMP(base->window,base->window->IDCMPFlags & ~INTUITICKS);
if( base->most && i->Class != GADGETDOWN )
{
pos = base->most;
pos *= pi->HorizPot;
pos /= 0xFFFF;
if( pos != base->left )
{
base->left = pos;
write_screen(base);
}
}
}
static void right_htik(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
if( base->left < base->most && i->Class != GADGETDOWN )
{
base->left++;
write_screen(base);
calc_hpot(base);
}
}
static void left_htik(base,i)
REGS Base *base;
REGS struct IntuiMessage *i;
{
if( base->left > 0 && i->Class != GADGETDOWN )
{
base->left--;
write_screen(base);
calc_hpot(base);
}
}
static void okay_pressed(base,i)
REGS Base *base;
struct IntuiMessage *i;
{
end(base,OKAY);
}
static void shadow_area(rp,r,front_color,outline_color)
REGS struct RastPort *rp;
Rect r;
REGS long front_color, outline_color;
{
SetAPen(rp,(long)front_color);
RectFill(rp,(long)r.x0,(long)r.y0,(long)r.x1,(long)r.y1);
SetAPen(rp,(long)outline_color);
r.x0--;
r.y0--;
r.x1++;
r.y1++;
Move(rp,(long)r.x0,(long)r.y0);
Draw(rp,(long)r.x0,(long)r.y1);
Draw(rp,(long)r.x1,(long)r.y1);
Draw(rp,(long)r.x1,(long)r.y0);
Draw(rp,(long)r.x0,(long)r.y0);
r.x0 += 3;
r.y0++;
r.x1++;
r.y1++;
Move(rp,(long)r.x0,(long)r.y1);
Draw(rp,(long)r.x1,(long)r.y1);
Draw(rp,(long)r.x1,(long)r.y0);
r.x1++;
Move(rp,(long)r.x1,(long)r.y0);
Draw(rp,(long)r.x1,(long)r.y1);
r.x1++;
Move(rp,(long)r.x1,(long)r.y0);
Draw(rp,(long)r.x1,(long)r.y1);
}
static void render_text(rp,t)
REGS struct RastPort *rp;
Txt *t;
{
SetAPen(rp,t->color);
SetDrMd(rp,(long)JAM1);
Move(rp,t->x,t->y);
Text(rp,t->line,t->len);
}
static void border_area(rp,r,front_color,outline_color)
REGS struct RastPort *rp;
Rect r;
long front_color, outline_color;
{
SetAPen(rp,front_color);
RectFill(rp,(long)r.x0,(long)r.y0,(long)r.x1,(long)r.y1);
SetAPen(rp,outline_color);
Move(rp,(long)r.x0,(long)r.y0);
Draw(rp,(long)r.x0,(long)r.y1);
Draw(rp,(long)r.x1,(long)r.y1);
Draw(rp,(long)r.x1,(long)r.y0);
Draw(rp,(long)r.x0,(long)r.y0);
r.x0++;
r.x1--;
Move(rp,(long)r.x0,(long)r.y0);
Draw(rp,(long)r.x0,(long)r.y1);
Move(rp,(long)r.x1,(long)r.y0);
Draw(rp,(long)r.x1,(long)r.y1);
}