#include #include #include #include #include #include #include "aesextra.h" #include "mp2audio.h" #include "window.h" #include "mp2ctrl.h" #include "mp2info.h" #include "console.h" #include "libshoe.h" #include "version.h" #include "stream.h" #include "replay.h" /* Functions in this module */ void main_event_loop(void); void bg_event_loop(void); void fg_event_loop(void); int ev2_loop(WINDFORM *, int, int); void toggle_object(WINDFORM *,int,int); int handle_message(int *); char *do_dragdrop(int *, int); void update_objects(WINDFORM *,int,int, int *); int do_formstuff(int); long calc_time(void); void update_time(void); void unquote(char *); /* global variables */ int fgbg,closed_acc=0,looping=0; int fgexit=0, display_time=0; char *app_name="MP2AUDIO"; /* global variables from mp2file.c */ extern char path[512], filename[512]; /* global variables from main.c */ extern int time_slice, count_dir; extern int replay,quit; extern long buffer,left; extern int acc_id,app_id; extern char *buffer_mem; /* Functions from bifs.c */ extern void call_control_key(char c); /* Functions from mp2info.c */ extern int getmp2info(int); extern void show_mp2_error(int); /* Functions from console.c */ extern void initialize_console(int w, int h); extern void prompt_console(int key, int delta); extern void redraw_console(int *xywh, int row); extern void print_line(char *text); #define FG 1 #define BG 0 #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) typedef struct { int x1,y1,x2,y2; } CORDS2; int quit_program() { window_close(WIND_CTRL); fgexit = 1; return 1; } void main_event_loop() { fgbg=(_app?FG:BG); while(!quit) { if(closed_acc) { evnt_timer(1000,0); #ifdef DEBUG form_alert(1,"[1][ACC reopened][Ok]"); #endif window_create(WIND_CTRL); closed_acc=0; } if(fgbg==FG) fg_event_loop(); else if(fgbg==BG) bg_event_loop(); } } /* No form window is open */ void bg_event_loop() { int x,y,kstate,key,clicks,event,state; int pipe[8]; #ifdef DEBUG form_alert(1,"[1][ACC bg][Ok]"); #endif do { event = evnt_multi( MU_MESAG | MU_TIMER, 2, 0x1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pipe, time_slice, 0, &x, &y, &state, &kstate, &key, &clicks ); if (event & MU_TIMER) if (replay) { stream_load(0); update_time(); } if (event & MU_MESAG) handle_message(pipe); /* no window to handle */ } while ((fgbg==BG) && !closed_acc); } /* Form window open */ void fg_event_loop() { int x,y,kstate,key,clicks,event,state; int pipe[8]; int tmph; fgexit = 0; window_open(WIND_CTRL); #ifdef DEBUG form_alert(1,"[1][ACC fg][Ok]"); #endif do { event = evnt_multi( MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD, 1, 0x3, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pipe, time_slice, 0, &x, &y, &state, &kstate, &key, &clicks ); if (event & MU_TIMER) if (replay) { stream_load(0); update_time(); } if(event & MU_KEYBD) { if(kstate & 0x04) call_control_key((char)(key&0xff)-1+(kstate&0x3?'A':'a')); else { wind_get(0, WF_TOP, &tmph); if(tmph == windforms[WIND_SHOE].whandle) prompt_console(key, 1); } #if 0 do_formstuff(obj_id); #endif } if(!fgexit) { if (event & MU_MESAG) fgexit=handle_message(pipe); if (event & MU_BUTTON) { if(wind_find(x,y) == windforms[WIND_CTRL].whandle) if(ev2_loop(&windforms[WIND_CTRL],x,y)) event=0; } } if(_app) quit=fgexit; else if(fgexit) fgbg=BG; } while ((replay || fgbg==FG) && !fgexit); } int ev2_loop(WINDFORM *wind,int mx,int my) { int x,y,kstate,key,clicks,event,state,org_state; int obj_id,ev2exit; int pipe[8]; CORDS t; fgexit = 0; if((obj_id=objc_find(wind->formtree,CTRL_FIRST,1,mx,my))>=0) { if(wind->formtree[obj_id].ob_flags & SELECTABLE) { org_state=wind->formtree[obj_id].ob_state & SELECTED; toggle_object(wind,obj_id,TOGGLE); objc_offset(wind->formtree,obj_id,&t.x,&t.y); t.w=wind->formtree[obj_id].ob_width; t.h=wind->formtree[obj_id].ob_height; ev2exit=0; do { event = evnt_multi( MU_MESAG | MU_TIMER | MU_BUTTON | MU_M1 | MU_M2, 1, 0x1, 0x0, 0, t.x, t.y, t.w, t.h, 1, t.x, t.y, t.w, t.h, pipe, time_slice, 0, &x, &y, &state, &kstate, &key, &clicks ); if (event & MU_TIMER) if (replay) { stream_load(0); update_time(); } if (event & MU_MESAG) fgexit=handle_message(pipe); if (event & MU_M1) { /* Enter area */ if(org_state==(wind->formtree[obj_id].ob_state & SELECTED)) toggle_object(wind,obj_id,TOGGLE); } if (event & MU_M2) { /* Leave area */ if(org_state!=(wind->formtree[obj_id].ob_state & SELECTED)) toggle_object(wind,obj_id,TOGGLE); } if (event & MU_BUTTON) { if(obj_id==objc_find(wind->formtree, CTRL_FIRST,1,x,y)) { toggle_object(wind,obj_id,TOGGLE); fgexit=do_formstuff(obj_id); } else { objc_change(wind->formtree,obj_id,0,wind->form.x, wind->form.y,wind->form.w,wind->form.h,org_state,0); update_objects(wind,obj_id,1,0); } ev2exit=1; } } while (((replay || fgbg==FG) && !fgexit) && !ev2exit); event=0; return 1; } } return 0; } void toggle_object(WINDFORM *wind,int obj_id,int mode) { if(mode == TOGGLE) { if(wind->formtree[obj_id].ob_state & SELECTED) mode = SET_NORMAL; else mode = SET_SELECTED; } /* Take button up */ if((mode==SET_NORMAL) && (wind->formtree[obj_id].ob_state & SELECTED)) { objc_change(wind->formtree,obj_id,0,wind->form.x, wind->form.y,wind->form.w,wind->form.h, NORMAL,0); wind->formtree[wind->formtree[obj_id].ob_head].ob_x--; wind->formtree[wind->formtree[obj_id].ob_head].ob_y--; /* Press button down */ } else if((mode==SET_SELECTED) && !(wind->formtree[obj_id].ob_state & SELECTED)) { objc_change(wind->formtree,obj_id,0,wind->form.x, wind->form.y,wind->form.w,wind->form.h, SELECTED,0); wind->formtree[wind->formtree[obj_id].ob_head].ob_x++; wind->formtree[wind->formtree[obj_id].ob_head].ob_y++; /* Nothing has changed */ } else { return; } update_objects(wind,obj_id,1,0); } int handle_message(int pipe[8]) { static int first_open=0; int wnr; static char hookcall[1024]; #ifdef DEBUG char tmp[128]; #endif switch (pipe[0]) { case AC_OPEN: if (pipe[4] == acc_id) { if(first_open) { if(windforms[WIND_CTRL].wind_open) wind_set(windforms[WIND_CTRL].whandle,WF_TOP); else fgbg=FG; } else { window_create(WIND_CTRL); fgbg=FG; first_open=1; } } #ifdef DEBUG form_alert(1,"[1][Got AC_OPEN][Ok]"); #endif break; case AC_CLOSE: /* if (pipe[4] == acc_id) */ { window_close(WIND_CTRL); window_close(WIND_INFO); window_close(WIND_SHOE); stream_save_state(); closed_acc=1; return 1; } /* break; */ case AP_TERM: quit=1; return 1; /* switch(pipe[5]) { case AP_RESCHG: printf("Got AP_RESCHG!\n"); break; case AP_TERM: printf("Got AP_TERM!"); break; default: printf("Got unknown AP_TERM!"); } */ /* break; */ case RESCHG_COMPLETED: /* printf("Got RESCHG_COMPLETED!"); */ break; case WM_REDRAW: if((wnr=find_windform(pipe[3]))>=0) update_objects(&windforms[wnr],windforms[wnr].firstobj, windforms[wnr].objdepth,pipe); break; case WM_MOVED: if((wnr=find_windform(pipe[3]))>=0) { window_move(wnr, pipe[4], pipe[5]); } break; case WM_CLOSED: if((wnr=find_windform(pipe[3]))>=0) { return window_close(wnr); } break; case WM_TOPPED: if((wnr=find_windform(pipe[3]))>=0) wind_set(pipe[3],WF_TOP); break; case AP_DRAGDROP: { char *file; if(find_windform(wind_find(pipe[4],pipe[5])) < 0) { file=do_dragdrop(pipe,DD_OK); if(file != NULL) { strcpy(hookcall, "(mp2-hook-dragumdroppum \""); strcat(hookcall, file); strcat(hookcall, "\")"); parse_eval(hookcall); } } else { do_dragdrop(pipe,DD_NAK); } } break; case VA_START: { char *vamsg; /* int avmsg[8]; */ vamsg=*((char **)&pipe[3]); /* This *should* be sent to the application which sent the VA_START msg, but it seems to hang Thing doing it. */ /* avmsg[0]=AV_STARTED; avmsg[1]=app_id; avmsg[2]=0; avmsg[3]=pipe[3]; avmsg[4]=pipe[4]; appl_write(pipe[1],5*2,avmsg); */ unquote(vamsg); strcpy(hookcall, "(mp2-hook-dragumdroppum \""); strcat(hookcall, vamsg); strcat(hookcall, "\")"); parse_eval(hookcall); } break; default: #ifdef DEBUG sprintf(tmp,"[1][Unimplemented| message: %d][Ok]",pipe[0]); form_alert(1,tmp); #endif break; } return 0; } char *do_dragdrop(int pipe[8], int mode) { static char misc[1024]; char dd_name[32],dd_cmsg; int i,dd_pipe,headsize,again=1; long datasize,err; strcpy(dd_name,"U:\\PIPE\\DRAGDROP."); strcat(dd_name,(char *)&pipe[7]); if((err=Fopen(dd_name,FO_RW)) >= 0) { dd_pipe=(int)err; dd_cmsg=(char)mode; Fwrite(dd_pipe,1,&dd_cmsg); if(mode==DD_OK) { strcpy(misc,"ARGS"); for(i=(int)strlen(misc) ; i<32 ; i++) misc[i] = '\0'; Fwrite(dd_pipe,32,misc); while(again) { Fread(dd_pipe,2,&headsize); if(headsize > 0) { Fread(dd_pipe,headsize,misc); if(!strncmp(misc,"ARGS",4)) { datasize = *((long *)&misc[4]); dd_cmsg=DD_OK; Fwrite(dd_pipe,1,&dd_cmsg); Fread(dd_pipe,datasize,misc); misc[datasize] = '\0'; unquote(misc); return misc; } else { dd_cmsg=DD_EXT; Fwrite(dd_pipe,1,&dd_cmsg); again=1; } } else again=0; } Fclose(dd_pipe); return NULL; } /* mode==DD_NAK do nothing*/ Fclose(dd_pipe); return NULL; } return NULL; } void update_objects(WINDFORM *wind,int obj_id,int depth, int pipe[8]) { CORDS2 r,u,o; CORDS t; if(pipe) { o.x1=pipe[4]; o.y1=pipe[5]; o.x2=pipe[4]+pipe[6]-1; o.y2=pipe[5]+pipe[7]-1; } graf_mouse(M_OFF,0); wind_update(BEG_UPDATE); wind_get(wind->whandle,WF_FIRSTXYWH,&t.x,&t.y,&t.w,&t.h); while(t.w || t.h) { if(pipe) { r.x1=t.x; r.y1=t.y; r.x2=t.x+t.w-1; r.y2=t.y+t.h-1; u.x1=max(r.x1,o.x1); u.y1=max(r.y1,o.y1); u.x2=min(r.x2,o.x2); u.y2=min(r.y2,o.y2); } else { u.x1=t.x; u.y1=t.y; u.x2=t.x+t.w-1; u.y2=t.y+t.h-1; } if((u.x2>=u.x1) && (u.y2>=u.y1)) { if(wind->wind_id == WIND_SHOE) { int xywh[4]; xywh[0] = u.x1; xywh[1] = u.y1; xywh[2] = u.x2-u.x1+1; xywh[3] = u.y2-u.y1+1; redraw_console(xywh, -1); /* redraw everything */ } else objc_draw(wind->formtree,obj_id,depth, u.x1, u.y1, u.x2-u.x1+1, u.y2-u.y1+1); } wind_get(wind->whandle,WF_NEXTXYWH,&t.x,&t.y,&t.w,&t.h); } wind_update(END_UPDATE); graf_mouse(M_ON,0); } void do_stop() { if(Dsp_Hf1(-1)) { /* If fast forwarding */ if(windforms[WIND_CTRL].formtree[CTRL_FF].ob_state & SELECTED) toggle_object(&windforms[WIND_CTRL],CTRL_FF,SET_NORMAL); Dsp_Hf1(0); } if(replay || replay_pausep()) { if(windforms[WIND_CTRL].formtree[CTRL_PAUSE].ob_state & SELECTED) toggle_object(&windforms[WIND_CTRL],CTRL_PAUSE,SET_NORMAL); replay_stop(); update_time(); } } void do_play() { if(replay_pausep() || Dsp_Hf1(-1)) { if(windforms[WIND_CTRL].formtree[CTRL_FF].ob_state & SELECTED) toggle_object(&windforms[WIND_CTRL],CTRL_FF,SET_NORMAL); Dsp_Hf1(0); if(windforms[WIND_CTRL].formtree[CTRL_PAUSE].ob_state & SELECTED) toggle_object(&windforms[WIND_CTRL],CTRL_PAUSE,SET_NORMAL); replay_continue(); } else if(!replay && stream_loadedp()) { replay_init(mp2info.sample_frequency); } } void do_pause() { if(replay_pausep()) { toggle_object(&windforms[WIND_CTRL],CTRL_PAUSE,SET_NORMAL); replay_continue(); } else { if(replay) { toggle_object(&windforms[WIND_CTRL],CTRL_PAUSE,SET_SELECTED); replay_pause(); } } } char *do_selectfile(char *pattern) { int button; static char file[1024],tfn[512]; strcpy(tfn,filename); strcat(path, pattern); fsel_exinput(path, tfn, &button, "Load MPEG"); strrchr(path, '\\')[1] = '\0'; if(button == 1 && *tfn) { strcpy(file,path); strcat(file, tfn); return file; } return NULL; } void do_loop() { toggle_object(&windforms[WIND_CTRL],CTRL_LOOP,TOGGLE); looping=(windforms[WIND_CTRL].formtree[CTRL_LOOP].ob_state & SELECTED); } void do_info() { /* Open info window */ if(windforms[WIND_INFO].wind_open) wind_set(windforms[WIND_INFO].whandle,WF_TOP); else { window_create(WIND_INFO); window_open(WIND_INFO); } } void do_ff() { if(replay || replay_pausep()) { toggle_object(&windforms[WIND_CTRL],CTRL_FF,TOGGLE); if(windforms[WIND_CTRL].formtree[CTRL_FF].ob_state & SELECTED) Dsp_Hf1(1); else Dsp_Hf1(0); } } void do_shoe() { /* Open Shoe window */ if(windforms[WIND_SHOE].wind_open) wind_set(windforms[WIND_SHOE].whandle,WF_TOP); else { static int console_online=0; window_create(WIND_SHOE); window_open(WIND_SHOE); if(!console_online) { initialize_console(CONSOLE_W, CONSOLE_H); print_line("Online Shoe Macro Console MP2 "VERSION_TEXT"."); print_line("COPYRIGHT 1999 by NoCrew Laboratories."); print_line("Ready."); prompt_console(0, 0); } console_online = 1; } } int do_formstuff(int obj_id) { switch(obj_id) { case CTRL_STOP: eval("(mp2-icon-stop)"); break; case CTRL_PLAY: eval("(mp2-icon-play)"); break; case CTRL_PAUSE: eval("(mp2-icon-pause)"); break; case CTRL_LOAD: eval("(mp2-icon-load)"); break; case CTRL_LOOP: eval("(mp2-icon-loop)"); break; case CTRL_INFO: eval("(mp2-icon-info)"); break; case CTRL_NEXT: eval("(mp2-icon-next)"); break; case CTRL_PREV: eval("(mp2-icon-previous)"); break; case CTRL_FF: eval("(mp2-icon-fast-forward)"); break; case CTRL_SHOE: eval("(mp2-icon-console)"); break; default: break; } return 0; } long calc_time() { return stream_position()/(mp2info.bitrate/8); } void set_title(char *title) { strcpy(windforms[WIND_CTRL].wind_title, title); wind_set(windforms[WIND_CTRL].whandle,WF_NAME, windforms[WIND_CTRL].wind_title); } void update_time() { long time; char tmp[64]; if(!display_time) return; if(count_dir) time = mp2info.timelength - calc_time(); else time = calc_time(); sprintf(tmp,"%02ld:%02ld",time/60,time%60); if(strcmp(tmp,windforms[WIND_CTRL].wind_title)) { set_title(tmp); } } void set_subtitle(char *subtitle) { char *text; text = windforms[WIND_CTRL].formtree[CTRL_FILENAME].ob_spec.tedinfo->te_ptext; strncpy(text, subtitle, 16); text[16] = '\0'; update_objects(&windforms[WIND_CTRL],CTRL_FNAME_BOX,0,0); update_objects(&windforms[WIND_CTRL],CTRL_FILENAME,0,0); } /* Convert quoted pathname to unquoted form */ void unquote(char *qname) { char temp[512], *tp; int i; if (qname[0] == '\'') { strcpy(temp, qname+1); tp = temp; for (i = 0; i < 512 ; i++) { if (tp[i] == '\'') { if (tp[i+1] == '\'') tp++; else tp[i] = '\0'; } qname[i] = tp[i]; if (tp[i] == '\0') break; } } else { if ((tp = strchr(qname, ' ')) != NULL) *tp = '\0'; } }