From d5c1127f425118e29121d5b23ceac10d6e95fda0 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sun, 23 Nov 2025 18:31:34 +0900 Subject: [PATCH] wip --- mauplay/db.c | 127 +++++++++++++++++++ mauplay/main.c | 302 +++++++++++++++++++++++++++++----------------- mauplay/mauplay.h | 23 ++++ mauplay/stb_ds.c | 2 + mauplay/ui.c | 97 +++++++++++++++ 5 files changed, 440 insertions(+), 111 deletions(-) create mode 100644 mauplay/db.c create mode 100644 mauplay/stb_ds.c create mode 100644 mauplay/ui.c diff --git a/mauplay/db.c b/mauplay/db.c new file mode 100644 index 0000000..75a287b --- /dev/null +++ b/mauplay/db.c @@ -0,0 +1,127 @@ +#include "mauplay.h" + +#include +#include +#include + +static sqlite3* db; + +int db_exec(const char* s) { + sqlite3_stmt* stmt; + int st = 0; + + if(sqlite3_prepare_v2(db, s, -1, &stmt, NULL) != SQLITE_OK) { + return 1; + } + + if(sqlite3_step(stmt) != SQLITE_DONE) { + st = 1; + } + + if(sqlite3_finalize(stmt) != SQLITE_OK) { + st = 1; + } + + return st; +} + +int db_init(void) { + struct passwd* pwd = getpwuid(getuid()); + char* dir = malloc(strlen(pwd->pw_dir) + 1 + strlen(".config/mauplay") + 1); + char* path; + int st = 0; + + strcpy(dir, pwd->pw_dir); + strcat(dir, "/.config/mauplay"); + + MDEDirectoryCreate(dir, 0755); + + path = malloc(strlen(dir) + 1 + strlen("mauplay.db") + 1); + strcpy(path, dir); + strcat(path, "/mauplay.db"); + + free(dir); + + if(sqlite3_open(path, &db) != SQLITE_OK) { + free(path); + return 1; + } + + free(path); + + if((st = db_exec("CREATE TABLE IF NOT EXISTS cache (path TEXT PRIMARY KEY, title TEXT, artist TEXT, album TEXT, genre TEXT, length INTEGER, mtime INTEGER)")) != 0) { + sqlite3_close(db); + return st; + } + + return st; +} + +static int db_bind(sqlite3_stmt* stmt, const char* path) { + SF_INFO sfi; + SNDFILE* sf = sf_open(path, SFM_READ, &sfi); + char* p; + const char* s_title; + const char* s_artist; + const char* s_album; + const char* s_genre; + int s_length; + struct stat s; + if(sf == NULL) return 1; + + s_title = sf_get_string(sf, SF_STR_TITLE); + s_artist = sf_get_string(sf, SF_STR_ARTIST); + s_album = sf_get_string(sf, SF_STR_ALBUM); + s_genre = sf_get_string(sf, SF_STR_GENRE); + s_length = sfi.frames / sfi.samplerate; + + if(s_title == NULL) s_title = path; + if(s_artist == NULL) s_artist = ""; + if(s_album == NULL) s_album = ""; + if(s_genre == NULL) s_genre = ""; + + p = MDEFileAbsolutePath(path); + + stat(p, &s); + + sqlite3_bind_text(stmt, 1, p, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 2, s_title, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 3, s_artist, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 4, s_album, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 5, s_genre, -1, SQLITE_TRANSIENT); + sqlite3_bind_int(stmt, 6, s_length); + sqlite3_bind_int64(stmt, 7, s.st_mtime); + + sf_close(sf); + + free(p); + + return 0; +} + +void db_add(const char* path) { + sqlite3_stmt* stmt; + + if(sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO cache VALUES(?,?,?,?,?,?,?)", -1, &stmt, NULL) != SQLITE_OK) { + return; + } + + if(db_bind(stmt, path) == 0) { + sqlite3_step(stmt); + } + sqlite3_finalize(stmt); +} + +void db_scan(void) { + sqlite3_stmt* stmt; + + if(sqlite3_prepare_v2(db, "SELECT * FROM cache", -1, &stmt, NULL) != SQLITE_OK) { + return; + } + + while(sqlite3_step(stmt) == SQLITE_ROW) { + printf("!\n"); + } + + sqlite3_finalize(stmt); +} diff --git a/mauplay/main.c b/mauplay/main.c index 164997c..43fd1cc 100644 --- a/mauplay/main.c +++ b/mauplay/main.c @@ -9,153 +9,228 @@ #include "repeat.xpm" #include "shuffle.xpm" -MwWidget window; -MwWidget menu, album, infoframe, infosep, bskipback, bplay, bpause, bstop, bskipfwd, modesep, brepeat, bshuffle, mainsep; -MwLLPixmap pxalbum, pxskipback, pxplay, pxpause, pxstop, pxskipfwd, pxrepeat, pxshuffle; +MwWidget window; +MwWidget menu, album, infoframe, info, infosep, bskipback, bplay, bpause, bstop, bskipfwd, modesep, brepeat, bshuffle; +MwWidget mainsep; +MwWidget eltime, seekbar, rmtime; +MwWidget tree, list; +MwLLPixmap pxalbum, pxskipback, pxplay, pxpause, pxstop, pxskipfwd, pxrepeat, pxshuffle; +unsigned char* pxalbumdata; -static void resize(MwWidget handle, void* user, void* client){ +static void resize(MwWidget handle, void* user, void* client) { int ww = MwGetInteger(window, MwNwidth); int wh = MwGetInteger(window, MwNheight) - MwGetInteger(menu, MwNheight); - int y = MwGetInteger(menu, MwNheight); + int y = MwGetInteger(menu, MwNheight); MwVaApply(album, - MwNx, 5, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(infoframe, - MwNx, 5 + 32 + 5, - MwNy, y + 5, - MwNwidth, ww - 5 - 32 - 5 - 5 - 10 - 10 - 32 * 7, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5, + MwNy, y + 5, + MwNwidth, ww - 5 - 32 - 5 - 5 - 10 - 10 - 32 * 7, + MwNheight, 32, + NULL); + + MwVaApply(info, + MwNx, MwDefaultBorderWidth(infoframe), + MwNy, MwDefaultBorderWidth(infoframe), + MwNwidth, MwGetInteger(infoframe, MwNwidth) - MwDefaultBorderWidth(infoframe) * 2, + MwNheight, MwGetInteger(infoframe, MwNheight) - MwDefaultBorderWidth(infoframe) * 2, + NULL); MwVaApply(infosep, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth), - MwNy, y + 5, - MwNwidth, 10, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth), + MwNy, y + 5, + MwNwidth, 10, + MwNheight, 32, + NULL); MwVaApply(bskipback, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(bplay, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(bpause, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 + 32, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 + 32, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(bstop, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 + 32 + 32, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 + 32 + 32, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(bskipfwd, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 + 32 + 32 + 32, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 + 32 + 32 + 32, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(modesep, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 * 5, - MwNy, y + 5, - MwNwidth, 10, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 * 5, + MwNy, y + 5, + MwNwidth, 10, + MwNheight, 32, + NULL); MwVaApply(brepeat, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 * 5 + 10, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 * 5 + 10, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(bshuffle, - MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 * 5 + 10 + 32, - MwNy, y + 5, - MwNwidth, 32, - MwNheight, 32, - NULL); + MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth) + 10 + 32 * 5 + 10 + 32, + MwNy, y + 5, + MwNwidth, 32, + MwNheight, 32, + NULL); MwVaApply(mainsep, - MwNx, 5, - MwNy, y + 5 + 32, - MwNwidth, ww - 5 - 5, - MwNheight, 10, - NULL); + MwNx, 5, + MwNy, y + 5 + 32, + MwNwidth, ww - 5 - 5, + MwNheight, 10, + NULL); + + MwVaApply(eltime, + MwNx, 5, + MwNy, y + 5 + 32 + 10, + MwNwidth, MwTextWidth(window, "00:00"), /* please, never put 1 hour music */ + MwNheight, 16, + NULL); + + MwVaApply(seekbar, + MwNx, 5 + MwTextWidth(window, "00:00") + 5, + MwNy, y + 5 + 32 + 10, + MwNwidth, ww - (5 + MwTextWidth(window, "00:00") + 5) * 2, + MwNheight, 16, + NULL); + + MwVaApply(rmtime, + MwNx, ww - 5 - MwTextWidth(window, "00:00"), + MwNy, y + 5 + 32 + 10, + MwNwidth, MwTextWidth(window, "00:00"), + MwNheight, 16, + NULL); + + MwVaApply(tree, + MwNx, 5, + MwNy, y + 5 + 32 + 10 + 16 + 5, + MwNwidth, 128 + 16, + MwNheight, wh - 5 - 32 - 10 - 16 - 5 - 5, + NULL); + + MwVaApply(list, + MwNx, 5 + 128 + 16 + 5, + MwNy, y + 5 + 32 + 10 + 16 + 5, + MwNwidth, ww - 5 - 128 - 16 - 5 - 5, + MwNheight, wh - 5 - 32 - 10 - 16 - 5 - 5, + NULL); } int main() { + int st; + + if((st = db_init()) != 0) return st; + MwLibraryInit(); - window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 400, - MwNtitle, "mauplay", - NULL); - menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0); - album = MwCreateWidget(MwImageClass, "album", window, 0, 0, 0, 0); - infoframe = MwVaCreateWidget(MwFrameClass, "info", window, 0, 0, 0, 0, - MwNbackground, "#000", - MwNforeground, "#0f0", - MwNhasBorder, 1, - MwNinverted, 1, - NULL); - infosep = MwVaCreateWidget(MwSeparatorClass, "infosep", window, 0, 0, 0, 0, - MwNorientation, MwVERTICAL, - NULL); + window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 400, + MwNtitle, "mauplay", + NULL); + menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0); + album = MwCreateWidget(MwImageClass, "album", window, 0, 0, 0, 0); + infoframe = MwVaCreateWidget(MwFrameClass, "infoframe", window, 0, 0, 0, 0, + MwNbackground, "#000", + MwNforeground, "#0f0", + MwNhasBorder, 1, + MwNinverted, 1, + NULL); + info = MwVaCreateWidget(MwLabelClass, "info", infoframe, 0, 0, 0, 0, + MwNalignment, MwALIGNMENT_BEGINNING, + NULL); + infosep = MwVaCreateWidget(MwSeparatorClass, "infosep", window, 0, 0, 0, 0, + MwNorientation, MwVERTICAL, + NULL); bskipback = MwVaCreateWidget(MwButtonClass, "skipback", window, 0, 0, 0, 0, - MwNflat, 1, - NULL); - bplay = MwVaCreateWidget(MwButtonClass, "play", window, 0, 0, 0, 0, - MwNflat, 1, - NULL); - bpause = MwVaCreateWidget(MwButtonClass, "pause", window, 0, 0, 0, 0, - MwNflat, 1, - NULL); - bstop = MwVaCreateWidget(MwButtonClass, "stop", window, 0, 0, 0, 0, - MwNflat, 1, - NULL); - bskipfwd = MwVaCreateWidget(MwButtonClass, "skipfwd", window, 0, 0, 0, 0, - MwNflat, 1, - NULL); - modesep = MwVaCreateWidget(MwSeparatorClass, "modesep", window, 0, 0, 0, 0, - MwNorientation, MwVERTICAL, - NULL); - brepeat = MwVaCreateWidget(MwButtonClass, "repeat", window, 0, 0, 0, 0, - MwNflat, 1, - NULL); - bshuffle = MwVaCreateWidget(MwButtonClass, "shuffle", window, 0, 0, 0, 0, - MwNflat, 1, - NULL); - mainsep = MwVaCreateWidget(MwSeparatorClass, "mainsep", window, 0, 0, 0, 0, - MwNorientation, MwHORIZONTAL, - NULL); + MwNflat, 1, + NULL); + bplay = MwVaCreateWidget(MwButtonClass, "play", window, 0, 0, 0, 0, + MwNflat, 1, + NULL); + bpause = MwVaCreateWidget(MwButtonClass, "pause", window, 0, 0, 0, 0, + MwNflat, 1, + NULL); + bstop = MwVaCreateWidget(MwButtonClass, "stop", window, 0, 0, 0, 0, + MwNflat, 1, + NULL); + bskipfwd = MwVaCreateWidget(MwButtonClass, "skipfwd", window, 0, 0, 0, 0, + MwNflat, 1, + NULL); + modesep = MwVaCreateWidget(MwSeparatorClass, "modesep", window, 0, 0, 0, 0, + MwNorientation, MwVERTICAL, + NULL); + brepeat = MwVaCreateWidget(MwButtonClass, "repeat", window, 0, 0, 0, 0, + MwNflat, 1, + NULL); + bshuffle = MwVaCreateWidget(MwButtonClass, "shuffle", window, 0, 0, 0, 0, + MwNflat, 1, + NULL); + mainsep = MwVaCreateWidget(MwSeparatorClass, "mainsep", window, 0, 0, 0, 0, + MwNorientation, MwHORIZONTAL, + NULL); + eltime = MwVaCreateWidget(MwLabelClass, "eltime", window, 0, 0, 0, 0, + MwNalignment, MwALIGNMENT_BEGINNING, + MwNtext, "00:00", + NULL); + seekbar = MwVaCreateWidget(MwScrollBarClass, "seekbar", window, 0, 0, 0, 0, + MwNorientation, MwHORIZONTAL, + MwNareaShown, 15, + NULL); + rmtime = MwVaCreateWidget(MwLabelClass, "rmtime", window, 0, 0, 0, 0, + MwNalignment, MwALIGNMENT_BEGINNING, + MwNtext, "00:00", + NULL); + tree = MwCreateWidget(MwTreeViewClass, "tree", window, 0, 0, 0, 0); + list = MwVaCreateWidget(MwListBoxClass, "list", window, 0, 0, 0, 0, + MwNhasHeading, 1, + MwNleftPadding, 16, + NULL); - pxalbum = MwLoadIcon(window, MwIconError); + pxalbumdata = malloc(128 * 128 * 4); + memset(pxalbumdata, 0, 128 * 128 * 4); + + pxalbum = MwLoadRaw(window, pxalbumdata, 128, 128); pxskipback = MwLoadXPM(window, skipback_xpm); - pxplay = MwLoadXPM(window, play_xpm); - pxpause = MwLoadXPM(window, pause_xpm); - pxstop = MwLoadXPM(window, stop_xpm); - pxskipfwd = MwLoadXPM(window, skipfwd_xpm); + pxplay = MwLoadXPM(window, play_xpm); + pxpause = MwLoadXPM(window, pause_xpm); + pxstop = MwLoadXPM(window, stop_xpm); + pxskipfwd = MwLoadXPM(window, skipfwd_xpm); - pxrepeat = MwLoadXPM(window, repeat_xpm); + free(pxalbumdata); + + pxrepeat = MwLoadXPM(window, repeat_xpm); pxshuffle = MwLoadXPM(window, shuffle_xpm); MwSetVoid(album, MwNpixmap, pxalbum); @@ -173,5 +248,10 @@ int main() { resize(window, NULL, NULL); + ui_init(); + + db_add("test.mp3"); + db_scan(); + MwLoop(window); } diff --git a/mauplay/mauplay.h b/mauplay/mauplay.h index 62fc327..563c205 100644 --- a/mauplay/mauplay.h +++ b/mauplay/mauplay.h @@ -10,6 +10,7 @@ /* External */ /* Standard */ +#include #include #include #include @@ -17,5 +18,27 @@ /* main.c */ extern MwWidget window; +extern MwWidget album, info; +extern MwWidget bskipback, bplay, bpause, bstop, bskipfwd, brepeat, bshuffle; +extern MwWidget eltime, seekbar, rmtime; +extern MwWidget tree, list; +extern MwLLPixmap pxalbum; + +/* db.c */ +int db_exec(const char* s); +int db_init(void); +void db_add(const char* path); +void db_scan(void); + +/* ui.c */ +void ui_list_reset(void); +void ui_tree_reset(void); +void ui_init(void); +void ui_set_play_queue(int v); +void ui_set_all_music(int v); +void ui_set_albums(int v); +void ui_set_artists(int v); +void ui_set_genres(int v); +void ui_set_playlists(int v); #endif diff --git a/mauplay/stb_ds.c b/mauplay/stb_ds.c new file mode 100644 index 0000000..689615c --- /dev/null +++ b/mauplay/stb_ds.c @@ -0,0 +1,2 @@ +#define STB_DS_IMPLEMENTATION +#include diff --git a/mauplay/ui.c b/mauplay/ui.c new file mode 100644 index 0000000..b668710 --- /dev/null +++ b/mauplay/ui.c @@ -0,0 +1,97 @@ +#include "mauplay.h" + +static void* play_queue; +static void* all_music; +static void* albums; +static void* artists; +static void* genres; +static void* playlists; + +void ui_list_reset(void) { + void* p; + + MwListBoxReset(list); + + p = MwListBoxCreatePacket(); + MwListBoxPacketInsert(p, -1); + MwListBoxPacketSet(p, 0, 0, "#"); + MwListBoxPacketSet(p, 0, 1, "Title"); + MwListBoxPacketSet(p, 0, 2, "Artist"); + MwListBoxPacketSet(p, 0, 3, "Length"); + + MwListBoxInsert(list, -1, p); + MwListBoxDestroyPacket(p); + + MwListBoxSetWidth(list, 0, 48); + MwListBoxSetWidth(list, 1, -48 - 128); + MwListBoxSetWidth(list, 2, 64); + MwListBoxSetWidth(list, 3, 64); + + MwListBoxSetAlignment(list, 0, MwALIGNMENT_CENTER); + MwListBoxSetAlignment(list, 2, MwALIGNMENT_END); + MwListBoxSetAlignment(list, 3, MwALIGNMENT_END); +} + +void ui_tree_reset(void) { + void* t; + + MwTreeViewReset(tree); + + play_queue = MwTreeViewAdd(tree, NULL, NULL, "Play Queue (?)"); + + t = MwTreeViewAdd(tree, NULL, NULL, "Library"); + all_music = MwTreeViewAdd(tree, t, NULL, "All Music (?)"); + albums = MwTreeViewAdd(tree, t, NULL, "Albums (?)"); + artists = MwTreeViewAdd(tree, t, NULL, "Artists (?)"); + genres = MwTreeViewAdd(tree, t, NULL, "Genres (?)"); + + playlists = MwTreeViewAdd(tree, NULL, NULL, "Playlists (?)"); +} + +void ui_set_play_queue(int v) { + char buf[64]; + sprintf(buf, "Play Queue (%d)", v); + MwTreeViewSetLabel(tree, play_queue, buf); +} + +void ui_set_all_music(int v) { + char buf[64]; + sprintf(buf, "All Music (%d)", v); + MwTreeViewSetLabel(tree, all_music, buf); +} + +void ui_set_albums(int v) { + char buf[64]; + sprintf(buf, "Albums (%d)", v); + MwTreeViewSetLabel(tree, albums, buf); +} + +void ui_set_artists(int v) { + char buf[64]; + sprintf(buf, "Artists (%d)", v); + MwTreeViewSetLabel(tree, artists, buf); +} + +void ui_set_genres(int v) { + char buf[64]; + sprintf(buf, "Genres (%d)", v); + MwTreeViewSetLabel(tree, genres, buf); +} + +void ui_set_playlists(int v) { + char buf[64]; + sprintf(buf, "Playlists (%d)", v); + MwTreeViewSetLabel(tree, playlists, buf); +} + +void ui_init(void) { + ui_list_reset(); + ui_tree_reset(); + + ui_set_play_queue(0); + ui_set_all_music(0); + ui_set_albums(0); + ui_set_artists(0); + ui_set_genres(0); + ui_set_playlists(0); +}