ecore
atspi-2
gobject-2.0
- ecore-x
+ ecore-x
+ dlog
+ vconf
+ tts
+
)
FOREACH(flag ${pkgs_CFLAGS})
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+#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
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+#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
<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>
BuildRequires: pkgconfig(evas)
BuildRequires: pkgconfig(bundle)
BuildRequires: cmake
+BuildRequires: tts
+BuildRequires: tts-devel
%description
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.
%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
#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"
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();
.reset = NULL
};
- ops.data = NULL;
+ ops.data = get_pointer_to_service_data_struct();
+
return appcore_efl_main("Smart Navigation", &argc, &argv, &ops);
}
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);
--- /dev/null
+#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;
+}
--- /dev/null
+/*
+ * 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");
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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;
+ }
+}