diff options
author | Paul Gevers <elbrus@debian.org> | 2017-07-04 20:44:02 +0200 |
---|---|---|
committer | Paul Gevers <elbrus@debian.org> | 2017-07-04 20:44:02 +0200 |
commit | 1f968825b8635ce792cb7ada6b3b180327c5a4cc (patch) | |
tree | ae0d19e51c636d85f3188f4dc276bd32615d752b /src/daisy-player.c | |
parent | d7b6c1da2f9a7e55d21061041ba4a3e42b9a54d7 (diff) |
New upstream version 10.4
Diffstat (limited to 'src/daisy-player.c')
-rw-r--r-- | src/daisy-player.c | 1784 |
1 files changed, 741 insertions, 1043 deletions
diff --git a/src/daisy-player.c b/src/daisy-player.c index f9f15d4..c34ace8 100644 --- a/src/daisy-player.c +++ b/src/daisy-player.c @@ -1,6 +1,6 @@ -/* daisy-player - A parser to play Daisy cd's. +/* daisy-player * - * Copyright (C)2003-2015 J. Lemmens + * Copyright (C)2003-2017 J. Lemmens * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -15,147 +15,115 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ + */ -#include "src/daisy.h" - -void playfile (misc_t *misc, char *in_file, char *in_type, - char *out_file, char *out_type, char *tempo) -{ - sox_format_t *sox_in, *sox_out; - sox_effects_chain_t *chain; - sox_effect_t *e; - char *args[MAX_STR], str[MAX_STR]; - - sox_globals.verbosity = 0; - sox_globals.stdout_in_use_by = NULL; - sox_init (); - if ((sox_in = sox_open_read (in_file, NULL, NULL, in_type)) == NULL) - failure (in_file, errno); - if ((sox_out = sox_open_write (out_file, &sox_in->signal, - NULL, out_type, NULL, NULL)) == NULL) - { -// if cannot write to out_file (pulseaudio?), try ALSA default - if ((sox_out = sox_open_write ("default", &sox_in->signal, - NULL, "alsa", NULL, NULL)) == NULL) - { - int e; - - e = errno; - beep (); - endwin (); - printf ("\n%s: %s\n\n", out_file, strerror (e)); - fflush (stdout); - put_bookmark (misc); - strncpy (misc->sound_dev, "hw:0", MAX_STR - 1); - save_rc (misc); - kill (misc->daisy_player_pid, SIGTERM); - } // if - } // if - if (strcmp (in_type, "cdda") == 0) - { - sox_in->encoding.encoding = SOX_ENCODING_SIGN2; - sox_in->encoding.bits_per_sample = 16; - sox_in->encoding.reverse_bytes = sox_option_no; - } // if - - chain = sox_create_effects_chain (&sox_in->encoding, &sox_out->encoding); - - e = sox_create_effect (sox_find_effect ("input")); - args[0] = (char *) sox_in, sox_effect_options (e, 1, args); - sox_add_effect (chain, e, &sox_in->signal, &sox_in->signal); - -/* Don't use the sox trim effect. It works nice, but is far too slow - char str2[MAX_STR]; - snprintf (str, MAX_STR - 1, "%f", misc->clip_begin); - snprintf (str2, MAX_STR - 1, "%f", misc->clip_end - misc->clip_begin); - e = sox_create_effect (sox_find_effect ("trim")); - args[0] = str; - args[1] = str2; - sox_effect_options (e, 2, args); - sox_add_effect (chain, e, &sox_in->signal, &sox_in->signal); -*/ - - e = sox_create_effect (sox_find_effect ("tempo")); - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - args[0] = "-m"; - else - args[0] = "-s"; - args[1] = tempo; - sox_effect_options (e, 2, args); - sox_add_effect (chain, e, &sox_in->signal, &sox_in->signal); - - snprintf (str, MAX_STR - 1, "%lf", sox_out->signal.rate); - e = sox_create_effect (sox_find_effect ("rate")); - args[0] = str, sox_effect_options (e, 1, args); - sox_add_effect (chain, e, &sox_in->signal, &sox_in->signal); - - snprintf (str, MAX_STR - 1, "%i", sox_out->signal.channels); - e = sox_create_effect (sox_find_effect ("channels")); - args[0] = str, sox_effect_options (e, 1, args); - sox_add_effect (chain, e, &sox_in->signal, &sox_in->signal); - - e = sox_create_effect (sox_find_effect ("output")); - args[0] = (char *) sox_out, sox_effect_options (e, 1, args); - sox_add_effect (chain, e, &sox_in->signal, &sox_out->signal); - - sox_flow_effects (chain, NULL, NULL); - sox_delete_effects_chain (chain); - sox_close (sox_out); - sox_close (sox_in); - sox_quit (); -} // playfile +#include "daisy.h" void put_bookmark (misc_t *misc) { - char str[MAX_STR]; xmlTextWriterPtr writer; struct passwd *pw;; pw = getpwuid (geteuid ()); - snprintf (str, MAX_STR - 1, "%s/.daisy-player", pw->pw_dir); - mkdir (str, 0755); - snprintf (str, MAX_STR - 1, "%s/.daisy-player/%s%s", + snprintf (misc->str, MAX_STR - 1, "%s/.daisy-player", pw->pw_dir); + mkdir (misc->str, 0755); + snprintf (misc->str, MAX_STR - 1, "%s/.daisy-player/%s%s", pw->pw_dir, misc->bookmark_title, get_mcn (misc)); - if (! (writer = xmlNewTextWriterFilename (str, 0))) + if (! (writer = xmlNewTextWriterFilename (misc->str, 0))) return; xmlTextWriterStartDocument (writer, NULL, NULL, NULL); xmlTextWriterStartElement (writer, BAD_CAST "bookmark"); if (misc->playing >= 0) - xmlTextWriterWriteFormatAttribute + xmlTextWriterWriteFormatAttribute (writer, BAD_CAST "item", "%d", misc->playing); else xmlTextWriterWriteFormatAttribute (writer, BAD_CAST "item", "%d", misc->current); if (misc->cd_type != CDIO_DISC_MODE_CD_DA) + { xmlTextWriterWriteFormatAttribute - (writer, BAD_CAST "clip-begin", "%f", misc->clip_begin); + (writer, BAD_CAST "id", "%s", misc->current_id); + } else xmlTextWriterWriteFormatAttribute - (writer, BAD_CAST "seconds", "%d", (int) (time (NULL) - misc->elapsed_seconds)); - xmlTextWriterWriteFormatAttribute (writer, BAD_CAST "level", "%d", misc->level); + (writer, BAD_CAST "seconds", "%d", + (int) (time (NULL) - misc->elapsed_seconds)); + xmlTextWriterWriteFormatAttribute (writer, BAD_CAST + "level", "%d", misc->level); xmlTextWriterEndElement (writer); xmlTextWriterEndDocument (writer); xmlFreeTextWriter (writer); } // put_bookmark +void get_clips (misc_t *misc, my_attribute_t *my_attribute) +{ + char begin_str[MAX_STR], *begin, *orig_begin, *end; + + if (misc->cd_type == CDIO_DISC_MODE_CD_DA) + return; + orig_begin = my_attribute->clip_begin; + end = my_attribute->clip_end; + if (! *orig_begin) + return; + strncpy (begin_str, orig_begin, MAX_STR - 1); + begin = begin_str; + while (! isdigit (*begin)) + begin++; + if (strchr (begin, 's')) + *strchr (begin, 's') = 0; + if (! strchr (begin, ':')) + misc->clip_begin = (float) atof (begin); + else + misc->clip_begin = read_time (begin); + +// fill end + while (! isdigit (*end)) + end++; + if (strchr (end, 's')) + *strchr (end, 's') = 0; + if (! strchr (end, ':')) + misc->clip_end = (float) atof (end); + else + misc->clip_end = read_time (end); +} // get_clips + +float read_time (char *p) +{ + char *h, *m, *s; + + s = strrchr (p, ':') + 1; + if (s > p) + *(s - 1) = 0; + if (strchr (p, ':')) + { + m = strrchr (p, ':') + 1; + *(m - 1) = 0; + h = p; + } + else + { + h = "0"; + m = p; + } // if + return atoi (h) * 3600 + atoi (m) * 60 + (float) atof (s); +} // read_time + void get_bookmark (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) { - char str[MAX_STR]; - float begin; xmlTextReaderPtr local_reader; - xmlDocPtr local_doc; + htmlDocPtr local_doc; struct passwd *pw; + char *id; if (misc->ignore_bookmark == 1) return; pw = getpwuid (geteuid ()); if (! *misc->bookmark_title) return; - snprintf (str, MAX_STR - 1, "%s/.daisy-player/%s%s", + snprintf (misc->str, MAX_STR - 1, "%s/.daisy-player/%s%s", pw->pw_dir, misc->bookmark_title, get_mcn (misc)); - local_doc = xmlRecoverFile (str); + local_doc = htmlParseFile (misc->str, "UTF-8"); if (! (local_reader = xmlReaderWalker (local_doc))) { xmlFreeDoc (local_doc); @@ -168,8 +136,11 @@ void get_bookmark (misc_t *misc, my_attribute_t *my_attribute, } while (strcasecmp (misc->tag, "bookmark") != 0); xmlTextReaderClose (local_reader); xmlFreeDoc (local_doc); - if (misc->current <= 0) + if (misc->current < 0) + { misc->current = 0; + return; + } // if if (misc->current >= misc->total_items) misc->current = 0; misc->displaying = misc->playing = misc->current; @@ -180,194 +151,98 @@ void get_bookmark (misc_t *misc, my_attribute_t *my_attribute, misc->elapsed_seconds = time (NULL) - misc->elapsed_seconds; return; } // if - get_clips (misc, my_attribute->clip_begin, my_attribute->clip_end); - begin = misc->clip_begin; - open_smil_file (misc, my_attribute, daisy[misc->current].smil_file, - daisy[misc->current].anchor); + id = my_attribute->id; + open_clips_file (misc, my_attribute, daisy[misc->current].clips_file, + daisy[misc->current].clips_anchor); while (1) { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - break; - if (strcasecmp (misc->tag, "audio") == 0) + if (strcmp (misc->current_id, id) == 0) { - strncpy (misc->current_audio_file, my_attribute->src, MAX_STR - 1); - get_clips (misc, my_attribute->clip_begin, my_attribute->clip_end); - if (misc->clip_begin == begin) - break; + start_playing (misc, daisy); + break; } // if + get_next_clips (misc, my_attribute, daisy); } // while - if (misc->level < 1) + if (misc->level < 1) misc->level = 1; - misc->current_page_number = daisy[misc->playing].page_number; + misc->current_page_number = daisy[misc->playing].page_number - 1; misc->just_this_item = -1; - skip_left (misc, my_attribute, daisy); - skip_right (misc); + pause_resume (misc, my_attribute, daisy); + pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); - return; } // get_bookmark -void get_page_number_2 (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy, char *p) +void get_next_clips (misc_t *misc, my_attribute_t *my_attribute, + daisy_t *daisy) { -// function for daisy 2.02 - char *anchor = 0, *id1, *id2; - xmlTextReaderPtr page; - xmlDocPtr doc; - - doc = xmlRecoverFile (daisy[misc->playing].smil_file); - if (! (page = xmlReaderWalker (doc))) - { - int e; - char str[MAX_STR]; - - e = errno; - snprintf (str, MAX_STR, - gettext ("Cannot read %s"), daisy[misc->playing].smil_file); - failure (str, e); - } // if - id1 = strdup (p); - do - { - if (! get_tag_or_label (misc, my_attribute, page)) - { - free (id1); - return; - } // if - } while (strcasecmp (my_attribute->id, id1) != 0); - do - { - if (! get_tag_or_label (misc, my_attribute, page)) - return; - } while (strcasecmp (misc->tag, "text") != 0); - id2 = strdup (my_attribute->id); - xmlTextReaderClose (page); - xmlFreeDoc (doc); - doc = xmlRecoverFile (misc->NCC_HTML); - if (! (page = xmlReaderWalker (doc))) - { - int e; - char str[MAX_STR]; + int eof; - e = errno; - snprintf (str, MAX_STR, gettext ("Cannot read %s"), misc->NCC_HTML); - failure (str, e); - } // if while (1) { - if (! get_tag_or_label (misc, my_attribute, page)) - return; - if (strcasecmp (misc->tag, "a") == 0) + eof = 1 - get_tag_or_label (misc, my_attribute, misc->reader); + if (strcasecmp (misc->tag, "audio") == 0) { - if (strchr (my_attribute->href, '#')) - anchor = strdup (strchr (my_attribute->href, '#') + 1); - if (strcasecmp (anchor, id2) == 0) - break; - } // if - } // while - do - { - if (! get_tag_or_label (misc, my_attribute, page)) + misc->current_audio_file = real_name (misc, my_attribute->src); + get_clips (misc, my_attribute); return; - } while (! *misc->label); - xmlTextReaderClose (page); - xmlFreeDoc (doc); - misc->current_page_number = atoi (misc->label); -} // get_page_number_2 - -int get_next_clips (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy) -{ - while (1) - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return 0; - if (strcasecmp (my_attribute->id, - daisy[misc->playing + 1].anchor) == 0 && - misc->playing + 1 != misc->total_items) - return 0; - if (strcasecmp (my_attribute->class, "pagenum") == 0) - if (strcasestr (misc->daisy_version, "3")) - get_page_number_3 (misc, my_attribute); - if (strcasecmp (misc->tag, "audio") == 0) + } // if + if (strcasestr (misc->daisy_version, "2.02") && + strcasecmp (misc->tag, "text") == 0) { - strncpy (misc->current_audio_file, my_attribute->src, MAX_STR - 1); - get_clips (misc, my_attribute->clip_begin, my_attribute->clip_end); - return 1; - } // if (strcasecmp (misc->tag, "audio") == 0) - } // while -} // get_next_clips - -int compare_playorder (const void *p1, const void *p2) -{ - return (*(int *)p1 - *(int*)p2); -} // compare_playorder - -void parse_smil_2 (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) -{ -// function for daisy 2.02 - int x; - xmlTextReaderPtr parse; - - misc->total_time = 0; - for (x = 0; x < misc->total_items; x++) - { - if (*daisy[x].smil_file == 0) - continue; - xmlDocPtr doc = xmlRecoverFile (daisy[x].smil_file); - if (! (parse = xmlReaderWalker (doc))) + if (get_page_number_2 (misc, my_attribute, daisy, my_attribute->src)) + return; + } // if + if (strcasestr (misc->daisy_version, "3") && + (strcasecmp (misc->tag, "pagenum") == 0 || + strcasecmp (my_attribute->class, "pagenum") == 0)) { - int e; - char str[MAX_STR]; - - e = errno; - snprintf (str, MAX_STR, - gettext ("Cannot read %s"), daisy[x].smil_file); - failure (str, e); + if (get_page_number_3 (misc, my_attribute)) + return; } // if -// parse this smil - do + if ((misc->playing + 1 < misc->total_items && + strcasecmp (my_attribute->id, + daisy[misc->playing + 1].clips_anchor) == 0) || + eof) { - if (! get_tag_or_label (misc, my_attribute, parse)) - break; - } while (strcasecmp (my_attribute->id, daisy[x].anchor) != 0); - daisy[x].duration = 0; - while (1) - { - if (! get_tag_or_label (misc, my_attribute, parse)) - break; - if (strcasecmp (misc->tag, "audio") == 0) + if (*daisy[misc->playing + 1].clips_anchor || eof) { - strncpy (misc->current_audio_file, my_attribute->src, MAX_STR - 1); - get_clips (misc, my_attribute->clip_begin, my_attribute->clip_end); - daisy[x].begin = misc->clip_begin; - daisy[x].duration += misc->clip_end - misc->clip_begin; - while (1) +// go to next item + strncpy (my_attribute->clip_begin, "0", 2); + misc->clip_begin = 0; + if (++misc->playing >= misc->total_items) { - if (! get_tag_or_label (misc, my_attribute, parse)) - break; - if (*daisy[x + 1].anchor) - if (strcasecmp (my_attribute->id, daisy[x + 1].anchor) == 0) - break; - if (strcasecmp (misc->tag, "audio") == 0) + struct passwd *pw; + + pw = getpwuid (geteuid ()); + quit_daisy_player (misc, daisy); + snprintf (misc->str, MAX_STR - 1, "%s/.daisy-player/%s%s", + pw->pw_dir, misc->bookmark_title, get_mcn (misc)); + unlink (misc->str); + _exit (0); + } // if + if (daisy[misc->playing].level <= misc->level) + misc->displaying = misc->current = misc->playing; + if (misc->just_this_item != -1) + { + if (daisy[misc->playing].level <= misc->level) { - get_clips (misc, my_attribute->clip_begin, - my_attribute->clip_end); - daisy[x].duration += misc->clip_end - misc->clip_begin; - } // if (strcasecmp (misc->tag, "audio") == 0) - } // while - if (*daisy[x + 1].anchor) - if (strcasecmp (my_attribute->id, daisy[x + 1].anchor) == 0) + misc->playing = misc->just_this_item = -1; break; - } // if (strcasecmp (misc->tag, "audio") == 0) - } // while - xmlTextReaderClose (parse); - xmlFreeDoc (doc); - misc->total_time += daisy[x].duration; - } // for -} // parse_smil_2 + } // if + } // if + if (misc->playing > -1) + { + open_clips_file (misc, my_attribute, + daisy[misc->playing].clips_file, + daisy[misc->playing].clips_anchor); + } // if + } // if + } // if + } // while +} // get_next_clips -void view_page (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) +void view_page (misc_t *misc, daisy_t *daisy) { if (misc->playing == -1) return; @@ -376,13 +251,9 @@ void view_page (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) if (misc->total_pages == 0) return; wattron (misc->screenwin, A_BOLD); - if (strcasestr (misc->daisy_version, "2.02")) - get_page_number_2 (misc, my_attribute, daisy, my_attribute->id); if (misc->current_page_number) mvwprintw (misc->screenwin, daisy[misc->playing].y, 62, "(%3d)", misc->current_page_number); - else - mvwprintw (misc->screenwin, daisy[misc->playing].y, 62, " "); wattroff (misc->screenwin, A_BOLD); wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); wrefresh (misc->screenwin); @@ -406,7 +277,8 @@ void view_time (misc_t *misc, daisy_t *daisy) { struct stat buf; - stat (misc->tmp_wav, &buf); + if (stat (misc->tmp_wav, &buf)) + return; elapsed_seconds = (misc->clip_begin - daisy[misc->playing].begin) + (time (NULL) - buf.st_atime); remain_seconds = daisy[misc->playing].duration - elapsed_seconds; @@ -421,7 +293,7 @@ void view_time (misc_t *misc, daisy_t *daisy) wattroff (misc->screenwin, A_BOLD); wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); wrefresh (misc->screenwin); -} // view_time +} // view_time void view_screen (misc_t *misc, daisy_t *daisy) { @@ -433,15 +305,24 @@ void view_screen (misc_t *misc, daisy_t *daisy) wprintw (misc->titlewin, "----------------------------------------"); mvwprintw (misc->titlewin, 1, 0, gettext ("'h' for help -")); if (misc->total_pages) - wprintw (misc->titlewin, gettext (" %d pages "), misc->total_pages); - mvwprintw (misc->titlewin, 1, 28, gettext (" level: %d of %d "), - misc->level, misc->depth); + { + wprintw (misc->titlewin, " "); + wprintw (misc->titlewin, gettext ("%d pages"), + misc->total_pages); + wprintw (misc->titlewin, " "); + } // if + mvwprintw (misc->titlewin, 1, 29, " "); + wprintw (misc->titlewin, gettext ("level: %d of %d"), + misc->level, misc->depth); + wprintw (misc->titlewin, " "); time = misc->total_time / misc->speed; int hours = time / 3600; int minutes = (time - hours * 3600) / 60; int seconds = time - (hours * 3600 + minutes * 60); - mvwprintw (misc->titlewin, 1, 47, gettext (" total length: %02d:%02d:%02d "), + mvwprintw (misc->titlewin, 1, 47, " "); + wprintw (misc->titlewin, gettext ("total length: %02d:%02d:%02d"), hours, minutes,seconds); + wprintw (misc->titlewin, " "); mvwprintw (misc->titlewin, 1, 74, " %d/%d ", daisy[misc->current].screen + 1, daisy[misc->total_items - 1].screen + 1); @@ -458,7 +339,8 @@ void view_screen (misc_t *misc, daisy_t *daisy) for (x2 = x; x2 < 59; x2 = x2 + 2) wprintw (misc->screenwin, " ."); if (daisy[i].page_number) - mvwprintw (misc->screenwin, daisy[i].y, 61, " (%3d)", daisy[i].page_number); + mvwprintw (misc->screenwin, daisy[i].y, 61, " (%3d)", + daisy[i].page_number); if (daisy[i].level <= misc->level) { int x, dur = 0; @@ -474,227 +356,113 @@ void view_screen (misc_t *misc, daisy_t *daisy) mvwprintw (misc->screenwin, daisy[i].y, 74, "%02d:%02d", (int) (dur + .5) / 60, (int) (dur + .5) % 60); } // if - if (i >= misc->total_items) + if (i >= misc->total_items - 1) break; - } while (daisy[++i].screen == daisy[misc->current].screen); + i++; + } while (daisy[i].screen == daisy[misc->current].screen); if (misc->just_this_item != -1 && daisy[misc->current].screen == daisy[misc->playing].screen) mvwprintw (misc->screenwin, daisy[misc->displaying].y, 0, "J"); wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); wrefresh (misc->screenwin); + view_page (misc, daisy); + view_time (misc, daisy); } // view_screen -void read_daisy_2 (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy) -{ -// function for daisy 2.02 - int indent = 0, found_page_normal = 0; - xmlTextReaderPtr ncc; - xmlDocPtr doc = NULL; - - if ((doc = xmlRecoverFile (misc->NCC_HTML)) == NULL) - failure ("read_daisy_2 ()", errno); - if (! (ncc = xmlReaderWalker (doc))) - { - char str[MAX_STR]; - int e; - - e = errno; - snprintf (str, MAX_STR, gettext ("Cannot read %s"), misc->NCC_HTML); - failure (str, e); - } // if - - misc->current = misc->displaying = 0; - while (1) - { - if (! get_tag_or_label (misc, my_attribute, ncc)) - break; - if (strcasecmp (misc->tag, "h1") == 0 || - strcasecmp (misc->tag, "h2") == 0 || - strcasecmp (misc->tag, "h3") == 0 || - strcasecmp (misc->tag, "h4") == 0 || - strcasecmp (misc->tag, "h5") == 0 || - strcasecmp (misc->tag, "h6") == 0) - { - int l; - - found_page_normal = 0; - daisy[misc->current].page_number = 0; - l = misc->tag[1] - '0'; - daisy[misc->current].level = l; - daisy[misc->current].x = l + 3 - 1; - indent = daisy[misc->current].x = (l - 1) * 3 + 1; - do - { - if (! get_tag_or_label (misc, my_attribute, ncc)) - break; - } while (strcasecmp (misc->tag, "a") != 0); - strncpy (daisy[misc->current].smil_file, my_attribute->href, - MAX_STR - 1); - - if (strchr (daisy[misc->current].smil_file, '#')) - { - strncpy (daisy[misc->current].anchor, - strchr (daisy[misc->current].smil_file, '#') + 1, MAX_STR - 1); - *strchr (daisy[misc->current].smil_file, '#') = 0; - } // if - do - { - if (! get_tag_or_label (misc, my_attribute, ncc)) - break; - } while (*misc->label == 0); - get_label (misc, daisy, indent); - misc->current++; - misc->displaying++; - } // if (strcasecmp (misc->tag, "h1") == 0 || ... - if (strcasecmp (my_attribute->class, "page-normal") == 0 && - found_page_normal == 0) - { - found_page_normal = 1; - do - { - if (! get_tag_or_label (misc, my_attribute, ncc)) - break; - } while (*misc->label == 0); - daisy[misc->current - 1].page_number = atoi (misc->label); - } // if (strcasecmp (my_attribute->class, "page-normal") - } // while - xmlTextReaderClose (ncc); - xmlFreeDoc (doc); - misc->total_items = misc->current; - parse_smil_2 (misc, my_attribute, daisy); -} // read_daisy_2 - -void player_ended () -{ - wait (NULL); -} // player_ended - -void play_now (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy) +void start_playing (misc_t *misc, daisy_t *daisy) { + if (strcasecmp (misc->tag, "audio") != 0) + return; if (misc->playing == -1) return; if (misc->clip_end - misc->clip_begin <= 0) return; - misc->elapsed_seconds = time (NULL); switch (misc->player_pid = fork ()) { case -1: - failure ("fork ()", errno); + failure (misc, "fork ()", errno); case 0: // child break; default: // parent return; } // switch - char tempo_str[15], cmd[MAX_CMD]; - int err; + char tempo_str[15]; - setsid (); - - view_page (misc, my_attribute, daisy); + view_page (misc, daisy); lseek (misc->tmp_wav_fd, SEEK_SET, 0); - snprintf (cmd, MAX_CMD - 1, "madplay -Q %s -s %f -t %f -o wav:\"%s\"", - misc->current_audio_file, misc->clip_begin, - misc->clip_end - misc->clip_begin, misc->tmp_wav); - if ((err = system (cmd)) != 0) + snprintf (misc->cmd, MAX_CMD - 1, + "/usr/bin/madplay -Q \"%s\" -s %f -t %f -o wav:\"%s\"", + misc->current_audio_file, misc->clip_begin, + misc->clip_end - misc->clip_begin, misc->tmp_wav); + if (system (misc->cmd) != 0) { - endwin (); + int e; + + e = errno; beep (); - printf ("\n%s: %s\n", cmd, strerror (err)); - printf ("Is madplay installed?"); - kill (misc->daisy_player_pid, SIGTERM); + endwin (); + printf ("\n"); + kill (getppid (), SIGTERM); + failure (misc, misc->cmd, e); } // if snprintf (tempo_str, 10, "%lf", misc->speed); playfile (misc, misc->tmp_wav, "wav", misc->sound_dev, "alsa", tempo_str); _exit (0); -} // play_now +} // start_playing -void open_smil_file (misc_t *misc, my_attribute_t *my_attribute, - char *smil_file, char *anchor) +void open_clips_file (misc_t *misc, my_attribute_t *my_attribute, + char *clips_file, char *anchor) { - xmlDocPtr local_doc; - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) return; - if (*smil_file == 0) - return; - local_doc = xmlRecoverFile (smil_file); - if (! (misc->reader = xmlReaderWalker (local_doc))) + if (! (misc->doc = htmlParseFile (clips_file, "UTF-8"))) { int e; char str[MAX_STR]; e = errno; - snprintf (str, MAX_STR, "open_smil_file(): %s\n", smil_file); - failure (str, e); + snprintf (str, MAX_STR, "htmlParseFile (%s)", clips_file); + failure (misc, str, e); } // if - -// skip to anchor - while (1) + if (! (misc->reader = xmlReaderWalker (misc->doc))) { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - break;; - if (strcasecmp (my_attribute->id, anchor) == 0) - break; - } // while - return; -} // open_smil_file + int e; + char str[MAX_STR]; -void pause_resume (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) -{ - if (misc->playing > -1) - { - misc->pause_resume_playing = misc->playing; - misc->pause_resume_clip_begin = misc->clip_begin; - misc->pause_resume_lsn_cursor = misc->lsn_cursor; - misc->playing = -1; - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - kill (misc->player_pid, SIGKILL); - else - { - kill (misc->player_pid, SIGKILL); - misc->player_pid = -2; - } // if - return; + e = errno; + snprintf (str, MAX_STR, "open_clips_file(): %s", clips_file); + failure (misc, str, e); } // if - misc->playing = misc->pause_resume_playing; - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - { - misc->player_pid = play_track (misc, misc->sound_dev, "alsa", - misc->pause_resume_lsn_cursor - 75 * 4); + + if (*anchor == 0) return; - } // if - open_smil_file (misc, my_attribute, daisy[misc->playing].smil_file, - daisy[misc->playing].anchor); + +// skip to anchor while (1) { if (! get_tag_or_label (misc, my_attribute, misc->reader)) + break;; + if (strcasecmp (my_attribute->id, anchor) == 0) break; - if (strcasecmp (misc->tag, "audio") == 0) - { - strncpy (misc->current_audio_file, my_attribute->src, MAX_STR - 1); - get_clips (misc, my_attribute->clip_begin, - my_attribute->clip_end); - if (misc->clip_begin == misc->pause_resume_clip_begin) - break; - } // if } // while - skip_left (misc, my_attribute, daisy); - skip_right (misc); -} // pause_resume +} // open_clips_file -void write_wav (misc_t *misc, daisy_t *daisy, char *outfile) +void write_wav (misc_t *misc, my_attribute_t *my_attribute, + daisy_t *daisy, char *outfile) { - char str[MAX_STR]; + char str_wav[MAX_STR]; struct passwd *pw; + int old_playing, old_displaying, old_current, old_just_this_item; pw = getpwuid (geteuid ()); - snprintf (str, MAX_STR - 1, "%s/%s", pw->pw_dir, outfile); - while (access (str, F_OK) == 0) - strncat (str, ".wav", MAX_STR - 1); + strcpy (str_wav, pw->pw_dir); + strcat (str_wav, "/"); + strcat (str_wav, outfile); + strcat (str_wav, ".wav"); + while (access (str_wav, R_OK) == 0) + strncat (str_wav, ".wav", MAX_STR - 1); if (misc->cd_type == CDIO_DISC_MODE_CD_DA) { @@ -704,7 +472,7 @@ void write_wav (misc_t *misc, daisy_t *daisy, char *outfile) sp = misc->speed; misc->speed = 1; - pid = play_track (misc, str, "wav", + pid = play_track (misc, str_wav, "wav", daisy[misc->current].first_lsn); misc->speed = sp; do @@ -721,43 +489,108 @@ void write_wav (misc_t *misc, daisy_t *daisy, char *outfile) return; } // if - char cmd[MAX_CMD]; + old_playing = misc->playing; + old_displaying = misc->displaying; + old_current = misc->current; + old_just_this_item = misc->just_this_item; + misc->just_this_item = misc->playing = misc->current; + + open_clips_file (misc, my_attribute, daisy[misc->current].clips_file, + daisy[misc->current].clips_anchor); + get_next_clips (misc, my_attribute, daisy); + snprintf (misc->cmd, MAX_CMD - 1, + "/usr/bin/madplay -Q \"%s\" -s %f -t %f -o wave:\"%s\"", + misc->current_audio_file, + daisy[misc->current].begin, daisy[misc->current].duration, + str_wav); + if (system (misc->cmd) != 0) + { + int e; - lseek (misc->tmp_wav_fd, SEEK_SET, 0); - snprintf (cmd, MAX_CMD, "madplay -Q \"%s\" -s %f -t %f -o wav:\"%s\"", - misc->current_audio_file, - daisy[misc->current].begin, daisy[misc->current].duration, str); - if (system (cmd) != 0) - failure (cmd, errno); + e = errno; + beep (); + endwin (); + printf ("\n"); + failure (misc, misc->cmd, e); + } // if + misc->playing = old_playing; + misc->displaying = old_displaying; + misc->current= old_current; + misc->just_this_item = old_just_this_item; + wmove (misc->screenwin, daisy[misc->playing].y, daisy[misc->playing].x); } // write_wav -void store_to_disk (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) +void pause_resume (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) { - char str[MAX_STR]; - int i, pause_flag; + if (misc->playing > -1) + { + misc->pause_resume_playing = misc->playing; + misc->pause_resume_id = misc->current_id; + misc->playing = -1; + misc->pause_resume_lsn_cursor = misc->lsn_cursor; + kill (misc->player_pid, SIGKILL); + if (misc->cd_type != CDIO_DISC_MODE_CD_DA) + misc->player_pid = -2; + return; + } // if + + misc->playing = misc->pause_resume_playing; + misc->lsn_cursor = misc->pause_resume_lsn_cursor; + if (misc->cd_type == CDIO_DISC_MODE_CD_DA) + { + misc->player_pid = play_track (misc, misc->sound_dev, "alsa", + misc->pause_resume_lsn_cursor - 75 * 4); + return; + } // if + if (misc->playing < 0) + return; + open_clips_file (misc, my_attribute, daisy[misc->playing].clips_file, + daisy[misc->playing].clips_anchor); + while (1) + { + get_next_clips (misc, my_attribute, daisy); + if (strcmp (misc->pause_resume_id, misc->current_id) == 0) + { + start_playing (misc, daisy); + view_screen (misc, daisy); + return; + } // if + } // while +} // pause_resume - pause_flag = misc->playing; - if (pause_flag > -1) +void store_to_disk (misc_t *misc, my_attribute_t *my_attribute, + daisy_t *daisy) +{ + char *str; + int i, current, playing; + + playing =misc->playing; + if (playing > -1) pause_resume (misc, my_attribute, daisy); wclear (misc->screenwin); - snprintf (str, MAX_STR - 1, "%s.wav", daisy[misc->current].label); + current = misc->current; + str = malloc (strlen (daisy[current].label) + 10); + snprintf (str, MAX_STR - 1, "%s", daisy[misc->current].label); wprintw (misc->screenwin, - "\nStoring \"%s\" as \"%s\" into your home-folder...", - daisy[misc->current].label, str); + "\nStoring \"%s\" as \"%s.wav\" into your home-folder...", + daisy[current].label, str); wrefresh (misc->screenwin); for (i = 0; str[i] != 0; i++) if (str[i] == '/') str[i] = '-'; - write_wav (misc, daisy, str); - if (pause_flag > -1) + write_wav (misc, my_attribute, daisy, str); + if (playing > -1) pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); } // store_to_disk -void help (misc_t *misc, daisy_t *daisy) +void help (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) { - int y, x; + int y, x, playing; + playing = misc->playing; + if (playing > -1) + pause_resume (misc, my_attribute, daisy); getyx (misc->screenwin, y, x); wclear (misc->screenwin); wprintw (misc->screenwin, "\n%s\n", gettext @@ -792,11 +625,11 @@ void help (misc_t *misc, daisy_t *daisy) ("/ - search for a label")); wprintw (misc->screenwin, "%s\n", gettext ("d - store current item to disk")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("D,- - decrease playing speed")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("e,. - quit daisy-player, place a bookmark and eject")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("f - find the currently playing item and place the cursor there")); if (misc->cd_type == CDIO_DISC_MODE_CD_DA) wprintw (misc->screenwin, "%s\n", gettext @@ -807,35 +640,41 @@ void help (misc_t *misc, daisy_t *daisy) if (misc->total_pages) wprintw (misc->screenwin, "%s\n", gettext ("G - go to page number")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("h,? - give this help")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("j,5 - just play current item")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("l - switch to next level")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("L - switch to previous level")); wprintw (misc->screenwin, "%s\n", gettext ("n - search forwards")); wprintw (misc->screenwin, "%s\n", gettext ("N - search backwards")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("o - select next output sound device")); wprintw (misc->screenwin, "%s\n", gettext ("p - place a bookmark")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("q - quit daisy-player and place a bookmark")); - wprintw (misc->screenwin, "%s\n", gettext + wprintw (misc->screenwin, "%s\n", gettext ("s - stop playing")); wprintw (misc->screenwin, "%s\n", gettext ("U,+ - increase playing speed")); - wprintw (misc->screenwin, "\n%s", gettext + wprintw (misc->screenwin, "%s\n", gettext + ("v,1 - decrease playback volume")); + wprintw (misc->screenwin, "%s\n", gettext + ("V,7 - increase playback volume (beware of Clipping)")); + wprintw (misc->screenwin, "\n%s", gettext ("Press any key to leave help...")); nodelay (misc->screenwin, FALSE); wgetch (misc->screenwin); nodelay (misc->screenwin, TRUE); view_screen (misc, daisy); wmove (misc->screenwin, y, x); + if (playing > -1) + pause_resume (misc, my_attribute, daisy); } // help void previous_item (misc_t *misc, daisy_t *daisy) @@ -870,184 +709,96 @@ void next_item (misc_t *misc, daisy_t *daisy) wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); } // next_item -void play_clip (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy) +void calculate_times_3 (misc_t *misc, my_attribute_t *my_attribute, + daisy_t *daisy) { - char str[MAX_STR]; - - if (kill (misc->player_pid, 0) == 0) -// if still playing - return; - misc->player_pid = -2; - if (get_next_clips (misc, my_attribute, daisy)) - { - play_now (misc, my_attribute, daisy); - return; - } // if + int x; + xmlTextReaderPtr parse; + htmlDocPtr doc; -// go to next item - strncpy (my_attribute->clip_begin, "0", 2); - misc->clip_begin = 0; - if (++misc->playing >= misc->total_items) + misc->total_time = 0; + for (x = 0; x < misc->total_items; x++) { - struct passwd *pw; - - pw = getpwuid (geteuid ()); - quit_daisy_player (misc); - snprintf (str, MAX_STR - 1, "%s/.daisy-player/%s%s", pw->pw_dir, - misc->bookmark_title, get_mcn (misc)); - unlink (str); - _exit (0); - } // if - if (daisy[misc->playing].level <= misc->level) - misc->displaying = misc->current = misc->playing; - if (misc->just_this_item != -1) - if (daisy[misc->playing].level <= misc->level) - misc->playing = misc->just_this_item = -1; - if (misc->playing > -1) - open_smil_file (misc, my_attribute, daisy[misc->playing].smil_file, - daisy[misc->playing].anchor); - view_screen (misc, daisy); -} // play_clip + daisy[x].duration = 0; + if (! *daisy[x].clips_file) + continue; + doc = htmlParseFile (daisy[x].clips_file, "UTF-8"); + if (! (parse = xmlReaderWalker (doc))) + { + endwin (); + beep (); + printf ("\n"); + printf (gettext ("Cannot read %s"), daisy[x].clips_file); + printf ("\n"); + fflush (stdout); + _exit (1); + } // if -void skip_left (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy) -{ - struct - { - char src[MAX_STR], clip_begin[MAX_STR], clip_end[MAX_STR]; - } curr, prev, orig; +// parse this smil + if (*daisy[x].clips_anchor) + { + while (1) + { + if (! get_tag_or_label (misc, my_attribute, parse)) + break; + if (strcasecmp (daisy[x].clips_anchor, my_attribute->id) == 0) + break; + } // while + } // if - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - return; - if (misc->playing < 0) - return; - if (misc->player_pid > 0) - while (kill (misc->player_pid, SIGKILL) != 0); - get_clips (misc, my_attribute->clip_begin, my_attribute->clip_end); - if (daisy[misc->playing].begin != misc->clip_begin) - { -// save current values in orig and curr arrays - strncpy (orig.clip_begin, my_attribute->clip_begin, MAX_STR - 1); - strncpy (orig.clip_end, my_attribute->clip_end, MAX_STR - 1); - strncpy (orig.src, my_attribute->src, MAX_STR - 1); - strncpy (curr.clip_begin, my_attribute->clip_begin, MAX_STR - 1); - strncpy (curr.clip_end, my_attribute->clip_end, MAX_STR - 1); - strncpy (curr.src, my_attribute->src, MAX_STR - 1); - open_smil_file (misc, my_attribute, daisy[misc->playing].smil_file, - daisy[misc->playing].anchor); while (1) { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return; - if (strcasecmp (my_attribute->class, "pagenum") == 0) - { - do - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return; - } while (strcasecmp (misc->tag, "/par") != 0); - } // if (strcasecmp (my_attribute->class, "pagenum") == 0) + if (! get_tag_or_label (misc, my_attribute, parse)) + break; +// get misc->clip_begin if (strcasecmp (misc->tag, "audio") == 0) - { - strncpy (prev.clip_begin, curr.clip_begin, MAX_STR - 1); - strncpy (prev.clip_end, curr.clip_end, MAX_STR - 1); - strncpy (prev.src, curr.src, MAX_STR - 1); - strncpy (curr.clip_begin, my_attribute->clip_begin, MAX_STR - 1); - strncpy (curr.clip_end, my_attribute->clip_end, MAX_STR - 1); - strncpy (curr.src, my_attribute->src, MAX_STR - 1); - if (strcasecmp (orig.clip_begin, curr.clip_begin) == 0 && - strcasecmp (orig.src, curr.src) == 0) + { + misc->has_audio_tag = 1; + get_clips (misc, my_attribute); + daisy[x].begin = misc->clip_begin; + daisy[x].duration += misc->clip_end - misc->clip_begin; + +// get clip_end + while (1) { - open_smil_file (misc, my_attribute, daisy[misc->playing].smil_file, - daisy[misc->playing].anchor); - while (1) + if (! get_tag_or_label (misc, my_attribute, parse)) + break; + if (x + 1 < misc->total_items) { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return; - if (strcasecmp (misc->tag , "audio") == 0) + if (*daisy[x + 1].clips_anchor) { - if (strcasecmp (my_attribute->clip_begin, - prev.clip_begin) == 0 && - strcasecmp (my_attribute->src, prev.src) == 0) + if (strcasecmp + (my_attribute->id, daisy[x + 1].clips_anchor) == 0) { - get_clips (misc, my_attribute->clip_begin, - my_attribute->clip_end); - play_now (misc, my_attribute, daisy); - return; - } // if (strcasecmp (my_attribute->clip_begin, prev.cli ... - } // if (strcasecmp (misc->tag , "audio") == 0) - } // while - } // if (strcasecmp (orig.clip_begin, curr.clip_begin) == 0 && + break; + } // if + } // if + } // if + if (strcasecmp (misc->tag, "audio") == 0) + { + get_clips (misc, my_attribute); + daisy[x].duration += misc->clip_end - misc->clip_begin; + } // IF + } // while + if (x < misc->total_items - 1 && *daisy[x + 1].clips_anchor) + if (strcasecmp + (my_attribute->id, daisy[x + 1].clips_anchor) == 0) + break; } // if (strcasecmp (misc->tag, "audio") == 0) } // while - } // if (clip_begin != daisy[misc->playing].begin) - -// go to end of previous item - misc->current = misc->displaying = --misc->playing; - if (misc->current < 0) + misc->total_time += daisy[x].duration; + xmlTextReaderClose (parse); + xmlFreeDoc (doc); + } // for + if (misc->total_time == 0) { beep (); - misc->current = misc->displaying = misc->playing = 0; - return; - } // if - open_smil_file (misc, my_attribute, daisy[misc->current].smil_file, daisy[misc->current].anchor); - while (1) - { -// search last clip - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - break; - if (strcasecmp (my_attribute->class, "pagenum") == 0) - { - do - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return; - } while (strcasecmp (misc->tag, "/par") != 0); - } // if (strcasecmp (my_attribute->class, "pagenum") == 0) - if (strcasecmp (misc->tag, "audio") == 0) - { - strncpy (curr.clip_begin, my_attribute->clip_begin, MAX_STR - 1); - strncpy (curr.clip_end, my_attribute->clip_end, MAX_STR - 1); - strncpy (curr.src, my_attribute->src, MAX_STR - 1); - } // if (strcasecmp (misc->tag, "audio") == 0) - if (strcasecmp (my_attribute->id, daisy[misc->current + 1].anchor) == 0) - break; - } // while - misc->just_this_item = -1; - open_smil_file (misc, my_attribute, daisy[misc->current].smil_file, - daisy[misc->current].anchor); - while (1) - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return; - if (strcasecmp (misc->tag , "audio") == 0) - { - if (strcasecmp (my_attribute->clip_begin, curr.clip_begin) == 0 && - strcasecmp (my_attribute->src, curr.src) == 0) - { - strncpy (misc->current_audio_file, my_attribute->src, MAX_STR - 1); - get_clips (misc, my_attribute->clip_begin, my_attribute->clip_end); - view_screen (misc, daisy); - play_now (misc, my_attribute, daisy); - return; - } // if (strcasecmp (my_attribute->clip_begin, curr.clip_begin) == 0 && - } // if (strcasecmp (misc->tag , "audio") == 0) - } // while -} // skip_left - -void skip_right (misc_t *misc) -{ - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - return; - if (misc->playing == -1) - return; - if (misc->cd_type != CDIO_DISC_MODE_CD_DA) - { - kill (misc->player_pid, SIGKILL); - misc->player_pid = -2; + quit_daisy_player (misc, daisy); + printf ("%s\n", gettext ( + "This book has no audio. Play this book with eBook-speaker")); + _exit (0); } // if -} // skip_right +} // calculate_times_3 void change_level (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, char key) @@ -1062,18 +813,16 @@ void change_level (misc_t *misc, my_attribute_t *my_attribute, if (key == 'L') if (--misc->level < 1) misc->level = misc->depth; - mvwprintw (misc->titlewin, 1, 0, gettext ("Please wait... -------------------------")); + mvwprintw (misc->titlewin, 1, 0, + gettext ("Please wait... -------------------------")); wprintw (misc->titlewin, "----------------------------------------"); wrefresh (misc->titlewin); c = misc->current; l = misc->level; if (strcasestr (misc->daisy_version, "2.02")) - read_daisy_2 (misc, my_attribute, daisy); + fill_daisy_struct_2 (misc, my_attribute, daisy); if (strcasestr (misc->daisy_version, "3")) - { - read_daisy_3 (misc, my_attribute, daisy); - parse_smil_3 (misc, my_attribute, daisy); - } // if + calculate_times_3 (misc, my_attribute, daisy); misc->current = c; misc->level = l; if (daisy[misc->current].level > misc->level) @@ -1082,22 +831,27 @@ void change_level (misc_t *misc, my_attribute_t *my_attribute, wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); } // change_level -void read_rc (misc_t *misc, my_attribute_t *my_attribute) +void read_preferences (misc_t *misc, my_attribute_t *my_attribute) { +// read the preferences from $PWD/.daisy-player.xml char str[MAX_STR]; struct passwd *pw;; xmlTextReaderPtr reader; - xmlDocPtr doc; + htmlDocPtr doc; pw = getpwuid (geteuid ()); - snprintf (str, MAX_STR - 1, "%s/.daisy-player.rc", pw->pw_dir); - doc = xmlRecoverFile (str); + snprintf (str, MAX_STR - 1, "%s/.daisy-player.xml", pw->pw_dir); + if ((doc = htmlParseFile (str, "UTF-8")) == NULL) + { + strncpy (misc->sound_dev, "hw:0", MAX_STR - 1); + return; + } // if if (! (reader = xmlReaderWalker (doc))) { strncpy (misc->sound_dev, "hw:0", MAX_STR - 1); return; } // if - do + do { if (! get_tag_or_label (misc, my_attribute, reader)) break; @@ -1106,16 +860,16 @@ void read_rc (misc_t *misc, my_attribute_t *my_attribute) xmlFreeDoc (doc); if (misc->cddb_flag != 'n' && misc->cddb_flag != 'y') misc->cddb_flag = 'y'; -} // read_rc +} // read_preferences -void save_rc (misc_t *misc) +void save_xml (misc_t *misc) { struct passwd *pw; char str[MAX_STR]; xmlTextWriterPtr writer; pw = getpwuid (geteuid ()); - snprintf (str, MAX_STR - 1, "%s/.daisy-player.rc", pw->pw_dir); + snprintf (str, MAX_STR - 1, "%s/.daisy-player.xml", pw->pw_dir); if (! (writer = xmlNewTextWriterFilename (str, 0))) return; xmlTextWriterStartDocument (writer, NULL, NULL, NULL); @@ -1131,17 +885,21 @@ void save_rc (misc_t *misc) xmlTextWriterEndElement (writer); xmlTextWriterEndDocument (writer); xmlFreeTextWriter (writer); -} // save_rc +} // save_xml -void quit_daisy_player (misc_t *misc) +void quit_daisy_player (misc_t *misc, daisy_t *daisy) { + view_screen (misc, daisy); endwin (); kill (misc->player_pid, SIGKILL); - misc->player_pid = -2; + if (misc->cd_type == CDIO_DISC_MODE_CD_DA) + kill (misc->cdda_pid, SIGKILL); put_bookmark (misc); - save_rc (misc); + save_xml (misc); close (misc->tmp_wav_fd); + unlink (misc->tmp_wav); puts (""); + remove_tmp_dir (misc); } // quit_daisy_player void search (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, @@ -1149,23 +907,28 @@ void search (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, { int c, found = 0, flag = 0; - if (misc->playing != -1) + if (misc->playing > -1) { + kill (misc->player_pid, SIGKILL); + misc->player_pid = -2; + misc->playing = misc->just_this_item = -1; + view_screen (misc, daisy); flag = 1; - pause_resume (misc, my_attribute, daisy); } // if if (mode == '/') { + misc->playing = misc->just_this_item = -1; mvwprintw (misc->titlewin, 1, 0, "----------------------------------------"); wprintw (misc->titlewin, "----------------------------------------"); - mvwprintw (misc->titlewin, 1, 0, gettext ("What do you search? ")); + mvwprintw (misc->titlewin, 1, 0, "%s ", + gettext ("What do you search?")); echo (); wgetnstr (misc->titlewin, misc->search_str, 25); noecho (); } // if if (mode == '/' || mode == 'n') { - for (c = start; c <= misc->total_items + 1; c++) + for (c = start; c < misc->total_items; c++) { if (strcasestr (daisy[c].label, misc->search_str)) { @@ -1197,7 +960,7 @@ void search (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, } // for if (! found) { - for (c = misc->total_items + 1; c > start; c--) + for (c = misc->total_items - 1; c > start; c--) { if (strcasestr (daisy[c].label, misc->search_str)) { @@ -1209,9 +972,10 @@ void search (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, } // if if (found) { - misc->playing = misc->displaying= misc->current = c; + misc->playing = misc->displaying = misc->current = c; misc->clip_begin = daisy[misc->current].begin; misc->just_this_item = -1; + misc->current_page_number = daisy[misc->current].page_number; view_screen (misc, daisy); if (misc->cd_type == CDIO_DISC_MODE_CD_DA) { @@ -1220,8 +984,8 @@ void search (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, daisy[misc->current].first_lsn); } else - open_smil_file (misc, my_attribute, daisy[misc->current].smil_file, - daisy[misc->current].anchor); + open_clips_file (misc, my_attribute, daisy[misc->current].clips_file, + daisy[misc->current].clips_anchor); } else { @@ -1237,159 +1001,28 @@ void search (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, } else { - skip_left (misc, my_attribute, daisy); - skip_right (misc); + pause_resume (misc, my_attribute, daisy); } // if } // if } // search -void go_to_page_number (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy) -{ - char filename[MAX_STR], *anchor = 0; - char pn[15], href[MAX_STR], prev_href[MAX_STR]; - - kill (misc->player_pid, SIGKILL); - misc->player_pid = -2; - mvwprintw (misc->titlewin, 1, 0, "----------------------------------------"); - wprintw (misc->titlewin, "----------------------------------------"); - mvwprintw (misc->titlewin, 1, 0, gettext ("Go to page number: ")); - echo (); - wgetnstr (misc->titlewin, pn, 5); - noecho (); - view_screen (misc, daisy); - if (! *pn || atoi (pn) > misc->total_pages || ! atoi (pn)) - { - beep (); - skip_left (misc, my_attribute, daisy); - skip_right (misc); - return; - } // if - if (strcasestr (misc->daisy_version, "2.02")) - { - xmlTextReaderClose (misc->reader); - xmlDocPtr doc = xmlRecoverFile (misc->NCC_HTML); - if (! (misc->reader = xmlReaderWalker (doc))) - { - int e; - char str[MAX_STR]; - - e = errno; - snprintf (str, MAX_STR, gettext ("Cannot read %s"), misc->NCC_HTML); - failure (str, e); - } // if - *href = 0; - while (1) - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return; - if (strcasecmp (misc->tag, "a") == 0) - { - strncpy (prev_href, href, MAX_STR - 1); - strncpy (href, my_attribute->href, MAX_STR - 1); - do - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return; - } while (! *misc->label); - if (strcasecmp (misc->label, pn) == 0) - break; - } // if (strcasecmp (misc->tag, "a") == 0) - } // while - if (*prev_href) - { - strncpy (filename, prev_href, MAX_STR - 1); - if (strchr (filename, '#')) - { - anchor = strdup (strchr (filename, '#') + 1); - *strchr (filename, '#') = 0; - } // if - } // if (*prev_href) - for (misc->current = misc->total_items - 1; misc->current >= 0; misc->current--) - { - if (! daisy[misc->current].page_number) - continue; - if (atoi (pn) >= daisy[misc->current].page_number) - break; - } // for - misc->playing = misc->displaying = misc->current; - view_screen (misc, daisy); - misc->current_page_number = atoi (pn); - wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); - misc->just_this_item = -1; - open_smil_file (misc, my_attribute, daisy[misc->current].smil_file, anchor); - free (anchor); - return; - } // if (strcasestr (misc->daisy_version, "2.02")) - - if (strcasestr (misc->daisy_version, "3")) - { - char *anchor = 0; - - xmlTextReaderClose (misc->reader); - xmlDocPtr doc = xmlRecoverFile (misc->NCC_HTML); - if (! (misc->reader = xmlReaderWalker (doc))) - { - int e; - char str[MAX_STR]; - - e = errno; - snprintf (str, MAX_STR, gettext ("Cannot read %s"), misc->NCC_HTML); - failure (str, e); - } // if - do - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - { - xmlFreeDoc (doc); - return; - } // if - } while (strcasecmp (misc->tag, "pageTarget") != 0 || - strcasecmp (my_attribute->value, pn) != 0); - do - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - { - xmlTextReaderClose (misc->reader); - xmlFreeDoc (doc); - return; - } // if - } while (strcasecmp (misc->tag, "content") != 0); - xmlFreeDoc (doc); - if (strchr (my_attribute->src, '#')) - { - anchor = strdup (strchr (my_attribute->src, '#') + 1); - *strchr (my_attribute->src, '#') = 0; - } // if - // search current item - for (misc->current = misc->total_items - 1; misc->current >= 0; misc->current--) - { - if (! daisy[misc->current].page_number) - continue; - if (atoi (pn) >= daisy[misc->current].page_number) - break; - } // for - misc->playing = misc->displaying = misc->current; - view_screen (misc, daisy); - misc->current_page_number = atoi (pn); - wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); - misc->just_this_item = -1; - open_smil_file (misc, my_attribute, my_attribute->src, anchor); - } // if (strcasestr (misc->daisy_version, "3")) -} // go_to_page_number - void go_to_time (misc_t *misc, daisy_t *daisy, my_attribute_t *my_attribute) { char time_str[10]; int secs; kill (misc->player_pid, SIGKILL); - misc->player_pid = -2; + if (misc->cd_type != CDIO_DISC_MODE_CD_DA) + misc->player_pid = -2; + misc->just_this_item = -1; + misc->playing = misc->displaying = misc->current; + view_screen (misc, daisy); mvwprintw (misc->titlewin, 1, 0, "----------------------------------------"); wprintw (misc->titlewin, "----------------------------------------"); while (1) { - mvwprintw (misc->titlewin, 1, 0, gettext ("Go to time (MM:SS): ")); + mvwprintw (misc->titlewin, 1, 0, "%s ", + gettext ("Go to time (MM:SS):")); echo (); wgetnstr (misc->titlewin, time_str, 5); noecho (); @@ -1420,78 +1053,21 @@ void go_to_time (misc_t *misc, daisy_t *daisy, my_attribute_t *my_attribute) misc->player_pid = play_track (misc, misc->sound_dev, "alsa", daisy[misc->current].first_lsn + (secs * 75)); misc->elapsed_seconds = time (NULL) - secs; - } - else - { - misc->clip_begin = 0; - open_smil_file (misc, my_attribute, daisy[misc->current].smil_file, - daisy[misc->current].anchor); - do - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - break; - if (strcasecmp (misc->tag, "audio") == 0) - { - get_clips (misc, my_attribute->clip_begin, - my_attribute->clip_end); - } // if - } while (misc->clip_begin / misc->speed < secs); - skip_left (misc, my_attribute, daisy); + misc->prev_id = strdup (misc->current_id); + return; } // if - misc->playing = misc->displaying = misc->current; -} // go_to_time -void select_next_output_device (misc_t *misc, daisy_t *daisy) -{ - FILE *r; - int n, y; - size_t bytes; - char *list[10], *trash; - - wclear (misc->screenwin); - wprintw (misc->screenwin, "\n%s\n\n", gettext ("Select a soundcard:")); - if (! (r = fopen ("/proc/asound/cards", "r"))) - failure (gettext ("Cannot read /proc/asound/cards"), errno); - for (n = 0; n < 10; n++) - { - list[n] = (char *) malloc (1000); - bytes = getline (&list[n], &bytes, r); - if ((int) bytes == -1) - break; - trash = (char *) malloc (1000); - bytes = getline (&trash, &bytes, r); - free (trash); - wprintw (misc->screenwin, " %s", list[n]); - free (list[n]); - } // for - fclose (r); - y = 3; - nodelay (misc->screenwin, FALSE); - for (;;) + misc->clip_begin = 0; + open_clips_file (misc, my_attribute, daisy[misc->current].clips_file, + daisy[misc->current].clips_anchor); + misc->current_id = strdup (daisy[misc->current].first_id); + do { - wmove (misc->screenwin, y, 2); - switch (wgetch (misc->screenwin)) - { - case 13: - snprintf (misc->sound_dev, 15, "hw:%i", y - 3); - view_screen (misc, daisy); - nodelay (misc->screenwin, TRUE); - return; - case KEY_DOWN: - if (++y == n + 3) - y = 3; - break; - case KEY_UP: - if (--y == 2) - y = n + 2; - break; - default: - view_screen (misc, daisy); - nodelay (misc->screenwin, TRUE); - return; - } // switch - } // for -} // select_next_output_device + get_next_clips (misc, my_attribute, daisy); + } while (misc->clip_begin / misc->speed < secs); + start_playing (misc, daisy); + view_screen (misc, daisy); +} // go_to_time void browse (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy, char *wd) @@ -1499,6 +1075,14 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, int old_screen, i; char str[MAX_STR]; + for (misc->current = 0; misc->current < misc->total_items; misc->current++) + { + daisy[misc->current].screen = misc->current / misc->max_y; + daisy[misc->current].y = + misc->current - daisy[misc->current].screen * misc->max_y; + if (strlen (daisy[misc->current].label) + daisy[misc->current].x > 60) + daisy[misc->current].label[60 - daisy[misc->current].x] = 0; + } // for misc->current = 0; misc->pause_resume_playing = misc->just_this_item = -1; misc->label_len = 0; @@ -1511,10 +1095,21 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, daisy[i].page_number = 0; } // for misc->depth = 1; + misc->player_pid = play_track (misc, misc->sound_dev, "alsa", + daisy[misc->current].first_lsn + (misc->seconds * 75)); + misc->elapsed_seconds = time (NULL) - misc->seconds; } // if view_screen (misc, daisy); nodelay (misc->screenwin, TRUE); wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); + if (misc->cd_type != CDIO_DISC_MODE_CD_DA && misc->has_audio_tag == 0) + { + beep (); + quit_daisy_player (misc, daisy); + printf ("%s\n", gettext ( + "This book has no audio. Play this book with eBook-speaker")); + _exit (0); + } // if for (;;) { @@ -1524,6 +1119,7 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, misc->just_this_item = -1; view_screen (misc, daisy); misc->playing = misc->displaying = misc->current; + misc->current_id = strdup (""); misc->current_page_number = daisy[misc->playing].page_number; if (misc->player_pid > -1) kill (misc->player_pid, SIGKILL); @@ -1548,7 +1144,7 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, default: break; } // switch - quit_daisy_player (misc); + quit_daisy_player (misc, daisy); _exit (0); } // if if (misc->cd_type == CDIO_DISC_MODE_CD_DA) @@ -1556,18 +1152,16 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, misc->player_pid = play_track (misc, misc->sound_dev, "alsa", daisy[misc->current].first_lsn); misc->elapsed_seconds = time (NULL); - } - else - { - open_smil_file (misc, my_attribute, - daisy[misc->current].smil_file, - daisy[misc->current].anchor); - misc->elapsed_seconds = time (NULL); + break; } // if + open_clips_file (misc, my_attribute, + daisy[misc->current].clips_file, + daisy[misc->current].clips_anchor); + misc->elapsed_seconds = time (NULL); break; case '/': if (misc->discinfo) - { + { beep (); break; } // if @@ -1590,6 +1184,7 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, break; } // if store_to_disk (misc, my_attribute, daisy); + view_screen (misc, daisy); break; case 'e': case '.': @@ -1600,19 +1195,14 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, break; } // if xmlTextReaderClose (misc->reader); - quit_daisy_player (misc); + quit_daisy_player (misc, daisy); while (kill (misc->player_pid, 0) == 0); - if (chdir ("/") == 0) + snprintf (misc->cmd, MAX_CMD, "eject -pm %s", misc->cd_dev); + switch (system (misc->cmd)) { - char cmd[MAX_CMD + 1]; - - snprintf (cmd, MAX_CMD, "eject %s", misc->cd_dev); - switch (system (cmd)) - { - default: - _exit (0); - } // switch - } // if + default: + break; + } // switch _exit (0); case 'f': if (misc->playing == -1) @@ -1628,6 +1218,11 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, go_to_time (misc, daisy, my_attribute); break; case 'G': + if (misc->discinfo) + { + beep (); + break; + } // if if (misc->total_pages) go_to_page_number (misc, my_attribute, daisy); else @@ -1635,30 +1230,8 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, break; case 'h': case '?': - { - int flag = 0; - - if (misc->playing < 0) - flag = 1; - if (! misc->discinfo) - pause_resume (misc, my_attribute, daisy); - misc->player_pid = -2; - help (misc, daisy); - if (flag) - break; - misc->playing = misc->displaying; - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - { - misc->playing = -1; - pause_resume (misc, my_attribute, daisy); - } - else - { - skip_left (misc, my_attribute, daisy); - skip_right (misc); - } // if + help (misc, my_attribute, daisy); break; - } case 'j': case '5': case KEY_B2: @@ -1674,7 +1247,8 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, mvwprintw (misc->screenwin, daisy[misc->displaying].y, 0, " "); if (misc->playing == -1) { - misc->just_this_item = misc->displaying = misc->playing = misc->current; + misc->just_this_item = misc->displaying = misc->playing = + misc->current; kill (misc->player_pid, SIGKILL); misc->player_pid = -2; if (misc->cd_type == CDIO_DISC_MODE_CD_DA) @@ -1683,8 +1257,9 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, daisy[misc->current].first_lsn); } else - open_smil_file (misc, my_attribute, - daisy[misc->current].smil_file, daisy[misc->current].anchor); + open_clips_file (misc, my_attribute, + daisy[misc->current].clips_file, + daisy[misc->current].clips_anchor); } // if wattron (misc->screenwin, A_BOLD); if (misc->just_this_item != -1 && @@ -1729,38 +1304,22 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, search (misc, my_attribute, daisy, misc->current - 1, 'N'); break; case 'o': - pause_resume (misc, my_attribute, daisy); - select_next_output_device (misc, daisy); - misc->playing = misc->displaying; - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - { - misc->playing = -1; - pause_resume (misc, my_attribute, daisy); - } - else - { - skip_left (misc, my_attribute, daisy); - skip_right (misc); - } // if + select_next_output_device (misc, my_attribute, daisy); break; case 'p': put_bookmark (misc); break; case 'q': - quit_daisy_player (misc); + quit_daisy_player (misc, daisy); _exit (0); case 's': - if (misc->cd_type == CDIO_DISC_MODE_CD_DA) - kill (misc->player_pid, SIGKILL); - else - { - kill (misc->player_pid, SIGKILL); + kill (misc->player_pid, SIGKILL); + if (misc->cd_type != CDIO_DISC_MODE_CD_DA) misc->player_pid = -2; - } // if misc->playing = misc->just_this_item = -1; - misc->phrase_nr = 0; view_screen (misc, daisy); - wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); + wmove (misc->screenwin, daisy[misc->current].y, + daisy[misc->current].x); break; case KEY_DOWN: case '2': @@ -1799,7 +1358,7 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, struct passwd *pw; pw = getpwuid (geteuid ()); - quit_daisy_player (misc); + quit_daisy_player (misc, daisy); snprintf (str, MAX_STR - 1, "%s/.daisy-player/%s%s", pw->pw_dir, misc->bookmark_title, get_mcn (misc)); unlink (str); @@ -1810,7 +1369,7 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, misc->lsn_cursor); break; } // if - skip_right (misc); + skip_right (misc, daisy); break; case KEY_LEFT: case '4': @@ -1823,7 +1382,7 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, if (misc->playing > 0) if (misc->just_this_item > -1) misc->lsn_cursor = daisy[misc->playing].first_lsn; - else + else misc->current = misc->displaying = --misc->playing; else if (misc->lsn_cursor < daisy[misc->playing].first_lsn) @@ -1845,7 +1404,8 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, old_screen = daisy[misc->current].screen; while (daisy[++misc->current].screen == old_screen); view_screen (misc, daisy); - wmove (misc->screenwin, daisy[misc->current].y, daisy[misc->current].x); + wmove (misc->screenwin, daisy[misc->current].y, + daisy[misc->current].x); break; case KEY_PPAGE: case '9': @@ -1869,17 +1429,18 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, beep (); break; } // if + pause_resume (misc, my_attribute, daisy); misc->speed += 0.1; if (misc->cd_type == CDIO_DISC_MODE_CD_DA) { kill (misc->player_pid, SIGKILL); - misc->player_pid = + misc->player_pid = play_track (misc, misc->sound_dev, "alsa", misc->lsn_cursor); + pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); break; } // if - skip_left (misc, my_attribute, daisy); - kill (misc->player_pid, SIGKILL); + pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); break; case 'D': @@ -1889,47 +1450,79 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, beep (); break; } // if + pause_resume (misc, my_attribute, daisy); misc->speed -= 0.1; if (misc->cd_type == CDIO_DISC_MODE_CD_DA) { kill (misc->player_pid, SIGKILL); misc->player_pid = play_track (misc, misc->sound_dev, "alsa", misc->lsn_cursor); + pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); break; } // if - skip_left (misc, my_attribute, daisy); - kill (misc->player_pid, SIGKILL); + pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); break; case KEY_HOME: case '*': - case '7': + pause_resume (misc, my_attribute, daisy); misc->speed = 1; if (misc->cd_type == CDIO_DISC_MODE_CD_DA) { - kill (misc->player_pid, SIGKILL); misc->player_pid = play_track (misc, misc->sound_dev, "alsa", misc->lsn_cursor); + pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); break; } // if - kill (misc->player_pid, SIGKILL); - skip_left (misc, my_attribute, daisy); - skip_right (misc); + pause_resume (misc, my_attribute, daisy); view_screen (misc, daisy); break; + case 'v': + case '1': + if (misc->volume <= 0) + { + beep (); + break; + } // if + misc->volume -= 0.1; + if (misc->playing == -1) + break; + pause_resume (misc, my_attribute, daisy); + pause_resume (misc, my_attribute, daisy); + break; + case 'V': + case '7': + if (misc->volume >= 3) + { + beep (); + break; + } // if + misc->volume += 0.1; + if (misc->playing == -1) + break; + pause_resume (misc, my_attribute, daisy); + pause_resume (misc, my_attribute, daisy); + break; default: beep (); break; } // switch - + if (misc->playing > -1 && misc->cd_type != CDIO_DISC_MODE_CD_DA) { - play_clip (misc, my_attribute, daisy); + if (kill (misc->player_pid, 0) != 0) + { +// if not playing + misc->player_pid = -2; + misc->prev_id = strdup (misc->audio_id); + get_next_clips (misc, my_attribute, daisy); + start_playing (misc, daisy); + view_screen (misc, daisy); + } // if view_time (misc, daisy); } // if - if (misc->playing == -1 || misc->cd_type != CDIO_DISC_MODE_CD_DA) { fd_set rfds; @@ -1942,7 +1535,6 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, // pause till a key has been pressed or 0.1 misc->elapsed_seconds are elapsed select (1, &rfds, NULL, NULL, &tv); } // if - if (misc->playing > -1 && misc->cd_type == CDIO_DISC_MODE_CD_DA) { int16_t *p_readbuf; @@ -1964,7 +1556,7 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, struct passwd *pw; pw = getpwuid (geteuid ()); - quit_daisy_player (misc); + quit_daisy_player (misc, daisy); snprintf (str, MAX_STR - 1, "%s/.daisy-player/%s%s", pw->pw_dir, misc->bookmark_title, get_mcn (misc)); unlink (str); @@ -1985,12 +1577,13 @@ void browse (misc_t *misc, my_attribute_t *my_attribute, void usage () { + beep (); printf (gettext ("Daisy-player - Version %s %s"), PACKAGE_VERSION, "\n"); - puts ("(C)2003-2015 J. Lemmens"); - printf (gettext ( - "%sUsage: %s [[directory_with_a_Daisy-structure | Daisy_book_archive]] "), - "\n", PACKAGE); - printf ("%s\n", gettext ("[-c cdrom_device] [-d ALSA_sound_device]")); + puts ("(C)2003-2017 J. Lemmens\n"); + printf (gettext + ("Usage: %s [directory_with_a_Daisy-structure] | [Daisy_book_archive]"), + PACKAGE); + printf ("\n%s ", gettext ("[-c cdrom_device] [-d ALSA_sound_device]")); printf ("[-i] [-n | -y]\n"); fflush (stdout); _exit (1); @@ -2003,7 +1596,7 @@ char *get_mount_point (misc_t *misc) char *str = NULL; if (! (proc = fopen ("/proc/mounts", "r"))) - failure (gettext ("Cannot read /proc/mounts."), errno); + failure (misc, gettext ("Cannot read /proc/mounts."), errno); while (1) { str = malloc (len + 1); @@ -2013,14 +1606,13 @@ char *get_mount_point (misc_t *misc) break; } // while fclose (proc); - if (strcasestr (str, "iso9660") || strcasestr (str, "udf")) + if (strcasestr (str, "iso9660") || + strcasestr (str, "udf")) { - strncpy (misc->daisy_mp, strchr (str, ' ') + 1, MAX_STR - 1); + misc->daisy_mp = strdup (strchr (str, ' ') + 1); *strchr (misc->daisy_mp, ' ') = 0; - free (str); return misc->daisy_mp; } // if - free (str); return NULL; } // get_mount_point @@ -2030,9 +1622,9 @@ void handle_discinfo (misc_t *misc, my_attribute_t *my_attribute, int h, m, s; float t = 0; xmlTextReaderPtr di, ncc; - xmlDocPtr doc; + htmlDocPtr doc; - doc = xmlRecoverFile (discinfo_html); + doc = htmlParseFile (discinfo_html, "UTF-8"); if (! (di = xmlReaderWalker (doc))) { int e; @@ -2040,7 +1632,7 @@ void handle_discinfo (misc_t *misc, my_attribute_t *my_attribute, e = errno; snprintf (str, MAX_STR, gettext ("Cannot read %s"), discinfo_html); - failure (str, e); + failure (misc, str, e); } // if (! (di = xmlReaderWalker (doc) while (1) { @@ -2057,8 +1649,10 @@ void handle_discinfo (misc_t *misc, my_attribute_t *my_attribute, } // if (strcasecmp (misc->tag, "title") == 0) if (strcasecmp (misc->tag, "a") == 0) { - strncpy (daisy[misc->current].filename, my_attribute->href, MAX_STR - 1); - xmlDocPtr doc = xmlRecoverFile (daisy[misc->current].filename); + strncpy (daisy[misc->current].filename, my_attribute->href, + MAX_STR - 1); + htmlDocPtr doc = + htmlParseFile (daisy[misc->current].filename, "UTF-8"); if (! (ncc = xmlReaderWalker (doc))) { int e; @@ -2067,7 +1661,7 @@ void handle_discinfo (misc_t *misc, my_attribute_t *my_attribute, e = errno; snprintf (str, MAX_STR, gettext ("Cannot read %s"), daisy[misc->current].filename); - failure (str, e); + failure (misc, str, e); } // if do { @@ -2084,9 +1678,9 @@ void handle_discinfo (misc_t *misc, my_attribute_t *my_attribute, if (! get_tag_or_label (misc, my_attribute, di)) break; } while (! *misc->label); - strncpy (daisy[misc->current].label, misc->label, 80); - strncpy (daisy[misc->current].daisy_mp, dirname (daisy[misc->current].filename), - MAX_STR - 1); + *daisy[misc->current].label = 0; + strncpy (daisy[misc->current].daisy_mp, + dirname (daisy[misc->current].filename), MAX_STR - 1); daisy[misc->current].level = 1; daisy[misc->current].x = 0; daisy[misc->current].y = misc->displaying; @@ -2112,30 +1706,42 @@ void handle_discinfo (misc_t *misc, my_attribute_t *my_attribute, int main (int argc, char *argv[]) { int opt; - char str[MAX_STR], DISCINFO_HTML[MAX_STR], start_wd[MAX_STR]; + char str[MAX_STR], DISCINFO_HTML[MAX_STR], *start_wd; misc_t misc; my_attribute_t my_attribute; - daisy_t *daisy = NULL; + daisy_t *daisy; + struct sigaction usr_action; - misc.daisy_player_pid = getpid (); - misc.speed = 1; + daisy = NULL; + misc.tmp_dir = misc.label = NULL; + misc.speed = misc.volume = 1; misc.playing = misc.just_this_item = -1; misc.discinfo = 0; misc.cd_type = -1; misc.ignore_bookmark = 0; + *misc.bookmark_title = 0; + misc.current_id = strdup (""); + misc.prev_id = misc.audio_id = strdup (""); + misc.total_time = 0; + *misc.daisy_title = 0; + *misc.ncc_html = 0; strncpy (misc.cd_dev, "/dev/sr0", 15); - signal (SIGCHLD, player_ended); - read_rc (&misc, &my_attribute); + usr_action.sa_handler = player_ended; + usr_action.sa_flags = 0; + sigaction (SIGCHLD, &usr_action, NULL); + read_preferences (&misc, &my_attribute); if (! setlocale (LC_ALL, "")) - failure ("setlocale ()", errno); + failure (&misc, "setlocale ()", errno); if (! setlocale (LC_NUMERIC, "C")) - failure ("setlocale ()", errno); + failure (&misc, "setlocale ()", errno); textdomain (PACKAGE); snprintf (str, MAX_STR, "%s/", LOCALEDIR); bindtextdomain (PACKAGE, str); - strncpy (start_wd, get_current_dir_name (), MAX_STR - 1); + make_tmp_dir (&misc); + start_wd = strdup (get_current_dir_name ()); opterr = 0; - while ((opt = getopt (argc, argv, "c:d:iny")) != -1) + misc.use_OPF = misc.use_NCX = 0; + while ((opt = getopt (argc, argv, "c:d:ijnyON")) != -1) { switch (opt) { @@ -2163,26 +1769,51 @@ int main (int argc, char *argv[]) misc.cddb_flag = 'n'; } // switch break; + case 'N': + misc.use_NCX = 1; + break; + case 'O': + misc.use_OPF = 1; + break; default: + beep (); + remove_tmp_dir (&misc); usage (); } // switch } // while initscr (); if (! (misc.titlewin = newwin (2, 80, 0, 0)) || ! (misc.screenwin = newwin (23, 80, 2, 0))) - failure ("No curses", errno); + failure (&misc, "No curses", errno); fclose (stderr); getmaxyx (misc.screenwin, misc.max_y, misc.max_x); - printw ("(C)2003-2015 J. Lemmens\n"); + printw ("(C)2003-2017 J. Lemmens\n"); printw (gettext ("Daisy-player - Version %s %s"), PACKAGE_VERSION, ""); printw ("\n"); printw (gettext ("A parser to play Daisy CD's with Linux")); printw ("\n"); printw (gettext ("Scanning for a Daisy CD...")); refresh (); + misc.total_pages = 0; + if (argv[optind]) // if there is an argument { +// look if arg exists + if (access (argv[optind], R_OK) == -1) + { + int e; + + e = errno; + endwin (); + printf (gettext ("Daisy-player - Version %s %s"), + PACKAGE_VERSION, "\n"); + puts ("(C)2003-2017 J. Lemmens"); + beep (); + remove_tmp_dir (&misc); + failure (&misc, argv[optind], e); + } // if + // determine filetype magic_t myt; @@ -2197,14 +1828,29 @@ int main (int argc, char *argv[]) printf ("%s: %s\n", argv[optind], strerror (e)); beep (); fflush (stdout); + remove_tmp_dir (&misc); usage (); } // if if (strcasestr (magic_file (myt, argv[optind]), "directory")) { - strncpy (misc.daisy_mp, argv[optind], MAX_STR - 1); - } + if (*argv[optind] == '/') + { +// absolute path + misc.daisy_mp = strdup (argv[optind]); + } + else + { +// relative path + misc.daisy_mp = malloc (strlen (start_wd) + + strlen (argv[optind]) + 5); + strcpy (misc.daisy_mp, start_wd); + strcat (misc.daisy_mp, "/"); + strcat (misc.daisy_mp, argv[optind]); + } // if + } // directory else if (strcasestr (magic_file (myt, argv[optind]), "Zip archive") || + strcasestr (magic_file (myt, argv[optind]), "tar archive") || strcasestr (magic_file (myt, argv[optind]), "RAR archive data") || strcasestr (magic_file (myt, argv[optind]), "Microsoft Cabinet archive data") || @@ -2212,38 +1858,36 @@ int main (int argc, char *argv[]) "gzip compressed data") || strcasestr (magic_file (myt, argv[optind]), "bzip2 compressed data") || - strcasestr (magic_file (myt, argv[optind]), "ISO 9660")) + strcasestr (magic_file (myt, argv[optind]), "ISO 9660") || + strcasestr (magic_file (myt, argv[optind]), "EPUB document")) { - char *str, cmd[MAX_CMD]; - - str = strdup ("/tmp/daisy-player.XXXXXX"); - if (! mkdtemp (str)) - failure ("mkdtemp ()", errno); - snprintf (cmd, MAX_CMD - 1, "unar \"%s\" -o %s > /dev/null", - argv[optind], str); - switch (system (cmd)) + snprintf (misc.cmd, MAX_CMD - 1, + "/usr/bin/unar \"%s\" -o %s > /dev/null", + argv[optind], misc.tmp_dir); + switch (system (misc.cmd)) { default: break; } // switch - wrefresh (misc.screenwin); DIR *dir; struct dirent *dirent; int entries = 0; - if (! (dir = opendir (str))) - failure (str, errno); + if (! (dir = opendir (misc.tmp_dir))) + failure (&misc, misc.tmp_dir, errno); while ((dirent = readdir (dir)) != NULL) { if (strcasecmp (dirent->d_name, ".") == 0 || strcasecmp (dirent->d_name, "..") == 0) continue; - snprintf (misc.daisy_mp, MAX_STR - 1, "%s/%s", str, dirent->d_name); + misc.daisy_mp = + malloc (strlen (misc.tmp_dir) + strlen (dirent->d_name) + 5); + sprintf (misc.daisy_mp, "%s/%s", misc.tmp_dir, dirent->d_name); entries++; } // while if (entries > 1) - snprintf (misc.daisy_mp, MAX_STR - 1, "%s", str); + misc.daisy_mp = strdup (misc.tmp_dir); closedir (dir); } // if unar else @@ -2251,6 +1895,7 @@ int main (int argc, char *argv[]) endwin (); printf ("\n%s\n", gettext ("No DAISY-CD or Audio-cd found")); beep (); + remove_tmp_dir (&misc); usage (); } // if magic_close (myt); @@ -2258,35 +1903,41 @@ int main (int argc, char *argv[]) else // try misc.cd_dev { - if (access (misc.cd_dev, R_OK) != 0) - failure (misc.cd_dev, errno); - - char cmd[MAX_CMD], *tmp; time_t start; CdIo_t *cd; - snprintf (cmd, MAX_CMD, "eject -t %s", misc.cd_dev); - switch (system (cmd)) + snprintf (misc.cmd, MAX_CMD, "eject -tp %s", misc.cd_dev); + switch (system (misc.cmd)) { default: break; } // switch start = time (NULL); - tmp = strdup ("/tmp/daisy-player.XXXXXX"); - strncpy (misc.daisy_mp, mkdtemp (tmp), MAX_STR); + + misc.daisy_mp = strdup (misc.cd_dev); cd = NULL; cdio_init (); do { - if (time (NULL) - start >= 30) - failure (gettext ("No Daisy CD in drive."), errno); + if (time (NULL) - start >= 60) + { + endwin (); + printf ("%s\n", gettext ("No Daisy CD in drive.")); + remove_tmp_dir (&misc); + _exit (0); + } // if cd = cdio_open (misc.cd_dev, DRIVER_UNKNOWN); } while (cd == NULL); start = time (NULL); do { - if (time (NULL) - start >= 30) - failure (gettext ("No Daisy CD in drive."), errno); + if (time (NULL) - start >= 20) + { + endwin (); + printf ("%s\n", gettext ("No Daisy CD in drive.")); + remove_tmp_dir (&misc); + _exit (0); + } // if switch (misc.cd_type = cdio_get_discmode (cd)) { case CDIO_DISC_MODE_CD_DATA: /**< CD-ROM form 1 */ @@ -2307,12 +1958,18 @@ int main (int argc, char *argv[]) do // if not found a mounted cd, try to mount one { - if (time (NULL) - start >= 30) - failure (gettext ("No Daisy CD in drive."), errno); - snprintf (cmd, MAX_CMD, + if (time (NULL) - start >= 10) + { + endwin (); + printf ("%s\n", gettext ("No Daisy CD in drive.")); + remove_tmp_dir (&misc); + _exit (0); + } // if + snprintf (misc.cmd, MAX_CMD, "udisksctl mount -b %s > /dev/null", misc.cd_dev); - switch (system (cmd)) + switch (system (misc.cmd)) { + default: break; } // switch get_mount_point (&misc); @@ -2322,7 +1979,7 @@ int main (int argc, char *argv[]) case CDIO_DISC_MODE_CD_DA: /**< CD-DA */ { // probably an Audio-CD - printw ("\n%s", gettext ("Found an Audio-CD. ")); + printw ("\n%s ", gettext ("Found an Audio-CD.")); if (misc.cddb_flag == 'y') printw (gettext ("Get titles from freedb.freedb.org...")); refresh (); @@ -2331,15 +1988,18 @@ int main (int argc, char *argv[]) init_paranoia (&misc); daisy = get_number_of_tracks (&misc); get_toc_audiocd (&misc, daisy); - strncpy (misc.daisy_mp, "/tmp", MAX_STR - 1); + misc.daisy_mp = strdup ("/tmp"); break; } // TRACK_COUNT_AUDIO case CDIO_DISC_MODE_CD_I: case CDIO_DISC_MODE_DVD_OTHER: case CDIO_DISC_MODE_NO_INFO: case CDIO_DISC_MODE_ERROR: - failure (gettext ("No DAISY-CD or Audio-cd found"), errno); - } // switch + endwin (); + printf ("%s\n", gettext ("No DAISY-CD or Audio-cd found")); + remove_tmp_dir (&misc); + return 0; + } // switch } while (misc.cd_type == -1); } // if use misc.cd_dev keypad (misc.screenwin, TRUE); @@ -2354,36 +2014,37 @@ int main (int argc, char *argv[]) e = errno; snprintf (str, MAX_STR, "daisy_mp %s", misc.daisy_mp); - failure (str, e); + remove_tmp_dir (&misc); + failure (&misc, str, e); } // if if (misc.cd_type != CDIO_DISC_MODE_CD_DA) { - daisy = create_daisy_struct (&misc, &my_attribute); + daisy = create_daisy_struct (&misc, &my_attribute, daisy); snprintf (DISCINFO_HTML, MAX_STR - 1, "discinfo.html"); if (access (DISCINFO_HTML, R_OK) == 0) handle_discinfo (&misc, &my_attribute, daisy, DISCINFO_HTML); if (! misc.discinfo) { - snprintf (misc.NCC_HTML, MAX_STR - 1, "ncc.html"); - if (access (misc.NCC_HTML, R_OK) == 0) + misc.has_audio_tag = 0; + if (access (misc.ncc_html, R_OK) == 0) { - xmlDocPtr doc; +// this is daisy2 + htmlDocPtr doc; - doc = xmlRecoverFile (misc.NCC_HTML); + doc = htmlParseFile (misc.ncc_html, "UTF-8"); if (! (misc.reader = xmlReaderWalker (doc))) { int e; - char str[MAX_STR]; - e = errno; - snprintf (str, MAX_STR, - gettext ("Cannot read %s"), misc.NCC_HTML); - failure (str, e); + snprintf (misc.str, MAX_STR, + gettext ("Cannot read %s"), misc.ncc_html); + remove_tmp_dir (&misc); + failure (&misc, misc.str, e); } // if while (1) { if (*misc.bookmark_title) - // if misc.bookmark_title already is set +// if misc.bookmark_title already is set break; if (! get_tag_or_label (&misc, &my_attribute, misc.reader)) break; @@ -2398,21 +2059,58 @@ int main (int argc, char *argv[]) } // if } // if } // while - read_daisy_2 (&misc, &my_attribute, daisy); + fill_daisy_struct_2 (&misc, &my_attribute, daisy); } else { - read_daisy_3 (&misc, &my_attribute, daisy); +// this is daisy3 + int i; + strncpy (misc.daisy_version, "3", 2); + read_daisy_3 (&misc, &my_attribute, daisy); + for (i = 0; i < misc.total_items - 1; i++) + { + htmlDocPtr doc; + xmlTextReaderPtr last; + + if (! (doc = htmlParseFile (daisy[i].xml_file, "UTF-8"))) + failure (&misc, daisy[i].xml_file, errno); + if (! (last = xmlReaderWalker (doc))) + failure (&misc, daisy[i].xml_file, errno); + while (1) + { + if (! get_tag_or_label (&misc, &my_attribute, last)) + break; + if (strcasecmp (my_attribute.id, daisy[i + 1].anchor) == 0) + break; + if (*my_attribute.id) + strcpy (daisy[i].last_id, my_attribute.id); + } // while + xmlTextReaderClose (last); + xmlFreeDoc (doc); + } // for + fill_page_numbers (&misc, daisy, &my_attribute); + calculate_times_3 (&misc, &my_attribute, daisy); } // if if (misc.total_items == 0) misc.total_items = 1; } // if (! misc.discinfo); } // if misc.audiocd == 0 + if (*misc.bookmark_title == 0) + { + strncpy (misc.bookmark_title, misc.daisy_title, MAX_STR - 1); + if (strchr (misc.bookmark_title, '/')) + { + int i = 0; + + while (misc.bookmark_title[i] != 0) + misc.bookmark_title[i++] = '-'; + } // if + } // if wattron (misc.titlewin, A_BOLD); snprintf (str, MAX_STR - 1, gettext ( - "Daisy-player - Version %s - (C)2015 J. Lemmens"), PACKAGE_VERSION); + "Daisy-player - Version %s - (C)2017 J. Lemmens"), PACKAGE_VERSION); mvwprintw (misc.titlewin, 0, 0, str); wrefresh (misc.titlewin); @@ -2425,12 +2123,12 @@ int main (int argc, char *argv[]) mvwprintw (misc.titlewin, 1, 0, "----------------------------------------"); wprintw (misc.titlewin, "----------------------------------------"); - mvwprintw (misc.titlewin, 1, 0, gettext ("Press 'h' for help ")); + mvwprintw (misc.titlewin, 1, 0, "%s ", gettext ("Press 'h' for help")); misc.level = 1; *misc.search_str = 0; - snprintf (misc.tmp_wav, MAX_STR, "/tmp/daisy-player_XXXXXX"); + snprintf (misc.tmp_wav, MAX_STR, "%s/daisy-player.wav", misc.tmp_dir); if ((misc.tmp_wav_fd = mkstemp (misc.tmp_wav)) == 01) - failure ("mkstemp ()", errno); + failure (&misc, "mkstemp ()", errno); browse (&misc, &my_attribute, daisy, start_wd); return 0; } // main |