DEBUG("reading %s", tmp1);
DEBUG("reading description %s", tmp2);
- tts_speak_customized(tmp1, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(tmp1, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
if (tmp2 && tmp2[0])
- tts_speak_customized(tmp2, EINA_FALSE, EINA_TRUE, associate_object ? obj : NULL, DESCRIPTION_SPEAK_DELAY);
+ tw_speak_customized(tmp2, EINA_FALSE, EINA_TRUE, associate_object ? obj : NULL, DESCRIPTION_SPEAK_DELAY);
g_free(tmp1);
g_free(tmp2);
}
}
GERROR_CHECK(err)
- Eina_Bool is_paused = tts_pause_get();
+ Eina_Bool is_paused = tw_pause_get();
if (is_paused) {
- tts_stop_set();
- tts_pause_set(EINA_FALSE);
+ tw_stop_set();
+ tw_pause_set(EINA_FALSE);
}
} else
DEBUG("Unable to highlight on object");
DEBUG("Caret position increment done");
gchar *text = atspi_text_get_text(text_interface, 0, 1, NULL);
DEBUG("SPEAK : %s", text ? text : "text nil");
- tts_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
//FIXME : This IDS value is not supported.
- //tts_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, nd->current_obj);
+ //tw_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, nd->current_obj);
g_free(text);
} else {
ERROR("Caret position increment error");
//FIXME : This IDS value is not supported.
/*DEBUG("Caret position increment done");
DEBUG("SPEAK:%s", _("IDS_TEXT_END"));
- tts_speak_customized(_("IDS_TEXT_END"), EINA_TRUE, EINA_TRUE, nd->current_obj);*/
+ tw_speak_customized(_("IDS_TEXT_END"), EINA_TRUE, EINA_TRUE, nd->current_obj);*/
} else
ERROR("Caret position to end error");
g_clear_error(&err);
//TODO: i18n - copy, cut
char buf[TTS_MAX_TEXT_SIZE] = "";
g_snprintf(buf, sizeof(buf), (is_cut) ? _("Cut , %s") : _("Copy , %s"), text);
- tts_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
}
g_free(text);
g_object_unref(e_text);
//TODO: i18n - paste
char buf[TTS_MAX_TEXT_SIZE] = "";
g_snprintf(buf, sizeof(buf), _("Paste , %s"), text);
- tts_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
g_free(text);
}
g_object_unref(e_text);
//TODO : i18n - "From %s to %s, selected", "All selected"
char buf[TTS_MAX_TEXT_SIZE] = "";
g_snprintf(buf, sizeof(buf), _("All selected , %s"), text);
- tts_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
g_free(text);
}
}
char buf[TTS_MAX_TEXT_SIZE] = "";
g_snprintf(buf, sizeof(buf), (is_selected) ? _("%s , Selected") : _("%s , Unselected"), text);
- tts_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(buf, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
g_free(text);
}
ret = atspi_text_set_caret_offset(text_interface, current_offset, &err);
if (offset_pos == atspi_text_get_character_count(text_interface, NULL)) {
//FIXME : This IDS value is not supported.
/*DEBUG("SPEAK:%s", _("IDS_TEXT_END"));
- tts_speak_customized(_("IDS_TEXT_END"), EINA_FALSE, EINA_TRUE, current_obj);*/
+ tw_speak_customized(_("IDS_TEXT_END"), EINA_FALSE, EINA_TRUE, current_obj);*/
} else {
DEBUG("SPEAK:%s", text ? text : "text nil");
const gchar *symtext = symbol_lookup(text);
if (symtext) {
- tts_speak_customized(_(symtext), EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(_(symtext), EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
}
else {
- tts_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
}
}
g_free(text);
DEBUG("SPEAK:%s", text ? text : "text nil");
const gchar *symtext = symbol_lookup(text);
if (symtext) {
- tts_speak_customized(_(symtext), EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(_(symtext), EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
}
else {
- tts_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
}
g_free(text);
//FIXME : This IDS value is not supported.
/*if (offset_pos == 0) {
DEBUG("SPEAK:%s", _("IDS_TEXT_BEGIN"));
- tts_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, nd->current_obj);
+ tw_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, nd->current_obj);
}*/
} else {
ERROR("Caret position decrement error");
DEBUG("START");
Eina_Bool res = EINA_FALSE;
- bool pause = tts_pause_get();
- res = tts_pause_set(!pause);
+ bool pause = tw_pause_get();
+ res = tw_pause_set(!pause);
if (!res)
ERROR("Failed to set pause state");
if (grd) {
char *granularity_text_to_speak = granularity_read_text_get(nd->current_obj, next);
if (granularity_text_to_speak) {
- tts_speak_customized(granularity_text_to_speak, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
+ tw_speak_customized(granularity_text_to_speak, EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
g_free(granularity_text_to_speak);
}
return EINA_TRUE;
_wm_text_selection_mode_set(nd, !nd->is_text_selection_mode);
if (nd->is_text_selection_mode) {
//TODO: i18n - "Selection mode enabled".
- tts_speak_customized(_("Selection mode enabled"),
+ tw_speak_customized(_("Selection mode enabled"),
EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
} else {
//TODO: i18n - "Selection mode disabled".
- tts_speak_customized(_("Selection mode disabled"),
+ tw_speak_customized(_("Selection mode disabled"),
EINA_TRUE, EINA_TRUE, nd->current_obj, 0);
}
} else
nd->read_quickpanel_cb = NULL;
nd->read_quickpanel_data = NULL;
- set_utterance_cb(_on_utterance, nd);
+ tw_set_utterance_cb(_on_utterance, nd, NULL);
navigator_gestures_tracker_register(on_gesture_detected, nd);
// register on active_window
nd->supported_gestures = NULL;
navigator_gestures_tracker_unregister();
- remove_utterance_cb();
+ tw_set_utterance_cb(NULL, NULL, NULL);
app_tracker_shutdown(nd->app_tracker_data);
smart_notification_shutdown();
#include <Ecore.h>
#include <atspi/atspi.h>
-#include "screen_reader_tts.h"
-#include "screen_reader_vconf.h"
-#include "screen_reader_system.h"
-#include "dbus_direct_reading_adapter.h"
-#include "logger.h"
-#include "utils.h"
-// ---------------------------- DEBUG HELPERS ------------------------------
+#include <dbus_direct_reading_adapter.h>
+#include <logger.h>
+#include <screen_reader_system.h>
+#include <screen_reader_tts.h>
+#include <screen_reader_vconf.h>
+#include <utils.h>
#define REMOVE_PRECEDING_READ_COMMANDS_LIMIT 1
+typedef enum _Play_Read_Command_Status Play_Read_Command_Status;
+
+typedef struct {
+ int init;
+ tts_h tts;
#ifndef SCREEN_READER_TV
-Ecore_Timer *display_lock_release_timer = NULL;
+ Ecore_Timer *display_lock_release_timer;
#endif
+ Eina_Bool pause_state;
+ Eina_List *read_command_queue;
+
+ // Current read command - the last accepted by the TTS and not yet completed.
+ Read_Command *last_read_command;
+
+ // Callback type
+ utterance_cb_t on_utterance_end;
+ void* on_utterance_end_user_data;
+ utterance_cb_t on_utterance_end_deleter;
+
+ Eina_Bool tts_speak_running;
+ int tts_speak_last_utterance;
+
+ Ecore_Timer *delay_timer;
+ bool request_speak_do;
+ bool running;
+} TWData;
+
+/* Forward delcarations - begin */
+static TWData *tw_get_instance(void);
+static void tw_speak_request(TWData *tw);
+static void overwrite_last_read_command_with(TWData *tw, Read_Command *new_value);
+static void _reading_status_notify(Signal signal, Read_Command *command);
+static void dispose_read_command(Read_Command *command, Signal playing_reason, Signal non_playing_reason);
+/* Forward delcarations - end */
-static Eina_Bool pause_state = EINA_FALSE;
-static Eina_List *read_command_queue = NULL;
-
-// Current read command - the last accepted by the TTS and not yet completed.
-static Read_Command *last_read_command = NULL;
-
-// Callback type
-typedef void (*utterance_completed_f)(void*);
-static utterance_completed_f on_utterance_end;
-static void* on_utterance_end_user_data;
-
-const char *sprintf_command(Read_Command *command)
+static const char *sprintf_command(Read_Command *command)
{
static char buffer[9999];
if (command) {
}
//-------------------------------------------------------------------------------------------------
-void state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void *user_data);
+static void tw_state_changed_cb(
+ tts_h tts,
+ tts_state_e previous,
+ tts_state_e current,
+ void *user_data)
+{
+ TWData *tw = (TWData*) user_data;
+ if (tw->pause_state) {
+ DEBUG("TTS is currently paused. Resume to start reading");
+ return;
+ }
-void set_utterance_cb(utterance_completed_f uter_cb, void *user_data)
-{
- on_utterance_end = uter_cb;
- on_utterance_end_user_data = user_data;
+ DEBUG("++++++++++++++++tw_state_changed_cb++++++++++++++++++");
+ DEBUG("current state:%s and previous state:%s\n", get_tts_state(current), get_tts_state(previous));
+ if (current == TTS_STATE_READY && previous == TTS_STATE_PLAYING
+ && tw->last_read_command && tw->last_read_command->is_playing) {
+ overwrite_last_read_command_with(tw, NULL);
+ }
+
+ if (TTS_STATE_READY == current)
+ tw_speak_request(tw);
}
-void* remove_utterance_cb() {
- void *ret = on_utterance_end_user_data;
- on_utterance_end = NULL;
- on_utterance_end_user_data = NULL;
- return ret;
+void tw_set_utterance_cb(
+ utterance_cb_t uter_cb,
+ void *user_data,
+ utterance_cb_t deleter)
+{
+ TWData *tw = tw_get_instance();
+ if (tw->on_utterance_end_user_data && tw->on_utterance_end_deleter)
+ tw->on_utterance_end_deleter(tw->on_utterance_end_user_data);
+
+ tw->on_utterance_end = uter_cb;
+ tw->on_utterance_end_user_data = user_data;
+ tw->on_utterance_end_deleter = deleter;
}
static Eina_Bool _do_atspi_action_by_name(AtspiAccessible *obj, const char *name)
}
}
-static void overwrite_last_read_command_with(Read_Command *new_value)
+static void overwrite_last_read_command_with(TWData *tw, Read_Command *new_value)
{
- Read_Command *old_head = last_read_command;
- last_read_command = new_value;
+ Read_Command *old_head = tw->last_read_command;
+ tw->last_read_command = new_value;
DEBUG("Replacing head: %s", sprintf_command(old_head));
if (old_head)
dispose_read_command(old_head, READING_CANCELLED, READING_STOPPED);
}
-Eina_Bool
-can_discard(const Read_Command *prev, const Read_Command *next)
+static Eina_Bool can_discard(const Read_Command *prev, const Read_Command *next)
{
DEBUG("[START] checking if can discard: prev (%p), next(%p)", prev, next);
char buffer[64];
return next == NULL ? EINA_FALSE : (prev == NULL ? EINA_TRUE : (prev->discardable && next->want_discard_previous_reading));
}
-Eina_Bool can_be_discarded(const Read_Command *prev)
+static Eina_Bool can_be_discarded(TWData *tw, const Read_Command *prev)
{
Eina_List *l;
Read_Command *command;
- EINA_LIST_FOREACH(read_command_queue, l, command) {
+ EINA_LIST_FOREACH(tw->read_command_queue, l, command) {
if (can_discard(prev, command))
return EINA_TRUE;
}
return can_discard(prev, NULL);
}
-static void _reading_status_notify(Signal signal, Read_Command *command);
-static void dispose_read_command(Read_Command *command, Signal playing_reason, Signal non_playing_reason);
-
// Retrieves first non-discardable command from the queue (if there is one)
// or the last command in the queue (if all are discardable).
//
//TODO: consider handling the case of discarding well-formed read command by subsequent malformed command
-static Read_Command *get_read_command_from_queue(Eina_List **cmd_list)
+static Read_Command *get_read_command_from_queue(TWData *tw, Eina_List **cmd_list)
{
if (cmd_list == NULL || *cmd_list == NULL)
return NULL;
*cmd_list = eina_list_remove(*cmd_list, result);
// command is not discardable
- if (!can_be_discarded(result) && (result->context.text != NULL))
+ if (!can_be_discarded(tw, result) && (result->context.text != NULL))
break;
// next command have delay_to_speak
FAILURE_NOT_RECOVERABLE = 2
};
-typedef enum _Play_Read_Command_Status Play_Read_Command_Status;
static bool is_separator(int unicode)
{
return 0;
}
-static volatile Eina_Bool tts_speak_running = false;
-static volatile int tts_speak_last_utterance = -1;
-
-static int send_chunk_to_tts(Service_Data *sd, const char *utf8_line, int *utt_id)
+static int send_chunk_to_tts(TWData *tw, const char *utf8_line, int *utt_id)
{
DEBUG("Passing TEXT: %s to TTS", utf8_line);
int utterance_id;
- int ret = tts_add_text(sd->tts, utf8_line, NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &utterance_id);
+ int ret = tts_add_text(tw->tts, utf8_line, NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &utterance_id);
if (ret) {
tts_state_e state = -1;
switch (ret) {
case TTS_ERROR_INVALID_STATE:
- tts_get_state(sd->tts, &state);
+ tts_get_state(tw->tts, &state);
dlog_print(DLOG_FATAL, NULL, "FAILED tts_add_text: error: TTS_ERROR_INVALID_STATE, tts_state: %d", state);
return FAILURE_RECOVERABLE;
case TTS_ERROR_INVALID_VOICE:
return FAILURE_NOT_RECOVERABLE;
}
} else {
- tts_speak_running = EINA_TRUE;
- tts_speak_last_utterance = utterance_id;
+ tw->tts_speak_running = EINA_TRUE;
+ tw->tts_speak_last_utterance = utterance_id;
if (utt_id) *utt_id = utterance_id;
DEBUG("chunk size (%d) added utterance id:%d\n", (int)strlen(utf8_line), utterance_id);
}
return SUCCESS;
}
-static void stop_speaking(Service_Data *sd)
+static void stop_speaking(TWData *tw)
{
- if (tts_speak_running) {
- tts_speak_running = EINA_FALSE;
- int ret = tts_stop(sd->tts);
+ if (tw->tts_speak_running) {
+ tw->tts_speak_running = EINA_FALSE;
+ int ret = tts_stop(tw->tts);
if (TTS_ERROR_NONE != ret)
DEBUG("Fail to stop TTS: result(%d)", ret);
}
* FAILURE_RECOVERABLE if the TTS was not ready to accept requests (and the function can be called again)
*/
static Play_Read_Command_Status
-send_command_to_tts(Service_Data *sd, Read_Command *command, tts_state_e state)
+send_command_to_tts(TWData *tw, tts_state_e state)
{
- if (!sd || !command) return FAILURE_NOT_RECOVERABLE;
+ Read_Command *command = tw->last_read_command;
+ if (!command) return FAILURE_NOT_RECOVERABLE;
if (command->chain_info) command->chain_info->reading_started_at_all = 1;
Read_Context *ctx = &command->context;
return FAILURE_NOT_RECOVERABLE;
}
remaining_text += consumed_chars;
- int result = send_chunk_to_tts(sd, utf8_line, &ctx->last_id);
+ int result = send_chunk_to_tts(tw, utf8_line, &ctx->last_id);
if (result == FAILURE_NOT_RECOVERABLE) {
remaining_text = NULL;
} else {
if (chunk_accepted) {
DEBUG("Chunk accepted id %d", ctx->last_id);
command->is_playing = EINA_TRUE;
- if (state == TTS_STATE_READY) tts_play(sd->tts);
+ if (state == TTS_STATE_READY) tts_play(tw->tts);
#ifndef SCREEN_READER_TV
- device_display_lock_request(sd->system_data);
- if (display_lock_release_timer)
- ecore_timer_reset(display_lock_release_timer);
+ /* TODO This is not proper way and place to do this. */
+ Service_Data *sd = get_pointer_to_service_data_struct();
+ if (!sd || !sd->system_data) {
+ ERROR("Critical: Service_Data or System_Data is null");
+ } else {
+ device_display_lock_request(sd->system_data);
+ }
+ if (tw->display_lock_release_timer)
+ ecore_timer_reset(tw->display_lock_release_timer);
#endif
return SUCCESS;
}
} else {
- DEBUG("TTS state is %s, %spaused", get_tts_state(state), pause_state ? "" : "NOT ");
+ DEBUG("TTS state is %s, %spaused", get_tts_state(state), tw->pause_state ? "" : "NOT ");
}
return FAILURE_RECOVERABLE;
}
*
* @return bool true iff there is a read command to be processed
*/
-static bool have_read_command(void)
+static bool have_read_command(TWData *tw)
{
- return last_read_command != NULL || eina_list_count(read_command_queue) > 0;
+ return tw->last_read_command != NULL || eina_list_count(tw->read_command_queue) > 0;
}
-static void tts_speak_request(void);
-static Ecore_Timer *delay_timer = NULL;
-static Eina_Bool tts_speak_delay_finished_cb(void *d)
+static Eina_Bool tw_speak_delay_finished_cb(void *d)
{
- delay_timer = NULL;
- if (last_read_command == d)
- tts_speak_request();
+ TWData *tw = tw_get_instance();
+
+ tw->delay_timer = NULL;
+ if (tw->last_read_command == d)
+ tw_speak_request(tw);
return ECORE_CALLBACK_CANCEL;
}
* This function is invoked in two places: when an item is added to the command queue,
* or TTS state change has happened.
*/
-static void tts_speak_do(void)
+static void tw_speak_do(TWData *tw)
{
- DEBUG("[START] tts_speak_do");
- Service_Data *sd = get_pointer_to_service_data_struct();
- if (!sd || !have_read_command()) return;
-
- while (have_read_command()) {
- Read_Command *command = read_command_queue ? read_command_queue->data : NULL;
+ DEBUG("[START] tw_speak_do");
+ while (have_read_command(tw)) {
+ Read_Command *command = tw->read_command_queue ? tw->read_command_queue->data : NULL;
- if (!command && last_read_command && (last_read_command->time_to_speak || last_read_command->delay_to_speak)) {
- if (!last_read_command->time_to_speak && last_read_command->delay_to_speak)
- last_read_command->time_to_speak = get_tick_count(last_read_command->delay_to_speak);
+ if (!command && tw->last_read_command && (tw->last_read_command->time_to_speak || tw->last_read_command->delay_to_speak)) {
+ if (!tw->last_read_command->time_to_speak && tw->last_read_command->delay_to_speak)
+ tw->last_read_command->time_to_speak = get_tick_count(tw->last_read_command->delay_to_speak);
// we substract to avoid wrap around problem (when one time will be at oxffffffff and the next one at 0x00000000,
// thus messing up comparision). time_to_speak is "ahead" (in future) to now only if after substraction
// we get positive number. since it's unsigned we check against 0x7fffffff. this will work even if
// unsigned int type will be 64 bit and 0x7fffffff is almost 600 hours, unlikely to every be mistaken.
unsigned int now = get_tick_count(0);
- unsigned int diff = last_read_command->time_to_speak - now;
+ unsigned int diff = tw->last_read_command->time_to_speak - now;
if (diff < 0x7fffffff) {
- if (delay_timer) ecore_timer_del(delay_timer);
+ if (tw->delay_timer) ecore_timer_del(tw->delay_timer);
DEBUG("delaying speaking for %d ms", diff);
- delay_timer = ecore_timer_add(diff * 0.001, tts_speak_delay_finished_cb, last_read_command);
+ tw->delay_timer = ecore_timer_add(diff * 0.001, tw_speak_delay_finished_cb, tw->last_read_command);
break;
}
- last_read_command->time_to_speak = last_read_command->delay_to_speak = 0;
+ tw->last_read_command->time_to_speak = tw->last_read_command->delay_to_speak = 0;
DEBUG("resuming delayed speaking");
}
tts_state_e state;
- tts_get_state(sd->tts, &state);
+ tts_get_state(tw->tts, &state);
- DEBUG("tts_speak_do: queue length %d, head(%s)", eina_list_count(read_command_queue), sprintf_command(last_read_command));
+ DEBUG("tw_speak_do: queue length %d, head(%s)", eina_list_count(tw->read_command_queue), sprintf_command(tw->last_read_command));
// Should the current command be skipped?
- if ((state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED) && command && can_discard(last_read_command, command) && !command->delay_to_speak) {
+ if ((state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED) && command && can_discard(tw->last_read_command, command) && !command->delay_to_speak) {
DEBUG("Stopping TTS");
- stop_speaking(sd);
+ stop_speaking(tw);
state = TTS_STATE_READY;
- overwrite_last_read_command_with(NULL);
+ overwrite_last_read_command_with(tw, NULL);
}
// Send the command to the tts, perhaps in chunks.
- if (!last_read_command || send_command_to_tts(sd, last_read_command, state) == FAILURE_NOT_RECOVERABLE) {
+ if (!tw->last_read_command || send_command_to_tts(tw, state) == FAILURE_NOT_RECOVERABLE) {
// If the command failed, take next from the queue.
- Read_Command *command = get_read_command_from_queue(&read_command_queue);
+ Read_Command *command = get_read_command_from_queue(tw, &(tw->read_command_queue));
if (command) {
char text[64];
g_strlcpy(text, command->context.text, 63);
DEBUG("TTS_STATE_NAME: %s", get_tts_state(state));
DEBUG("START COMMAND PROCESSING");
}
- overwrite_last_read_command_with(command);
+ overwrite_last_read_command_with(tw, command);
} else break;
} // while (have something to read)
- DEBUG("[END] tts_speak_do");
+ DEBUG("[END] tw_speak_do");
}
-// TODO: this is not synchronized, but it probably should
-static volatile bool request_speak_do = false;
-static volatile bool running = false;
-static void tts_speak_request(void)
+static void tw_speak_request(TWData *tw)
{
- DEBUG("[START] tts_speak_request %srunning", running ? "" : "not ");
- if (running) {
- request_speak_do = true;
+ DEBUG("[START] tw_speak_request %srunning", tw->running ? "" : "not ");
+
+ if (tw->running) {
+ tw->request_speak_do = true;
return;
}
- running = true;
+ tw->running = true;
do {
- request_speak_do = false;
- tts_speak_do();
- } while (request_speak_do);
- running = false;
- DEBUG("[END] tts_speak_request");
+ tw->request_speak_do = false;
+ tw_speak_do(tw);
+ } while (tw->request_speak_do);
+ tw->running = false;
+ DEBUG("[END] tw_speak_request");
}
static int get_next_seq()
}
Read_Command *
-tts_speak_customized(char *text_to_speak, Eina_Bool want_discard_previous_reading,
+tw_speak_customized(char *text_to_speak, Eina_Bool want_discard_previous_reading,
Eina_Bool discardable, AtspiAccessible *obj, unsigned int delay)
{
+ TWData *tw = tw_get_instance();
+
if (text_to_speak == NULL) return NULL;
char *text_to_speak_sanitized = duplicate_and_sanitize(text_to_speak);
free(text_to_speak_sanitized);
return NULL;
}
- Service_Data *sd = get_pointer_to_service_data_struct();
- if (!sd || !sd->tts)
+ if (!tw->tts)
{
- ERROR("Problem with accessing service data struct!");
+ ERROR("Problem with accessing tts!");
free(text_to_speak_sanitized);
return NULL;
}
tts_state_e state;
- tts_get_state(sd->tts, &state);
+ tts_get_state(tw->tts, &state);
char text[64];
g_strlcpy(text, text_to_speak_sanitized, 63);
text[63] = 0;
rc->time_to_speak = 0;
rc->delay_to_speak = delay;
if (delay) {
- Read_Command *previous = read_command_queue ? read_command_queue->data : last_read_command;
+ Read_Command *previous = tw->read_command_queue ? tw->read_command_queue->data : tw->last_read_command;
if (previous) {
Read_Command_Chain_Info *chain = g_malloc0(sizeof(Read_Command_Chain_Info));
if (chain) {
previous->chain_info = rc->chain_info = chain;
}
}
- DEBUG("BEFORE ADD: (#%d, last %s)", eina_list_count(read_command_queue),
- read_command_queue ? sprintf_command(read_command_queue->data) : "empty");
- if (want_discard_previous_reading) compress_command_queue(&read_command_queue, rc);
+ DEBUG("BEFORE ADD: (#%d, last %s)", eina_list_count(tw->read_command_queue),
+ tw->read_command_queue ? sprintf_command(tw->read_command_queue->data) : "empty");
+ if (want_discard_previous_reading) compress_command_queue(&(tw->read_command_queue), rc);
// There is no eina_list_empty()...
- bool queue_head_changed = eina_list_last(read_command_queue) == NULL;
- read_command_queue = eina_list_append(read_command_queue, rc);
+ bool queue_head_changed = eina_list_last(tw->read_command_queue) == NULL;
+ tw->read_command_queue = eina_list_append(tw->read_command_queue, rc);
DEBUG("AFTER ADD: %s (head %schanged)",
- read_command_queue ? sprintf_command(read_command_queue->data) : "(empty)",
+ tw->read_command_queue ? sprintf_command(tw->read_command_queue->data) : "(empty)",
queue_head_changed ? "" : "un");
// Only request housekeeping if list head changed
- if (queue_head_changed) tts_speak_request();
+ if (queue_head_changed) tw_speak_request(tw);
DEBUG("tts_speak_customized: END");
return rc;
}
-Read_Command *tts_speak(char *text_to_speak, Eina_Bool want_discard_previous_reading)
+Read_Command *tw_speak(char *text_to_speak, Eina_Bool want_discard_previous_reading)
{
- return tts_speak_customized(text_to_speak, want_discard_previous_reading, EINA_TRUE, NULL, 0);
+ return tw_speak_customized(text_to_speak, want_discard_previous_reading, EINA_TRUE, NULL, 0);
}
-static void tts_utt_started_cb(tts_h tts, int utt_id, void *user_data)
+static void tw_utt_started_cb(tts_h tts, int utt_id, void *user_data)
{
DEBUG("Utterance started : utt id(%d) \n", utt_id);
return;
#ifndef SCREEN_READER_TV
static Eina_Bool _display_lock_release_timer_cb(void *data)
{
- Service_Data *sd = (Service_Data *)data;
+ TWData *tw = (TWData*)data;
- if (last_read_command && last_read_command->is_playing) {
+ if (tw->last_read_command && tw->last_read_command->is_playing) {
return ECORE_CALLBACK_RENEW;
}
+ /* TODO This not a proper way and place to do this. */
+ Service_Data *sd = get_pointer_to_service_data_struct();
if (!sd || !sd->system_data) {
ERROR("Critical: Service_Data or System_Data is null");
- } else
+ } else {
device_display_lock_release(sd->system_data);
+ }
- display_lock_release_timer = NULL;
+ tw->display_lock_release_timer = NULL;
return ECORE_CALLBACK_CANCEL;
}
#endif
-static void tts_utt_completed_cb(tts_h tts, int utt_id, void *user_data)
+static void tw_utt_completed_cb(tts_h tts, int utt_id, void *user_data)
{
DEBUG("Utterance completed : utt id(%d) \n", utt_id);
+ TWData *tw = (TWData*)user_data;
- if (tts_speak_last_utterance == utt_id)
- tts_speak_running = EINA_FALSE;
- if (last_read_command && last_read_command->context.last_id == utt_id) {
+ if (tw->tts_speak_last_utterance == utt_id)
+ tw->tts_speak_running = EINA_FALSE;
+ if (tw->last_read_command && tw->last_read_command->context.last_id == utt_id) {
DEBUG("LAST UTTERANCE");
- if (last_read_command->chain_info) --last_read_command->chain_info->chunks_yet_to_read;
+ if (tw->last_read_command->chain_info) --(tw->last_read_command->chain_info->chunks_yet_to_read);
#ifndef SCREEN_READER_TV
- if (!last_read_command->is_screen_turn_off) {
- if (display_lock_release_timer) ecore_timer_del(display_lock_release_timer);
+ if (!tw->last_read_command->is_screen_turn_off) {
+ if (tw->display_lock_release_timer) ecore_timer_del(tw->display_lock_release_timer);
DEBUG("resetting timer");
- display_lock_release_timer = ecore_timer_add(vc_get_lcd_backlight_timeout() < 0.01 ? 0.01 : vc_get_lcd_backlight_timeout(),
+ tw->display_lock_release_timer = ecore_timer_add(vc_get_lcd_backlight_timeout() < 0.01 ? 0.01 : vc_get_lcd_backlight_timeout(),
_display_lock_release_timer_cb, user_data);
}
- pause_state = EINA_FALSE;
+ tw->pause_state = EINA_FALSE;
- if (on_utterance_end)
- on_utterance_end(on_utterance_end_user_data);
+ if (tw->on_utterance_end)
+ tw->on_utterance_end(tw->on_utterance_end_user_data);
#endif
- last_read_command->is_playing = EINA_FALSE;
- Service_Data *sd = (Service_Data *)user_data;
- stop_speaking(sd);
- overwrite_last_read_command_with(NULL);
+ tw->last_read_command->is_playing = EINA_FALSE;
+ stop_speaking(tw);
+ overwrite_last_read_command_with(tw, NULL);
}
- tts_speak_request();
+ tw_speak_request(tw);
return;
}
-
-bool tts_init(void *data)
+static
+void tw_init_internal(TWData *tw)
{
DEBUG("--------------------- TTS_init START ---------------------");
- Service_Data *sd = data;
- int r = tts_create(&sd->tts);
+ int r = tts_create(&tw->tts);
DEBUG("Create tts %d (%s)", r, get_tts_error(r));
if (TTS_ERROR_NONE != r) {
ERROR("Fail to create tts (%s)", get_tts_error(r));
- return false;
+ return;
}
-
- r = tts_set_mode(sd->tts, TTS_MODE_SCREEN_READER);
+#ifndef SCREEN_READER_TV
+ tw->display_lock_release_timer = NULL;
+#endif
+ tw->pause_state = EINA_FALSE;
+ tw->read_command_queue = NULL;
+ tw->last_read_command = NULL;
+ tw->on_utterance_end = NULL;
+ tw->on_utterance_end_user_data = NULL;
+ tw->tts_speak_running = false;
+ tw->tts_speak_last_utterance = -1;
+ tw->delay_timer = NULL;
+ tw->request_speak_do = false;
+ tw->running = false;
+
+ r = tts_set_mode(tw->tts, TTS_MODE_SCREEN_READER);
DEBUG("Set tts mode SR %d (%s)", r, get_tts_error(r));
- r = tts_prepare(sd->tts);
+ r = tts_prepare(tw->tts);
tts_state_e state;
- tts_get_state(sd->tts, &state);
+ tts_get_state(tw->tts, &state);
DEBUG("Prepare tts %d (%s), state %d (%s)", r, get_tts_error(r), state, get_tts_state(state));
- r = tts_set_state_changed_cb(sd->tts, state_changed_cb, sd);
+ r = tts_set_state_changed_cb(tw->tts, tw_state_changed_cb, tw);
if (TTS_ERROR_NONE != r) {
ERROR("Fail to set state changed cb (%s)", get_tts_error(r));
}
- r = tts_set_utterance_started_cb(sd->tts, tts_utt_started_cb, sd);
+ r = tts_set_utterance_started_cb(tw->tts, tw_utt_started_cb, tw);
if (TTS_ERROR_NONE != r) {
ERROR("Fail to set utterance started cb (%s)", get_tts_error(r));
}
- r = tts_set_utterance_completed_cb(sd->tts, tts_utt_completed_cb, sd);
+ r = tts_set_utterance_completed_cb(tw->tts, tw_utt_completed_cb, tw);
if (TTS_ERROR_NONE != r) {
ERROR("Fail to set utterance completed cb (%s)", get_tts_error(r));
}
+
+ tw->init = 1;
DEBUG("---------------------- TTS_init END ----------------------\n\n");
- return true;
}
-void tts_shutdown(void *data)
+static
+TWData *tw_get_instance(void) {
+ static TWData instance = {0};
+ if (!instance.init)
+ tw_init_internal(&instance);
+
+ return &instance;
+}
+
+bool tw_init(void)
+{
+ DEBUG("--------------------- TTS_init START ---------------------");
+ return tw_get_instance()->init;
+}
+
+void tw_shutdown(void)
{
+ TWData *tw = tw_get_instance();
#ifndef SCREEN_READER_TV
- if (display_lock_release_timer) {
- ecore_timer_del(display_lock_release_timer);
- display_lock_release_timer = NULL;
+ if (tw->display_lock_release_timer) {
+ ecore_timer_del(tw->display_lock_release_timer);
+ tw->display_lock_release_timer = NULL;
}
#endif
- Service_Data *sd = data;
- if (!sd) {
- ERROR("Invalid parameter");
- return;
- }
- g_free(sd->current_value);
- sd->current_value = NULL;
- stop_speaking(sd);
+ stop_speaking(tw);
+ tts_destroy(tw->tts);
+ tw->tts = NULL;
+ tw->init = 0;
}
-void tts_purge(Eina_Bool only_discardables)
+void tw_purge(Eina_Bool only_discardables)
{
DEBUG("BEGIN");
- purge_commands_from_queue(&read_command_queue, only_discardables);
- if (last_read_command && last_read_command->is_playing && (last_read_command->discardable || !only_discardables)) {
- Service_Data *sd = get_pointer_to_service_data_struct();
- stop_speaking(sd);
- overwrite_last_read_command_with(NULL);
+ TWData *tw = tw_get_instance();
+ purge_commands_from_queue(&(tw->read_command_queue), only_discardables);
+ if (tw->last_read_command && tw->last_read_command->is_playing && (tw->last_read_command->discardable || !only_discardables)) {
+ stop_speaking(tw);
+ overwrite_last_read_command_with(tw, NULL);
}
DEBUG("END");
}
-Eina_Bool tts_pause_get(void)
+Eina_Bool tw_pause_get(void)
{
- DEBUG("PAUSE STATE: %d", pause_state);
- return pause_state;
+ TWData *tw = tw_get_instance();
+ DEBUG("PAUSE STATE: %d", tw->pause_state);
+ return tw->pause_state;
}
-void tts_stop_set(void)
+void tw_stop_set(void)
{
- if (last_read_command && last_read_command->discardable) {
- Service_Data *sd = get_pointer_to_service_data_struct();
- stop_speaking(sd);
- overwrite_last_read_command_with(NULL);
+ TWData *tw = tw_get_instance();
+ if (tw->last_read_command && tw->last_read_command->discardable) {
+ stop_speaking(tw);
+ overwrite_last_read_command_with(tw, NULL);
}
}
-Eina_Bool tts_pause_set(Eina_Bool pause_switch)
+Eina_Bool tw_pause_set(Eina_Bool pause_switch)
{
- Service_Data *sd = get_pointer_to_service_data_struct();
- if (!sd)
- return EINA_FALSE;
+ TWData *tw = tw_get_instance();
if (pause_switch) {
- pause_state = EINA_TRUE;
+ tw->pause_state = EINA_TRUE;
- if (tts_pause(sd->tts)) {
- pause_state = EINA_FALSE;
+ if (tts_pause(tw->tts)) {
+ tw->pause_state = EINA_FALSE;
return EINA_FALSE;
}
- if (last_read_command) {
- _reading_status_notify(READING_PAUSED, last_read_command);
+ if (tw->last_read_command) {
+ _reading_status_notify(READING_PAUSED, tw->last_read_command);
}
} else if (!pause_switch) {
// TODO(t.wozniak): close the state machine (non-empty queue and empty TTS).
- pause_state = EINA_FALSE;
+ tw->pause_state = EINA_FALSE;
- if (tts_play(sd->tts)) {
- pause_state = EINA_TRUE;
+ if (tts_play(tw->tts)) {
+ tw->pause_state = EINA_TRUE;
return EINA_FALSE;
}
- if (last_read_command) {
- _reading_status_notify(READING_RESUMED, last_read_command);
+ if (tw->last_read_command) {
+ _reading_status_notify(READING_RESUMED, tw->last_read_command);
}
}
return EINA_TRUE;
}
-void state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void *user_data)
-{
- if (pause_state) {
- DEBUG("TTS is currently paused. Resume to start reading");
- return;
- }
-
- DEBUG("++++++++++++++++state_changed_cb++++++++++++++++++");
- DEBUG("current state:%s and previous state:%s\n", get_tts_state(current), get_tts_state(previous));
- if (current == TTS_STATE_READY && previous == TTS_STATE_PLAYING
- && last_read_command && last_read_command->is_playing) {
- overwrite_last_read_command_with(NULL);
- }
-
- if (TTS_STATE_READY == current)
- tts_speak_request();
-}