--- daisy-player-11.6.1.1/src/common.c 2018-09-06 18:59:44.000000000 +0200 +++ daisy-player-11.6.2.2/src/common.c 2018-12-17 15:32:23.000000000 +0100 @@ -19,6 +19,8 @@ #include "daisy.h" +char sink_info[10][100]; + char *convert_URL_name (misc_t *misc, char *file) { int i, j; @@ -54,6 +56,7 @@ printf ("\n\n%s: %s\n", str, strerror (e)); fflush (stdout); remove_tmp_dir (misc); + printf ("reset"); kill (misc->main_pid, SIGTERM); } // failure @@ -62,9 +65,7 @@ pid_t kidpid; int status; - while ((kidpid = waitpid(-1, &status, WNOHANG)) > 0) - { - } // while + while ((kidpid = waitpid (-1, &status, WNOHANG)) > 0); } // player_ended void get_path_name (char *dir, char *search_str, char *found) @@ -76,7 +77,7 @@ if (total == -1) { printf ("scandir: %s: %s\n", dir, strerror (errno)); - exit (-1); + exit (EXIT_FAILURE); } // if for (n = 0; n < total; n++) { @@ -87,9 +88,11 @@ sprintf (path, "%s%s", dir, namelist[n]->d_name); else sprintf (path, "%s/%s", dir, namelist[n]->d_name); - if (strcasecmp (namelist[n]->d_name, basename (search_str)) == 0) + if (strcasecmp (namelist[n]->d_name, basename (search_str)) == 0) { strcpy (found, path); + free (path); + free (namelist); return; } // if free (path); @@ -114,7 +117,7 @@ char *get_dir_content (misc_t *misc, char *dir_name, char *search_str) { - char *found; + char *found; DIR *dir; struct dirent *entry; @@ -149,7 +152,10 @@ found = malloc (MAX_STR); strcpy (found, get_dir_content (misc, path, search_str)); if (strcasestr (found, search_str) && *search_str) + { + free (path); return found; + } // if free (path); } // if } while ((entry = readdir (dir))); @@ -158,6 +164,7 @@ void find_index_names (misc_t *misc) { + get_path_name (misc->daisy_mp, "ncc.html", misc->ncc_html); *misc->ncx_name = 0; strncpy (misc->ncx_name, @@ -169,157 +176,6 @@ MAX_STR - 1); } // find_index_names -int get_page_number_2 (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy, char *attr) -{ -// function for daisy 2.02 - if (daisy[misc->playing].page_number == 0) - return 0; -#ifdef DAISY_PLAYER - char *src, *anchor; - xmlTextReaderPtr page; - htmlDocPtr doc; - - src = malloc (strlen (misc->daisy_mp) + strlen (attr) + 3); - anchor = strdup (""); - if (strchr (attr, '#')) - { - anchor = strdup (strchr (attr, '#') + 1); - *strchr (attr, '#') = 0; - } // if - get_path_name (misc->daisy_mp, attr, src); - doc = htmlParseFile (src, "UTF-8"); - if (! (page = xmlReaderWalker (doc))) - { - int e; - char str[MAX_STR]; - - e = errno; - snprintf (str, MAX_STR, gettext ("Cannot read %s"), src); - failure (misc, str, e); - } // if - if (*anchor) - { - do - { - if (! get_tag_or_label (misc, my_attribute, page)) - { - xmlTextReaderClose (page); - xmlFreeDoc (doc); - return 0; - } // if - } while (strcasecmp (my_attribute->id, anchor) != 0); - } // if - while (1) - { - if (! get_tag_or_label (misc, my_attribute, page)) - { - xmlTextReaderClose (page); - xmlFreeDoc (doc); - return 0; - } // if - if (*misc->label) - { - xmlTextReaderClose (page); - xmlFreeDoc (doc); - misc->current_page_number = atoi (misc->label); - return 1; - } // if - } // while -#endif - -#ifdef EBOOK_SPEAKER - while (1) - { - if (*misc->label) - { - misc->current_page_number = atoi (misc->label); - return 1; - } // if - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return 0; - } // while - attr = attr; // don't need it in eBook-speaker -#endif -} // get_page_number_2 - -int get_page_number_3 (misc_t *misc, my_attribute_t *my_attribute) -{ -// function for daisy 3 - while (1) - { - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return 0; -#ifdef DAISY_PLAYER - if (strcasecmp (misc->tag, "text") == 0) - { - char *file, *anchor; - xmlTextReaderPtr page; - htmlDocPtr doc; - - anchor = strdup (""); - if (strchr (my_attribute->src, '#')) - { - anchor = strdup (strchr (my_attribute->src, '#') + 1); - *strchr (my_attribute->src, '#') = 0; - } // if - file = malloc (strlen (misc->daisy_mp) + - strlen (my_attribute->src) + 5); - get_path_name (misc->daisy_mp, - convert_URL_name (misc, my_attribute->src), file); - doc = htmlParseFile (file, "UTF-8"); - if (! (page = xmlReaderWalker (doc))) - { - int e; - char str[MAX_STR]; - - e = errno; - snprintf (str, MAX_STR, gettext ("Cannot read %s"), file); - failure (misc, str, e); - } // if - if (*anchor) - { - do - { - if (! get_tag_or_label (misc, my_attribute, page)) - { - xmlTextReaderClose (page); - xmlFreeDoc (doc); - return 0; - } // if - } while (strcasecmp (my_attribute->id, anchor) != 0); - } // if anchor - while (1) - { - if (! get_tag_or_label (misc, my_attribute, page)) - { - xmlTextReaderClose (page); - xmlFreeDoc (doc); - return 0; - } // if - if (*misc->label) - { - xmlTextReaderClose (page); - xmlFreeDoc (doc); - misc->current_page_number = atoi (misc->label); - return 1; - } // if - } // while - } // if text -#endif - -#ifdef EBOOK_SPEAKER - if (*misc->label) - { - misc->current_page_number = atoi (misc->label); - return 1; - } // if - if (! get_tag_or_label (misc, my_attribute, misc->reader)) - return 0; -#endif - } // while -} // get_page_number_3 - void kill_player (misc_t *misc) { while (kill (misc->player_pid, SIGHUP) == 0); @@ -351,18 +207,14 @@ kill_player (misc); } // skip_right -#ifdef DAISY_PLAYER int handle_ncc_html (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) -#endif -#ifdef EBOOK_SPEAKER -int handle_ncc_html (misc_t *misc, my_attribute_t *my_attribute) -#endif { // lookfor "ncc.html" htmlDocPtr doc; xmlTextReaderPtr ncc; + free (misc->daisy_mp); misc->daisy_mp = strdup (misc->ncc_html); misc->daisy_mp = dirname (misc->daisy_mp); strncpy (misc->daisy_version, "2.02", 4); @@ -392,12 +244,12 @@ gettext ("Please try to play this book with daisy-player")); beep (); #ifdef DAISY_PLAYER - quit_daisy_player (misc, daisy); + quit_daisy_player (misc, my_attribute, daisy); #endif #ifdef EBOOK_SPEAKER - quit_eBook_speaker (misc); + quit_eBook_speaker (misc, my_attribute, daisy); #endif - _exit (0); + _exit (EXIT_SUCCESS); } // if return misc->total_items; } // handle_ncc_html @@ -502,13 +354,8 @@ free (namelist); } // create_ncc_html -#ifdef DAISY_PLAYER -daisy_t *create_daisy_struct (misc_t *misc, my_attribute_t *my_attribute, - daisy_t *daisy) -#endif -#ifdef EBOOK_SPEAKER -daisy_t *create_daisy_struct (misc_t *misc, my_attribute_t *my_attribute) -#endif +daisy_t *create_daisy_struct (misc_t *misc, + my_attribute_t *my_attribute, daisy_t *daisy) { htmlDocPtr doc; xmlTextReaderPtr ptr; @@ -518,25 +365,20 @@ *misc->ncc_html = *misc->ncx_name = *misc->opf_name = 0; find_index_names (misc); -// lookfor "ncc.html" +// handle "ncc.html" if (*misc->ncc_html) { -#ifdef DAISY_PLAYER misc->total_items = handle_ncc_html (misc, my_attribute, daisy); -#endif -#ifdef EBOOK_SPEAKER - misc->total_items = handle_ncc_html (misc, my_attribute); -#endif return calloc (misc->total_items + 1, sizeof (daisy_t)); } // if ncc.html -// lookfor *.ncx +// handle *.ncx if (*misc->ncx_name) strncpy (misc->daisy_version, "3", 2); if (strlen (misc->ncx_name) < 4) *misc->ncx_name = 0; -// lookfor "*.opf"" +// handle "*.opf"" if (*misc->opf_name) strncpy (misc->daisy_version, "3", 2); if (strlen (misc->opf_name) < 4) @@ -545,12 +387,7 @@ if (*misc->ncc_html == 0 && *misc->ncx_name == 0 && *misc->opf_name == 0) { create_ncc_html (misc); -#ifdef DAISY_PLAYER misc->total_items = handle_ncc_html (misc, my_attribute, daisy); -#endif -#ifdef EBOOK_SPEAKER - misc->total_items = handle_ncc_html (misc, my_attribute); -#endif return (daisy_t *) calloc (misc->total_items + 1, sizeof (daisy_t)); } // if @@ -589,23 +426,30 @@ gettext ("Please try to play this book with daisy-player")); beep (); #ifdef DAISY_PLAYER - quit_daisy_player (misc, daisy); + quit_daisy_player (misc, my_attribute, daisy); #endif #ifdef EBOOK_SPEAKER - quit_eBook_speaker (misc); + quit_eBook_speaker (misc, my_attribute, daisy); #endif - _exit (0); + _exit (EXIT_SUCCESS); } // if misc->total_items = misc->items_in_ncx; if (misc->items_in_opf > misc->items_in_ncx) misc->total_items = misc->items_in_opf; switch (chdir (misc->daisy_mp)); +#ifdef EBOOK_SPEAKER + snprintf (misc->eBook_speaker_txt, MAX_STR, + "%s/eBook-speaker.txt", misc->daisy_mp); + snprintf (misc->tmp_wav, MAX_STR, + "%s/eBook-speaker.wav", misc->daisy_mp); +#endif return (daisy_t *) calloc (misc->total_items + 1, sizeof (daisy_t)); } // create_daisy_struct void make_tmp_dir (misc_t *misc) { + free (misc->tmp_dir); misc->tmp_dir = strdup ("/tmp/" PACKAGE ".XXXXXX"); if (! mkdtemp (misc->tmp_dir)) { @@ -655,16 +499,6 @@ } // if } // remove_tmp_dir -void clear_tmp_dir (misc_t *misc) -{ - if (strstr (misc->tmp_dir, "/tmp/")) - { -// Be sure not to remove wrong files - snprintf (misc->cmd, MAX_CMD - 1, "rm -rf %s/*", misc->tmp_dir); - switch (system (misc->cmd)); - } // if -} // clear_tmp_dir - void get_attributes (misc_t *misc, my_attribute_t *my_attribute, xmlTextReaderPtr ptr) { @@ -682,9 +516,9 @@ (ptr, (xmlChar *) "break_on_eol")); if (strcmp (attr, "(null)")) { - misc->break_on_EOL = attr[0]; - if (misc->break_on_EOL != 'y' && misc->break_on_EOL != 'n') - misc->break_on_EOL = 'n'; + misc->break_phrase = attr[0]; + if (misc->break_phrase != 'y' && misc->break_phrase != 'n') + misc->break_phrase = 'n'; } // if } // if snprintf (attr, MAX_STR - 1, "%s", (char *) @@ -716,15 +550,20 @@ strncpy (my_attribute->href, attr, MAX_STR - 1); if (xmlTextReaderGetAttribute (ptr, (const xmlChar *) "id") != NULL) { + free (my_attribute->id); my_attribute->id = strdup ((char *) xmlTextReaderGetAttribute (ptr, (const xmlChar *) "id")); #ifdef DAISY_PLAYER if (strcmp (my_attribute->id, misc->current_id) != 0) + { + free (misc->current_id); misc->current_id = strdup (my_attribute->id); + } // if #endif } // if if (xmlTextReaderGetAttribute (ptr, (const xmlChar *) "idref") != NULL) - { + { + free (my_attribute->idref); my_attribute->idref = strdup ((char *) xmlTextReaderGetAttribute (ptr, (const xmlChar *) "idref")); } // if @@ -814,9 +653,10 @@ if (strcmp (attr, "(null)")) strncpy (my_attribute->smilref, attr, MAX_STR - 1); snprintf (attr, MAX_STR - 1, "%s", (char *) - xmlTextReaderGetAttribute (ptr, (const xmlChar *) "pulseaudio_device")); + xmlTextReaderGetAttribute (ptr, + (const xmlChar *) "pulseaudio_device")); if (strcmp (attr, "(null)")) - misc->pulseaudio_device = strdup (attr); + strcpy (misc->pulseaudio_device, attr); snprintf (attr, MAX_STR - 1, "%s", (char *) xmlTextReaderGetAttribute (ptr, (const xmlChar *) "ocr_language")); if (strcmp (attr, "(null)")) @@ -830,7 +670,7 @@ xmlTextReaderGetAttribute (ptr, (const xmlChar *) "cddb_flag")); if (strcmp (attr, "(null)")) misc->cddb_flag = (char) attr[0]; -#endif +#endif snprintf (attr, MAX_STR - 1, "%s", (char *) xmlTextReaderGetAttribute (ptr, (const xmlChar *) "speed")); if (strcmp (attr, "(null)")) @@ -841,6 +681,7 @@ } // if if (xmlTextReaderGetAttribute (ptr, (const xmlChar *) "src") != NULL) { + free (my_attribute->src); my_attribute->src = strdup ((char *) xmlTextReaderGetAttribute (ptr, (const xmlChar *) "src")); } // if @@ -864,7 +705,8 @@ int type; *misc->tag = 0; - misc->label = strdup (""); + misc->label = realloc (misc->label, 1); + *misc->label = 0; #ifdef EBOOK_SPEAKER *my_attribute->my_class = 0; #endif @@ -873,10 +715,13 @@ *my_attribute->clip_begin = *my_attribute->clip_end = 0; #endif *my_attribute->href = *my_attribute->media_type = - *my_attribute->playorder = *my_attribute->smilref = + *my_attribute->playorder = *my_attribute->smilref = 0; *my_attribute->toc = *my_attribute->value = 0; + free (my_attribute->id); my_attribute->id = strdup (""); + free (my_attribute->idref); my_attribute->idref = strdup (""); + free (my_attribute->src); my_attribute->src = strdup (""); if (! reader) @@ -923,7 +768,9 @@ #ifdef DAISY_PLAYER if (strcasecmp (misc->tag, "audio") == 0) { + free (misc->prev_id); misc->prev_id = strdup (misc->audio_id); + free (misc->audio_id); misc->audio_id = strdup (misc->current_id); } // if #endif @@ -1019,7 +866,7 @@ daisy[misc->playing].clips_anchor); #endif #ifdef EBOOK_SPEAKER - open_text_file (misc, my_attribute, daisy[misc->playing].xml_file, + open_xml_file (misc, my_attribute, daisy[misc->playing].xml_file, daisy[misc->playing].anchor); #endif while (1) @@ -1040,7 +887,7 @@ daisy[misc->playing].clips_anchor); #endif #ifdef EBOOK_SPEAKER - open_text_file (misc, my_attribute, daisy[misc->playing].xml_file, + open_xml_file (misc, my_attribute, daisy[misc->playing].xml_file, daisy[misc->playing].anchor); #endif return; @@ -1056,14 +903,9 @@ void select_next_output_device (misc_t *misc, daisy_t *daisy) { - FILE *p; - int n, y, found; - size_t bytes; - char *card; + int c, n, found; struct group *grp; - wclear (misc->screenwin); - wprintw (misc->screenwin, "\n%s\n\n", gettext ("Select a soundcard:")); grp = getgrnam ("audio"); found = 0; for (n = 0; grp->gr_mem[n]; n++) @@ -1082,122 +924,191 @@ printf ("Please give the following command:\n"); printf ("\n sudo gpasswd -a audio\n\n"); printf ("Logout and login again and you can use daisy-player.\n"); - _exit (0); + _exit (EXIT_FAILURE); } // if - grp = getgrnam ("pulse"); - found = 0; - for (n = 0; grp->gr_mem[n]; n++) - { - if (strcmp (grp->gr_mem[n], cuserid (NULL)) == 0) - { - found = 1; - break; - } // if - } // for - if (found == 0) + wclear (misc->screenwin); + wprintw (misc->screenwin, "\n%s\n\n", gettext ("Select a soundcard:")); + if (access ("/usr/bin/pacmd", X_OK) == -1) { - beep (); - endwin (); - printf ("You need to be a member of the group \"pulse\".\n"); - printf ("Please give the following command:\n"); - printf ("\n sudo gpasswd -a pulse\n\n"); - printf ("Logout and login again and you can use daisy-player.\n"); - _exit (0); - } //; if + int e; - system ("pulseaudio --start"); - if ((p = popen ("/usr/bin/pacmd list-cards", "r")) == NULL) - { - beep (); - endwin (); - printf ("%s\n", - "Be sure the package pulseaudio-utils is installed onto your system."); - _exit (-1); + e = errno; + printf ("\7\n\n%s: %s\n", gettext + ("Be sure the package pulseaudio-utils is installed onto your system."), + strerror (e)); + _exit (EXIT_FAILURE); } // if - for (n = 0; n < 10; n++) + + if (*misc->pulseaudio_device) + c = atoi (misc->pulseaudio_device); + else + c = 0; + nodelay (misc->screenwin, FALSE); + for (;;) { - int m; + char dev[5]; + FILE *p; - misc->pulseaudio_device = malloc (10); - sprintf (misc->pulseaudio_device, "%d", n); - do - { - card = NULL; - bytes = 0; - bytes = getline (&card, &bytes, p); - if ((int) bytes == -1) - { - card = NULL; - break; - } // if - } while (strcasestr (card, "index:") == NULL); + if ((p = popen ("/usr/bin/pactl list sinks", "r")) == NULL) + { + beep (); + endwin (); + printf ("%s\n", + "Be sure the package pulseaudio-utils is installed onto your system."); + _exit (EXIT_FAILURE); + } // if + + size_t len = 0; + int total; + char *str = NULL; + n = -1; while (1) { - card = NULL; - bytes = 0; - bytes = getline (&card, &bytes, p); - if ((int) bytes == -1) - { - card = NULL; + if (getline (&str, &len, p) == -1) break; - } // if - if (strcasestr (card, "device.vendor.name")) + if (strncmp (str, "Sink", 4) == 0) { - for (m = 0; m < (int) strlen (card); m++) - if (card[m] == '=') - break; - card += m + 3; - if (strlen (card) > 2) - card[strlen (card) - 2] = 0; - wprintw (misc->screenwin, " %d %s ", n, card); - wrefresh (misc->screenwin); + memset (sink_info[++n], ' ', 70); continue; - } // if + } // if + if (strstr (str, "Description:")) + { + int x; - if (strcasestr (card, "device.product.name")) + strcpy (sink_info[n], str + 14); + for (x = strlen (sink_info[n]) - 1; x < 70; x++) + sink_info[n][x] = ' '; + sink_info[n][x] = 0 ; + } // if + if (strstr (str, "Mute:")) { - for (m = 0; m < (int) strlen (card); m++) - if (card[m] == '=') + strcpy (sink_info[n] + 53, strstr (str, "Mute:")); + sink_info[n][52] = ' '; + } // if + if (strcasestr (str, "Volume:")) + { + if (strcasestr (str, "Base")) + continue; + int x; + + sink_info[n][strlen (sink_info[n]) - 1] = ' '; + sink_info[n][strlen (sink_info[n])] = ' '; + strcpy (sink_info[n] + 63, strstr (str, "Volume:")); + sink_info[n][70] = 0; + for (x = strlen (str); x >= 0; x--) + if (str[x] == '%') break; - card += m + 3; - if (strlen (card) > 2) - card[strlen (card) - 2] = 0; - wprintw (misc->screenwin, "%s\n", card); - wrefresh (misc->screenwin); - break; + str[x + 1] = 0; + for (x = strlen (str); x >= 0; x--) + if (str[x] == ' ') + break; + strcat (sink_info[n], str + x); } // if } // while - if ((int) bytes == -1) - break; - } // for - wrefresh (misc->screenwin); - fclose (p); - y = 3; - nodelay (misc->screenwin, FALSE); - for (;;) - { - wmove (misc->screenwin, y, 2); + total = n + 1; + pclose (p); + +/* The build-in pactl function with argument list gives problems. + So for the time being the external application pactl is used instead. + + memcpy (sink_info, pactl ("list", "0", "0"), 1000); +*/ + + for (n = 0; n < total; n++) + mvwprintw (misc->screenwin, n + 3, 0, "%2d %s ", n, sink_info[n]); + wmove (misc->screenwin, c + 3, 2); + wrefresh (misc->screenwin); + switch (wgetch (misc->screenwin)) { - case 13: // - misc->pulseaudio_device = malloc (10); - snprintf (misc->pulseaudio_device, 3, "%d", y - 3); + case 13: + sprintf (misc->pulseaudio_device, "%d", c); view_screen (misc, daisy); nodelay (misc->screenwin, TRUE); return; case KEY_DOWN: - if (++y == n + 3) - y = 3; + if (++c >= total) + c = 0; break; case KEY_UP: - if (--y == 2) - y = n + 2; + if (--c == -1) + c = total - 1; + break; + case 'm': + if (fork () == 0) + { + sprintf (dev, "%d", c); + pactl ("set-sink-mute", dev, "toggle"); + _exit (EXIT_SUCCESS); + } // if + break; + case 'q': + view_screen (misc, daisy); + return; + case 'v': + case '1': + if (fork () == 0) + { + sprintf (dev, "%d", c); + pactl ("set-sink-volume", dev, "-5%"); + _exit (EXIT_SUCCESS); + } // if + break; + case 'V': + case '7': + if (fork () == 0) + { + sprintf (dev, "%d", c); + pactl ("set-sink-volume", dev, "+5%"); + _exit (EXIT_SUCCESS); + } // if break; default: beep (); break; } // switch + + fd_set rfds; + struct timeval tv; + + FD_ZERO (&rfds); + FD_SET (0, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 100000; +// pause till a key has been pressed or 0.1 seconds are elapsed + select (1, &rfds, NULL, NULL, &tv); } // for } // select_next_output_device + +void free_all (misc_t *misc, my_attribute_t *my_attribute, daisy_t *daisy) +{ +#ifdef DAISY_PLAYER + free (misc->pause_resume_id); + free (misc->prev_id); + free (misc->current_id); + free (misc->audio_id); + free (misc->current_audio_file); +#endif +#ifdef EBOOK_SPEAKER + free (misc->src_dir); +#endif + free (misc->daisy_mp); + free (misc->tmp_dir); + free (misc->label); + free (my_attribute->id); + free (my_attribute->idref); + free (my_attribute->src); + for (misc->current = 0; misc->current < misc->total_items; + misc->current++) + { + free (daisy[misc->current].xml_file); + free (daisy[misc->current].anchor); + free (daisy[misc->current].clips_file); + free (daisy[misc->current].clips_anchor); + free (daisy[misc->current].orig_smil); + } // for + delwin (misc->titlewin); + delwin (misc->screenwin); +} // free_all