/* RECCLI.C The record application's client window and its components */ #include #include #include #include #include #include #include #include #include #include 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>=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;ireccli.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;ireccli.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); }