From: Rocky B. <ro...@us...> - 2003-04-11 14:54:31
|
Update of /cvsroot/xine/xine-vcdnav/input In directory sc8-pr-cvs1:/tmp/cvs-serv9626 Modified Files: Tag: cdio-branch xineplug_inp_cd.c Log Message: List of tracks via get_dir now works. Index: xineplug_inp_cd.c =================================================================== RCS file: /cvsroot/xine/xine-vcdnav/input/Attic/xineplug_inp_cd.c,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- xineplug_inp_cd.c 11 Apr 2003 06:09:42 -0000 1.1.2.4 +++ xineplug_inp_cd.c 11 Apr 2003 14:54:24 -0000 1.1.2.5 @@ -23,7 +23,7 @@ * Rewritten to use *LIBRARIES* * libcdio - for disc reading and CD control * libcddb - for CDDB processing - * R. Bernstein (ro...@pa...) + * and completed by R. Bernstein (ro...@pa...) * * If you find yourself adding OS-specific code here, you are probably doing * something wrong. @@ -139,32 +139,31 @@ #endif track_t cur_track; /* The track we are currently playing */ - track_t num_tracks; /* The number of tracks on this CD */ - char *mrl; /* The MRL for the current play item */ - lsn_t first_frame; /* LSN of first frame of this track */ - lsn_t current_frame;/* LSN of current frame to read */ - lsn_t last_frame; /* LSN of last frame of this track */ - CdIo * cdio; /* libcdio uses this to read */ + track_t num_tracks; /* The number of tracks on this CD */ + track_t first_track; /* The number of first track of CD. + This is usually 1. */ + char *mrl; /* The MRL for the current play item */ + lsn_t first_frame; /* LSN of first frame of this track */ + lsn_t current_frame;/* LSN of current frame to read */ + lsn_t last_frame; /* LSN of last frame of this track */ + CdIo * cdio; /* libcdio uses this to read */ } cdda_input_plugin_t; typedef struct { + /* The below stuff most plugins will probably use. */ input_class_t input_class; - xine_t *xine; config_values_t *config; + cdda_input_plugin_t *ip; - char *cdda_device; - - cdda_input_plugin_t *ip; - - int show_hidden_files; - char *origin_path; - - int mrls_allocated_entries; xine_mrl_t **mrls; - + int num_mrls; /* count of above */ + + char *cdda_device; /* Device name to use when + none specified in MRL + */ char *autoplaylist[CDIO_CD_MAX_TRACKS]; } cdda_input_class_t; @@ -177,9 +176,9 @@ static void fn_name(void *data, xine_cfg_entry_t *cfg) \ { \ cdda_input_class_t *class = (cdda_input_class_t *) data; \ - dbg_print(INPUT_DBG_CALL, "Called setting %d\n", cfg->num_value); \ + dbg_print(INPUT_DBG_CALL, "called setting %d\n", cfg->num_value); \ \ - if(class->ip) { \ + if (class->ip) { \ cdda_input_plugin_t *this = class->ip; \ this->var = cfg->field; \ } \ @@ -189,7 +188,8 @@ /* * Config callbacks */ -static void cdda_device_cb(void *data, xine_cfg_entry_t *cfg) { +static void +cdda_device_cb(void *data, xine_cfg_entry_t *cfg) { cdda_input_class_t *class = (cdda_input_class_t *) data; class->cdda_device = cfg->str_value; @@ -280,7 +280,8 @@ /* * Free allocated memory for CDDB informations */ -static void _cdda_free_cddb_info(cdda_input_plugin_t *this) { +static void +_cdda_free_cddb_info(cdda_input_plugin_t *this) { if(this->cddb.cdiscid) free(this->cddb.cdiscid); @@ -297,110 +298,97 @@ cddb_disc_destroy(this->cddb.disc); } -/* - * ********** END OF CDDB *************** - */ #endif /*CDDB*/ -static uint32_t cdda_plugin_get_capabilities (input_plugin_t *this_gen) { - - return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK; -} - - -static off_t cdda_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { - - /* only allow reading in block-sized chunks */ - - return 0; -} - -static buf_element_t * -cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, - off_t nlen) { - - cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; - buf_element_t *buf; - unsigned char frame_data[CDIO_CD_FRAMESIZE_RAW]; - - dbg_print((INPUT_DBG_CALL), "called\n"); - - if (nlen != CDIO_CD_FRAMESIZE_RAW) - return NULL; - - cdda_handle_events(this); - - if (this->current_frame >= this->last_frame) - return NULL; +/* + * **************** MRL-releated ********************* + */ - if (cdio_read_audio_sector(this->cdio, frame_data, this->current_frame++)) { - return NULL; +/*! Add another MRL to the MRL list inside "this" to be displayed. + mrl is the string name to add; size is the size of the entry in bytes. + The number of mrls in "this" is incremented. +*/ +static void +cdda_add_mrl_slot(cdda_input_class_t *this, const char *mrl, + off_t size, track_t i) +{ + dbg_print(INPUT_DBG_MRL, "called to add slot %d: %s, size %u\n", + i, mrl, (unsigned int) size); + + this->mrls[i] = malloc(sizeof(xine_mrl_t)); + if (NULL==this->mrls[i]) { + LOG_ERR("Can't malloc %d bytes for MRL slot %d (%s)", + sizeof(xine_mrl_t), i, mrl); + return; + } + this->mrls[i]->link = NULL; + this->mrls[i]->origin = NULL; + this->mrls[i]->type = mrl_cda; + this->mrls[i]->size = size * CDIO_CD_FRAMESIZE_RAW; + + this->mrls[i]->mrl = (char *) malloc(strlen(mrl) + 1); + if (NULL==this->mrls[i]->mrl) { + LOG_ERR("Can't malloc %d bytes for MRL name %s", sizeof(xine_mrl_t), mrl); + } else { + sprintf(this->mrls[i]->mrl, "%s", mrl); } - - buf = fifo->buffer_pool_alloc(fifo); - buf->content = buf->mem; - buf->type = BUF_DEMUX_BLOCK; - buf->size = CDIO_CD_FRAMESIZE_RAW; - memcpy(buf->mem, frame_data, CDIO_CD_FRAMESIZE_RAW); - - return buf; -} - -static off_t -cdda_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { - cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; - int seek_to_frame; - - dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "Called: %ld %d\n", - (long int) offset, origin); - - /* compute the proposed frame and check if it is within bounds */ - if (origin == SEEK_SET) - seek_to_frame = offset / CDIO_CD_FRAMESIZE_RAW + this->first_frame; - else if (origin == SEEK_CUR) - seek_to_frame = offset / CDIO_CD_FRAMESIZE_RAW + this->current_frame; - else - seek_to_frame = offset / CDIO_CD_FRAMESIZE_RAW + this->last_frame; - - if ((seek_to_frame >= this->first_frame) && - (seek_to_frame <= this->last_frame)) - this->current_frame = seek_to_frame; - - return (this->current_frame - this->first_frame) * CDIO_CD_FRAMESIZE_RAW; -} - -static off_t cdda_plugin_get_current_pos (input_plugin_t *this_gen){ - cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; - - return (this->current_frame - this->first_frame) * CDIO_CD_FRAMESIZE_RAW; } +static bool +cdda_build_mrl_list(cdda_input_class_t *class, /*out*/ char *cdda_device) +{ -/* The get_length routine is called a bit. Make reasonably fast by - caching the last value which doesn't change all that much. - */ - -static off_t old_get_length = 0; -static track_t old_cur_track = CDIO_INVALID_TRACK; + char *mrl; + CdIo *cdio; + bool destroy_cdio = false; + track_t first_track, i; + unsigned int size; + + if (class->ip && class->ip->cdio) { + cdio = class->ip->cdio; + } else { + cdio = cdio_open(class->cdda_device, DRIVER_UNKNOWN); + if (NULL == cdio) { + LOG_MSG("%s", _("cdio open failed")); + return false; + } + destroy_cdio = true; + } + + xine_free_mrls(&(class->num_mrls), class->mrls); -static off_t cdda_plugin_get_length (input_plugin_t *this_gen) { - cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; + class->num_mrls = cdio_get_num_tracks(cdio); + class->mrls = calloc(class->num_mrls, sizeof(xine_mrl_t *)); - if (this->cur_track == old_cur_track) return old_get_length; + if (NULL == class->mrls) { + LOG_ERR("Can't calloc %d MRL entries", class->num_mrls); + class->num_mrls = 0; + return false; + } - old_cur_track = this->cur_track; - old_get_length = (this->last_frame - this->first_frame + 1) * - CDIO_CD_FRAMESIZE_RAW; - return old_get_length; -} + size = MRL_PREFIX_LEN+strlen(cdda_device)+6; + mrl = (char *) malloc(size); + if (NULL==mrl) { + LOG_ERR("Can't malloc %d bytes for MRL", size); + return false; + } -static uint32_t cdda_plugin_get_blocksize (input_plugin_t *this_gen) { + /* Record MRL's for tracks */ + first_track = cdio_get_first_track_num(cdio); + for ( i= 0; i <= class->num_mrls; i++) { + memset(mrl, 0, sizeof (mrl)); + sprintf(mrl, "%s/%s:%u", MRL_PREFIX, cdda_device, first_track+i); + cdda_add_mrl_slot(class, mrl, + cdio_get_track_sec_count(cdio, first_track+i), i); + } - return CDIO_CD_FRAMESIZE_RAW; + free(mrl); + if (destroy_cdio) cdio_destroy(cdio); + + return true; } - /*! parses a MRL which has the format cdda:/[cd_path][:number]? @@ -458,31 +446,41 @@ } if ('/' == p[0]) p++; + + /* try to match device (part after cdda: and before next colon) + and track number (integer after colon). + */ count = sscanf (p, "%[^:]:%u", device_str, &num); switch (count) { case 2: + /* Got both device and track. device was set above. */ *track_num = num; return true; case 1: { + /* Matched device, but nothing beyond that */ + int len_p = strlen(p); int len_d = strlen(device_str); - /* Matched device, but nothing beyond that */ + + /* If there was a colon but more stuff after that, then fail. + A single colon at the end is okay though. + */ if ((len_p==len_d+1) && (':' != p[len_d])) return false; if (len_p != len_d && len_p != len_d+1) return false; - /* See if we have old-style MRL with no type specifier. - If so, we assume "track". */ + /* See if we have old-style MRL, e.g. cdda:n */ count = sscanf (device_str, "%u", &num); if (1==count) { *track_num = num; strcpy(device_str, default_device); return true; } else if (0==count) { + /* Have device, so just take default track 1. */ *track_num = 1; return true; } else @@ -513,12 +511,245 @@ return false; } -static char* cdda_plugin_get_mrl (input_plugin_t *this_gen) { +static char* +cdda_plugin_get_mrl (input_plugin_t *this_gen) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; return this->mrl; } +/*! + From xine plugin spec: + + generate autoplay list + return value: list of MRLs + +-- The list of MRLs returned goes into the playlist. + This is called when the SHORT_PLUGIN_NAME button is pressed. +*/ + +static char ** +cdda_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { + + cdda_input_class_t *this = (cdda_input_class_t *) this_gen; + char track_mrl[20]; + int i; + track_t first_track; + CdIo *cdio; + + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "called\n"); + + /* free old playlist */ + for( i = 0; this->autoplaylist[i]; i++ ) { + free( this->autoplaylist[i] ); + this->autoplaylist[i] = NULL; + } + + cdio = cdio_open(this->cdda_device, DRIVER_UNKNOWN); + if (NULL == cdio) { + LOG_MSG("%s", _("cdio open failed")); + return NULL; + } + first_track = cdio_get_first_track_num(cdio); + *num_files = cdio_get_num_tracks(cdio); + for( i = 0; i <= *num_files; i++ ) { + sprintf(track_mrl, "%s/%s:%u", MRL_PREFIX, this->cdda_device, + first_track+i); + dbg_print((INPUT_DBG_MRL), "track_mrl: %s\n", track_mrl); + this->autoplaylist[i] = strdup(track_mrl); + } + cdio_destroy(cdio); + + return this->autoplaylist; +} + +/* + * **************** LOGGING ********************* + */ + +/* Pointer to cdio default log handler. Set by init_input_plugin + routine. Perhaps can remove. */ +static cdio_log_handler_t gl_default_cdio_log_handler = NULL; + +/*! This routine is called by vcd routines on error. + Setup is done by init_input_plugin. +*/ +static void +cdda_log_handler (cdio_log_level_t level, const char message[]) +{ + switch (level) { + case CDIO_LOG_DEBUG: + case CDIO_LOG_INFO: + if (!(cdda_debug & INPUT_DBG_INFO)) + return; + /* Fall through if to warn case */ + case CDIO_LOG_WARN: + LOG_MSG("%s\n", message); + break; + case CDIO_LOG_ERROR: + case CDIO_LOG_ASSERT: + LOG_ERR("%s\n", message); + break; + default: + LOG_ERR("%s\n%s %d\n", + message, + _("The above message had unknown cdio log level"), + level); + } + + /* gl_default_cdio_log_handler (level, message); */ +} + +/*! This routine is called by libcdio routines on error. + Setup is done by init_input_plugin. +*/ +static void +cdio_log_handler (cdio_log_level_t level, const char message[]) +{ + switch (level) { + case CDIO_LOG_DEBUG: + case CDIO_LOG_INFO: + if (!(cdda_debug & INPUT_DBG_CDIO)) return; + /* Fall through if to warn case */ + default: + cdda_log_handler (level, message); + } +} + +/*! This routine is when xine is not around. + Setup is done by cdio_class_displose. +*/ +static void +uninit_log_handler (cdio_log_level_t level, const char message[]) +{ + switch (level) { + case CDIO_LOG_DEBUG: + case CDIO_LOG_INFO: + if (!(cdda_debug & (INPUT_DBG_INFO|INPUT_DBG_CDIO))) + return; + /* Fall through if to warn case */ + case CDIO_LOG_WARN: + fprintf(stderr, "WARN: %s\n", message); + break; + case CDIO_LOG_ERROR: + fprintf(stderr, "ERROR: %s\n", message); + break; + case CDIO_LOG_ASSERT: + fprintf(stderr, "ASSERT ERROR: %s\n", message); + break; + default: + fprintf(stderr, "UNKNOWN ERROR: %s\n%s %d", + message, + _("The above message had unknown cdio log level"), + level); + } + + /* gl_default_cdio_log_handler (level, message); */ +} + +static uint32_t +cdda_plugin_get_capabilities (input_plugin_t *this_gen) { + + uint32_t ret = INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK | INPUT_CAP_CHAPTERS; + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "returning %d\n", ret); + return ret; +} + + +static off_t +cdda_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { + + /* only allow reading in block-sized chunks */ + + return 0; +} + +static buf_element_t * +cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, + off_t nlen) { + + cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; + buf_element_t *buf; + unsigned char frame_data[CDIO_CD_FRAMESIZE_RAW]; + + dbg_print((INPUT_DBG_CALL), "called\n"); + + if (nlen != CDIO_CD_FRAMESIZE_RAW) + return NULL; + + cdda_handle_events(this); + + if (this->current_frame >= this->last_frame) + return NULL; + + if (cdio_read_audio_sector(this->cdio, frame_data, this->current_frame++)) { + return NULL; + } + + buf = fifo->buffer_pool_alloc(fifo); + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + buf->size = CDIO_CD_FRAMESIZE_RAW; + memcpy(buf->mem, frame_data, CDIO_CD_FRAMESIZE_RAW); + + return buf; +} + +static off_t +cdda_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { + cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; + int seek_to_frame; + + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "called: %ld %d\n", + (long int) offset, origin); + + /* compute the proposed frame and check if it is within bounds */ + if (origin == SEEK_SET) + seek_to_frame = offset / CDIO_CD_FRAMESIZE_RAW + this->first_frame; + else if (origin == SEEK_CUR) + seek_to_frame = offset / CDIO_CD_FRAMESIZE_RAW + this->current_frame; + else + seek_to_frame = offset / CDIO_CD_FRAMESIZE_RAW + this->last_frame; + + if ((seek_to_frame >= this->first_frame) && + (seek_to_frame <= this->last_frame)) + this->current_frame = seek_to_frame; + + return (this->current_frame - this->first_frame) * CDIO_CD_FRAMESIZE_RAW; +} + +static off_t cdda_plugin_get_current_pos (input_plugin_t *this_gen){ + cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; + + return (this->current_frame - this->first_frame) * CDIO_CD_FRAMESIZE_RAW; +} + + +/* The get_length routine is called a bit. Make reasonably fast by + caching the last value which doesn't change all that much. + */ + +static off_t old_get_length = 0; +static track_t old_cur_track = CDIO_INVALID_TRACK; + +static off_t cdda_plugin_get_length (input_plugin_t *this_gen) { + cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; + + if (this->cur_track == old_cur_track) return old_get_length; + + old_cur_track = this->cur_track; + old_get_length = (this->last_frame - this->first_frame + 1) * + CDIO_CD_FRAMESIZE_RAW; + + return old_get_length; +} + +static uint32_t cdda_plugin_get_blocksize (input_plugin_t *this_gen) { + + return CDIO_CD_FRAMESIZE_RAW; +} + + /* Handle a keyboard/mouse event. Return TRUE if this causes a change in the play item. @@ -615,89 +846,10 @@ return false; } -static int cdda_plugin_get_optional_data (input_plugin_t *this_gen, - void *data, int data_type) { - return 0; -} - -/* Pointer to cdio default log handler. Set by init_input_plugin - routine. Perhaps can remove. */ -static cdio_log_handler_t gl_default_cdio_log_handler = NULL; - -/*! This routine is called by vcd routines on error. - Setup is done by init_input_plugin. -*/ -static void -cdda_log_handler (cdio_log_level_t level, const char message[]) -{ - switch (level) { - case CDIO_LOG_DEBUG: - case CDIO_LOG_INFO: - if (!(cdda_debug & INPUT_DBG_INFO)) - return; - /* Fall through if to warn case */ - case CDIO_LOG_WARN: - LOG_MSG("%s\n", message); - break; - case CDIO_LOG_ERROR: - case CDIO_LOG_ASSERT: - LOG_ERR("%s\n", message); - break; - default: - LOG_ERR("%s\n%s %d\n", - message, - _("The above message had unknown vcdimager log level"), - level); - } - - /* gl_default_cdio_log_handler (level, message); */ -} - -/*! This routine is called by libcdio routines on error. - Setup is done by init_input_plugin. -*/ -static void -cdio_log_handler (cdio_log_level_t level, const char message[]) -{ - switch (level) { - case CDIO_LOG_DEBUG: - case CDIO_LOG_INFO: - if (!(cdda_debug & INPUT_DBG_CDIO)) return; - /* Fall through if to warn case */ - default: - cdda_log_handler (level, message); - } -} - -/*! This routine is when xine is not around. - Setup is done by cdio_class_displose. -*/ -static void -uninit_log_handler (cdio_log_level_t level, const char message[]) -{ - switch (level) { - case CDIO_LOG_DEBUG: - case CDIO_LOG_INFO: - if (!(cdda_debug & (INPUT_DBG_INFO|INPUT_DBG_CDIO))) - return; - /* Fall through if to warn case */ - case CDIO_LOG_WARN: - fprintf(stderr, "WARN: %s\n", message); - break; - case CDIO_LOG_ERROR: - fprintf(stderr, "ERROR: %s\n", message); - break; - case CDIO_LOG_ASSERT: - fprintf(stderr, "ASSERT ERROR: %s\n", message); - break; - default: - fprintf(stderr, "UNKNOWN ERROR: %s\n%s %d", - message, - _("The above message had unknown vcdimager log level"), - level); - } - - /* gl_default_cdio_log_handler (level, message); */ +static int +cdda_plugin_get_optional_data (input_plugin_t *this_gen, void *data, + int data_type) { + return INPUT_OPTIONAL_UNSUPPORTED; } static void @@ -728,7 +880,7 @@ static bool cdda_play_track (cdda_input_plugin_t *this, track_t track_num) { - dbg_print((INPUT_DBG_CALL), "Called track: %d\n", track_num); + dbg_print((INPUT_DBG_CALL), "called track: %d\n", track_num); if (track_num > this->num_tracks) { LOG_ERR("CD has %d tracks, and you requested track %d\n", @@ -745,7 +897,8 @@ #ifdef HAVE_CDDB if (this->cddb.enabled) { - cddb_track_t *t=cddb_disc_get_track(this->cddb.disc, track_num); + cddb_track_t *t=cddb_disc_get_track(this->cddb.disc, + track_num-this->first_track); meta_info_assign(XINE_META_INFO_TITLE, this->stream, t->title); } @@ -768,7 +921,7 @@ (char *) malloc(strlen(mrl)+strlen(class->cdda_device)+1); char *my_mrl = strdup(mrl) ; - dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "Called %s\n", mrl); + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "called %s\n", mrl); old_cur_track = CDIO_INVALID_TRACK; @@ -787,6 +940,7 @@ this->event_queue = xine_event_new_queue (stream); this->cdio = cdio; this->num_tracks = cdio_get_num_tracks(cdio); + this->first_track = cdio_get_first_track_num(cdio); /* * Lookup config entries. @@ -921,89 +1075,78 @@ } -/*! - From xine plugin spec: - - generate autoplay list - return value: list of MRLs - --- The list of MRLs returned goes into the playlist. - This is called when the SHORT_PLUGIN_NAME button is pressed. -*/ - -static char ** -cdda_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { - - cdda_input_class_t *this = (cdda_input_class_t *) this_gen; - char track_mrl[20]; - int i; - track_t first_track; - CdIo *cdio; - - dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "Called\n"); - - /* free old playlist */ - for( i = 0; this->autoplaylist[i]; i++ ) { - free( this->autoplaylist[i] ); - this->autoplaylist[i] = NULL; - } - - cdio = cdio_open(this->cdda_device, DRIVER_UNKNOWN); - if (NULL == cdio) { - dbg_print((INPUT_DBG_MRL), "cdio open failed\n"); - return NULL; - } - first_track = cdio_get_first_track_num(cdio); - *num_files = cdio_get_num_tracks(cdio); - for( i = 0; i <= *num_files; i++ ) { - sprintf(track_mrl, "cdda:%d", i+first_track); - dbg_print((INPUT_DBG_MRL), "track_mrl]: %s\n", track_mrl); - this->autoplaylist[i] = strdup(track_mrl); - } - cdio_destroy(cdio); - - return this->autoplaylist; -} - -static char *cdda_class_get_identifier (input_class_t *this_gen) { +static char * +cdda_class_get_identifier (input_class_t *this_gen) { return strdup("cdda"); } -static char *cdda_class_get_description (input_class_t *this_gen) { - return _(strdup("CD Digital Audio (aka. CDDA)")); +static char * +cdda_class_get_description (input_class_t *this_gen) { + return _(strdup("Compact Disc Digital Audio (also known as CD-DA)")); } -static xine_mrl_t **cdda_class_get_dir (input_class_t *this_gen, - const char *filename, int *nFiles) { +/*! + From xine plugin spec: + ls function + return value: NULL => filename is a file, **char=> filename is a dir - cdda_input_class_t *this = (cdda_input_class_t *) this_gen; +-- This list returned forms the entries of the GUI MRL "browser". +*/ - *nFiles = 0; /* Unsupported */ - return this->mrls; +static xine_mrl_t ** +cdda_class_get_dir (input_class_t *this_gen, const char *filename, + int *num_files) { + + cdda_input_class_t *class = (cdda_input_class_t *) this_gen; + + char intended_cdda_device[1024]=""; + track_t track_num; + + if (filename == NULL) { + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), + "called with NULL\n"); + cdda_build_mrl_list(class, class->cdda_device); + } else { + char *mrl = strdup(filename); + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), + "called with %s\n", filename); + if ( !cdda_parse_mrl(class->cdda_device, mrl, intended_cdda_device, + &track_num) ) { + *num_files = 0; + free (mrl); + return NULL; + } + free (mrl); + } + + *num_files = class->num_mrls; + return class->mrls; } -static void cdda_class_dispose (input_class_t *this_gen) { +static void +cdda_class_dispose (input_class_t *this_gen) { cdda_input_class_t *this = (cdda_input_class_t *) this_gen; - dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "Called\n"); + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "called\n"); free (this->mrls); free (this); } static int cdda_class_eject_media (input_class_t *this_gen) { cdda_input_class_t *this = (cdda_input_class_t *) this_gen; - dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "Called\n"); + dbg_print((INPUT_DBG_CALL|INPUT_DBG_XINECALL), "called\n"); return cdio_eject_media(this->ip->cdio); } static void cdda_debug_cb(void *this_gen, xine_cfg_entry_t *entry) { - dbg_print(INPUT_DBG_CALL, "Called setting %d\n", entry->num_value); + dbg_print(INPUT_DBG_CALL, "called setting %d\n", entry->num_value); cdda_debug = entry->num_value; } -static void *init_plugin (xine_t *xine, void *data) { +static void * +init_plugin (xine_t *xine, void *data) { cdda_input_class_t *this; config_values_t *config; @@ -1019,8 +1162,7 @@ this->input_class.open_plugin = cdda_open_plugin; this->input_class.get_identifier = cdda_class_get_identifier; this->input_class.get_description = cdda_class_get_description; - /* this->input_class.get_dir = cdda_class_get_dir; */ - this->input_class.get_dir = NULL; + this->input_class.get_dir = cdda_class_get_dir; this->input_class.get_autoplay_list = cdda_class_get_autoplay_list; this->input_class.dispose = cdda_class_dispose; this->input_class.eject_media = cdda_class_eject_media; @@ -1030,8 +1172,8 @@ default_cdda_device = strdup("/dev/cdrom"); } - this->mrls = (xine_mrl_t **) xine_xmalloc(sizeof(xine_mrl_t*)); - this->mrls_allocated_entries = 0; + this->mrls = (xine_mrl_t **) xine_xmalloc(sizeof(xine_mrl_t*)); + this->num_mrls = 0; this->cdda_device = config->register_string(config, "input.cdda_device", default_cdda_device, |