📄 music.c
字号:
#include <u.h>#include <libc.h>#include <thread.h>#include <draw.h>#include <keyboard.h>#include <mouse.h>#include <control.h>#include "colors.h"#include "client.h"#include "playlist.h"#include "../debug.h"int debug = 0; //DBGSERVER|DBGPUMP|DBGSTATE|DBGPICKLE|DBGPLAY;char usage[] = "Usage: %s [-d mask] [-t] [-w]\n";typedef struct But { char *name; Control *ctl;} But;typedef struct Simpleitem { char *address; char *data;} Simpleitem;typedef struct Multiitem { char *address; int ndata; char **data;} Multiitem;enum { WinBrowse, WinPlay, WinPlaylist, WinError, Topselect = 0x7fffffff, Browsedepth = 63,};typedef enum { PlayIdle, PlayStart, Playing, PlayPause,} Playstate;typedef enum { User, Troot, Rroot, Tchildren, Rchildren, Tparent, Rparent, Tinfo, Rinfo, Tparentage, Rparentage, Tplay, Rplay,} Srvstate;enum { Exitbutton, Pausebutton, Playbutton, Stopbutton, Prevbutton, Nextbutton, Rootbutton, Deletebutton, Helpbutton, Volume, Browsetopwin, Browsebotwin, Browsebotscr, Playevent, Playlistwin, Nalt,};But buts[] = { [Exitbutton] = {"skull", nil}, [Pausebutton] = {"pause", nil}, [Playbutton] = {"play", nil}, [Stopbutton] = {"stop", nil}, [Prevbutton] = {"prev", nil}, [Nextbutton] = {"next", nil}, [Rootbutton] = {"root", nil}, [Deletebutton] = {"trash", nil}, [Helpbutton] = {"question", nil},};struct tab { char *tabname; char *winname; Control *tab; Control *win;} tabs[4] = { [WinBrowse] = {"Browse", "browsewin", nil, nil}, [WinPlay] = {"Playing", "playwin", nil, nil}, [WinPlaylist] = {"Playlist", "listwin", nil, nil}, [WinError] = {"Errors", "errorwin", nil, nil},};char *helptext[] = { "Buttons, left to right:", " Exit: exit jukebox", " Pause: pause/resume playback", " Play: play selection in Playlist", " Stop: stop playback", " Prev: play previous item in Playlist", " Next: play next item in Playlist", " Root: browse to root of database tree", " Delete: empty Playlist, reread database", " Help: show this window", "", "Browse window: (click tab to bring forward)", " Top window displays current item", " Bottom window displays selectable subitems", " Mouse commands:", " Left: selected subitem becomes current", " Right: parent of current item becomes current", " Middle: add item or subitem to Playlist", "", "Playing window", " Displays item currently playing", "", "Playlist window", " Displays contents of Playlist", " Mouse commands:", " Left: select item", " (then click the play button)", "", "Error window", " Displays error messages received from player", " (e.g., can't open file)", nil,};struct Browsestack { char *onum; int scrollpos;} browsestack[Browsedepth];int browsesp; /* browse stack pointer */int browseline; /* current browse position */Control *vol;Control *browsetopwin;Control *browsebotwin;Control *playlistwin;Control *errortext;Control *browsetopscr;Control *browsebotscr;Playstate playstate;ulong playingbuts = 1<<Pausebutton | 1<<Stopbutton | 1<<Prevbutton | 1<<Nextbutton;ulong activebuts;int tabht;Image *vol1img;Image *vol2img;int resizeready;int borderwidth = 1;int butht, butwid;int errorlines;int tflag;int pflag;Controlset *cs;char *root;Multiitem parent;Simpleitem children[2048];int nchildren;int selected;Channel *playevent;voidreadbuts(void){ static char str[32], file[64]; But *b; int fd; Image *img, *mask; for(b = buts; b < &buts[nelem(buts)]; b++){ sprint(file, "%s/%s.bit", ICONPATH, b->name); if((fd = open(file, OREAD)) < 0) sysfatal("open: %s: %r", file); mask = readimage(display, fd, 0); close(fd); butwid = Dx(mask->r); butht = Dy(mask->r); b->ctl = createbutton(cs, b->name); chanprint(cs->ctl, "%q align center", b->name); chanprint(cs->ctl, "%q border 0", b->name); img = allocimage(display, mask->r, screen->chan, 0, 0xe0e0ffff); draw(img, img->r, darkgreen, mask, mask->r.min); sprint(str, "%s.active", b->name); namectlimage(img, str); img = allocimage(display, mask->r, screen->chan, 0, 0xe0e0ffff); draw(img, img->r, lightblue, mask, mask->r.min); sprint(str, "%s.passive", b->name); namectlimage(img, str); chanprint(cs->ctl, "%q image %q", b->name, str); sprint(str, "%s.mask", b->name); namectlimage(mask, str); chanprint(cs->ctl, "%q mask %q", b->name, str); chanprint(cs->ctl, "%q light red", b->name); chanprint(cs->ctl, "%q size %d %d %d %d", b->name, butwid, butht, butwid, butht); }}voidactivatebuttons(ulong mask){ // mask bit i corresponds to buts[i]; ulong bit; But *b; static char str[40]; int i; for(i = 0; i < nelem(buts); i++){ b = &buts[i]; bit = 1 << i; if((mask & bit) && (activebuts & bit) == 0){ // button was `deactive' activate(b->ctl); activebuts |= bit; sprint(str, "%s.active", b->name); chanprint(cs->ctl, "%q image %q", b->name, str); chanprint(cs->ctl, "%q show", b->name); } }}voiddeactivatebuttons(ulong mask){ // mask bit i corresponds with buts[i]; ulong bit; But *b; static char str[40]; int i; for(i = 0; i < nelem(buts); i++){ b = &buts[i]; bit = 1 << i; if((mask & bit) && (activebuts & bit)){ // button was active deactivate(b->ctl); activebuts &= ~bit; sprint(str, "%s.passive", b->name); chanprint(cs->ctl, "%q image %q", b->name, str); chanprint(cs->ctl, "%q show", b->name); } }}voidresizecontrolset(Controlset *){ static Point pol[3]; char *p; if(getwindow(display, Refbackup) < 0) sysfatal("getwindow"); draw(screen, screen->r, bordercolor, nil, screen->r.min); if(!resizeready) return;#ifndef REPLACESEMANTICS if(vol1img) chanprint(cs->ctl, "volume image darkgreen"); if(vol2img) chanprint(cs->ctl, "volume indicatorcolor red"); chanprint(cs->ctl, "wholewin size"); chanprint(cs->ctl, "wholewin rect %R", screen->r); chanprint(cs->ctl, "sync"); p = recvp(cs->data); if(strcmp(p, "sync")) sysfatal("huh?"); free(p); if(vol1img){ freectlimage("volume.img"); freeimage(vol1img); } if(vol2img){ freectlimage("indicator.img"); freeimage(vol2img); } vol1img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); vol2img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); pol[0] = Pt(vol->rect.min.x, vol->rect.max.y); pol[1] = Pt(vol->rect.max.x, vol->rect.min.y); pol[2] = vol->rect.max; fillpoly(vol1img, pol, 3, 0, darkgreen, ZP); fillpoly(vol2img, pol, 3, 0, red, ZP); namectlimage(vol1img, "volume.img"); namectlimage(vol2img, "indicator.img"); chanprint(cs->ctl, "volume image volume.img"); chanprint(cs->ctl, "volume indicatorcolor indicator.img");#else chanprint(cs->ctl, "wholewin size"); chanprint(cs->ctl, "wholewin rect %R", screen->r); chanprint(cs->ctl, "sync"); p = recvp(cs->data); if(strcmp(p, "sync")) sysfatal("huh?"); free(p); new1img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); new2img = allocimage(display, vol->rect, screen->chan, 0, 0xe0e0ffff); pol[0] = Pt(vol->rect.min.x, vol->rect.max.y); pol[1] = Pt(vol->rect.max.x, vol->rect.min.y); pol[2] = vol->rect.max; fillpoly(new1img, pol, 3, 0, darkgreen, ZP); fillpoly(new2img, pol, 3, 0, red, ZP); namectlimage(new1img, "volume.img"); namectlimage(new2img, "indicator.img"); if(vol1img) freeimage(vol1img); else chanprint(cs->ctl, "volume image volume.img"); if(vol2img) freeimage(vol2img); else chanprint(cs->ctl, "volume indicatorcolor indicator.img"); vol1img = new1img; vol2img = new2img;#endif chanprint(cs->ctl, "browsetopscr vis '%d'", Dy(controlcalled("browsetopscr")->rect)/romanfont->height); chanprint(cs->ctl, "browsebotscr vis '%d'", Dy(controlcalled("browsebotscr")->rect)/romanfont->height); chanprint(cs->ctl, "playscr vis '%d'", Dy(controlcalled("playscr")->rect)/romanfont->height); chanprint(cs->ctl, "playlistscr vis '%d'", Dy(controlcalled("playlistscr")->rect)/romanfont->height); chanprint(cs->ctl, "wholewin show");}voidmaketab(void){ int i; tabht = boldfont->height + 1 + borderwidth; createtab(cs, "tabs"); for(i = 0; i < nelem(tabs); i++){ tabs[i].tab = createtextbutton(cs, tabs[i].tabname);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -