[screen reader] support basic application - enhanced
authorShinwoo Kim <cinoo.kim@samsung.com>
Fri, 21 Jun 2013 14:20:09 +0000 (23:20 +0900)
committerSungho Kwak <sungho1.kwak@samsung.com>
Thu, 27 Jun 2013 06:13:31 +0000 (15:13 +0900)
Change-Id: I37cbcba652351f98ce6699f4331f4ba976a6f382

Conflicts:

packaging/efl-assist.spec

packaging/efl-assist.spec
src/include/efl_assist.h
src/include/efl_assist_screen_reader.h [new file with mode: 0644]
src/lib/CMakeLists.txt
src/lib/efl_assist_screen_reader.c [new file with mode: 0644]

index 6b04c25..295d7c0 100644 (file)
@@ -10,6 +10,8 @@ BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(capi-appfw-application)
 BuildRequires:  cmake
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(tts)
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 
index f914dce..e1a6201 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "efl_assist_editfield.h"
 #include "efl_assist_events.h"
+#include "efl_assist_screen_reader.h"
 
 #endif /* __EFL_ASSIST_H__ */
 
diff --git a/src/include/efl_assist_screen_reader.h b/src/include/efl_assist_screen_reader.h
new file mode 100644 (file)
index 0000000..42c20a8
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+#ifndef __EFL_ASSIST_SCREEN_READER_H__
+#define __EFL_ASSIST_SCREEN_READER_H__
+
+#include <Elementary.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Set an application window property whether the application supports screen reader or not.
+ *
+ * @return ret The return value that indicates this function works properly or not.
+ *             If this function works without error, the ret will be EINA_TRUE.
+ *
+ * @param[in] win The window(elm_win) object of the application.
+ * @param[in] support The property value that will set to the windonw(elm_win).
+ *
+ * @brief  This function sets an application window property which indicates the application
+ *         supports screen reader or not.
+ */
+EAPI Eina_Bool ea_screen_reader_support_set(Evas_Object *win, Eina_Bool support);
+
+/**
+ * Get an application window property whether the application supports screen reader or not.
+ *
+ * @return property The property value that an application has currently.
+ *
+ * @brief  This function gets an application window property which indicates the application
+ *         supports screen reader or not.
+ */
+EAPI Eina_Bool ea_screen_reader_support_get();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EFL_ASSIST_SCREEN_READER_H__ */
index 3e3656c..e45b392 100644 (file)
@@ -9,7 +9,8 @@ else (DESKTOP)
        SET(LIB_SRCS
                efl_assist.c
                efl_assist_editfield.c
-               efl_assist_events.c)
+               efl_assist_events.c
+               efl_assist_screen_reader.c)
 endif (DESKTOP)
 
 ADD_LIBRARY(${LIB_NAME} SHARED ${LIB_SRCS})
@@ -19,7 +20,7 @@ if (DESKTOP)
        ADD_DEFINITIONS("-DDESKTOP=1")
        ADD_DEFINITIONS("-DEXPORT_API=__attribute__((visibility(\"default\")))")
 else (DESKTOP)
-       PKG_CHECK_MODULES(LIB_PKGS REQUIRED elementary capi-base-common capi-appfw-application)
+       PKG_CHECK_MODULES(LIB_PKGS REQUIRED elementary capi-base-common capi-appfw-application vconf tts)
 endif (DESKTOP)
 
 FOREACH(flag ${LIB_PKGS_CFLAGS})
diff --git a/src/lib/efl_assist_screen_reader.c b/src/lib/efl_assist_screen_reader.c
new file mode 100644 (file)
index 0000000..506308f
--- /dev/null
@@ -0,0 +1,179 @@
+#include "efl_assist.h"
+#include "efl_assist_private.h"
+#include <Ecore_X.h>
+#include <vconf.h>
+#include <tts.h>
+#define UNAVAILABLE_TEXT "Screen reader is unavailable during using this application. You can press home or back key to go back to home screen."
+
+static tts_h tts = NULL;
+
+static void _tts_shutdown(void)
+{
+   int ret = 0;
+   if (tts)
+     {
+        /* check current state */
+        tts_state_e state;
+        tts_get_state(tts, &state);
+        if (state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED)
+          {
+             ret = tts_stop(tts);
+             if (TTS_ERROR_NONE != ret)
+               {
+                  fprintf(stderr, "Fail to stop handle : result(%d)", ret);
+                  return;
+               }
+          }
+
+        /* it is possible to try to shutdown before the state is ready,
+           because tts_prepare(); works Asynchronously. see elm_modapi_init(): */
+        if (state == TTS_STATE_READY)
+          {
+             ret = tts_unprepare(tts);
+             if (TTS_ERROR_NONE != ret)
+               {
+                  fprintf(stderr, "Fail to unprepare handle : result(%d)", ret);
+                  return;
+               }
+
+             ret = tts_unset_state_changed_cb(tts);
+             if (TTS_ERROR_NONE != ret)
+               {
+                  fprintf(stderr, "Fail to set callback : result(%d)", ret);
+                  return;
+               }
+          }
+
+        ret = tts_destroy(tts);
+        if (TTS_ERROR_NONE != ret)
+          {
+             fprintf(stderr, "Fail to destroy handle : result(%d)", ret);
+             return;
+          }
+
+        if (tts) tts = NULL;
+     }
+}
+
+void _tts_state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* data)
+{
+   int ret = 0;
+   int u_id = 0;
+
+   if (TTS_STATE_CREATED == previous && TTS_STATE_READY == current)
+     {
+        ret = tts_add_text(tts, UNAVAILABLE_TEXT, NULL, TTS_VOICE_TYPE_AUTO,
+                           TTS_SPEED_AUTO, &u_id);
+        if (TTS_ERROR_NONE != ret)
+          {
+             fprintf(stderr, "Fail to add kept text : ret(%d)\n", ret);
+          }
+
+        ret = tts_play(tts);
+        if (TTS_ERROR_NONE != ret)
+          {
+             fprintf(stderr, "Fail to play TTS : ret(%d)\n", ret);
+          }
+     }
+}
+
+static void _tts_init(void)
+{
+   int ret = 0;
+
+   ret = tts_create(&tts);
+   if (TTS_ERROR_NONE != ret)
+     {
+        fprintf(stderr, "Fail to get handle : result(%d)", ret);
+        return;
+     }
+
+   ret = tts_set_state_changed_cb(tts, _tts_state_changed_cb, NULL);
+   if (TTS_ERROR_NONE != ret)
+     {
+        fprintf(stderr, "Fail to set callback : result(%d)", ret);
+        return;
+     }
+
+   ret = tts_set_mode(tts, TTS_MODE_SCREEN_READER);
+   if (TTS_ERROR_NONE != ret)
+     {
+        fprintf(stderr, "Fail to set mode : result(%d)", ret);
+        return;
+     }
+
+   ret = tts_prepare(tts);
+   if (TTS_ERROR_NONE != ret)
+     {
+        fprintf(stderr, "Fail to prepare handle : result(%d)", ret);
+        return;
+     }
+}
+
+static void _timeout_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   Ecore_X_Window xwin;
+   unsigned int val;
+
+   xwin = elm_win_xwindow_get(data);
+   if (!xwin) return;
+
+   evas_object_del(obj);
+
+   val = 2;
+   ecore_x_window_prop_card32_set
+     (xwin, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, &val, 1);
+
+   _tts_shutdown();
+}
+
+EAPI Eina_Bool
+ea_screen_reader_support_set(Evas_Object *win, Eina_Bool support)
+{
+   Ecore_X_Window xwin;
+   unsigned int val;
+   int tts_val;
+   Evas_Object *base;
+   Evas_Object *body;
+   Evas_Object *popup;
+
+   if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &tts_val) != 0)
+     return EINA_FALSE;
+
+   if (!tts_val) return EINA_FALSE;
+
+   if (!win) return EINA_FALSE;
+
+   xwin = elm_win_xwindow_get(win);
+   if (!xwin) return EINA_FALSE;
+
+   if (support)
+     {
+        val = 0;
+        elm_config_access_set(EINA_TRUE);
+
+        ecore_x_window_prop_card32_set
+          (xwin, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, &val, 1);
+     }
+   else
+     {
+        elm_config_access_set(EINA_FALSE);
+
+        popup = elm_popup_add(win);
+        evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        elm_object_text_set(popup, UNAVAILABLE_TEXT);
+        elm_popup_timeout_set(popup, 12.0);
+        evas_object_smart_callback_add(popup, "timeout", _timeout_cb, win);
+
+        _tts_init();
+        evas_object_show(popup);
+     }
+
+   return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ea_screen_reader_support_get()
+{
+   return elm_config_access_get();
+}