Permalink
Browse files

BarReadline rewrite

Doesn't use c streams any more, allows multiplexing of fifo/stdin in all
situations.
  • Loading branch information...
PromyLOPh committed Jan 6, 2011
1 parent 58398e4 commit ce8503f859345990a14be90bf89dadf7f73d7613
Showing with 197 additions and 143 deletions.
  1. +1 −1 COPYING
  2. +30 −53 src/main.c
  3. +3 −7 src/main.h
  4. +31 −24 src/ui.c
  5. +8 −6 src/ui.h
  6. +16 −14 src/ui_act.c
  7. +2 −2 src/ui_act.h
  8. +79 −31 src/ui_readline.c
  9. +27 −5 src/ui_readline.h
View
@@ -1,4 +1,4 @@
-Copyright (c) 2008-2010
+Copyright (c) 2008-2011
Lars-Dominik Braun <lars@6xq.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
View
@@ -53,7 +53,7 @@ THE SOFTWARE.
#include "ui_act.h"
#include "ui_readline.h"
-typedef void (*BarKeyShortcutFunc_t) (BarApp_t *app, FILE *curFd);
+typedef void (*BarKeyShortcutFunc_t) (BarApp_t *app);
/* copy proxy settings to waitress handle
*/
@@ -94,17 +94,19 @@ static bool BarMainLoginUser (BarApp_t *app) {
/* ask for username/password if none were provided in settings
*/
-static void BarMainGetLoginCredentials (BarSettings_t *settings) {
+static void BarMainGetLoginCredentials (BarSettings_t *settings,
+ BarReadlineFds_t *input) {
if (settings->username == NULL) {
char nameBuf[100];
BarUiMsg (MSG_QUESTION, "Username: ");
- BarReadlineStr (nameBuf, sizeof (nameBuf), 0, stdin);
+ BarReadlineStr (nameBuf, sizeof (nameBuf), input, BAR_RL_DEFAULT);
settings->username = strdup (nameBuf);
}
if (settings->password == NULL) {
char passBuf[100];
BarUiMsg (MSG_QUESTION, "Password: ");
- BarReadlineStr (passBuf, sizeof (passBuf), 1, stdin);
+ BarReadlineStr (passBuf, sizeof (passBuf), input, BAR_RL_NOECHO);
+ write (STDIN_FILENO, "\n", 1);
settings->password = strdup (passBuf);
}
}
@@ -136,8 +138,8 @@ static void BarMainGetInitialStation (BarApp_t *app) {
}
/* no autostart? ask the user */
if (app->curStation == NULL) {
- app->curStation = BarUiSelectStation (&(app->ph), "Select station: ",
- app->settings.sortOrder, stdin);
+ app->curStation = BarUiSelectStation (&app->ph, "Select station: ",
+ app->settings.sortOrder, &app->input);
}
if (app->curStation != NULL) {
BarUiPrintStation (app->curStation);
@@ -147,35 +149,12 @@ static void BarMainGetInitialStation (BarApp_t *app) {
/* wait for user input
*/
static void BarMainHandleUserInput (BarApp_t *app) {
- struct timeval selectTimeout;
- fd_set readSetCopy;
- char buf = '\0';
-
- /* select modifies its arguments => copy the set */
- memcpy (&readSetCopy, &app->readSet, sizeof (app->readSet));
- selectTimeout.tv_sec = 1;
- selectTimeout.tv_usec = 0;
-
- /* in the meantime: wait for user actions */
- if (select (app->maxFd, &readSetCopy, NULL, NULL, &selectTimeout) > 0) {
- FILE *curFd = NULL;
-
- if (FD_ISSET(app->selectFds[0], &readSetCopy)) {
- curFd = stdin;
- } else if (app->selectFds[1] != -1 && FD_ISSET(app->selectFds[1],
- &readSetCopy)) {
- curFd = app->ctlFd;
- }
- buf = fgetc (curFd);
- if (buf == EOF) {
- /* select() is going wild if fdset contains EOFed fd's */
- FD_CLR (fileno (curFd), &app->readSet);
- }
-
- size_t i;
- for (i = 0; i < BAR_KS_COUNT; i++) {
+ char buf[2];
+ if (BarReadline (buf, sizeof (buf), NULL, &app->input,
+ BAR_RL_FULLRETURN | BAR_RL_NOECHO, 1) > 0) {
+ for (size_t i = 0; i < BAR_KS_COUNT; i++) {
if (app->settings.keys[i] != BAR_KS_DISABLED &&
- app->settings.keys[i] == buf) {
+ app->settings.keys[i] == buf[0]) {
static const BarKeyShortcutFunc_t idToF[] = {BarUiActHelp,
BarUiActLoveSong, BarUiActBanSong,
BarUiActAddMusic, BarUiActCreateStation,
@@ -188,11 +167,11 @@ static void BarMainHandleUserInput (BarApp_t *app) {
BarUiActPrintUpcoming, BarUiActSelectQuickMix,
BarUiActDebug, BarUiActBookmark, BarUiActVolDown,
BarUiActVolUp};
- idToF[i] (app, curFd);
+ idToF[i] (app);
break;
}
- }
- }
+ } /* end for */
+ } /* end if */
}
/* append current song to history list and move to the next song
@@ -345,7 +324,7 @@ static void BarMainPrintTime (BarApp_t *app) {
static void BarMainLoop (BarApp_t *app) {
pthread_t playerThread;
- BarMainGetLoginCredentials (&app->settings);
+ BarMainGetLoginCredentials (&app->settings, &app->input);
BarMainLoadProxy (&app->settings, &app->waith);
@@ -435,28 +414,26 @@ int main (int argc, char **argv) {
}
/* init fds */
- FD_ZERO(&app.readSet);
- app.selectFds[0] = fileno (stdin);
- FD_SET(app.selectFds[0], &app.readSet);
+ FD_ZERO(&app.input.set);
+ app.input.fds[0] = STDIN_FILENO;
+ FD_SET(app.input.fds[0], &app.input.set);
BarGetXdgConfigDir (PACKAGE "/ctl", ctlPath, sizeof (ctlPath));
- /* FIXME: why is r_+_ required? */
- app.ctlFd = fopen (ctlPath, "r+");
- if (app.ctlFd != NULL) {
- app.selectFds[1] = fileno (app.ctlFd);
- FD_SET(app.selectFds[1], &app.readSet);
+ /* open fifo read/write so it won't EOF if nobody writes to it */
+ assert (sizeof (app.input.fds) / sizeof (*app.input.fds) >= 2);
+ app.input.fds[1] = open (ctlPath, O_RDWR);
+ if (app.input.fds[1] != -1) {
+ FD_SET(app.input.fds[1], &app.input.set);
BarUiMsg (MSG_INFO, "Control fifo at %s opened\n", ctlPath);
- } else {
- app.selectFds[1] = -1;
}
- app.maxFd = app.selectFds[0] > app.selectFds[1] ? app.selectFds[0] :
- app.selectFds[1];
- ++app.maxFd;
+ app.input.maxfd = app.input.fds[0] > app.input.fds[1] ? app.input.fds[0] :
+ app.input.fds[1];
+ ++app.input.maxfd;
BarMainLoop (&app);
- if (app.ctlFd != NULL) {
- fclose (app.ctlFd);
+ if (app.input.fds[1] != -1) {
+ close (app.input.fds[1]);
}
PianoDestroy (&app.ph);
View
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2008-2010
+Copyright (c) 2008-2011
Lars-Dominik Braun <lars@6xq.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,10 +27,9 @@ THE SOFTWARE.
#include <piano.h>
#include <waitress.h>
-#include <sys/select.h>
-
#include "player.h"
#include "settings.h"
+#include "ui_readline.h"
typedef struct {
PianoHandle_t ph;
@@ -42,10 +41,7 @@ typedef struct {
PianoSong_t *songHistory;
PianoStation_t *curStation;
char doQuit;
- fd_set readSet;
- int maxFd;
- int selectFds[2];
- FILE *ctlFd;
+ BarReadlineFds_t input;
} BarApp_t;
#endif /* _MAIN_H */
View
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2008-2010
+Copyright (c) 2008-2011
Lars-Dominik Braun <lars@6xq.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -297,13 +297,16 @@ PianoStation_t **BarSortedStations (PianoStation_t *unsortedStations,
/* let user pick one station
* @param piano handle
+ * @param prompt string
+ * @param station list sort order
+ * @param input fds
* @return pointer to selected station or NULL
*/
PianoStation_t *BarUiSelectStation (PianoHandle_t *ph, const char *prompt,
- BarStationSorting_t order, FILE *curFd) {
+ BarStationSorting_t order, BarReadlineFds_t *input) {
PianoStation_t **sortedStations = NULL, *retStation = NULL;
size_t stationCount, i;
- int input;
+ int selected;
if (ph->stations == NULL) {
BarUiMsg (MSG_ERR, "No station available.\n");
@@ -323,12 +326,12 @@ PianoStation_t *BarUiSelectStation (PianoHandle_t *ph, const char *prompt,
BarUiMsg (MSG_QUESTION, prompt);
/* FIXME: using a _signed_ int is ugly */
- if (BarReadlineInt (&input, curFd) == 0) {
+ if (BarReadlineInt (&selected, input) == 0) {
free (sortedStations);
return NULL;
}
- if (input < stationCount) {
- retStation = sortedStations[input];
+ if (selected < stationCount) {
+ retStation = sortedStations[selected];
}
free (sortedStations);
return retStation;
@@ -337,18 +340,18 @@ PianoStation_t *BarUiSelectStation (PianoHandle_t *ph, const char *prompt,
/* let user pick one song
* @param pianobar settings
* @param song list
- * @param current fd
+ * @param input fds
* @return pointer to selected item in song list or NULL
*/
PianoSong_t *BarUiSelectSong (const BarSettings_t *settings,
- PianoSong_t *startSong, FILE *curFd) {
+ PianoSong_t *startSong, BarReadlineFds_t *input) {
PianoSong_t *tmpSong = NULL;
int i = 0;
i = BarUiListSongs (settings, startSong);
BarUiMsg (MSG_QUESTION, "Select song: ");
- if (BarReadlineInt (&i, curFd) == 0) {
+ if (BarReadlineInt (&i, input) == 0) {
return NULL;
}
@@ -363,9 +366,11 @@ PianoSong_t *BarUiSelectSong (const BarSettings_t *settings,
/* let user pick one artist
* @param artists (linked list)
+ * @param input fds
* @return pointer to selected artist or NULL on abort
*/
-PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist, FILE *curFd) {
+PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist,
+ BarReadlineFds_t *input) {
PianoArtist_t *tmpArtist = NULL;
int i = 0;
@@ -377,7 +382,7 @@ PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist, FILE *curFd) {
tmpArtist = tmpArtist->next;
}
BarUiMsg (MSG_QUESTION, "Select artist: ");
- if (BarReadlineInt (&i, curFd) == 0) {
+ if (BarReadlineInt (&i, input) == 0) {
return NULL;
}
tmpArtist = startArtist;
@@ -389,20 +394,20 @@ PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist, FILE *curFd) {
}
/* search music: query, search request, return music id
- * @param piano handle
- * @param read data from fd
+ * @param app handle
* @param allow seed suggestions if != NULL
* @return musicId or NULL on abort/error
*/
-char *BarUiSelectMusicId (BarApp_t *app, FILE *curFd, char *similarToId) {
+char *BarUiSelectMusicId (BarApp_t *app, char *similarToId) {
char *musicId = NULL;
char lineBuf[100], selectBuf[2];
PianoSearchResult_t searchResult;
PianoArtist_t *tmpArtist;
PianoSong_t *tmpSong;
BarUiMsg (MSG_QUESTION, "Search for artist/title: ");
- if (BarReadlineStr (lineBuf, sizeof (lineBuf), 0, curFd) > 0) {
+ if (BarReadlineStr (lineBuf, sizeof (lineBuf), &app->input,
+ BAR_RL_DEFAULT) > 0) {
if (strcmp ("?", lineBuf) == 0 && similarToId != NULL) {
PianoReturn_t pRet;
WaitressReturn_t wRet;
@@ -436,29 +441,31 @@ char *BarUiSelectMusicId (BarApp_t *app, FILE *curFd, char *similarToId) {
searchResult.artists != NULL) {
/* songs and artists found */
BarUiMsg (MSG_QUESTION, "Is this an [a]rtist or [t]rack name? ");
- BarReadline (selectBuf, sizeof (selectBuf), "at", 1, 0, curFd);
+ BarReadline (selectBuf, sizeof (selectBuf), "at", &app->input,
+ BAR_RL_FULLRETURN, -1);
if (*selectBuf == 'a') {
- tmpArtist = BarUiSelectArtist (searchResult.artists, curFd);
+ tmpArtist = BarUiSelectArtist (searchResult.artists,
+ &app->input);
if (tmpArtist != NULL) {
musicId = strdup (tmpArtist->musicId);
}
} else if (*selectBuf == 't') {
tmpSong = BarUiSelectSong (&app->settings, searchResult.songs,
- curFd);
+ &app->input);
if (tmpSong != NULL) {
musicId = strdup (tmpSong->musicId);
}
}
} else if (searchResult.songs != NULL) {
/* songs found */
tmpSong = BarUiSelectSong (&app->settings, searchResult.songs,
- curFd);
+ &app->input);
if (tmpSong != NULL) {
musicId = strdup (tmpSong->musicId);
}
} else if (searchResult.artists != NULL) {
/* artists found */
- tmpArtist = BarUiSelectArtist (searchResult.artists, curFd);
+ tmpArtist = BarUiSelectArtist (searchResult.artists, &app->input);
if (tmpArtist != NULL) {
musicId = strdup (tmpArtist->musicId);
}
@@ -472,9 +479,9 @@ char *BarUiSelectMusicId (BarApp_t *app, FILE *curFd, char *similarToId) {
}
/* browse genre stations and create shared station
- * @param piano handle
+ * @param app handle
*/
-void BarStationFromGenre (BarApp_t *app, FILE *curFd) {
+void BarStationFromGenre (BarApp_t *app) {
PianoReturn_t pRet;
WaitressReturn_t wRet;
PianoGenreCategory_t *curCat;
@@ -504,7 +511,7 @@ void BarStationFromGenre (BarApp_t *app, FILE *curFd) {
}
/* select category or exit */
BarUiMsg (MSG_QUESTION, "Select category: ");
- if (BarReadlineInt (&i, curFd) == 0) {
+ if (BarReadlineInt (&i, &app->input) == 0) {
return;
}
curCat = app->ph.genreStations;
@@ -522,7 +529,7 @@ void BarStationFromGenre (BarApp_t *app, FILE *curFd) {
curGenre = curGenre->next;
}
BarUiMsg (MSG_QUESTION, "Select genre: ");
- if (BarReadlineInt (&i, curFd) == 0) {
+ if (BarReadlineInt (&i, &app->input) == 0) {
return;
}
curGenre = curCat->genres;
View
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2008-2010
+Copyright (c) 2008-2011
Lars-Dominik Braun <lars@6xq.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,18 +30,20 @@ THE SOFTWARE.
#include "settings.h"
#include "player.h"
#include "main.h"
+#include "ui_readline.h"
typedef enum {MSG_NONE, MSG_INFO, MSG_PLAYING, MSG_TIME, MSG_ERR,
MSG_QUESTION, MSG_LIST} uiMsg_t;
void BarUiMsg (uiMsg_t type, const char *format, ...);
PianoReturn_t BarUiPrintPianoStatus (PianoReturn_t ret);
PianoStation_t *BarUiSelectStation (PianoHandle_t *, const char *,
- BarStationSorting_t, FILE *);
-PianoSong_t *BarUiSelectSong (const BarSettings_t *, PianoSong_t *, FILE *);
-PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist, FILE *curFd);
-char *BarUiSelectMusicId (BarApp_t *, FILE *, char *);
-void BarStationFromGenre (BarApp_t *, FILE *);
+ BarStationSorting_t, BarReadlineFds_t *);
+PianoSong_t *BarUiSelectSong (const BarSettings_t *, PianoSong_t *,
+ BarReadlineFds_t *);
+PianoArtist_t *BarUiSelectArtist (PianoArtist_t *, BarReadlineFds_t *);
+char *BarUiSelectMusicId (BarApp_t *, char *);
+void BarStationFromGenre (BarApp_t *);
void BarUiPrintStation (PianoStation_t *);
void BarUiPrintSong (const BarSettings_t *, const PianoSong_t *,
const PianoStation_t *);
Oops, something went wrong.

0 comments on commit ce8503f

Please sign in to comment.