📄 music.c
字号:
} chanprint(cs->ctl, "browsebot show"); free(onum);}voidbrowsedown(char *onum){ if(browsesp == 0){ /* Make room for an entry by deleting the last */ free(browsestack[Browsedepth-1].onum); memmove(browsestack + 1, browsestack, (Browsedepth-1) * sizeof(browsestack[0])); browsesp++; } /* Store current position in current stack frame */ assert(browsesp > 0 && browsesp < Browsedepth); browsestack[browsesp].onum = strdup(parent.address); browsestack[browsesp].scrollpos = browseline; browsesp--; browseline = 0; if(browsestack[browsesp].onum && strcmp(browsestack[browsesp].onum, onum) == 0) browseline = browsestack[browsesp].scrollpos; browseto(onum, browseline);}voidbrowseup(char *onum){ if(browsesp == Browsedepth){ /* Make room for an entry by deleting the first */ free(browsestack[0].onum); memmove(browsestack, browsestack + 1, browsesp * sizeof(browsestack[0])); browsesp--; } /* Store current position in current stack frame */ assert(browsesp >= 0 && browsesp < Browsedepth); browsestack[browsesp].onum = strdup(parent.address); browsestack[browsesp].scrollpos = browseline; browsesp++; browseline = 0; if(browsestack[browsesp].onum && strcmp(browsestack[browsesp].onum, onum) == 0) browseline = browsestack[browsesp].scrollpos; browseto(onum, browseline);}voidaddplaytext(char *s){ chanprint(cs->ctl, "playtext accumulate %q", s);}voidwork(void){ static char *eventstr, *args[64], *s; static char buf[4096]; int a, n, i; Alt alts[] = { [Exitbutton] = {buts[Exitbutton].ctl->event, &eventstr, CHANRCV}, [Pausebutton] = {buts[Pausebutton].ctl->event, &eventstr, CHANRCV}, [Playbutton] = {buts[Playbutton].ctl->event, &eventstr, CHANRCV}, [Stopbutton] = {buts[Stopbutton].ctl->event, &eventstr, CHANRCV}, [Prevbutton] = {buts[Prevbutton].ctl->event, &eventstr, CHANRCV}, [Nextbutton] = {buts[Nextbutton].ctl->event, &eventstr, CHANRCV}, [Rootbutton] = {buts[Rootbutton].ctl->event, &eventstr, CHANRCV}, [Deletebutton] = {buts[Deletebutton].ctl->event, &eventstr, CHANRCV}, [Helpbutton] = {buts[Helpbutton].ctl->event, &eventstr, CHANRCV}, [Volume] = {vol->event, &eventstr, CHANRCV}, [Browsetopwin] = {browsetopwin->event, &eventstr, CHANRCV}, [Browsebotwin] = {browsebotwin->event, &eventstr, CHANRCV}, [Browsebotscr] = {browsebotscr->event, &eventstr, CHANRCV}, [Playevent] = {playevent, &eventstr, CHANRCV}, [Playlistwin] = {playlistwin->event, &eventstr, CHANRCV}, [Nalt] = {nil, nil, CHANEND} }; activate(vol); activate(controlcalled("tabs")); activatebuttons(1 << Exitbutton | 1 << Rootbutton | 1 << Helpbutton); root = getroot(); setparent(root); clearchildren(); addparent("Root"); chanprint(cs->ctl, "browsetop show"); fillbrowsebot(root); chanprint(cs->ctl, "browsebot show"); eventstr = nil; selected = -1; for(;;){ a = alt(alts); if(debug & DBGCONTROL) fprint(2, "Event: %s\n", eventstr); n = tokenize(eventstr, args, nelem(args)); switch(a){ default: sysfatal("Illegal event %d in work", a); case Volume: if(n != 3 || strcmp(args[0], "volume") || strcmp(args[1], "volume")) sysfatal("Bad Volume event[%d]: %s %s", n, args[0], args[1]); setvolume(args[2]); break; case Exitbutton: return; case Pausebutton: if(n != 3 || strcmp(args[0], "pause:") || strcmp(args[1], "value")) sysfatal("Bad Pausebutton event[%d]: %s %s", n, args[0], args[1]); if(strcmp(args[2], "0") == 0) fprint(playctlfd, "resume"); else fprint(playctlfd, "pause"); break; case Playbutton: if(n != 3 || strcmp(args[0], "play:") || strcmp(args[1], "value")) sysfatal("Bad Playbutton event[%d]: %s %s", n, args[0], args[1]); if(playlist.selected >= 0){ fprint(playctlfd, "play %d", playlist.selected); }else fprint(playctlfd, "play"); break; case Stopbutton: if(n != 3 || strcmp(args[0], "stop:") || strcmp(args[1], "value")) sysfatal("Bad Stopbutton event[%d]: %s %s", n, args[0], args[1]); if(strcmp(args[2], "0") == 0) chanprint(cs->ctl, "%q value 1", buts[Stopbutton].ctl->name); fprint(playctlfd, "stop"); break; case Prevbutton: if(n != 3 || strcmp(args[0], "prev:") || strcmp(args[1], "value")) sysfatal("Bad Prevbutton event[%d]: %s %s", n, args[0], args[1]); if(strcmp(args[2], "0") == 0) break; chanprint(cs->ctl, "%q value 0", buts[Prevbutton].ctl->name); fprint(playctlfd, "skip -1"); break; case Nextbutton: if(n != 3 || strcmp(args[0], "next:") || strcmp(args[1], "value")) sysfatal("Bad Nextbutton event[%d]: %s %s", n, args[0], args[1]); if(strcmp(args[2], "0") == 0) break; chanprint(cs->ctl, "%q value 0", buts[Nextbutton].ctl->name); fprint(playctlfd, "skip 1"); break; case Playlistwin: if(debug & (DBGCONTROL|DBGPLAY)) fprint(2, "Playlistevent: %s %s\n", args[0], args[1]); if(n != 4 || strcmp(args[0], "playlistwin:") || strcmp(args[1], "select")) sysfatal("Bad Playlistwin event[%d]: %s %s", n, args[0], args[1]); n = atoi(args[2]); if(n < 0 || n >= playlist.nentries) sysfatal("Selecting line %d of %d", n, playlist.nentries); if(playlist.selected >= 0 && playlist.selected < playlist.nentries){ chanprint(cs->ctl, "playlistwin select %d 0", playlist.selected); chanprint(cs->ctl, "playlistwin show"); } playlist.selected = -1; deactivatebuttons(1<<Playbutton); if(strcmp(args[3], "1") == 0) playlistselect(n); break; case Rootbutton: chanprint(cs->ctl, "%q value 0", buts[Rootbutton].ctl->name); setparent(root); clearchildren(); addparent("Root"); chanprint(cs->ctl, "browsetop show"); fillbrowsebot(root); chanprint(cs->ctl, "browsebot show"); break; case Deletebutton: if(n != 3 || strcmp(args[0], "trash:") || strcmp(args[1], "value")) sysfatal("Bad Deletebutton event[%d]: %s %s", n, args[0], args[1]); if(strcmp(args[2], "0") == 0) break; chanprint(cs->ctl, "%q value 0", buts[Deletebutton].ctl->name); sendplaylist(nil, nil); break; case Helpbutton: chanprint(cs->ctl, "%q value 0", buts[Helpbutton].ctl->name); if(errorlines > 0){ chanprint(cs->ctl, "errortext clear"); chanprint(cs->ctl, "errortext topline 0"); chanprint(cs->ctl, "errorscr max 0"); chanprint(cs->ctl, "errorscr value 0"); } if(errorlines >= 0){ for(i = 0; helptext[i]; i++) chanprint(cs->ctl, "errortext accumulate %q", helptext[i]); chanprint(cs->ctl, "errorscr max %d", i); } chanprint(cs->ctl, "errortext topline 0"); chanprint(cs->ctl, "errorscr value 0"); errorlines = -1; chanprint(cs->ctl, "tabs value %d", WinError); break; case Browsetopwin: if(n != 4 || strcmp(args[0], "browsetopwin:") || strcmp(args[1], "select")) sysfatal("Bad Browsetopwin event[%d]: %s %s", n, args[0], args[1]); if(strcmp(args[3], "0") == 0) break; chanprint(cs->ctl, "browsetopwin select %s 0", args[2]); selected = -1; if(strcmp(args[3], "2") == 0) doplay(parent.address); else if(strcmp(args[3], "4") == 0){ s = getparent(parent.address); browsedown(s); } break; case Browsebotwin: if(n != 4 || strcmp(args[0], "browsebotwin:") || strcmp(args[1], "select")) sysfatal("Bad Browsebotwin event[%d]: %s %s", n, args[0], args[1]); n = atoi(args[2]); if(n < 0 || n >= nchildren) sysfatal("Selection out of range: %d [%d]", n, nchildren); if(strcmp(args[3], "0") == 0){ selected = -1; break; } if(n < 0) break; chanprint(cs->ctl, "browsebotwin select %d 0", n); selected = n; if(selected >= nchildren) sysfatal("Select out of range: %d [0⋯%d)", selected, nchildren); if(strcmp(args[3], "1") == 0){ browseup(children[selected].address); }else if(strcmp(args[3], "2") == 0) doplay(children[selected].address); else if(strcmp(args[3], "4") == 0) browsedown(getparent(parent.address)); break; case Browsebotscr: browseline = atoi(args[2]); chanprint(cs->ctl, "browsebotwin topline %d", browseline); break; case Playevent: if(n < 3 || strcmp(args[0], "playctlproc:")) sysfatal("Bad Playevent event[%d]: %s", n, args[0]); if(debug & (DBGCONTROL|DBGPLAY)) fprint(2, "Playevent: %s %s\n", args[1], args[2]); if(strcmp(args[1], "error") ==0){ if(n != 4){ fprint(2, "Playevent: %s: arg count: %d\n", args[1], n); break; } if(errorlines < 0){ chanprint(cs->ctl, "errortext clear"); chanprint(cs->ctl, "errortext topline 0"); chanprint(cs->ctl, "errorscr max 0"); chanprint(cs->ctl, "errorscr value 0"); errorlines = 0; } n = errorlines; chanprint(cs->ctl, "errortext accumulate %q", args[3]); chanprint(cs->ctl, "errorscr max %d", ++errorlines); if(n >= 0 && n <= errorlines - Dy(errortext->rect)/romanfont->height) n--; else n = errorlines - Dy(errortext->rect)/romanfont->height + 1; if(n < 0) n = 0; if(n < errorlines){ chanprint(cs->ctl, "errortext topline %d", n); chanprint(cs->ctl, "errorscr value %d", n); } chanprint(cs->ctl, "tabs value %d", WinError); }else if(strcmp(args[1], "play") ==0){ chanprint(cs->ctl, "%q value 1", buts[Playbutton].ctl->name); chanprint(cs->ctl, "%q value 0", buts[Stopbutton].ctl->name); chanprint(cs->ctl, "%q value 0", buts[Pausebutton].ctl->name); playlistselect(strtoul(args[2], nil, 0)); chanprint(cs->ctl, "playtext clear"); chanprint(cs->ctl, "playtext topline 0"); chanprint(cs->ctl, "playscr max 0"); chanprint(cs->ctl, "playscr value 0"); playstate = Playing; activatebuttons(playingbuts); qlock(&playlist); if(playlist.selected < playlist.nentries){ fillplaytext(playlist.entry[playlist.selected].onum); chanprint(cs->ctl, "playscr max %d", n); } qunlock(&playlist); chanprint(cs->ctl, "playwin show"); }else if(strcmp(args[1], "stop") ==0){ chanprint(cs->ctl, "%q value 0", buts[Playbutton].ctl->name); chanprint(cs->ctl, "%q value 1", buts[Stopbutton].ctl->name); chanprint(cs->ctl, "%q value 0", buts[Pausebutton].ctl->name); playlistselect(strtoul(args[2], nil, 0)); chanprint(cs->ctl, "%q show", tabs[WinPlaylist].winname); playstate = PlayIdle; deactivatebuttons(playingbuts); }else if(strcmp(args[1], "pause") ==0){ activatebuttons(playingbuts); chanprint(cs->ctl, "%q value 1", buts[Playbutton].ctl->name); chanprint(cs->ctl, "%q value 0", buts[Stopbutton].ctl->name); if(playstate == PlayPause){ chanprint(cs->ctl, "%q value 0", buts[Pausebutton].ctl->name); playstate = Playing; }else{ chanprint(cs->ctl, "%q value 1", buts[Pausebutton].ctl->name); playstate = PlayPause; } }else if(strcmp(args[1], "exits") ==0){ threadexits("exitevent"); }else{ fprint(2, "Unknown play event:"); for(i=0; i<n; i++) fprint(2, " %s", args[i]); fprint(2, "\n"); } break; } if(eventstr){ free(eventstr); eventstr = nil; } }}voidthreadmain(int argc, char *argv[]){ int wflag; wflag = 0; ARGBEGIN{ case 'd': debug = strtol(ARGF(), nil, 0); break; case 't': tflag = 1; break; case 'w': wflag = 1; break; default: sysfatal(usage, argv0); }ARGEND quotefmtinstall(); if(tflag) makewindow(320, 320, wflag); else makewindow(480, 480, wflag); playlist.selected = -1; playctlfd = open(playctlfile, OWRITE); if(playctlfd < 0) sysfatal("%s: %r", playctlfile); proccreate(playlistproc, nil, 8192); playevent = chancreate(sizeof(char *), 1); proccreate(playctlproc, playevent, 8192); proccreate(playvolproc, cs->ctl, 8192); work(); closecontrolset(cs); threadexitsall(nil);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -