Files
sibo-playground/code/SIBOSDK/record/reccli.c
T
2026-07-06 18:01:36 +01:00

474 lines
13 KiB
C

/*
RECCLI.C
The record application's client window and its components
*/
#include <p_std.h>
#include <p_sys.h>
#include <p_date.h>
#include <epoc.h>
#include <p_config.h>
#include <record.g>
#include <hwim.h>
#include <record.rsg>
#include <fonts.h>
#include <olib.h>
GLREF_D PR_RECWSERV * const w_ws;
GLREF_D PR_APPMAN * const w_am;
GLREF_D PR_RECENG * const receng;
#define TIMEBAR_HEIGHT 13
#define RECBUT_HIDE_DRAW 0
#define RECBUT_HIDE_HIDE 1
#define RECBUT_HIDE_CLEAR 2
#define RECBUT_HALF_WIDTH 34
#define RECBUT_HALF_HEIGHT 10
#define RECBUT_ASCENT 16
#define RECBUT_MARGIN 20
#define RECCLI_NBUTTONS 5
#define RECCLI_3BUT_MASK 0x7 /* 1st 3 buttons */
#define RECCLI_STOP_MASK 0x8 /* 4th button */
#define RECCLI_START_MASK 0x10 /* 5th button */
LOCAL_D UBYTE recbut_hide[RECCLI_NBUTTONS]=
{RECBUT_HIDE_CLEAR,RECBUT_HIDE_HIDE,RECBUT_HIDE_CLEAR,RECBUT_HIDE_HIDE,RECBUT_HIDE_HIDE};
LOCAL_C TEXT *NextZTS(TEXT *str)
{
while (*str++);
return(str);
}
LOCAL_C VOID StartFRC(PR_TIMEBAR *self)
{
UWORD tick,mode;
mode=E_FRC_REPEATING;
tick=100;
p_iow4(self->active.pcb,P_FSTART,&mode,&tick);
}
LOCAL_C INT BarLength(PR_TIMEBAR *self)
{
INT width;
width=self->timebar.rect.br.x-self->timebar.rect.tl.x-2;
if (self->timebar.tenths0)
width-=(UINT)((width*self->timebar.tenths)/self->timebar.tenths0);
return(width);
}
LOCAL_C VOID DrawBar(PR_TIMEBAR *self,INT border,INT createGC)
{
INT x1,x2;
P_RECT r;
x1=self->timebar.x;
x2=BarLength(self);
if (x2==x1 && self->timebar.visible && !border)
return;
if (createGC)
gCreateTempGC0(self->timebar.wid);
r=self->timebar.rect;
if (!self->timebar.visible)
{
gClrRect(&r,G_TRMODE_CLR);
goto exit;
}
if (border)
gBorderRect(&r,W_BORD_CORNER_1);
p_insrec(&r,1,1);
if (x1>x2)
{
gClrRect(&r,G_TRMODE_CLR);
x1=0;
}
self->timebar.x=x2;
r.tl.x+=x1;
r.br.x=r.tl.x+x2-x1;
gFillPattern(&r,WS_BITMAP_GREY,G_TRMODE_REPL);
exit:
if (createGC)
{
gFreeTempGC();
wFlush();
}
}
LOCAL_C VOID DrawButton(PR_RECBUT *self,INT state)
{
wDrawButton2(W_BUTTON_TYPE_2,&self->recbut.rect,&self->recbut.inlabel[0],state);
}
LOCAL_C VOID PrintHeader(PR_RECCLI *self,INT y,TEXT *fmt,...)
{
INT len;
TEXT bb[256];
P_RECT rect;
rect.tl.x=8;
rect.tl.y=y;
rect.br.x=rect.tl.x+self->reccli.width-16;
rect.br.y=y+30;
if (fmt==NULL)
{
gClrRect(&rect,G_TRMODE_CLR);
return;
}
len=p_atob(&bb[0],fmt,&fmt+1);
gPrintBoxText(&rect,20,G_TEXT_ALIGN_CENTRE,0,&bb[0],len);
}
LOCAL_C VOID HideButtons(PR_RECCLI *self,INT mask)
/*
Set the hidden state of the buttons to hide depending on the bits in mask.
*/
{
INT i;
for (i=0;i<RECCLI_NBUTTONS;i++,mask>>=1)
self->reccli.recbut[i]->recbut.hide=(mask&1)?recbut_hide[i]:RECBUT_HIDE_DRAW;
}
LOCAL_C VOID DrawWin(PR_RECCLI *self)
{
G_GC gc;
gc.flags=G_GC_FLAG_BOTH_PLANES;
gCreateTempGC(self->win.id,G_GC_MASK_GREY,&gc);
p_send2(self,O_WN_DRAW);
gFreeTempGC();
}
LOCAL_C VOID PrintDuration(PR_RECCLI *self,TEXT *buf,ULONG tenths)
{
ULONG seconds;
UINT secs;
P_DAYSEC ds;
P_DATE dt;
seconds=tenths/10;
if (seconds<60)
{
secs=(UINT)seconds;
p_atos(buf,"%d.%d %s",secs,(UINT)tenths-10*secs,self->reccli.secs);
return;
}
p_sttods(&seconds,&ds);
p_dstodt(&ds,&dt);
ds.day-=25567; /* base days at Jan 1 1970 */
if (ds.day>0)
{ /* show number of days */
p_atos(buf,"%ld ",ds.day);
buf+=p_slen(buf);
}
if (dt.hour>0 || ds.day>0)
{ /* show number of hours */
p_atos(buf,"%02d%c",dt.hour,self->reccli.tsep);
buf+=p_slen(buf);
}
p_atos(buf,"%02d%c%02d",dt.minute,self->reccli.tsep,dt.second);
}
#pragma METHOD_CALL
METHOD VOID timebar_tb_draw(PR_TIMEBAR *self)
{
self->timebar.x=0;
DrawBar(self,TRUE,FALSE);
}
METHOD VOID timebar_ao_init(PR_TIMEBAR *self,INT wid,P_RECT *prect)
{
self->active.priority=PRIORITY_ACTIVE_REPEATER;
p_send3(w_am,O_AM_ADD_TASK,self);
self->timebar.wid=wid;
self->timebar.rect=*prect;
}
METHOD VOID timebar_ao_queue(PR_TIMEBAR *self)
{
p_ioc3(self->active.pcb,P_FREAD,&self->active.stat);
self->active.isactive=TRUE;
}
METHOD INT timebar_ao_run(PR_TIMEBAR *self)
{
if (self->active.stat<0)
{ /* possibly because the machine was switched off then on */
StartFRC(self); /* restart the FRC */
self->active.stat=0;
}
self->timebar.tenths-=self->active.stat;
if (self->timebar.tenths<=0)
{
self->timebar.tenths=0; /* stops re-queue */
p_close(self->active.pcb);
self->active.pcb=NULL;
}
DrawBar(self,FALSE,TRUE);
if (self->timebar.tenths)
timebar_ao_queue(self);
return(RUN_ACTIVE_USED);
}
METHOD VOID timebar_tb_start(PR_TIMEBAR *self,ULONG *tenths)
{
self->timebar.tenths0=*tenths;
self->timebar.tenths=self->timebar.tenths0;
self->timebar.x=0;
self->timebar.visible=TRUE;
if (self->timebar.tenths<10 || p_open(&self->active.pcb,"FRC:",-1)<0)
return;
StartFRC(self);
DrawBar(self,TRUE,TRUE);
timebar_ao_queue(self);
}
METHOD VOID timebar_tb_stop(PR_TIMEBAR *self)
{
p_send2(self,O_AO_CANCEL);
self->timebar.visible=FALSE;
p_close(self->active.pcb);
self->active.pcb=NULL;
}
METHOD VOID recbut_destroy(PR_RECBUT *self)
{
p_free(self->recbut.buttxt);
p_supersend2(self,O_DESTROY);
}
METHOD VOID recbut_rb_init(PR_RECBUT *self,INT wid,P_POINT *pc,INT rid)
{
self->recbut.wid=wid;
self->recbut.rect.tl.x=pc->x-RECBUT_HALF_WIDTH;
self->recbut.rect.br.x=pc->x+RECBUT_HALF_WIDTH;
self->recbut.rect.tl.y=pc->y-RECBUT_HALF_HEIGHT;
self->recbut.rect.br.y=pc->y+RECBUT_HALF_HEIGHT;
hLoadResource(rid,&self->recbut.buttxt);
self->recbut.inlabel=(TEXT *)(((WORD *)self->recbut.buttxt)+1);
self->recbut.caption=NextZTS(self->recbut.inlabel);
self->recbut.caplen=p_slen(self->recbut.caption);
}
METHOD VOID recbut_rb_draw(PR_RECBUT *self)
{
P_RECT r;
if (self->recbut.hide==RECBUT_HIDE_HIDE)
return;
r.tl.x=self->recbut.rect.tl.x-RECBUT_MARGIN;
r.br.x=self->recbut.rect.br.x+RECBUT_MARGIN;
r.br.y=self->recbut.rect.tl.y;
r.tl.y=r.br.y-(2*RECBUT_HALF_HEIGHT);
if (self->recbut.hide==RECBUT_HIDE_CLEAR)
{
gClrRect(&r,G_TRMODE_CLR);
gClrRect(&self->recbut.rect,G_TRMODE_CLR);
return;
}
DrawButton(self,0);
gPrintBoxText(&r,RECBUT_ASCENT,G_TEXT_ALIGN_CENTRE,0,self->recbut.caption,self->recbut.caplen);
}
METHOD VOID recbut_rb_depress(PR_RECBUT *self)
{
gCreateTempGC0(self->recbut.wid);
DrawButton(self,2);
wFlush();
p_sleep(2L);
DrawButton(self,0);
wFlush();
gFreeTempGC();
}
METHOD VOID recbut_rb_hide(PR_RECBUT *self,INT hide)
{
self->recbut.hide=hide;
}
METHOD VOID reccli_destroy(PR_RECCLI *self)
{
p_free(self->reccli.clitxt);
p_supersend2(self,O_DESTROY);
}
METHOD VOID reccli_wn_connect(PR_RECCLI *self,PR_WIN *par,UINT fields,W_WINDATA *pwd)
{
INT i,dx;
P_POINT c;
P_RECT rect;
E_CONFIG config;
p_getctd(&config);
self->reccli.tsep=config.timeSeparator;
self->reccli.width=pwd->extent.width;
pwd->background=W_WIN_BACK_CLR|W_WIN_BACK_GREY_CLR;
p_supersend5(self,O_WN_CONNECT,par,fields|W_WIN_BACKGROUND,pwd);
hInitVis(self);
p_send3(self,O_WN_EMPHASISE,TRUE);
rect.tl.x=12;
rect.br.x=self->reccli.width-rect.tl.x;
rect.tl.y=74;
rect.br.y=rect.tl.y+TIMEBAR_HEIGHT;
self->reccli.timebar=f_newsend(CAT_RECORD_RECORD,C_TIMEBAR,O_AO_INIT,self->win.id,&rect);
dx=(self->reccli.width-6)/6;
c.y=130;
for (i=0;i<RECCLI_NBUTTONS;i++)
{
c.x=3+dx+(((i<3)?i*dx:dx)<<1);
self->reccli.recbut[i]=f_newsend(CAT_RECORD_RECORD,C_RECBUT,O_RB_INIT,self->win.id,&c,CLIBUT_REC_NEW+i);
}
HideButtons(self,RECCLI_STOP_MASK|RECCLI_START_MASK);
hLoadResource(RECCLI_TEXT,&self->reccli.clitxt);
self->reccli.secs=(TEXT *)(((WORD *)self->reccli.clitxt)+1);
self->reccli.title=NextZTS(self->reccli.secs);
self->reccli.sub=NextZTS(self->reccli.title);
wValidateWin(self->win.id); /* saves screen flicker on startup */
}
METHOD VOID reccli_wn_draw(PR_RECCLI *self)
{
INT i,len,y;
WVEFILE_INFO info;
TEXT name[16];
TEXT duration[20],total[20];
G_GC gc;
p_supersend(self,O_WN_DRAW); /* draw border */
p_send2(self->reccli.timebar,O_TB_DRAW); /* draw time bar */
/* draw buttons */
for (i=0;i<RECCLI_NBUTTONS;recbut_rb_draw(self->reccli.recbut[i++]));
p_send3(receng,O_ENG_FILE_INFO,&info);
*p_bcpy(&name[0],info.name,len=info.nmlen)=0;
p_scap(&name[0]);
if (*info.device!='M')
{
name[len++]='[';
name[len++]=*info.device;
name[len++]=']';
}
name[len]=0;
gc.style=G_STY_BOLD;
gc.font=FONT_ID_SWISS_16;
gSetGC(0,G_GC_MASK_STYLE|G_GC_MASK_FONT,&gc);
y=8;
if (info.duration)
{
PrintDuration(self,&duration[0],(LONG)info.duration);
/* %s %s %d Kbyte */
PrintHeader(self,y,self->reccli.title,&name[0],&duration[0],(INT)(info.flen>>10));
}
else
PrintHeader(self,y,"%s",&name[0]); /* might be a % character in name[] */
y=40;
if (info.repeats<=1 && info.silence==0)
{
PrintHeader(self,y,NULL); /* clear rectangle */
return;
}
gc.style=G_STY_NORMAL;
gc.font=FONT_ID_SWISS_13;
gSetGC(0,G_GC_MASK_STYLE|G_GC_MASK_FONT,&gc);
PrintDuration(self,&duration[0],(LONG)info.silence);
PrintDuration(self,&total[0],info.total);
/* Repeats: %d Trailing silence: %s Total: %s */
PrintHeader(self,y,self->reccli.sub,info.repeats,&duration[0],&total[0]);
}
METHOD VOID reccli_cl_update(PR_RECCLI *self)
{
p_send2(self->reccli.timebar,O_TB_STOP);
self->reccli.running=FALSE;
w_ws->wserv.filter=NULL;
wDisableKeyClick(FALSE);
HideButtons(self,RECCLI_STOP_MASK|RECCLI_START_MASK);
DrawWin(self);
wFlush();
}
METHOD VOID reccli_wn_key(PR_RECCLI *self,UINT keycode,UINT modifiers)
{
switch (keycode)
{
case W_KEY_TAB:
recbut_rb_depress(self->reccli.recbut[0]);
hWservComSend(O_COM_RECORD_NEW);
break;
case ' ':
recbut_rb_depress(self->reccli.recbut[1]);
hWservComSend(O_COM_RE_RECORD);
break;
case W_KEY_RETURN:
recbut_rb_depress(self->reccli.recbut[2]);
p_send2(receng,O_ENG_SOUND_PLAY);
break;
}
}
METHOD INT reccli_cl_sound_filter(PR_RECCLI *self,UINT keycode,UINT modifiers)
{
if (keycode==W_KEY_ESCAPE)
{
p_send2(receng,O_ENG_SOUND_STOP);
recbut_rb_depress(self->reccli.recbut[3]);
}
return(WN_KEY_CHANGED);
}
METHOD INT reccli_cl_pause_filter(PR_RECCLI *self,UINT keycode,UINT modifiers)
/*
Waiting to record.
*/
{
if (keycode==W_KEY_ESCAPE)
p_send3(receng,O_ENG_OPEN_FILE,NULL);
else if (keycode==' ')
{
w_ws->wserv.filter=NULL;
p_send3(receng,O_ENG_SOUND_RECORD,self->reccli.duration);
}
return(WN_KEY_CHANGED);
}
METHOD VOID reccli_cl_begin_sound(PR_RECCLI *self,ULONG *tenths)
{
p_send3(self->reccli.timebar,O_TB_START,tenths);
self->reccli.running=TRUE;
w_ws->wserv.filter=(PR_WIN *)self;
w_ws->wserv.filmethod=-O_CL_SOUND_FILTER;
wDisableKeyClick(TRUE);
HideButtons(self,RECCLI_3BUT_MASK|RECCLI_START_MASK);
DrawWin(self);
wFlush();
}
METHOD VOID reccli_cl_pause(PR_RECCLI *self,UINT duration)
{
self->reccli.duration=duration;
w_ws->wserv.filter=(PR_WIN *)self;
w_ws->wserv.filmethod=-O_CL_PAUSE_FILTER;
HideButtons(self,RECCLI_3BUT_MASK|RECCLI_STOP_MASK);
DrawWin(self);
wFlush();
}
METHOD VOID recman_am_clean_up(PR_RECMAN *self,INT err,UBYTE *htask)
{
PR_RECCLI *cli;
cli=(PR_RECCLI *)w_ws->wserv.cli;
w_ws->wserv.filter=NULL;
wDisableKeyClick(FALSE);
p_send2(cli->reccli.timebar,O_TB_STOP);
p_supersend4(self,O_AM_CLEAN_UP,err,htask);
p_send3(receng,O_ENG_OPEN_FILE,NULL);
}