[Toxine-cvs] CVS: toxine/src commands.c,1.5,1.6 common.h,1.1.1.1,1.2 main.c,1.3,1.4 utils.c,1.1.1.1,
Brought to you by:
f1rmb
From: Daniel Caujolle-B. <f1...@us...> - 2002-06-30 15:38:58
|
Update of /cvsroot/toxine/toxine/src In directory usw-pr-cvs1:/tmp/cvs-serv14762/src Modified Files: commands.c common.h main.c utils.c utils.h xine_commands.c Log Message: Add playlist support (keep 'set mrl <mrl>' compatibility). Index: commands.c =================================================================== RCS file: /cvsroot/toxine/toxine/src/commands.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- commands.c 21 Jun 2002 08:57:25 -0000 1.5 +++ commands.c 30 Jun 2002 15:38:54 -0000 1.6 @@ -119,6 +119,7 @@ static void do_syntax(commands_t *, toxine_t *, void *); static void do_waitfor(commands_t *, toxine_t *, void *); static void do_events(commands_t *, toxine_t *, void *); +static void do_playlist(commands_t *, toxine_t *, void *); static commands_t commands[] = { { "commands", NO_ARGS, do_help, @@ -271,6 +272,17 @@ "select" }, /* End of event aliases */ + { "playlist", REQUIRE_ARGS, do_playlist, + "playlist management", + "playlist show\n" + "playlist select #\n" + "playlist next\n" + "playlist previous\n" + "playlist add <mrl> ...\n" + "playlist from <plugin>\n" + "playlist delete # ...\n" + "playlist delete all" + }, { "version", NO_ARGS, do_version, "Display some version informations", "version" @@ -284,6 +296,25 @@ /* + * Callback called on XINE_EVENT_PLAYBACK_FINISHED event + */ +static void finished_cb(toxine_t *tox) { + + if(tox->ignore_finished) + return; + + tox->playlist.cur++; + + if (tox->playlist.cur < tox->playlist.num) { + toxine_set_current_mrl_from_cur(tox); + _xine_play(NULL, tox, (void *)NO_ARGS); + } + else + tox->playlist.cur--; + +} + +/* * Listener of xine engine events. */ void toxine_event_listener(void *data, xine_event_t *event) { @@ -293,6 +324,28 @@ tox->event.last.type = event->type; pthread_mutex_unlock(&tox->event.mutex); + switch(tox->event.last.type) { + case XINE_EVENT_PLAYBACK_FINISHED: + // next entry in playback; + finished_cb(tox); + tox->ignore_finished = 0; + break; + + case XINE_EVENT_NEED_NEXT_MRL: { + xine_next_mrl_event_t *uevent = (xine_next_mrl_event_t *)event; + + uevent->handled = 1; + uevent->mrl = toxine_get_next_mrl(tox); + } + break; + + case XINE_EVENT_BRANCHED: + toxine_branched(tox); + break; + + } + + #if 0 pinfo("Get xine event:\n"); poutalign(); @@ -341,7 +394,7 @@ pout("XINE_EVENT_INPUT_SELECT"); break; case XINE_EVENT_PLAYBACK_FINISHED: - pout("****XINE_EVENT_PLAYBACK_FINISHED"); + pout("XINE_EVENT_PLAYBACK_FINISHED"); break; case XINE_EVENT_BRANCHED: pout("XINE_EVENT_BRANCHED"); @@ -660,7 +713,7 @@ if(tox->autoinit) _xine_init(NULL, tox, NULL); - if(tox->script.use) { + if(tox->script.in_use) { toxine_handle_script(tox); tox->running = 0; } @@ -1322,6 +1375,168 @@ if(!strncmp(command->command, event_aliases[i].alias, strlen(command->command))) { _xine_send_event(command, tox, (void *) event_aliases[i].event); break; + } + } +} + +static void do_playlist(commands_t *command, toxine_t *tox, void *data) { + int nargs; + + /* + "playlist select #" + "playlist add <mrl> <...>" + "playlist from <plugin>" + "playlist delete #" + "playlist delete all" + + */ + + nargs = toxine_is_args(tox); + + if(nargs == 1) { + if(toxine_is_arg_contain(tox, 1, "show")) { + + if(tox->playlist.num) { + int i; + + pinfo("Playlist (* is current):\n"); + for(i = 0; i < tox->playlist.num; i++) { + poutalign(); + if(tox->playlist.cur == i) { + pout("*%4d: '%s'\n", i, tox->playlist.entries[i]); + } + else { + pout(" %4d: '%s'\n", i, tox->playlist.entries[i]); + } + } + pinfo(".\n"); + } + else + pinfo("Empty playlist.\n"); + } + else if(toxine_is_arg_contain(tox, 1, "next")) { + tox->ignore_finished = 0; + finished_cb(tox); + } + else if(toxine_is_arg_contain(tox, 1, "prev")) { + + tox->ignore_finished = 1; + tox->playlist.cur--; + + if((tox->playlist.cur >= 0) && (tox->playlist.cur < tox->playlist.num)) { + + toxine_set_current_mrl_from_cur(tox); + _xine_play(NULL, tox, (void *)NO_ARGS); + + } + else { + tox->playlist.cur = 0; + tox->ignore_finished = 0; + } + + } + + } + else if(nargs >= 2) { + + if(toxine_is_arg_contain(tox, 1, "select")) { + int entry = atoi(toxine_get_arg(tox, 2)); + int old_cur = tox->playlist.cur; + + if(entry < tox->playlist.num) { + tox->playlist.cur = entry; + toxine_set_current_mrl_from_cur(tox); + } + + /* + * If xine engine is in PLAY status, and new selected entry is != than old one, + * start playback with new selected stream + */ + if(tox->xine && (old_cur != tox->playlist.cur)) { + int status = xine_get_status(tox->xine); + + if(status == XINE_PLAY) + _xine_play(NULL, tox, (void *)NO_ARGS); + + } + + } + else if(toxine_is_arg_contain(tox, 1, "add")) { + char *mrl; + int i = 2; + + while((mrl = (char *) (toxine_get_arg(tox, i))) != NULL) { + + tox->playlist.entries[tox->playlist.num++] = strdup(mrl); + + if(tox->playlist.cur == -1) { + tox->playlist.cur = 0; + toxine_set_current_mrl_from_cur(tox); + } + i++; + } + } + else if(toxine_is_arg_contain(tox, 1, "from")) { + char **ap; + int i, mrls; + + CHECK_XINE(tox); + + pinfo("Grab mrls from '%s' input plugin.\n", toxine_get_arg(tox, 2)); + ap = xine_get_autoplay_mrls(tox->xine, (char *) (toxine_get_arg(tox, 2)), &mrls); + if(ap) { + + for(i = 0; i < mrls; i++) + tox->playlist.entries[tox->playlist.num++] = strdup(ap[i]); + } + + if((!ap) || (!mrls)) + pinfo("Plugin '%s' returned nothing.\n", toxine_get_arg(tox, 2)); + + } + else if(toxine_is_arg_contain(tox, 1, "delete")) { + + if(toxine_is_arg_contain(tox, 2, "all")) { + if(tox->playlist.num) { + + for(; tox->playlist.num >= 0; tox->playlist.num--) + _FREE(tox->playlist.entries[tox->playlist.num]); + + tox->playlist.num = 0; + tox->playlist.cur = -1; + } + } + else { + char *argument; + int i = 2; + + while((argument = (char *) (toxine_get_arg(tox, i)))) { + int entry = atoi(argument); + + if(tox->playlist.num && (entry < tox->playlist.num)) { + int j; + + if(tox->playlist.cur >= entry) { + tox->playlist.cur = -1; + } + + _FREE(tox->playlist.entries[entry]); + + for(j = entry; j < tox->playlist.num; j++) + tox->playlist.entries[j] = tox->playlist.entries[j + 1]; + + tox->playlist.entries[j] = NULL; + tox->playlist.num--; + + if(tox->playlist.num && (tox->playlist.cur == -1)) { + tox->playlist.cur = 0; + toxine_set_current_mrl_from_cur(tox); + } + } + + i++; + } + } } } } Index: common.h =================================================================== RCS file: /cvsroot/toxine/toxine/src/common.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- common.h 13 May 2002 20:46:35 -0000 1.1.1.1 +++ common.h 30 Jun 2002 15:38:54 -0000 1.2 @@ -45,6 +45,8 @@ #define ERROR_PREFIX " (!) " #define EMPTY_PREFIX " " #define PROMPT "toxine{%s}> " +#define MAX_PLAYLIST 2048 /* Max playlist length */ + #define poutalign() { \ fprintf(stdout, "%s", EMPTY_PREFIX); \ @@ -80,6 +82,7 @@ } \ } + typedef struct { int xine_state; char *state; @@ -95,6 +98,8 @@ config_values_t *config; xine_t *xine; + int ignore_finished; + int msg_fd; struct { @@ -140,12 +145,19 @@ } command; char *current_mrl; + + struct { + char *entries[MAX_PLAYLIST]; + int num; /* number of entries in playlist */ + int cur; /* current entry in playlist */ + char *current; /* pointer to current playlist entry */ + } playlist; char prompt[32]; int interactive; struct { - int use; + int in_use; char *filename; FILE *fd; char buf[256]; Index: main.c =================================================================== RCS file: /cvsroot/toxine/toxine/src/main.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- main.c 24 Jun 2002 21:35:05 -0000 1.3 +++ main.c 30 Jun 2002 15:38:54 -0000 1.4 @@ -105,6 +105,11 @@ if(tox->msg_fd >= 0) close(tox->msg_fd); + if(tox->playlist.num) { + for(; tox->playlist.num >= 0; tox->playlist.num--) + _FREE(tox->playlist.entries[tox->playlist.num]); + } + _FREE(tox->configfile); _FREE(tox->video.name); _FREE(tox->audio.name); @@ -145,6 +150,7 @@ tox->command.command = NULL; tox->command.execute = 0; tox->msg_fd = -1; + tox->playlist.cur = -1; /* * parse command line @@ -157,7 +163,7 @@ if(optarg != NULL) { if(tox->script.filename == NULL) { tox->script.filename = strdup(optarg); - tox->script.use = 1; + tox->script.in_use = 1; } else fprintf(stderr, "script filename already set: '%s'\n", tox->script.filename); @@ -222,7 +228,7 @@ } if(tox->msg_fd >= 0) { - if((!tox->script.use) && (!tox->command.execute)) { + if((!tox->script.in_use) && (!tox->command.execute)) { fprintf(stderr, "You can't use message redirection in prompt mode.\n"); toxine_free(tox); exit(1); Index: utils.c =================================================================== RCS file: /cvsroot/toxine/toxine/src/utils.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- utils.c 13 May 2002 20:46:36 -0000 1.1.1.1 +++ utils.c 30 Jun 2002 15:38:54 -0000 1.2 @@ -163,13 +163,73 @@ } /* + * Look for first entry in playlist matching with 'mrl' + */ +static int toxine_lookup_in_playlist(toxine_t *tox, const char *mrl) { + int i; + + if(tox->playlist.num) { + for(i = 0; i < tox->playlist.num; i++) { + if(!strcmp(mrl, tox->playlist.entries[i])) + return i; + } + } + + return -1; +} + +/* + * + */ +void toxine_set_current_mrl_from_cur(toxine_t *tox) { + if(tox) { + if((tox->playlist.cur >= 0) && (tox->playlist.entries[tox->playlist.cur] != NULL)) + tox->current_mrl = tox->playlist.entries[tox->playlist.cur]; + else + tox->current_mrl = NULL; + } +} + +/* * Set current mrl from mrl */ void toxine_set_current_mrl(toxine_t *tox, const char *mrl) { + if(tox && mrl) { - if(tox->current_mrl) - free(tox->current_mrl); - tox->current_mrl = strdup(mrl); + if((tox->playlist.cur = toxine_lookup_in_playlist(tox, mrl)) == -1) { + tox->playlist.cur = tox->playlist.num++; + tox->playlist.entries[tox->playlist.cur] = strdup(mrl); + } + + toxine_set_current_mrl_from_cur(tox); + } +} + +/* + * Return next mrl in playlist. + */ +char *toxine_get_next_mrl(toxine_t *tox) { + if(tox) { + + if(tox->playlist.cur >= (tox->playlist.num - 1)) + return NULL; + + return tox->playlist.entries[tox->playlist.cur + 1]; + } + + return NULL; +} + +/* + * Branching was successfully accomplished, update playlist. + */ +void toxine_branched(toxine_t *tox) { + + if(tox) { + if(tox->playlist.cur < (tox->playlist.num - 1)) { + tox->playlist.cur++; + toxine_set_current_mrl_from_cur(tox); + } } } Index: utils.h =================================================================== RCS file: /cvsroot/toxine/toxine/src/utils.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- utils.h 13 May 2002 20:46:35 -0000 1.1.1.1 +++ utils.h 30 Jun 2002 15:38:54 -0000 1.2 @@ -27,9 +27,12 @@ int toxine_system(int dont_run_as_root, char *command); int toxine_get_bool_value(const char *val); void toxine_set_command_line(toxine_t *tox, char *line); +void toxine_set_current_mrl_from_cur(toxine_t *tox); void toxine_set_current_mrl(toxine_t *tox, const char *mrl); int toxine_is_args(toxine_t *tox); const char *toxine_get_arg(toxine_t *tox, int num); int toxine_is_arg_contain(toxine_t *tox, int pos, const char *arg); +char *toxine_get_next_mrl(toxine_t *tox); +void toxine_branched(toxine_t *tox); #endif Index: xine_commands.c =================================================================== RCS file: /cvsroot/toxine/toxine/src/xine_commands.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- xine_commands.c 3 Jun 2002 14:53:18 -0000 1.4 +++ xine_commands.c 30 Jun 2002 15:38:54 -0000 1.5 @@ -266,6 +266,9 @@ if(data) ignore_args = (int) data; + if(tox->ignore_finished) + tox->ignore_finished = 0; + nargs = toxine_is_args(tox); if((!nargs) || (ignore_args == NO_ARGS)) { @@ -362,6 +365,7 @@ void _xine_stop(commands_t *command, toxine_t *tox, void *data) { CHECK_XINE(tox); pinfo("xine_stop()\n"); + tox->ignore_finished = 1; xine_stop(tox->xine); pinfo(".\n"); } |