Merge screen-reader with smart-navigator
authorLukasz Stanislawski <l.stanislaws@samsung.com>
Tue, 30 Dec 2014 16:01:00 +0000 (17:01 +0100)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Tue, 30 Dec 2014 16:02:28 +0000 (17:02 +0100)
20 files changed:
CMakeLists.txt
include/common_helpers.h [new file with mode: 0644]
include/dbg.h [new file with mode: 0644]
include/screen_reader.h [new file with mode: 0644]
include/screen_reader_spi.h [new file with mode: 0644]
include/screen_reader_tts.h [new file with mode: 0644]
include/screen_reader_vconf.h [new file with mode: 0644]
include/screen_reader_xml.h [new file with mode: 0644]
include/xml_parser.h [new file with mode: 0644]
org.tizen.smart-navigator.manifest
packaging/org.tizen.etest.spec~
packaging/org.tizen.smart-navigator.spec
src/main.c
src/navigator.c
src/screen_reader.c [new file with mode: 0755]
src/screen_reader_spi.c [new file with mode: 0644]
src/screen_reader_tts.c [new file with mode: 0644]
src/screen_reader_vconf.c [new file with mode: 0644]
src/screen_reader_xml.c [new file with mode: 0644]
src/xml_parser.c [new file with mode: 0755]

index 9020d8b..10e6629 100755 (executable)
@@ -16,7 +16,11 @@ pkg_check_modules(pkgs REQUIRED
        ecore
        atspi-2
        gobject-2.0
-        ecore-x
+       ecore-x
+       dlog
+       vconf
+       tts
+
 )
 
 FOREACH(flag ${pkgs_CFLAGS})
diff --git a/include/common_helpers.h b/include/common_helpers.h
new file mode 100644 (file)
index 0000000..a34ccf1
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * common_helpers.h
+ *
+ *  Created on: Feb 19, 2014
+ *      Author: m.skorupinsk
+ */
+
+#ifndef COMMON_HELPERS_H_
+#define COMMON_HELPERS_H_
+
+#include <dlog.h>
+
+#ifdef DEBUG
+       #define PLOG(fmt, ...) \
+               fprintf(stderr, "<D> %s(%d) --> ", __FUNCTION__, __LINE__); \
+               fprintf(stderr, fmt, ##__VA_ARGS__);\
+               fprintf(stderr, "\n");\
+               LOGD(fmt, ##__VA_ARGS__);
+
+       #define PLOGD(fmt, ...) \
+               PLOG(fmt, ##__VA_ARGS__)
+
+       #define PLOGW(fmt, ...) \
+               fprintf(stderr, "<W> %s(%d) --> ", __FUNCTION__, __LINE__); \
+               fprintf(stderr, fmt, ##__VA_ARGS__);\
+               fprintf(stderr, "\n");\
+               LOGD(fmt, ##__VA_ARGS__);
+
+       #define PLOGE(fmt, ...) \
+               fprintf(stderr, "<E> %s(%d) --> ", __FUNCTION__, __LINE__); \
+               fprintf(stderr, fmt, ##__VA_ARGS__);\
+               fprintf(stderr, "\n");\
+               LOGD(fmt, ##__VA_ARGS__);
+
+       #define PLOGI(fmt, ...) \
+               fprintf(stderr, "<I> %s(%d) --> ", __FUNCTION__, __LINE__); \
+               fprintf(stderr, fmt, ##__VA_ARGS__);\
+               fprintf(stderr, "\n");\
+               LOGD(fmt, ##__VA_ARGS__);
+
+#else
+
+       #define PLOG(fmt, ...) \
+               LOGD(fmt, ##__VA_ARGS__);
+
+       #define PLOGD(fmt, ...) \
+               PLOG(fmt, ##__VA_ARGS__);
+
+       #define PLOGW(fmt, ...) \
+               LOGW(fmt, ##__VA_ARGS__);
+
+       #define PLOGE(fmt, ...) \
+               LOGE(fmt, ##__VA_ARGS__);
+
+       #define PLOGI(fmt, ...) \
+               LOGI(fmt, ##__VA_ARGS__);\
+
+#endif
+
+#endif /* COMMON_HELPERS_H_ */
diff --git a/include/dbg.h b/include/dbg.h
new file mode 100644 (file)
index 0000000..fa50e0b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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 __DBG_H__
+
+#include <dlog.h>
+
+#ifdef  LOG_TAG
+#undef  LOG_TAG
+#endif
+#define LOG_TAG "org.tizen.clientDBusWrapper"
+
+#ifndef _ERR
+#define _ERR(fmt, args...) LOGE("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
+#endif
+
+#ifndef _DBG
+#define _DBG(fmt, args...) LOGD("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
+#endif
+
+#ifndef _INFO
+#define _INFO(fmt, args...) LOGI("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
+#endif
+
+
+#endif /* __DBG_H__ */
diff --git a/include/screen_reader.h b/include/screen_reader.h
new file mode 100644 (file)
index 0000000..dc7735e
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef __screen_reader_H__
+#define __screen_reader_H__
+
+#include <atspi/atspi.h>
+#include <Eldbus.h>
+#include <tts.h>
+
+#define LAN_NAME 6
+
+#define MAX_REACHED ", maximum value reached"
+#define MIN_REACHED ", minimum value reached"
+#define MAX_POS_REACHED ", end of text reached"
+#define MIN_POS_REACHED ", begin of text reached"
+
+#define HIGHLIGHT_SIG "highlighted"
+#define FOCUS_SIG "focused"
+
+#define HIGHLIGHT_CHANGED_SIG "object:state-changed:highlighted"
+#define FOCUS_CHANGED_SIG "object:state-changed:focused"
+#define VALUE_CHANGED_SIG "object:property-change:accessible-value"
+#define CARET_MOVED_SIG "object:text-caret-moved"
+
+typedef struct
+{
+       char *language;
+       int voice_type;
+} Voice_Info;
+
+
+typedef enum
+{
+       read_as_xml,
+       read_as_plain,
+       dont_read
+} Wrong_Validation_Reacction;
+
+typedef struct _Service_Data
+{
+       //Set by vconf
+       int information_level;
+       bool run_service;
+       char language[LAN_NAME];
+       int voice_type;
+       int reading_speed;
+       char *tracking_signal_name;
+
+       //Set by tts
+       tts_h tts;
+       Eina_List *available_languages;
+
+       char *text_to_say_text;
+       char *description_text;
+       char *text_to_say_info;
+       char *current_value;
+       char *current_char;
+
+       //Actions to do when tts state is 'ready'
+       int _dbus_txt_readed;
+       bool say_text;
+       bool update_language_list;
+
+       //Set by spi
+       AtspiEventListener *state_changed_listener;
+       AtspiEventListener *value_changed_listener;
+       AtspiEventListener *caret_moved_listener;
+
+       AtspiAccessible  *currently_focused;
+       AtspiAccessible  *mouse_down_widget;
+       AtspiAccessible  *clicked_widget;
+
+       //Set by dbus
+       Eldbus_Proxy *proxy;
+       char **last_tokens;
+       char *available_requests;
+       char **available_apps;
+
+       const char *text_from_dbus;
+
+} Service_Data;
+
+Service_Data *get_pointer_to_service_data_struct();
+
+int screen_reader_create_service(void *data);
+
+int screen_reader_terminate_service(void *data);
+
+#endif
diff --git a/include/screen_reader_spi.h b/include/screen_reader_spi.h
new file mode 100644 (file)
index 0000000..4056e84
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * screen_reader_spi.h
+ *
+ *  Created on: Feb 20, 2014
+ *      Author: m.skorupinsk
+ */
+
+#ifndef SCREEN_READER_SPI_H_
+#define SCREEN_READER_SPI_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlog.h>
+
+#include <atspi/atspi.h>
+#include "screen_reader_tts.h"
+
+#include "screen_reader.h"
+#include "common_helpers.h"
+
+void spi_init(Service_Data *sd);
+void spi_on_state_changed_cb(const AtspiEvent *event, void *user_data);
+void spi_on_caret_move_cb(const AtspiEvent *event, void *user_data);
+void spi_on_access_value_changed_cb(const AtspiEvent *event, void *user_data);
+
+#endif /* SCREEN_READER_SPI_H_ */
diff --git a/include/screen_reader_tts.h b/include/screen_reader_tts.h
new file mode 100644 (file)
index 0000000..17eca2a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * screen_reader_tts.h
+ *
+ *  Created on: Feb 19, 2014
+ *      Author: m.skorupinsk
+ */
+
+#ifndef SCREEN_READER_TTS_H_
+#define SCREEN_READER_TTS_H_
+
+//#include <app_service.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <Ecore.h>
+
+#include <tts.h>
+
+#include "screen_reader.h"
+#include "common_helpers.h"
+
+
+extern tts_h h_tts;
+extern char* language;
+extern int voice;
+extern int speed;
+
+bool tts_init(void *data);
+void state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* user_data);
+bool update_supported_voices(void *data);
+void spi_prepare_text(void *data);
+void tts_append_text(void *data);
+void spi_stop(void *data);
+
+#endif /* SCREEN_READER_TTS_H_ */
diff --git a/include/screen_reader_vconf.h b/include/screen_reader_vconf.h
new file mode 100644 (file)
index 0000000..c598632
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * screen_reader_vconf.h
+ *
+ *  Created on: Feb 19, 2014
+ *      Author: m.skorupinsk
+ */
+
+#ifndef SCREEN_READER_VCONF_H_
+#define SCREEN_READER_VCONF_H_
+
+#include "screen_reader.h"
+#include <vconf.h>
+
+bool vconf_init(Service_Data *service_data);
+
+#endif /* SCREEN_READER_VCONF_H_ */
diff --git a/include/screen_reader_xml.h b/include/screen_reader_xml.h
new file mode 100644 (file)
index 0000000..40e5615
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * screen_reader_xml.h
+ *
+ *  Created on: Mar 26, 2014
+ *      Author: m.skorupinsk
+ */
+
+#ifndef SCREEN_READER_XML_H_
+#define SCREEN_READER_XML_H_
+
+#include <Eina.h>
+#include "xml_parser.h"
+#include "screen_reader.h"
+#include "common_helpers.h"
+
+void xml_init(Service_Data *sd);
+char *get_text_to_read(const char *action, AtspiAccessible *widget);
+
+#endif /* SCREEN_READER_XML_H_ */
diff --git a/include/xml_parser.h b/include/xml_parser.h
new file mode 100644 (file)
index 0000000..6cb13ef
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __ETEST_H__
+#define __ETEST_H__
+
+#include <stdbool.h>
+
+typedef struct
+{
+       char *tag_type;
+       Eina_Simple_XML_Attribute **pairs;
+} Tag;  //TODO: Zamienić na standard ??
+
+void test_fun();
+
+char *get_string_str(Tag *tags, char *descr, Eina_Simple_XML_Attribute **pairs, char *tag_name);
+
+void print_tree(Eina_Simple_XML_Node_Tag *tag, int text_offset);
+
+Eina_Simple_XML_Node_Tag *modify_tag(Tag *tags,  Eina_Simple_XML_Node_Tag *root,
+               const char *tag_name,     Eina_Simple_XML_Attribute **pairs,
+               const char *new_tag_name, Eina_Simple_XML_Attribute **new_pairs, const char *new_data);
+
+Eina_Simple_XML_Node_Tag *add_tag(Tag *tags,  Eina_Simple_XML_Node_Tag *root,
+               const char *tag, const char *data, Eina_Simple_XML_Attribute **pairs);
+
+Eina_Simple_XML_Node_Tag *add_tag_str(Tag *tags,  Eina_Simple_XML_Node_Root *root, const char *tag_str);
+
+#endif
index b5f0f1a..384adae 100644 (file)
@@ -5,28 +5,31 @@
        <smack permit="dbus" type="rwx" />
        <smack permit="atspi" type="rwx" />
        <smack permit="e17" type="rwx" />
+       <smack permit="tts-server" type="rwx" />
     </permit>
     <request>
        <smack request="sdbd" type="rwx" />
        <smack request="atspi" type="rwx" />
        <smack request="dbus" type="rwx" />
        <smack request="xorg" type="rwx" />
-       <smack request="system::vconf_multimedia" type="rwx" />
-       <smack request="pulseaudio" type="rwx" />
+       <smack request="pulseaudio" type="rwxat" />
        <smack request="pkgmgr::db" type="rwx" />
        <smack request="device::app_logging" type="rwx" />
        <smack request="ail::db" type="rwx" />
-        <smack request="system::vconf_setting" type="rwx" />
-         <smack request="system::vconf_system" type="rwx" />
-        <smack request="isf" type="rwx" />
-        <smack request="system::vconf" type="rwx" />
-        <smack request="system::vconf_inhouse" type="rwx" />
+       <smack request="system::vconf" type="rwx" />
+       <smack request="system::vconf_setting" type="rwx" />
+       <smack request="system::vconf_system" type="rwx" />
+       <smack request="system::vconf_inhouse" type="rwx" />
+       <smack request="system::vconf_multimedia" type="rwx" />
+       <smack request="system::vconf_misc" type="rwx" />
+       <smack request="isf" type="rwx" />
        <smack request="system::homedir" type="rwx" />
        <smack request="sys-assert::core" type="rwxat" />
-       <smack request="system::vconf_misc" type="rwx" />
        <smack request="device::sys_logging" type="rwx" />
-     <smack request="svi-data" type="rwx" />
-     <smack request="e17" type="rwx" />
+       <smack request="svi-data" type="rwx" />
+       <smack request="e17" type="rwx" />
+       <smack request="tts-server" type="rwx" />
+       <smack request="home-lite" type="rwx" />
     </request>
  </define>
 
index 1966ae5..5beebce 100644 (file)
@@ -15,6 +15,8 @@ BuildRequires:  pkgconfig(eina)
 BuildRequires:  pkgconfig(evas)
 BuildRequires:  pkgconfig(bundle)
 BuildRequires:  cmake
+BuildRequires:  tts
+BuildRequires:  tts-devel
 
 
 %description
index fc7aa6b..19f9d0f 100755 (executable)
@@ -9,15 +9,22 @@ Release:    1
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 
-BuildRequires:  pkgconfig(appcore-efl)
-BuildRequires:  pkgconfig(eldbus)
-BuildRequires:  pkgconfig(ecore)
-BuildRequires:  pkgconfig(bundle)
-BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  at-spi2-core
 BuildRequires:  at-spi2-core-devel
 BuildRequires:  cmake
+BuildRequires:  pkgconfig(appcore-efl)
+BuildRequires:  pkgconfig(ecore)
 BuildRequires:  pkgconfig(ecore-x)
+BuildRequires:  pkgconfig(edje)
+BuildRequires:  pkgconfig(eina)
+BuildRequires:  pkgconfig(eldbus)
+BuildRequires:  pkgconfig(elementary)
+BuildRequires:  pkgconfig(bundle)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  smack
+BuildRequires:  tts
+BuildRequires:  tts-devel
+BuildRequires:  vconf
 
 %description
 An utility library for developers of the menu screen.
@@ -35,6 +42,10 @@ rm -rf %{buildroot}
 
 %post 
 /sbin/ldconfig
+vconftool set -t string db/setting/accessibility/language "en_US" -u 5000 -s smart-navigator -f
+vconftool set -t int db/setting/accessibility/information_level 2 -u 5000 -s smart-navigator -f
+vconftool set -t int db/setting/accessibility/voice 1 -u 5000 -s smart-navigator -f
+vconftool set -t string db/setting/accessibility/tracking_signal "highlighted" -u 5000 -s smart-navigator -f
 
 %postun -p /sbin/ldconfig
 
index d928fe8..7047a92 100755 (executable)
@@ -4,6 +4,7 @@
 #include "window_tracker.h"
 #include "gesture_tracker.h"
 #include "logger.h"
+#include "screen_reader.h"
 
 #define A11Y_BUS "org.a11y.Bus"
 #define A11Y_INTERFACE "org.a11y.Bus"
@@ -33,11 +34,17 @@ static int app_create(void *data)
     Eldbus_Object *a11y_obj = eldbus_object_get(session_conn, A11Y_BUS, A11Y_PATH);
     Eldbus_Proxy *manager = eldbus_proxy_get(a11y_obj, A11Y_INTERFACE);
     eldbus_proxy_call(manager, A11Y_GET_ADDRESS, _init_modules, data, -1, "");
+
+    screen_reader_create_service(data);
+
     return 0;
 }
 
 static int app_terminate(void *data)
 {
+
+    screen_reader_terminate_service(data);
+
     eldbus_connection_unref(a11y_conn);
     gesture_tracker_shutdown();
     navigator_shutdown();
@@ -59,6 +66,7 @@ int main(int argc, char **argv)
         .reset = NULL
     };
 
-    ops.data = NULL;
+    ops.data = get_pointer_to_service_data_struct();
+
     return appcore_efl_main("Smart Navigation", &argc, &argv, &ops);
 }
index 9d0dc94..4b82100 100644 (file)
@@ -478,13 +478,13 @@ static void _activate_widget(void)
 
         for (i=0; i<number; i++)
         {
-            actionName = atspi_action_get_name(action, i, err);
+            actionName = atspi_action_get_name(action, i, &err);
             ERROR("Action name = %s\n", actionName);
             GERROR_CHECK(err)
 
             if (actionName && !strcmp("click", actionName))
             {
-                atspi_action_do_action(action, 0, err);
+                atspi_action_do_action(action, 0, &err);
                 GERROR_CHECK(err)
                 #ifdef DEBUG_MODE
                     test_debug(current_widget);
diff --git a/src/screen_reader.c b/src/screen_reader.c
new file mode 100755 (executable)
index 0000000..686e0f6
--- /dev/null
@@ -0,0 +1,100 @@
+#include "screen_reader.h"
+#include <vconf.h>
+#include "logger.h"
+
+
+#ifdef RUN_IPC_TEST_SUIT
+       #include "test_suite/test_suite.h"
+       #include "test_suite/xml_parser_test.h"
+#endif
+
+
+#define BUF_SIZE 1024
+
+Service_Data service_data = {
+               //Set by vconf
+               .information_level = 1,
+               .run_service = 1,
+               .language = "en_US",
+               .voice_type = TTS_VOICE_TYPE_FEMALE,
+               .reading_speed = 2,
+               .tracking_signal_name = HIGHLIGHT_CHANGED_SIG,
+
+
+               //Set by tts
+               .tts = NULL,
+               .available_languages = NULL,
+
+               //Actions to do when tts state is 'ready'
+               .say_text = false,
+               .update_language_list = false,
+
+
+               .text_to_say_text = NULL,
+               .text_to_say_info = NULL
+};
+
+Service_Data *get_pointer_to_service_data_struct()
+{
+  return &service_data;
+}
+
+int screen_reader_create_service(void *data)
+{
+       DEBUG("Service Create Callback \n");
+
+       Service_Data *service_data = data;
+
+       tts_init(service_data);
+       vconf_init(service_data);
+       spi_init(service_data);
+       xml_init(service_data);
+
+
+       /* XML TEST */
+
+       #ifdef RUN_IPC_TEST_SUIT
+               run_xml_tests();
+               test_suite_init();
+       #endif
+
+       return 0;
+}
+
+int screen_reader_terminate_service(void *data)
+{
+       DEBUG("Service Terminate Callback \n");
+
+       Service_Data *service_data = data;
+
+       int vconf_ret = vconf_set_bool("db/setting/accessibility/screen_reader", EINA_FALSE);
+       if(vconf_ret == 0)
+       {
+               DEBUG("TTS key set to false");
+       }
+       else
+       {
+               DEBUG("COULD NOT SET tts key to 0");
+       }
+
+       
+       vconf_ret = vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, EINA_FALSE);
+       if(vconf_ret == 0)
+       {
+               DEBUG("TTS key set to false");
+       }
+       else
+       {
+               DEBUG("COULD NOT SET tts key to 0");
+       }
+
+       tts_stop(service_data->tts);
+       tts_unprepare(service_data->tts);
+       tts_destroy(service_data->tts);
+       service_data->text_to_say_text = NULL;
+       service_data->description_text = NULL;
+       service_data->text_from_dbus = NULL;
+       service_data->current_value = NULL;
+
+       return 0;
+}
diff --git a/src/screen_reader_spi.c b/src/screen_reader_spi.c
new file mode 100644 (file)
index 0000000..b334088
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * sreen_reader_spi.c
+ *
+ *  Created on: Feb 20, 2014
+ *  Author: m.skorupinsk
+ */
+
+#include <unistd.h>
+#include "screen_reader_spi.h"
+#include "screen_reader_xml.h"
+#ifdef RUN_IPC_TEST_SUIT
+       #include "test_suite/test_suite.h"
+#endif
+
+static Service_Data *service_data;
+
+#ifdef LOG_TAG
+       #undef LOG_TAG
+#endif
+#define LOG_TAG "SCREEN READER SPI"
+
+typedef struct
+{
+       char *key;
+       char *val;
+} Attr;
+
+static void display_info(const AtspiEvent *event)
+{
+       AtspiAccessible  *source = event->source;
+       gchar *name= atspi_accessible_get_name(source, NULL);
+       gchar *role= atspi_accessible_get_role_name(source, NULL);
+       gchar *toolkit = atspi_accessible_get_toolkit_name(source, NULL);
+
+       PLOG("--------------------------------------------------------");
+       PLOG("Toolkit: %s; Event_type: %s; (%d, %d)", toolkit, event->type, event->detail1, event->detail2);
+       PLOG("Name: %s; Role: %s", name, role);
+       PLOG("--------------------------------------------------------");
+}
+
+Eina_Bool double_click_timer_cb(void *data)
+{
+       Service_Data *sd = data;
+       sd->clicked_widget = NULL;
+
+       return EINA_FALSE;
+}
+
+void spi_on_state_changed_cb(const AtspiEvent *event, void *user_data)
+{
+       PLOG("START");
+       PLOG("STATE CHANGED");
+       Service_Data *sd = user_data;
+
+       display_info(event);
+       if(strcmp(event->type, sd->tracking_signal_name) == 0 && event->detail1 == 1)
+       {
+               sd->currently_focused = event->source;
+
+               PLOG("->->->->->-> WIDGET GAINED HIGHLIGHT: %s <-<-<-<-<-<-<-",
+                               atspi_accessible_get_name(sd->currently_focused, NULL));
+
+               sd->description_text = atspi_accessible_get_description(sd->currently_focused, NULL);
+               if(strcmp(sd->description_text, "\0") == 0)
+               {
+                       sd->description_text = atspi_accessible_get_name(sd->currently_focused, NULL);
+                       if(strcmp(sd->description_text, "\0") == 0)
+                               sd->description_text = (char*)atspi_accessible_get_role_name(sd->currently_focused, NULL);
+               }
+               sd->text_to_say_text = get_text_to_read("on_focus", sd->currently_focused);
+               spi_prepare_text(sd);
+       }
+
+       PLOG("END");
+}
+
+void spi_on_caret_move_cb(const AtspiEvent *event, void *user_data)
+{
+       PLOG("START");
+       PLOG("CARET MOVED");
+       Service_Data *sd = user_data;
+       int char_count;
+       gint caret_pos;
+       char buf[256];
+
+       display_info(event);
+       if(strcmp(event->type, CARET_MOVED_SIG) == 0)
+       {
+               sd->currently_focused = event->source;
+
+               AtspiText *text_interface = atspi_accessible_get_text(sd->currently_focused);
+               if(text_interface)
+               {
+                       PLOG("->->->->->-> WIDGET CARET MOVED: %s <-<-<-<-<-<-<-",
+                                atspi_accessible_get_name(sd->currently_focused, NULL));
+
+                       char_count = (int)atspi_text_get_character_count(text_interface, NULL);
+                       caret_pos = atspi_text_get_caret_offset(text_interface, NULL);
+                       if(!caret_pos)
+                       {
+                               PLOG("MIN POSITION REACHED");
+                               sprintf(buf, "%s %s", (char*)atspi_text_get_text(text_interface, caret_pos, caret_pos + 1, NULL), MIN_POS_REACHED);
+                       }
+                       else if(char_count == caret_pos)
+                       {
+                               PLOG("MAX POSITION REACHED");
+                               sprintf(buf, "%s %s", (char*)atspi_text_get_text(text_interface, caret_pos, caret_pos + 1, NULL), MAX_POS_REACHED);
+                       }
+                       else
+                               sprintf(buf, "%s", (char*)atspi_text_get_text(text_interface, caret_pos, caret_pos + 1, NULL));
+
+                       sd->text_to_say_text = strdup(buf);
+                       spi_prepare_text(sd);
+               }
+       }
+
+       PLOG("END");
+}
+
+void spi_on_access_value_changed_cb(const AtspiEvent *event, void *user_data)
+{
+       PLOG("START");
+       PLOG("STATE CHANGED");
+       Service_Data *sd = user_data;
+       double current_temp_value;
+       char buf[256];
+
+       display_info(event);
+       if(strcmp(event->type, VALUE_CHANGED_SIG) == 0)
+       {
+               sd->currently_focused = event->source;
+
+               AtspiValue *value_interface = atspi_accessible_get_value(sd->currently_focused);
+               if(value_interface)
+               {
+                       PLOG("->->->->->-> WIDGET VALUE CHANGED: %s <-<-<-<-<-<-<-",
+                                atspi_accessible_get_name(sd->currently_focused, NULL));
+
+                       current_temp_value = (double)atspi_value_get_current_value(value_interface, NULL);
+                       if(current_temp_value == atspi_value_get_maximum_value(value_interface, NULL))
+                       {
+                               PLOG("MAX VALUE REACHED");
+                               sprintf(buf, "%.2f %s", current_temp_value, MAX_REACHED);
+                       }
+                       else if(current_temp_value == atspi_value_get_minimum_value(value_interface, NULL))
+                       {
+                               PLOG("MIN VALUE REACHED");
+                               sprintf(buf, "%.2f %s", current_temp_value, MIN_REACHED);
+                       }
+                       else
+                               sprintf(buf, "%.2f", current_temp_value);
+
+                       sd->text_to_say_text = strdup(buf);
+                       spi_prepare_text(sd);
+               }
+       }
+       PLOG("END");
+}
+
+void spi_init(Service_Data *sd)
+{
+
+       PLOG( "--------------------- SPI_init START ---------------------");
+       service_data = sd;
+
+       PLOG( ">>> Creating listeners <<<");
+
+       sd->state_changed_listener = atspi_event_listener_new(spi_on_state_changed_cb, service_data, NULL);
+       if(sd->state_changed_listener == NULL)
+       {
+               PLOG("FAILED TO CREATE spi state changed listener")
+       }
+
+       sd->caret_moved_listener = atspi_event_listener_new(spi_on_caret_move_cb, service_data, NULL);
+       if(sd->caret_moved_listener == NULL)
+       {
+               PLOG("FAILED TO CREATE spi state changed listener")
+       }
+
+       sd->value_changed_listener = atspi_event_listener_new(spi_on_access_value_changed_cb, service_data, NULL);
+       if(sd->value_changed_listener == NULL)
+       {
+               PLOG("FAILED TO CREATE spi state changed listener")
+       }
+
+       // ---------------------------------------------------------------------------------------------------
+
+       gboolean ret1 = atspi_event_listener_register(sd->state_changed_listener, sd->tracking_signal_name, NULL);
+       if(ret1 == false)
+       {
+               PLOG("FAILED TO REGISTER spi focus/highlight listener");
+       }
+
+       gboolean ret2 = atspi_event_listener_register(sd->caret_moved_listener, CARET_MOVED_SIG, NULL);
+       if(ret2 == false)
+       {
+               PLOG("FAILED TO REGISTER spi caret moved listener");
+       }
+
+       gboolean ret3 = atspi_event_listener_register(sd->value_changed_listener, VALUE_CHANGED_SIG, NULL);
+       if(ret3 == false)
+       {
+               PLOG("FAILED TO REGISTER spi value changed listener");
+       }
+
+       if(ret1 == true && ret2 == true && ret3 == true)
+       {
+               PLOG("spi listener REGISTERED");
+       }
+
+       PLOG( "---------------------- SPI_init END ----------------------\n\n");
+}
diff --git a/src/screen_reader_tts.c b/src/screen_reader_tts.c
new file mode 100644 (file)
index 0000000..e0bfa31
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * screen_reader_tts.c
+ *
+ *  Created on: Feb 19, 2014
+ *  Author: m.skorupinsk
+ */
+#include "screen_reader_tts.h"
+#include "logger.h"
+
+// ---------------------------- DEBUG HELPERS ------------------------------
+
+static char * get_tts_error( int r )
+{
+       switch( r )
+       {
+               case TTS_ERROR_NONE:
+               {
+                       return "no error";
+               }
+               case TTS_ERROR_INVALID_PARAMETER:
+               {
+                       return "inv param";
+               }
+               case TTS_ERROR_OUT_OF_MEMORY:
+               {
+                       return "out of memory";
+               }
+               case TTS_ERROR_OPERATION_FAILED:
+               {
+                       return "oper failed";
+               }
+               case TTS_ERROR_INVALID_STATE:
+               {
+                       return "inv state";
+               }
+               default:
+               {
+                       return "inny error";
+               }
+       }
+}
+
+static char * get_tts_state( tts_state_e r )
+{
+       switch( r )
+       {
+               case TTS_STATE_CREATED:
+               {
+                       return "created";
+               }
+               case TTS_STATE_READY:
+               {
+                       return "ready";
+               }
+               case TTS_STATE_PLAYING:
+               {
+                       return "playing";
+               }
+               case TTS_STATE_PAUSED:
+               {
+                       return "pause";
+               }
+               default:
+               {
+                       return "uknown state";
+               }
+       }
+}
+
+// -------------------------------------------------------------------------------------------------
+
+bool get_supported_voices_cb(tts_h tts, const char* language, int voice_type, void* user_data)
+{
+       DEBUG("LANG: %s; TYPE: %d", language, voice_type);
+
+       Service_Data *sd = user_data;
+       Voice_Info *vi = calloc(1, sizeof(Voice_Info));
+
+       int len = strlen(language);
+
+       vi->language = calloc(len + 1, sizeof(char));
+       strcpy(vi->language, language);
+
+       vi->voice_type = voice_type;
+
+       sd->available_languages = eina_list_append(sd->available_languages, vi);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+static void __tts_test_utt_started_cb(tts_h tts, int utt_id, void* user_data)
+{
+       DEBUG("Utterance started : utt id(%d) \n", utt_id);
+
+       return;
+}
+
+static void __tts_test_utt_completed_cb(tts_h tts, int utt_id, void* user_data)
+{
+       DEBUG("Utterance completed : utt id(%d) \n", utt_id);
+
+       return;
+}
+
+bool tts_init(void *data)
+{
+       DEBUG( "--------------------- TTS_init START ---------------------");
+       Service_Data *sd = data;
+
+       int r = tts_create( &sd->tts );
+       DEBUG( "Create tts %d (%s)", r, get_tts_error( r ) );
+
+       r = tts_set_mode( sd->tts, TTS_MODE_DEFAULT );
+       DEBUG( "Set tts mode SR %d (%s)", r, get_tts_error( r ) );
+
+       r = tts_prepare( sd->tts );
+       DEBUG( "Prepare tts %d (%s)", r, get_tts_error( r ) );
+
+       tts_set_state_changed_cb(sd->tts, state_changed_cb, sd);
+
+       tts_set_utterance_started_cb(sd->tts, __tts_test_utt_started_cb, sd);
+       tts_set_utterance_completed_cb( sd->tts,  __tts_test_utt_completed_cb,  sd);
+
+       DEBUG( "---------------------- TTS_init END ----------------------\n\n");
+       return true;
+}
+
+Eina_Bool tts_speak( void * data )
+{
+       Service_Data *sd = data;
+       int speak_id;
+       const char * text_to_speak = NULL;
+
+       if (sd->_dbus_txt_readed == 0 && sd->text_from_dbus ) {
+               text_to_speak = sd->text_from_dbus;
+               sd->_dbus_txt_readed = 1;
+       }
+       else
+               text_to_speak = sd->text_to_say_text;
+
+       DEBUG( "tts_speak\n");
+       DEBUG( "text to say:%s\n", text_to_speak);
+       if ( !text_to_speak ) return EINA_FALSE;
+       if ( !text_to_speak[0] ) return EINA_FALSE;
+
+       tts_add_text( sd->tts, text_to_speak, NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &speak_id );
+       DEBUG("added id to:%d\n", speak_id);
+
+       tts_play( sd->tts );
+       return EINA_FALSE;
+
+}
+
+bool update_supported_voices(void *data)
+{
+       DEBUG("START");
+       tts_state_e state;
+
+       Service_Data *sd = data;
+
+       int res = tts_get_state(sd->tts, &state);
+
+       if(res != TTS_ERROR_NONE)
+       {
+               DEBUG("CANNOT RETRIVE STATE");
+               return false;
+       }
+
+       if(state == TTS_STATE_READY)
+       {
+               tts_foreach_supported_voices(sd->tts, get_supported_voices_cb, sd);
+       }
+       else
+       {
+               sd->update_language_list = true;
+       }
+
+       DEBUG("END")
+       return true;
+}
+
+void state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* user_data)
+{
+       DEBUG("++++++++++++++++state_changed_cb\n++++++++++++++++++");
+       DEBUG("current state:%s and previous state:%s\n", get_tts_state(current), get_tts_state(previous));
+       Service_Data *sd = user_data;
+
+       if(current == TTS_STATE_READY) {
+               DEBUG("State is ready after prepare\n");
+               tts_speak(sd);
+       }
+    else
+    {
+        DEBUG("State is diffrent then ready after prepare!\n");
+    }
+}
+
+void spi_prepare_text(void *data)
+{
+       Service_Data *sd = data;
+       sd->say_text = true;
+       sd->update_language_list = false;
+    DEBUG("PREPARE TEXT!!!!!!!!!!!!!!\n");
+        
+    tts_stop(sd->tts);
+    tts_append_text(sd);
+}
+
+void tts_append_text(void *data)
+{
+       Service_Data *sd = data;
+       tts_state_e state;
+       tts_get_state(sd->tts, &state);
+
+       DEBUG("text append:::!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+       if(state == TTS_STATE_READY)
+       {
+        DEBUG("TTS state == ready!\n");
+               tts_speak(data);
+       }
+    else
+    {
+        DEBUG("TTS state != ready!\n");
+    }
+}
+
+void spi_stop( void *data)
+{
+       Service_Data *sd = data;
+       sd->say_text = false;
+       sd->update_language_list = false;
+       free(sd->text_to_say_text);
+       free(sd->description_text);
+       free((char*)sd->text_from_dbus);
+       free(sd->current_value);
+       sd->text_to_say_text = NULL;
+       sd->description_text = NULL;
+       sd->text_from_dbus = NULL;
+       sd->current_value = NULL;
+       tts_stop(sd->tts);
+}
diff --git a/src/screen_reader_vconf.c b/src/screen_reader_vconf.c
new file mode 100644 (file)
index 0000000..fe09307
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * screen_reader_vconf.c
+ *
+ *  Created on: Feb 19, 2014
+ *      Author: m.skorupinsk
+ */
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <appcore-efl.h>
+//#include <Evas.h>
+//#include <Ecore_X.h>
+//#include <Eina.h>
+//#include "common_helpers.h"
+#include <Elementary.h>
+#include "screen_reader_vconf.h"
+#include "screen_reader_spi.h"
+#include "logger.h"
+
+#ifdef RUN_IPC_TEST_SUIT
+       #include "test_suite/test_suite.h"
+#endif
+
+#ifdef LOG_TAG
+       #undef LOG_TAG
+#endif
+#define LOG_TAG "SCREEN READER VCONF"
+
+
+keylist_t *keys = NULL;
+
+bool set_langauge(Service_Data *sd, const char *new_language, int new_voice)
+{
+       DEBUG("START");
+
+       Eina_List *l;
+       Voice_Info *vi;
+
+       if(strncmp(sd->language, new_language, LAN_NAME - 1) == 0 && sd->voice_type == new_voice)
+       {
+               DEBUG("No need to change accessibility language: %s(%d) -> %s(%d)",
+                               sd->language, sd->voice_type, new_language, new_voice);
+
+               return true;
+       }
+
+       EINA_LIST_FOREACH(sd->available_languages, l, vi)
+       {
+               DEBUG("foreach %s <- %s", vi->language, new_language);
+               if(strncmp(vi->language, new_language, LAN_NAME - 1) == 0 &&
+                               vi->voice_type == new_voice)
+               {
+                       DEBUG("str_cpy %s (%d) -> %s (%d)", sd->language, sd->voice_type, vi->language, vi->voice_type);
+                       strncpy(sd->language, vi->language, LAN_NAME - 1);
+                       sd->voice_type = vi->voice_type;
+                       DEBUG("after_str_cpy");
+
+                       DEBUG("ACCESSIBILITY LANGUAGE CHANGED");
+                       DEBUG("END");
+                       return true;
+               }
+       }
+
+       DEBUG("ACCESSIBILITY LANGUAGE FAILED TO CHANGED");
+
+       vconf_set_str("db/setting/accessibility/language", sd->language);
+       vconf_set_int("db/setting/accessibility/voice", sd->voice_type);
+
+       DEBUG("END");
+       return false;
+}
+
+char *fold_tracker_signal(const char *signal_name)
+{
+       if(strcmp(signal_name, FOCUS_SIG) == 0)
+       {
+               return FOCUS_CHANGED_SIG;
+       }
+       else
+       {
+               return HIGHLIGHT_CHANGED_SIG;
+       }
+}
+
+bool set_tracking_listener(Service_Data *sd, const char *signal_name)
+{
+       DEBUG("START");
+
+       char *new_tracking_signal;
+
+       new_tracking_signal = fold_tracker_signal(signal_name);
+
+       if(strcmp(sd->tracking_signal_name, new_tracking_signal) == 0)
+       {
+               DEBUG("No need to change accessibility tracking signal: %s == %s",
+                               sd->tracking_signal_name, new_tracking_signal);
+
+               return true;
+       }
+
+       gboolean ret = atspi_event_listener_deregister(sd->state_changed_listener, sd->tracking_signal_name, NULL);
+       if(ret == false)
+       {
+               DEBUG("Tracking signal listerner deregister successful");
+       }
+
+       sd->state_changed_listener = NULL;
+       sd->tracking_signal_name = strdup(new_tracking_signal);
+
+       sd->state_changed_listener = atspi_event_listener_new(spi_on_state_changed_cb, sd, NULL);
+       if(sd->state_changed_listener == NULL)
+       {
+               DEBUG("FAILED TO CREATE spi state changed listener")
+       }
+
+       gboolean ret1 = atspi_event_listener_register(sd->state_changed_listener, sd->tracking_signal_name, NULL);
+       if(ret1 == false)
+       {
+               DEBUG("FAILED TO REGISTER spi focus/highlight listener");
+               return false;
+       }
+       else
+       {
+               DEBUG("Tracking listener register for new signal");
+       }
+       return true;
+}
+
+// ------------------------------ vconf callbacks----------------------
+
+void information_level_cb(keynode_t *node, void *user_data)
+{
+       DEBUG("START");
+       DEBUG("Information level set: %d", node->value.i);
+
+       Service_Data *service_data = user_data;
+       service_data->information_level = node->value.i;
+
+       DEBUG("END");
+}
+
+void app_termination_cb(keynode_t *node, void *user_data)
+{
+       DEBUG("START");
+       DEBUG("Application terminate %d", !node->value.i);
+
+       Service_Data *service_data = user_data;
+       service_data->run_service = node->value.i;
+
+       if(service_data->run_service == 0)
+       {
+               elm_exit();
+       }
+
+       DEBUG("END");
+}
+
+void language_cb(keynode_t *node, void *user_data)
+{
+       DEBUG("START");
+       DEBUG("Trying to set language to: %s", node->value.s);
+
+       Service_Data *sd = user_data;
+
+       int voice_type;
+
+       vconf_get_int("db/setting/accessibility/voice", (int*)(&voice_type));
+       set_langauge(sd, node->value.s, voice_type);
+
+       DEBUG("END");
+}
+
+void voice_cb(keynode_t *node, void *user_data)
+{
+       DEBUG("START");
+       DEBUG("Voice set to: %d", node->value.i);
+
+       Service_Data *sd = user_data;
+
+       const char *lang = vconf_get_str("db/setting/accessibility/language");
+       set_langauge(sd, lang, (int)node->value.i);
+
+       DEBUG("END");
+}
+
+void reading_speed_cb(keynode_t *node, void *user_data)
+{
+       DEBUG("START");
+       DEBUG("Reading speed set to: %d", node->value.i);
+
+       Service_Data *service_data = user_data;
+       service_data->reading_speed = node->value.i;
+
+       DEBUG("END");
+}
+
+void tracking_signal_changed_cb(keynode_t *node, void *user_data)
+{
+       DEBUG("START");
+       DEBUG("Tracking signal set to: %s", node->value.s);
+
+       Service_Data *sd = user_data;
+       const char *tracking_signal = vconf_get_str("db/setting/accessibility/tracking_signal");
+       set_tracking_listener(sd, tracking_signal);
+}
+
+// --------------------------------------------------------------------
+
+int get_key_values(Service_Data *sd)
+{
+       DEBUG("START");
+
+       char *language = vconf_get_str("db/setting/accessibility/language");
+
+       if(sd->language == NULL)
+       {
+               DEBUG("FAILED TO SET LANGUAGE");
+       }
+
+       int ret = -1;
+       int to_ret = 0;
+
+
+       int voice;
+       ret = vconf_get_int("db/setting/accessibility/voice", &voice);
+       if(ret != 0)
+       {
+               to_ret -= -1;
+               DEBUG("FAILED TO SET VOICE TYPE: %d", ret);
+       }
+
+       set_langauge(sd, language, voice);
+
+       ret = vconf_get_int("db/setting/accessibility/speech_rate", &sd->reading_speed);
+       if(ret != 0)
+       {
+               to_ret -= -2;
+               DEBUG("FAILED TO SET READING SPEED: %d", ret);
+       }
+
+       ret = vconf_get_int("db/setting/accessibility/information_level", &sd->information_level);
+       if(ret != 0)
+       {
+               to_ret -= -4;
+               DEBUG("FAILED TO SET INFORMATION LEVEL: %d", ret);
+       }
+
+       DEBUG("SCREEN READER DATA SET TO: Language: %s; Voice: %d, Reading_Speed: %d, Information_Level: %d, Tracking signal: %s;",
+                       sd->language, sd->voice_type, sd->reading_speed, sd->information_level, sd->tracking_signal_name);
+
+       DEBUG("END");
+       return to_ret;
+}
+
+bool vconf_init(Service_Data *service_data)
+{
+       DEBUG( "--------------------- VCONF_init START ---------------------");
+       int ret = 0;
+
+       //TODO: Remove when adequate keys in the settings(control?) panel are added
+       // -----------------------  TEST ONLY -----------------------------------------------
+       DEBUG("TESTS START");
+       keys = vconf_keylist_new();
+       vconf_keylist_add_int(keys, "db/setting/accessibility/information_level", 2);
+       vconf_keylist_add_str(keys, "db/setting/accessibility/language", "en_US");
+       vconf_keylist_add_int(keys, "db/setting/accessibility/voice", 1);
+       vconf_keylist_add_str(keys, "db/setting/accessibility/tracking_signal", HIGHLIGHT_SIG);
+    //-----------------------------------------------------------------------------------
+       //vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, EINA_TRUE);
+
+       if(vconf_set(keys))
+       {
+               DEBUG("nothing is written\n");
+       }
+       else
+       {
+               DEBUG("everything is written\n");
+       }
+
+       vconf_keylist_free(keys);
+       // ----------------------------------------------------------------------------------
+
+       ret = get_key_values(service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not set data from vconf: %d", ret);
+       }
+
+       ret = vconf_notify_key_changed("db/setting/accessibility/information_level", information_level_cb, service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not add information level callback");
+               return false;
+       }
+
+       ret = vconf_notify_key_changed("db/setting/accessibility/screen_reader", app_termination_cb, service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not add app termination callback");
+               return false;
+       }
+
+       ret = vconf_notify_key_changed("db/menu_widget/language", language_cb, service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not add language callback");
+               return false;
+       }
+
+       ret = vconf_notify_key_changed("db/setting/accessibility/language", language_cb, service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not add language callback");
+               return false;
+       }
+
+       ret = vconf_notify_key_changed("db/setting/accessibility/voice", voice_cb, service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not add voice callback");
+               return false;
+       }
+
+       ret = vconf_notify_key_changed("db/setting/accessibility/speech_rate", reading_speed_cb, service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not add reading speed callback callback");
+               return false;
+       }
+
+       ret = vconf_notify_key_changed("db/setting/accessibility/tracking_signal", tracking_signal_changed_cb, service_data);
+       if(ret != 0)
+       {
+               DEBUG("Could not add reading speed callback callback");
+               return false;
+       }
+
+       DEBUG("ALL CALBACKS ADDED");
+
+       DEBUG( "---------------------- VCONF_init END ----------------------\n\n");
+       return true;
+}
diff --git a/src/screen_reader_xml.c b/src/screen_reader_xml.c
new file mode 100644 (file)
index 0000000..1693498
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * screen_reader_xml.c
+ *
+ *  Created on: Mar 26, 2014
+ *      Author: m.skorupinsk
+ */
+
+#include "screen_reader_xml.h"
+
+static Service_Data *service_data;
+
+char *get_text_to_read(const char *action, AtspiAccessible *widget)
+{
+       char *description = service_data->description_text;
+
+       PLOG("DESCRIPTION %s\n", description);
+
+       if(description == NULL)
+       {
+               PLOG("NULL DESCRIPTION\n");
+               return NULL;
+       }
+       else if(description[0] == 0)
+       {
+               PLOG("DESCRIPTION[0] = 0\n");
+               return NULL;
+       }
+
+       int level = service_data->information_level;
+
+       Eina_Simple_XML_Attribute *attributes[2] = {NULL, NULL};
+
+       char level_str[2];
+       snprintf(level_str, 2, "%d", level);
+
+       PLOG("THE LEVEL STRING: %s LEVEL: %d\n", level_str, level);
+
+       attributes[0] = eina_simple_xml_attribute_new(NULL, "level", level_str);
+       char *ret_str = NULL;
+
+       ret_str = get_string_str(NULL, description, attributes, "Information_Level");
+
+       eina_simple_xml_attribute_free(attributes[0]);
+
+       PLOG("\n\n-> -> -> THE STRING TO SAY: <- <- <- \n%s\n\n", ret_str);
+
+       return ret_str;
+}
+
+void xml_init(Service_Data *sd)
+{
+       service_data = sd;
+}
diff --git a/src/xml_parser.c b/src/xml_parser.c
new file mode 100755 (executable)
index 0000000..769ec16
--- /dev/null
@@ -0,0 +1,1196 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <Eina.h>
+#include "xml_parser.h"
+
+#define BUF_SIZE 1024
+
+
+void test_fun()
+{
+       printf("HELLO LIB\n");
+}
+
+
+typedef struct
+{
+       char *key;
+       int values_count;
+       char **values;
+} Attribute_Info;
+
+
+typedef struct
+{
+       int attribute_count;
+       char *tag_type;
+       Eina_Simple_XML_Type type;
+       Attribute_Info **available_arguments;
+} Item_Info;
+
+typedef struct
+{
+       const char *descr;
+       Item_Info *item_info;
+
+       const char *current_tag;
+       int current_tag_len;
+       int current_offset;
+       const char *error_message;
+
+       Eina_Bool xml_header;
+       Eina_Bool complex_header;
+       Eina_Bool tag_validation;
+
+       Eina_List *tag_stash;
+       Eina_List *available_tags;
+
+       int call_count;
+       int last_error_offset;
+       int last_error_line;
+
+
+       Eina_List *found_names;
+} S_is_xml;
+
+S_is_xml is_xml;
+
+#ifndef EINA_INLIST_FREE
+       #define EINA_INLIST_FREE(list, it) \
+               for(it = (__typeof__(it)) list; list; it = (__typeof__(it)) list)
+#endif
+
+
+// =========================================== Print ==============================
+
+void print_tree(Eina_Simple_XML_Node_Tag *tag, int text_offset)
+{
+       printf("DEBUG: %s start\n", __FUNCTION__);
+
+       if(tag == NULL)
+       {
+               printf("No tree found\n");
+       }
+       else if(tag->base.type == EINA_SIMPLE_XML_NODE_ROOT)
+       {
+               printf("Tree of root\n");
+       }
+
+       printf("%s\n\n", eina_simple_xml_node_dump(&tag->base, "        "));
+}
+
+// ========================= is xml description callbacks =========================
+
+static Eina_Bool
+is_xml_description_cb(void *data, Eina_Simple_XML_Type type, const char *content, unsigned offset, unsigned length)
+{
+       printf("DEBUG: %s start\n", __FUNCTION__);
+
+       S_is_xml *is_xml = data;
+
+       if(type != EINA_SIMPLE_XML_IGNORED)
+       {
+               is_xml->call_count++;
+       }
+
+       printf("CONTENT: %.*s\n", length, content);
+
+       switch(type)
+       {
+               case EINA_SIMPLE_XML_PROCESSING:
+                       printf("EINA_SIMPLE_XML_PROCESSING\n");
+                       if(!strncmp(content, "xml version=\"1.0\" encoding=\"UTF-8\"", length) && is_xml->call_count <= 2)
+                       {
+                               is_xml->xml_header = true;
+                       }
+               break;
+               case EINA_SIMPLE_XML_OPEN_EMPTY:
+                       printf("EINA_SIMPLE_XML_OPEN_EMPTY\n");
+                       if(!strncmp(content, "org_tizen_complex_desc", length) && is_xml->call_count <= 2)
+                       {
+                               is_xml->complex_header = true;
+                       }
+               break;
+               default:
+               break;
+       }
+
+       if(is_xml->complex_header && is_xml->xml_header)
+       {
+               return EINA_FALSE;
+       }
+
+       return EINA_TRUE;
+}
+
+// ========================= is xml description =========================
+S_is_xml is_xml;
+
+Attribute_Info *attribute_info_new(char *key, char **values, int count)
+{
+       Attribute_Info *attr = calloc(1, sizeof(Attribute_Info));
+
+       attr->key = key;
+       attr->values = values;
+       attr->values_count = count;
+
+       return attr;
+}
+
+void add_test_tag(char *tag, Eina_Simple_XML_Type type, Attribute_Info **attr, int attribute_count)
+{
+       Item_Info *ii = calloc(1, sizeof(Item_Info));
+       ii->tag_type = tag;
+       ii->type = type;
+       ii->attribute_count = attribute_count;
+       ii->available_arguments = attr;
+
+
+       is_xml.available_tags = eina_list_append(is_xml.available_tags, ii);
+}
+
+Eina_Bool is_xml_description(char *desc)
+{
+       is_xml.descr = desc;
+       is_xml.xml_header = false;
+       is_xml.complex_header = false;
+       is_xml.tag_validation = true;
+       is_xml.available_tags = NULL;
+
+       is_xml.call_count = 0;
+       is_xml.last_error_offset = 0;
+       is_xml.last_error_line = 1;
+
+       is_xml.found_names = NULL;
+
+       Attribute_Info *attr_info[3];
+       attr_info[0] = attribute_info_new("name", NULL, 0);
+       attr_info[1] = attribute_info_new("level", NULL, 0);
+       char *actions_info[2];
+       actions_info[0] = "on_focus";
+       actions_info[1] = "on_activate";
+       attr_info[2] = attribute_info_new("action", actions_info, 2);
+       add_test_tag("Information_Level", EINA_SIMPLE_XML_OPEN, attr_info, 3);
+
+       int size = strlen(desc);
+
+       eina_simple_xml_parse(desc, size, EINA_TRUE, is_xml_description_cb, &is_xml);
+
+       if(is_xml.complex_header && is_xml.xml_header)
+       {
+               return true;
+       }
+       else
+       {
+               return false;
+       }
+}
+
+/* ****************************************************************************************************** */
+
+
+// =========================================== Create Tree ==============================
+Eina_Simple_XML_Node_Tag *find_item_by_params(Eina_Simple_XML_Attribute **pairs, const char *name, Eina_Simple_XML_Node_Tag *tag);
+const char *get_param(Eina_Simple_XML_Node_Tag *item, char *key);
+
+int find_children_count_by_params(Eina_Simple_XML_Attribute **pairs,
+               const char *searched_tag_name, Eina_Inlist *first, int limit)
+{
+       printf("DEBUG: %s\n", __FUNCTION__);
+       Eina_Simple_XML_Node *child_node;
+       Eina_Simple_XML_Node_Tag *to_ret;
+       Eina_Simple_XML_Attribute *attr;
+       int counter = 0;
+       int attr_count;
+
+       printf("============================\n");
+       printf("SEARCHED: %s\n",searched_tag_name);
+
+       int i =0;
+       for(i = 0; pairs[i] != NULL; ++i)
+       {
+               printf("%s = \"%s\"\n", pairs[i]->key, pairs[i]->value);
+       }
+
+       printf("END PAIRS\n");
+
+       if(first && eina_inlist_count(first) > 0)
+       {
+               EINA_INLIST_FOREACH(first, child_node)
+               {
+                       if(child_node->type == EINA_SIMPLE_XML_NODE_TAG)
+                       {
+                               Eina_Simple_XML_Node_Tag *child_tag = (Eina_Simple_XML_Node_Tag *)child_node;
+
+                               const char *name = get_param(child_tag, "name");
+                               int param_count = 0;
+
+                               for(i = 0; pairs[i] != NULL; ++i)
+                               {
+                                       param_count++;
+                               }
+
+                               if(name != NULL)
+                               {
+                                       attr_count = eina_inlist_count(child_tag->attributes) - 1;
+                               }
+                               else
+                               {
+                                       attr_count = eina_inlist_count(child_tag->attributes);
+                               }
+
+                               printf("Child: %s > ", child_tag->name);
+                               EINA_INLIST_FOREACH(child_tag->attributes, attr)
+                               {
+                                       printf("%s = \"%s\" ", attr->key, attr->value);
+                               }
+
+                               printf("\n");
+
+                               printf("ATTR COUNT: %d <>  PARAM_COUT: %d\n", attr_count, param_count);
+
+                               if(attr_count == param_count)
+                               {
+                                       to_ret = find_item_by_params(pairs, searched_tag_name, child_tag);
+
+                                       if(to_ret)
+                                       {
+                                               printf("to_ret: %s > ", to_ret->name);
+                                               EINA_INLIST_FOREACH(to_ret->attributes, attr)
+                                               {
+                                                       printf("%s = \"%s\" ", attr->key, attr->value);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               printf("to_ret == NULL");
+                                       }
+
+                                       printf("\n");
+
+                                       if(to_ret != NULL)
+                                       {
+                                               counter++;
+                                       }
+
+
+                                       if(counter >= limit)
+                                       {
+                                               printf("ERROR   \n");
+                                               return counter;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return counter;
+}
+
+void find_duplicates(Eina_Simple_XML_Node_Tag *pattern, Eina_Inlist *first)
+{
+       Eina_Simple_XML_Attribute **pairs = NULL;
+       int attr_count = eina_inlist_count(pattern->attributes);
+
+       Eina_Simple_XML_Attribute *key = NULL;
+
+       pairs = calloc(attr_count + 1, sizeof(Eina_Simple_XML_Attribute **));
+
+       int i = 0;
+       EINA_INLIST_FOREACH(pattern->attributes, key)
+       {
+
+               if(strcmp(key->key, "name") != 0)
+               {
+                       pairs[i] =  key;
+                       ++i;
+               }
+       }
+
+       int found_count = 0;
+       if(strcmp(pattern->name, "Information_Level") == 0)
+       {
+               found_count = find_children_count_by_params(pairs, pattern->name, first, 1);
+               printf("FOUND COUNT %d\n", found_count);
+       }
+
+
+       if(found_count >= 1)
+       {
+               printf("Found widgets: %d\n", found_count);
+               printf("->->->->->->->->-> Error in XML tree: duplicate of %s found\n", pattern->name);
+       }
+
+
+}
+
+
+void traverse_xml_tree(Eina_Simple_XML_Node_Tag *top)
+{
+       Eina_Simple_XML_Node *node;
+       Eina_Simple_XML_Node_Tag *child;
+
+       EINA_INLIST_FOREACH(top->children, node)
+       {
+               if(node->type == EINA_SIMPLE_XML_NODE_TAG)
+               {
+                       child = (Eina_Simple_XML_Node_Tag *)node;
+
+                       printf(">>>>>>>>>>>>>>> CHILD TYPE: %s\n", child->name);
+
+                       find_duplicates(child, EINA_INLIST_GET(node)->next);
+                       traverse_xml_tree(child);
+               }
+       }
+}
+
+
+Eina_Simple_XML_Node_Root *create_tree(char *desc, bool test_duplicates)
+{
+       printf("DEBUG: %s start\n", __FUNCTION__);
+       Eina_Simple_XML_Node_Root* root = eina_simple_xml_node_load(desc, strlen(desc) - 1, true);
+
+       print_tree(root, 4);
+
+       if(test_duplicates == true)
+       {
+               traverse_xml_tree(root);
+       }
+
+       return root;
+}
+
+
+// ========================= Search functions =========================
+Eina_Simple_XML_Node_Tag *find_item_by_params(Eina_Simple_XML_Attribute **pairs, const char *name, Eina_Simple_XML_Node_Tag *tag)
+{
+       int i = 0;
+
+       Eina_Simple_XML_Attribute *arg;
+
+       int conditions = 0;
+       int found_matches = 0;
+
+       printf("DEBUG: %s start\n", __FUNCTION__);
+
+       if(tag->base.type !=  EINA_SIMPLE_XML_NODE_TAG )
+       {
+               printf("Not a tag\n");
+               return NULL;
+       }
+
+       if(name == NULL || !strcmp(name, tag->name)) //tag == NULL means that we don't care about tag name
+       {
+               printf("Found tag with name: %s\n", tag->name);
+
+               if(pairs) //no attributes means that we search only by tag name
+               {
+                       for(i = 0; pairs[i] != NULL; ++i)
+                       {
+                                       conditions++;
+                       }
+
+                       EINA_INLIST_FOREACH(tag->attributes, arg)
+                       {
+                               for(i = 0; pairs[i] != NULL; ++i)
+                               {
+                                       int cmp1 = strcmp(pairs[i]->key, arg->key);
+                                       int cmp2 = strcmp(pairs[i]->value, arg->value); //Strange code needed for debuging
+
+                                       if(!cmp1 && !cmp2)
+                                       {
+                                               found_matches++;
+                                       }
+                               }
+
+                               if(found_matches == conditions)
+                               {
+                                       return tag;
+                               }
+                       }
+               }
+               else
+               {
+                       return tag;
+               }
+       }
+
+       printf("%s RETURNING NULL\n", __FUNCTION__);
+       return NULL;
+}
+
+
+Eina_Simple_XML_Node_Tag *find_child_by_params(Eina_Simple_XML_Attribute **pairs, const char *searched_tag_name, Eina_Simple_XML_Node_Tag *tag)
+{
+       printf("DEBUG: %s\n", __FUNCTION__);
+       Eina_Simple_XML_Node *child_node;
+       Eina_Simple_XML_Node_Tag *to_ret;
+
+       if(tag->base.type !=  EINA_SIMPLE_XML_NODE_TAG && tag->base.type !=  EINA_SIMPLE_XML_NODE_ROOT)
+       {
+               return NULL;
+       }
+
+       if(tag->children && eina_inlist_count(tag->children) > 0)
+       {
+               EINA_INLIST_FOREACH(tag->children, child_node)
+               {
+                       to_ret = find_item_by_params(pairs, searched_tag_name, (Eina_Simple_XML_Node_Tag *)child_node);
+
+                       if(to_ret != NULL)
+                               return to_ret;
+               }
+       }
+
+       printf("%s RETURNING NULL\n", __FUNCTION__);
+       return NULL;
+}
+
+Eina_Simple_XML_Node_Tag *find_item_by_params_recursive(Eina_Simple_XML_Attribute **pairs, const char *name, Eina_Simple_XML_Node_Tag *top_tag)
+{
+       Eina_Simple_XML_Node_Tag *tag = find_item_by_params(pairs, name, top_tag);
+
+       if(tag != NULL)
+       {
+               return tag;
+       }
+       else
+       {
+               return find_child_by_params(pairs, name, top_tag);
+       }
+
+       //TODO: Czy to napewno zadziaÅ‚a bo chyba nie
+
+}
+
+
+
+const char *get_param(Eina_Simple_XML_Node_Tag *item, char *key)
+{
+       printf("DEBUG %s\n", __FUNCTION__);
+       Eina_Simple_XML_Attribute *attribute;
+
+       EINA_INLIST_FOREACH(item->attributes, attribute)
+       {
+               if(strcmp(attribute->key, key) == 0)
+               {
+                       return attribute->value;
+               }
+       }
+
+       return NULL;
+}
+
+Eina_Inlist *find_refs(Eina_Simple_XML_Node_Tag *root, Eina_Simple_XML_Node_Tag *tag, Eina_Inlist *refs)
+{
+       printf("DEBUG %s\n", __FUNCTION__);
+       Eina_Simple_XML_Node *child;
+
+       Eina_Simple_XML_Attribute *names[2] = {NULL, NULL};
+       printf("Tag name: %s\n", tag->name);
+
+       EINA_INLIST_FOREACH(tag->children, child)
+       {
+               printf("Child type: %d\n", child->type);
+
+               if(child->type == EINA_SIMPLE_XML_NODE_TAG || child->type == EINA_SIMPLE_XML_NODE_ROOT)
+               {
+                       Eina_Simple_XML_Node_Tag *child_tag = (Eina_Simple_XML_Node_Tag *)child;
+                       printf("CHILD TAG NAME: %s\n", child_tag->name);
+
+                       if(!strcmp(child_tag->name, "Ref"))
+                       {
+                               printf("Ref found\n");
+                               const char *value = get_param(child_tag, "name");
+                               names[0] = eina_simple_xml_attribute_new(NULL, "name", value);
+
+
+                               Eina_Simple_XML_Node_Tag *found_child_tag = find_item_by_params_recursive(names,  NULL, root);
+                               Eina_Simple_XML_Node *found_child = &found_child_tag->base;
+
+                               refs = eina_inlist_append(refs, EINA_INLIST_GET(found_child));
+
+                               refs = find_refs(root, found_child_tag, refs);
+                       }
+               }
+       }
+
+       return refs;
+}
+
+Eina_Inlist *find_refs_and_children(Eina_Simple_XML_Node_Tag *root, Eina_Simple_XML_Node_Tag *tag, Eina_Inlist *refs, char **children_xml, Tag *tags, bool *selected)
+{
+       printf("DEBUG %s\n", __FUNCTION__);
+       Eina_Simple_XML_Node *child;
+
+       Eina_Simple_XML_Attribute *names[2] = {NULL, NULL};
+       printf("Tag name: %s\n", tag->name);
+
+       EINA_INLIST_FOREACH(tag->children, child)
+       {
+               printf("Child type: %d\n", child->type);
+
+               if(child->type == EINA_SIMPLE_XML_NODE_TAG || child->type == EINA_SIMPLE_XML_NODE_ROOT)
+               {
+                       Eina_Simple_XML_Node_Tag *child_tag = (Eina_Simple_XML_Node_Tag *)child;
+                       printf("CHILD TAG NAME: %s\n", child_tag->name);
+
+                       if(strcmp(child_tag->name, "Ref") == 0 || strcmp(child_tag->name, "Read_Children") == 0 || strcmp(child_tag->name, "Text_Block") == 0)
+                       {
+                               if(child_tag->name[2] == 'f')
+                               {
+                                       printf("Ref found\n");
+                                       const char *value = get_param(child_tag, "name");
+                                       names[0] = eina_simple_xml_attribute_new(NULL, "name", value);
+
+
+                                       Eina_Simple_XML_Node_Tag *found_child_tag = find_item_by_params_recursive(names,  NULL, root);
+                                       Eina_Simple_XML_Node *found_child = &found_child_tag->base;
+
+                                       refs = eina_inlist_append(refs, EINA_INLIST_GET(found_child));
+                                       refs = find_refs_and_children(root, found_child_tag, refs, children_xml, tags, selected);
+                               }
+                               /*else if(child_tag->name[2] == 'x') //TODO
+                               {
+                                       printf("Text_Block found\n");
+                                       refs = eina_inlist_append(refs, child);
+                                       refs = find_refs_and_children(root, child, refs, children_xml, tags, selected);
+                               }*/
+                               else if(child_tag->name[2] == 'a')
+                               {
+                                       int i = 0;
+                                       printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CHILDREN FOUND \n");
+
+                                       for(i = 0; children_xml[i] != NULL; ++i)
+                                       {
+                                               Eina_Simple_XML_Attribute *child_xml_attr[2] = {NULL, NULL};
+                                               const char *value = get_param(child_tag, "level");
+                                               const char *mode = get_param(child_tag, "mode");
+                                               bool mode_val;
+
+                                               if(mode != NULL && strcmp(mode, "selected") == 0)
+                                                       mode_val = true;
+                                               else
+                                                       mode_val = false;
+
+                                               printf("selected: %d\n", selected[i]);
+                                               if((mode_val == true && selected[i] == true) || mode_val == false)
+                                               {
+                                                       child_xml_attr[0] = eina_simple_xml_attribute_new(NULL, "level", value);
+
+                                                       printf("Attribute: %s=%s\n", child_xml_attr[0]->key, child_xml_attr[0]->value);
+
+                                                       char *string = get_string_str(tags, children_xml[i], child_xml_attr, "Information_Level");
+
+                                                       printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! String from child %s\n", string);
+
+                                                       Eina_Simple_XML_Node_Data *found_node_data = eina_simple_xml_node_data_new(NULL, string, strlen(string)+ 1);
+                                                       Eina_Simple_XML_Node *found_data = &found_node_data->base;
+
+
+                                                       printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! AFTER NEW NODE\n");
+
+                                                       refs = eina_inlist_append(refs, EINA_INLIST_GET(found_data));
+                                                       eina_simple_xml_attribute_free(child_xml_attr[0]);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+
+       printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RETURNING\n");
+       return refs;
+}
+
+
+char *concat_string(Eina_Inlist *nodes)
+{
+       printf("DEBUG: %s\n", __FUNCTION__);
+       Eina_Simple_XML_Node *node = NULL;
+       Eina_Simple_XML_Node_Tag *tag = NULL;
+
+       Eina_Simple_XML_Node *child_node = NULL;
+       Eina_Simple_XML_Node_Data *data = NULL;
+
+       Eina_Strbuf *buf = eina_strbuf_new();
+
+       EINA_INLIST_FOREACH(nodes, node)
+       {
+               tag = (Eina_Simple_XML_Node_Tag *)node;
+
+               if(node->type == EINA_SIMPLE_XML_NODE_TAG)
+               {
+                       EINA_INLIST_FOREACH(tag->children, child_node)
+                       {
+                               if(child_node->type == EINA_SIMPLE_XML_NODE_DATA)
+                               {
+                                       data = (Eina_Simple_XML_Node_Data *)child_node;
+                                       eina_strbuf_append_n(buf, data->data, data->length);
+                                       eina_strbuf_append(buf, ". ");
+                               }
+
+                       }
+               }
+               else if(node->type == EINA_SIMPLE_XML_NODE_DATA)
+               {
+                       data = (Eina_Simple_XML_Node_Data *)node;
+                       eina_strbuf_append_n(buf, data->data, data->length);
+                       eina_strbuf_append(buf, ". ");
+               }
+       }
+
+       char *to_ret = eina_strbuf_string_steal(buf);
+       eina_strbuf_free(buf);
+       return to_ret;
+}
+
+/* ========================= get string from description ========================= */
+char *get_string_tree(Tag *tags, Eina_Simple_XML_Node_Tag *root, Eina_Simple_XML_Attribute **pairs, char *tag_name)
+{
+       printf("DEBUG %s\n", __FUNCTION__);
+       Eina_Simple_XML_Node_Tag *top_tag = root;
+       int i = 0;
+       Tag *current_tag = NULL;
+
+       printf("BEFORE TAGS\n");
+       if(tags != NULL)
+       {
+               printf("IN TAGS\n");
+               current_tag = &tags[0];
+
+               while(current_tag->tag_type != NULL)
+               {
+                       printf("Top item before: %s\n", top_tag->name);
+
+                       top_tag = find_child_by_params(current_tag->pairs, current_tag->tag_type, top_tag);
+
+                       printf("Top item after: %p\n", top_tag);
+
+                       i++;
+                       current_tag = &tags[i];
+               }
+
+               if(top_tag == NULL)
+               {
+                       printf("%s RETURNING NULL\n", __FUNCTION__);
+                       return NULL;
+               }
+
+       }
+
+
+
+       printf("-----------================   Searching...   ================-----------\n");
+
+       if(top_tag->base.type == EINA_SIMPLE_XML_NODE_TAG)
+       {
+               printf("SEARCH TOP LEVEL: %s\n", top_tag->name);
+       }
+       else if(top_tag->base.type == EINA_SIMPLE_XML_NODE_ROOT)
+       {
+               printf("SEARCH FROM ROOT\n");
+       }
+
+       Eina_Simple_XML_Node_Tag *tag = find_child_by_params(pairs, tag_name, top_tag);
+
+       Eina_Inlist *refs = NULL;
+
+       if(tag == NULL)
+       {
+               printf("returning NULL %s\n", __FUNCTION__);
+               return NULL;
+       }
+
+       refs = find_refs(root, tag, refs);
+
+       Eina_Simple_XML_Node *node = &tag->base;
+       refs = eina_inlist_prepend(refs, EINA_INLIST_GET(node)); //need to add the found item to the list so it's
+                                                                                       //string can be added to output
+
+       char *the_string = concat_string(refs);
+
+       return the_string;
+}
+
+char *get_string_str(Tag *tags, char *descr, Eina_Simple_XML_Attribute **pairs, char *tag_name)
+{
+       printf("DEBUG %s\n", __FUNCTION__);
+       bool xml = is_xml_description(descr);
+
+       if(xml == true)
+       {
+               Eina_Simple_XML_Node_Root *root = create_tree(descr, false);
+               char *the_string = get_string_tree(tags, root, pairs, tag_name);
+
+               return the_string;
+       }
+       else
+       {
+               return descr;
+       }
+}
+
+const char *list_pop(Eina_List **list)
+{
+       printf("Popping tag\n");
+       Eina_List *l;
+       printf("Get Last\n");
+       l = eina_list_last(*list);
+       printf("Get data\n");
+       const char *content = eina_list_data_get(l);
+       printf("Remove\n");
+       *list = eina_list_remove_list(*list, l);
+       return content;
+}
+
+
+//void get_error_messgage(const char *message, const char *tag, S_is_xml *is_xml, int offset, int length)
+void get_error_messgage(S_is_xml *is_xml)
+{
+       int line_count =is_xml->last_error_line;
+       int i = 0;
+       for(i = is_xml->last_error_offset; i < is_xml->current_offset; ++i)
+       {
+               if(is_xml->descr[i] == '\n')
+               {
+                       line_count++;
+               }
+       }
+
+       printf("->->->->->->->->-> Error in XML validation: %s", is_xml->error_message);
+
+       if(is_xml->current_tag)
+       {
+               printf(" %*.*s\n", is_xml->current_tag_len, is_xml->current_tag_len, is_xml->current_tag);
+       }
+
+       printf(" line: %d\n", line_count);
+
+       is_xml->last_error_offset = is_xml->current_offset;
+       is_xml->last_error_line = line_count;
+
+}
+
+static Eina_Bool
+_xml_attr_cb(void *data, const char *key, const char *value)
+{
+       printf("Test attribute\n");
+
+       S_is_xml *is_xml = data;
+       Item_Info *ii = is_xml->item_info;
+       Attribute_Info *ai;
+       int i, j;
+       Eina_Bool key_found = EINA_FALSE;
+       printf("Tag NAME: %s\n", ii->tag_type);
+       Eina_List *l;
+       char *name = NULL;
+       bool name_found = false;
+
+       if(strcmp(key, "name") == 0)
+       {
+               printf("NAME key found\n");
+               EINA_LIST_FOREACH(is_xml->found_names, l, name)
+               {
+                       printf("Testing names: %s vs %s\n", name, value);
+
+                       if(name != NULL && strcmp(value, name) == 0)
+                       {
+                               name_found = true;
+                               break;
+                       }
+               }
+
+               printf("After Loop\n");
+
+               if(name_found == false)
+               {
+                       printf("Add name to list: %s\n", value);
+                       is_xml->found_names = eina_list_append(is_xml->found_names, eina_stringshare_add(value));
+               }
+               else
+               {
+                       printf("Name already exists: %s\n", value);
+                       is_xml->error_message = "Name already exists";
+                       is_xml->tag_validation = 0;
+                       get_error_messgage(is_xml);
+               }
+       }
+       else if(strcmp(key, "refs") == 0)
+       {
+               printf("NAME key found\n");
+               EINA_LIST_FOREACH(is_xml->found_names, l, name)
+               {
+                       printf("Testing names: %s vs %s\n", name, value);
+
+                       if(name != NULL && strcmp(value, name) == 0)
+                       {
+                               name_found = true;
+                               break;
+                       }
+               }
+
+               printf("Name already exists: %s\n", value);
+               is_xml->error_message = "Cannot reference tag with given name";
+               is_xml->tag_validation = 0;
+               get_error_messgage(is_xml);
+
+               printf("After Loop\n");
+
+               if(name_found == false)
+               {
+                       printf("Add name to list: %s\n", value);
+                       is_xml->found_names = eina_list_append(is_xml->found_names, eina_stringshare_add(value));
+               }
+               else
+               {
+
+               }
+       }
+
+
+
+       if(ii->attribute_count > 0)
+       {
+               for(i = 0; i < ii->attribute_count; ++i)
+               {
+                       printf("Get attribute\n");
+
+                       ai = ii->available_arguments[i];
+
+                       printf("Test attribute: \n%s\n%s   key_found: %d\n", key, ai->key, key_found);
+                       if(strcmp(key, ai->key) == 0)
+                       {
+                               printf("Attribute found: \n%s\n%s\n", key, ai->key);
+                               key_found = EINA_TRUE;
+
+                               printf("Iterate values count: %d\n", ai->values_count);
+                               if(ai->values_count)
+                               {
+                                       for(j = 0; j < ai->values_count; ++j)
+                                       {
+                                               printf("Compare values \n%s\n%s\n", value, ai->values[j]);
+                                               if(strcmp(ai->values[j], value) == 0)
+                                               {
+                                                       return EINA_TRUE;
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       printf("KEY OK\n");
+                                       return EINA_TRUE;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               printf("->->->->->->->->->->->-> Argument in no-argument tag: %s in tag: %s\n", key, ii->tag_type);
+
+               is_xml->error_message = "Argument in no-argument tag";
+               is_xml->tag_validation = 0;
+               get_error_messgage(is_xml);
+               return EINA_FALSE;
+       }
+
+       printf("key_found %d\n", key_found);
+
+       if(key_found == EINA_FALSE)
+       {
+               printf("->->->->->->->->->->->-> Unknown attribute: %s in tag: %s\n", key, ii->tag_type);
+               is_xml->error_message = "Unknown attribute in";
+               is_xml->tag_validation = 0;
+               get_error_messgage(is_xml);
+       }
+       else
+       {
+               printf("->->->->->->->->->->->-> Unknown attribute value: %s with key: %s. Tag: %s\n", value, key, ii->tag_type);
+               is_xml->error_message = "Unknown attribute value ";
+               is_xml->tag_validation = 0;
+               get_error_messgage(is_xml);
+       }
+
+       return EINA_TRUE;
+}
+
+
+Eina_Bool check_tag(S_is_xml *is_xml, Eina_Simple_XML_Type type, const char *tag, const char *attr, int str_len)
+{
+       printf("DEBUG %s\n", __FUNCTION__);
+
+       if(is_xml->available_tags == NULL)
+       {
+               printf("No available tags\n");
+               return true;
+       }
+
+       Eina_List *l;
+       Item_Info *ii;
+
+       int len = 0;
+       if(attr)
+       {
+               len = attr - tag - 1;
+       }
+       else
+       {
+               len = str_len;
+       }
+
+       printf("TAG: %*.*s type: %d\n", len, len, tag, type);
+
+       EINA_LIST_FOREACH(is_xml->available_tags, l, ii)
+       {
+               printf("Wzorzec: %*.*s %d\n", len, len, ii->tag_type, ii->type);
+
+               if(strncmp(tag, ii->tag_type, len - 1) == 0 && type == ii->type)
+               {
+                       is_xml->item_info = ii;
+                       is_xml->current_offset = tag - is_xml->descr;
+                       is_xml->current_tag_len = str_len;
+                       is_xml->current_tag = tag;
+                       eina_simple_xml_attributes_parse(attr, str_len - (attr - tag), _xml_attr_cb, is_xml);
+                       return EINA_TRUE;
+               }
+       }
+
+       return EINA_FALSE;
+}
+
+
+
+Eina_Simple_XML_Node_Tag *modify_tag(Tag *tags,  Eina_Simple_XML_Node_Tag *root,
+               const char *tag_name,     Eina_Simple_XML_Attribute **pairs,
+               const char *new_tag_name, Eina_Simple_XML_Attribute **new_pairs, const char *new_data)
+{
+       printf("DEBUG: %s start\n", __FUNCTION__);
+
+       Eina_Simple_XML_Node_Tag *top_tag = NULL;
+       Eina_Simple_XML_Node_Tag *tag = NULL;
+       Tag *current_tag = NULL;
+
+       if(root == NULL)
+       {
+               printf("Root == NULL\n");
+
+               char *buf = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+                                       "<org_tizen_complex_desc/>\n";
+
+               root = eina_simple_xml_node_load (buf, strlen(buf), EINA_TRUE);
+               top_tag = root;
+       }
+       else
+       {
+               printf("Root != NULL\n");
+               top_tag = root;
+
+               if(tags != NULL)
+               {
+                       printf("Tags != NULL\n");
+                       printf("IN TAGS\n");
+                       current_tag = &tags[0];
+
+                       int i = 0;
+                       while(current_tag->tag_type != NULL)
+                       {
+                               printf("Top item before: %s\n", top_tag->name);
+
+                               top_tag = find_child_by_params(current_tag->pairs, current_tag->tag_type, top_tag);
+
+                               printf("Top item after: %s\n", top_tag->name);
+
+                               i++;
+                               current_tag = &tags[i];
+                       }
+
+                       if(top_tag == NULL)
+                       {
+                               return NULL;
+                       }
+               }
+
+               if(top_tag->base.type == EINA_SIMPLE_XML_NODE_TAG)
+               {
+                       printf("SEARCH TOP LEVEL: %s\n", top_tag->name);
+               }
+               else if(top_tag->base.type == EINA_SIMPLE_XML_NODE_ROOT)
+               {
+                       printf("SEARCH FROM ROOT\n");
+               }
+
+               tag = find_child_by_params(pairs, tag_name, top_tag);
+       }
+
+       //add new tag to xml tree
+       if(tag == NULL)
+       {
+               printf("Adding new tag\n");
+
+               tag = eina_simple_xml_node_tag_new(top_tag, new_tag_name);
+
+               printf("Adding new tag %s\n", __FUNCTION__);
+
+               //removing attibutes;
+               Eina_Simple_XML_Attribute *attr;
+
+               EINA_INLIST_FOREACH(tag->attributes, attr)
+               {
+                       eina_simple_xml_attribute_free(attr);
+               }
+
+               int i = 0;
+               while(pairs[i] != NULL)
+               {
+                       Eina_Simple_XML_Attribute *attr = new_pairs[i];
+                       eina_simple_xml_attribute_new(tag, attr->key, attr->value);
+                       ++i;
+               }
+       }
+       //Modify existing tag
+       else
+       {
+               printf("Modifying tag %s\n", tag->name);
+
+               Eina_Simple_XML_Node *node;
+               Eina_Simple_XML_Node_Tag *to_remove_tag;
+               Eina_Simple_XML_Node_Data *to_remove_data;
+
+               printf("Removing children\n");
+               EINA_INLIST_FREE(tag->children, node)
+               {
+                       switch(node->type)
+                       {
+                               case EINA_SIMPLE_XML_NODE_ROOT:
+                               case EINA_SIMPLE_XML_NODE_TAG:
+                                       to_remove_tag = (Eina_Simple_XML_Node_Tag *)node;
+                                       eina_simple_xml_node_tag_free(to_remove_tag);
+                               break;
+                               case EINA_SIMPLE_XML_NODE_DATA:
+                                       to_remove_data = (Eina_Simple_XML_Node_Data *)node;
+                                       eina_simple_xml_node_data_free(to_remove_data);
+                               break;
+                               default:
+                               break;
+                       }
+
+               }
+
+               printf("Adding attributes\n");
+
+               Eina_Simple_XML_Attribute *attr;
+
+               printf("Removing old attributes\n");
+               EINA_INLIST_FREE(tag->attributes, attr)
+               {
+                       eina_simple_xml_attribute_free(attr);
+               }
+
+               printf("Adding new attributes\n");
+
+               int i = 0;
+               while(pairs[i] != NULL)
+               {
+                       Eina_Simple_XML_Attribute *attr = new_pairs[i];
+                       eina_simple_xml_attribute_new(tag, attr->key, attr->value);
+                       ++i;
+               }
+
+               printf("Setting name\n");
+               tag->name = eina_stringshare_add(new_tag_name);
+       }
+
+       if(new_data != NULL)
+       {
+               eina_simple_xml_node_data_new(tag, new_data, strlen(new_data));
+       }
+
+       return root;
+}
+
+Eina_Simple_XML_Node_Tag *add_tag(Tag *tags,  Eina_Simple_XML_Node_Tag *root,
+               const char *tag, const char *data, Eina_Simple_XML_Attribute **pairs)
+{
+       Eina_Simple_XML_Node_Tag * ret = modify_tag(tags,  root,
+                                                                                               tag, pairs,
+                                                                                               tag, pairs, data);
+
+       return ret;
+}
+
+Eina_Simple_XML_Node_Tag *add_tag_str(Tag *tags,  Eina_Simple_XML_Node_Root *root, const char *tag_str)
+{
+       Eina_Simple_XML_Node_Root *tag = eina_simple_xml_node_load (tag_str, strlen(tag_str) - 1, EINA_TRUE);
+       Eina_Simple_XML_Node_Tag * ret = root;
+
+       printf("the tag tree:\n");
+       print_tree(tag, 4);
+
+
+       if(tag)
+       {
+               Eina_Simple_XML_Node *root_child_node = NULL;
+               Eina_Simple_XML_Node *child_node = NULL;
+               Eina_Simple_XML_Node_Data *child_node_data = NULL;
+               Eina_Simple_XML_Node_Tag *child_tag =NULL;
+               Eina_Simple_XML_Attribute *attr = NULL;
+               Eina_Simple_XML_Attribute **array = NULL;
+
+               printf("finding data\n");
+
+               EINA_INLIST_FOREACH(tag->children, root_child_node)
+               {
+                       printf("checking children list\n");
+
+                       if(root_child_node->type == EINA_SIMPLE_XML_NODE_TAG)
+                       {
+                               child_tag = (Eina_Simple_XML_Node_Tag *)root_child_node;
+
+                               EINA_INLIST_FOREACH(child_tag->children, child_node)
+                               {
+                                       if(child_node->type == EINA_SIMPLE_XML_NODE_DATA)
+                                       {
+                                               child_node_data = (Eina_Simple_XML_Node_Data *)child_node;
+                                       }
+                               }
+
+                               int list_count = eina_inlist_count(child_tag->attributes);
+                               array = calloc(list_count, sizeof(Eina_Simple_XML_Attribute *));
+
+                               printf("creating attribute array\n");
+
+                               int i = 0;
+                               EINA_INLIST_FOREACH(child_tag->attributes, attr)
+                               {
+                                       array[i] = attr;
+                                       i++;
+                               }
+
+                               printf("Calling modify\n");
+                               printf("Tag name: %s\n", child_tag->name);
+
+                               if(child_node_data != NULL)
+                               {
+                                       ret = modify_tag(tags,  ret,
+                                                                       child_tag->name, array,
+                                                                       child_tag->name, array, child_node_data->data);
+                               }
+                               else
+                               {
+                                       ret = modify_tag(tags,  ret,
+                                                                       child_tag->name, array,
+                                                                       child_tag->name, array, NULL);
+                               }
+
+                               free(array);
+                       }
+               }
+
+               return ret;
+       }
+       else
+       {
+               return NULL;
+       }
+}