speechd-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/6] move src/c/api to src/api/c


From: william hubbs
Subject: [PATCH 2/6] move src/c/api to src/api/c
Date: Wed, 15 Sep 2010 20:55:44 -0000

From: William Hubbs <address@hidden>
To: address@hidden

---
 configure.ac                |    4 +-
 src/Makefile.am             |    4 +-
 src/api/Makefile.am         |    4 +
 src/api/c/Makefile.am       |   13 +
 src/api/c/libspeechd.c      | 1722 +++++++++++++++++++++++++++++++++++++++++++
 src/api/c/libspeechd.h      |  278 +++++++
 src/c/Makefile.am           |    5 -
 src/c/api/Makefile.am       |   13 -
 src/c/api/libspeechd.c      | 1722 -------------------------------------------
 src/c/api/libspeechd.h      |  278 -------
 src/clients/say/Makefile.am |    4 +-
 src/tests/Makefile.am       |    4 +-
 12 files changed, 2025 insertions(+), 2026 deletions(-)
 create mode 100644 src/api/Makefile.am
 create mode 100644 src/api/c/Makefile.am
 create mode 100644 src/api/c/libspeechd.c
 create mode 100644 src/api/c/libspeechd.h
 delete mode 100644 src/c/Makefile.am
 delete mode 100644 src/c/api/Makefile.am
 delete mode 100644 src/c/api/libspeechd.c
 delete mode 100644 src/c/api/libspeechd.h

diff --git a/configure.ac b/configure.ac
index dab09c5..7902cf6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -422,10 +422,10 @@ AC_CONFIG_FILES([Makefile
        include/Makefile
        po/Makefile.in
        src/Makefile
+       src/api/Makefile
+       src/api/c/Makefile
        src/audio/Makefile
        src/audio/static_plugins.c
-       src/c/Makefile
-       src/c/api/Makefile
        src/clients/Makefile
        src/clients/say/Makefile
        src/clients/spdsend/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index bd04add..ea7168d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,11 +10,11 @@ EXTRA_DIST = cl/ChangeLog cl/README cl/configuration.lisp 
cl/elisp.lisp \
              guile/ChangeLog guile/Makefile guile/README guile/gssip.scm.in \
              guile/gssip.c guile/gssip.h
 
-SUBDIRS=common server audio c modules clients tests
+SUBDIRS=common server audio modules api clients tests
 
 if HAVE_PYTHON
 SUBDIRS += python
 endif
 
-DIST_SUBDIRS=common server audio c modules clients tests python
+DIST_SUBDIRS=common server audio modules api clients tests python
 
diff --git a/src/api/Makefile.am b/src/api/Makefile.am
new file mode 100644
index 0000000..9bee85e
--- /dev/null
+++ b/src/api/Makefile.am
@@ -0,0 +1,4 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS= c
+
diff --git a/src/api/c/Makefile.am b/src/api/c/Makefile.am
new file mode 100644
index 0000000..1c380a5
--- /dev/null
+++ b/src/api/c/Makefile.am
@@ -0,0 +1,13 @@
+
+localedir = $(datadir)/locale
+inc_local = "-I$(top_srcdir)/include/"
+
+AM_CFLAGS = @ERROR_CFLAGS@ -DLOCALEDIR=\"$(localedir)\" -D_GNU_SOURCE 
-I/usr/include/ $(inc_local) @glib_include@ 
-DSPD_SPAWN_CMD=\""@prefix@/bin/speech-dispatcher"\"
+
+lib_LTLIBRARIES = libspeechd.la
+libspeechd_la_SOURCES = libspeechd.c
+libspeechd_la_HEADERS = libspeechd.h
+libspeechd_ladir = $(includedir)
+libspeechd_la_LDFLAGS = -version-info 
@LIB_SPD_CURRENT@:@LIB_SPD_REVISION@:@LIB_SPD_AGE@ -lpthread
+libspeechd_la_LIBADD = @glib_libs@
+
diff --git a/src/api/c/libspeechd.c b/src/api/c/libspeechd.c
new file mode 100644
index 0000000..7ef94c2
--- /dev/null
+++ b/src/api/c/libspeechd.c
@@ -0,0 +1,1722 @@
+/*
+  libspeechd.c - Shared library for easy acces to Speech Dispatcher functions
+ *
+ * Copyright (C) 2001, 2002, 2003, 2006, 2007, 2008 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this package; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $Id: libspeechd.c,v 1.37 2008-12-23 09:15:32 pdm Exp $
+ */
+
+
+#include <sys/types.h>
+#include <wchar.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <glib.h>
+#include <errno.h>
+#include <assert.h>
+#include <netdb.h>
+
+#include "libspeechd.h"
+
+/* Comment/uncomment to switch debugging on/off */
+// #define LIBSPEECHD_DEBUG 1
+
+/* --------------  Private functions headers ------------------------*/
+
+#ifdef LIBSPEECHD_DEBUG
+FILE *spd_debug = NULL;
+#endif
+
+
+static int spd_set_priority(SPDConnection* connection, SPDPriority priority);
+static char* escape_dot(const char *text);
+static int isanum(char* str);          
+static char* get_reply(SPDConnection *connection);
+static int get_err_code(char *reply);
+static char* get_param_str(char* reply, int num, int *err);
+static int get_param_int(char* reply, int num, int *err);
+static void *xmalloc(size_t bytes);
+static void xfree(void *ptr);   
+static int ret_ok(char *reply);
+static void SPD_DBG(char *format, ...);
+static void* spd_events_handler(void*);
+
+pthread_mutex_t spd_logging_mutex;
+
+#if !(defined(__GLIBC__) && defined(_GNU_SOURCE))
+/* Added by Willie Walker - strndup and getline are gcc-isms */
+char *strndup ( const char *s, size_t n)
+{
+        size_t nAvail;
+        char *p;
+
+        if ( !s )
+                return 0;
+
+        if ( strlen(s) > n )
+                nAvail = n + 1;
+        else
+                nAvail = strlen(s) + 1;
+        p = malloc ( nAvail );
+        memcpy ( p, s, nAvail );
+        p[nAvail - 1] = '\0';
+
+        return p;
+}
+
+#define BUFFER_LEN 256
+ssize_t getline (char **lineptr, size_t *n, FILE *f)
+{
+        char ch;
+        size_t m = 0;
+        ssize_t buf_len = 0;
+        char * buf = NULL;
+        char * p = NULL;
+
+       if (errno != 0) {
+                SPD_DBG("getline: errno came in as %d!!!\n", errno);
+               errno = 0;
+       }
+        while ( (ch = getc(f)) !=EOF )
+        {
+                if (errno != 0)
+                        return -1;
+                if ( m++ >= buf_len )
+                {
+                        buf_len += BUFFER_LEN;
+                        buf = (char *) realloc(buf, buf_len + 1);
+                        if ( buf == NULL )
+                        {
+                                SPD_DBG("buf==NULL");
+                                return -1;
+                        }
+                        p = buf + buf_len - BUFFER_LEN;
+                }
+                *p = ch;
+                p++;
+                if ( ch == '\n' )
+                        break;
+        }
+        if ( m == 0 )
+        {
+                SPD_DBG("getline: m=%d!",m);
+                return -1;
+        } else {
+                *p = '\0';
+                *lineptr = buf;
+                *n = m;
+                return m;
+        }
+}
+#endif /* !(defined(__GLIBC__) && defined(_GNU_SOURCE)) */
+
+/* --------------------- Public functions ------------------------- */
+
+#define SPD_REPLY_BUF_SIZE 65536
+
+/* Determine address for the unix socket */
+static char*
+_get_default_unix_socket_name(void)
+{
+  GString* socket_filename;
+  char *h;
+  const char *homedir = g_getenv("HOME");
+  if (!homedir)
+    homedir = g_get_home_dir();
+  socket_filename = g_string_new("");
+  g_string_printf(socket_filename, "%s/.speech-dispatcher/speechd.sock", 
homedir);
+  // Do not regurn glib string, but glibc string...
+  h = strdup(socket_filename->str);
+  g_string_free(socket_filename, 1);
+  return h;
+}
+
+SPDConnectionAddress*
+spd_get_default_address(char **error)
+{
+  const gchar *env_address = g_getenv("SPEECHD_ADDRESS");
+  gchar **pa; /* parsed address */
+  SPDConnectionAddress *address = malloc(sizeof(SPDConnectionAddress));
+
+  if (env_address == NULL){ // Default method = unix sockets
+    address->method = SPD_METHOD_UNIX_SOCKET;
+    address->unix_socket_name = _get_default_unix_socket_name();
+  }else{
+    pa = g_strsplit(env_address, ":", 0);
+    assert (pa);
+    if (!g_strcmp0(pa[0], "unix_socket") || pa[0] == NULL){ // Unix sockets
+      address->method = SPD_METHOD_UNIX_SOCKET;
+      if (pa[1] == NULL){
+       address->unix_socket_name = _get_default_unix_socket_name();
+      }else{
+       address->unix_socket_name = strdup(pa[1]);
+      }
+    }else if (!g_strcmp0(pa[0], "inet_socket")){ // Inet sockets
+      address->method = SPD_METHOD_INET_SOCKET;
+      if (pa[1] == NULL){
+       address->inet_socket_host = strdup("127.0.0.1");
+       address->inet_socket_port = 6560;
+      }else{
+       address->inet_socket_host = strdup(pa[1]);
+       if (pa[2] == NULL){
+         address->inet_socket_port = SPEECHD_DEFAULT_PORT;
+       }else{
+         address->inet_socket_port = atoi(pa[2]);
+        }
+      }
+    }else{ // Unknown or unsupported method requested
+      *error = strdup("Unknown or unsupported communication method");
+      address = NULL;
+    }
+    g_strfreev(pa);
+  }
+  return address;
+}
+
+
+static void _init_debug(void)
+{
+#ifdef LIBSPEECHD_DEBUG
+  if (!spd_debug){
+    spd_debug = fopen("/tmp/libspeechd.log", "w");
+    if (spd_debug == NULL) SPD_FATAL("COULDN'T ACCES FILE INTENDED FOR DEBUG");
+     
+    if(pthread_mutex_init(&spd_logging_mutex, NULL)){
+      fprintf(stderr, "Mutex initialization failed");
+      fflush(stderr);
+      exit(1);
+    }
+    SPD_DBG("Debugging started");
+  }
+#endif /* LIBSPEECHD_DEBUG */
+}
+
+/* Opens a new Speech Dispatcher connection.
+ * Returns socket file descriptor of the created connection
+ * or -1 if no connection was opened. */
+
+SPDConnection*
+spd_open(const char* client_name, const char* connection_name, const char* 
user_name,
+        SPDConnectionMode mode)
+{
+  char *error;
+  int autospawn = 1;
+  SPDConnection *conn;
+  conn = spd_open2(client_name, connection_name, user_name,
+                  mode, NULL, autospawn, &error);
+  if (!conn){
+    _init_debug();
+    assert(error);
+    SPD_DBG("Could not connect to Speech Dispatcher: %s", error);
+    xfree(error);
+  }
+  return conn;
+}
+
+#define MAX_IP_SIZE 16+1
+/* TODO: This only works in IPV4 */
+static char*
+resolve_host(char* host_name_or_ip, int *is_localhost, gchar **error)
+{
+    struct addrinfo *addr_result;
+    int err;
+    char *resolve_buffer = malloc(MAX_IP_SIZE*sizeof(char));
+    const char *resolved_ip = NULL;
+    char *ip;
+    *error = NULL;
+    struct sockaddr_in *addr_in;
+    
+    if (resolve_buffer == NULL) {
+       *error = g_strdup("Failed to allocate memory.");
+       return NULL;
+    }
+
+    err = getaddrinfo(host_name_or_ip, 0, NULL, &addr_result);
+    if (err){
+       *error = g_strdup_printf("Can't resolve address %d due to error %s:",
+                                err, gai_strerror(err));
+       xfree(resolve_buffer);
+       return NULL;
+    }
+    /* Take the first address returned as we are only interested in host ip */
+    addr_in = (struct sockaddr_in *) addr_result->ai_addr;
+    resolved_ip = inet_ntop(AF_INET, &(addr_in->sin_addr.s_addr), 
resolve_buffer, MAX_IP_SIZE);
+    if (resolved_ip == NULL) {
+       *error = g_strdup_printf("Could not convert address, due to the 
following error: %s",
+                                strerror(errno));
+       freeaddrinfo(addr_result);
+       xfree(resolve_buffer);
+       return NULL;
+    }
+
+    if (!strncmp(resolved_ip, "127.",4)){
+       *is_localhost = 1;
+       /* In case of local addresses, use 127.0.0.1 which is guaranteed
+          to be local and the server listens on it */
+       xfree(resolve_buffer);
+       ip = strdup("127.0.0.1");
+    }else{
+       *is_localhost = 0;
+       ip = resolve_buffer;
+    }
+    freeaddrinfo(addr_result);
+    return ip;
+}
+
+static int
+spawn_server(SPDConnectionAddress *address, int is_localhost, gchar 
**spawn_error)
+{
+    gchar **speechd_cmd = malloc(16*sizeof(char*));
+    gchar *stderr_output;
+    gboolean spawn_ok;
+    GError *gerror = NULL;
+    int exit_status;
+    int i;
+
+    if ((address->method==SPD_METHOD_INET_SOCKET) && (!is_localhost)){
+       *spawn_error = g_strdup("Spawn failed, the given network address 
doesn't seem to be on localhost");
+       return 1;
+    }
+
+    speechd_cmd[0] = g_strdup(SPD_SPAWN_CMD);
+    speechd_cmd[1] = g_strdup("--spawn");
+    speechd_cmd[2] = g_strdup("--communication-method");
+    if (address->method==SPD_METHOD_INET_SOCKET){
+       speechd_cmd[3] = g_strdup("inet_socket");
+       speechd_cmd[4] = g_strdup("--port");
+       speechd_cmd[5] = g_strdup_printf("%d",address->inet_socket_port);
+       speechd_cmd[6] = NULL;
+    }else if (address->method==SPD_METHOD_UNIX_SOCKET){
+       speechd_cmd[3] = g_strdup("unix_socket");
+       speechd_cmd[4] = g_strdup("--socket-path");
+       speechd_cmd[5] = g_strdup_printf("%s", address->unix_socket_name);
+       speechd_cmd[6] = NULL;
+    }else assert (0);
+    
+    spawn_ok = g_spawn_sync(NULL, (gchar**)speechd_cmd, NULL, 
G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL,
+                           NULL, NULL, NULL, &stderr_output, &exit_status, 
&gerror);
+    for (i=0;speechd_cmd[i]!=NULL;i++)
+       g_free(speechd_cmd[i]);
+    if (!spawn_ok){
+       *spawn_error = g_strdup_printf("Autospawn failed. Spawn error %d: %s", 
gerror->code, gerror->message);
+       return 1;
+    }else{
+       if (exit_status){
+           *spawn_error = g_strdup_printf("Autospawn failed. Speech Dispatcher 
refused to start with error code, " \
+                                          "stating this as a reason: %s", 
stderr_output);
+           return 1;
+       }else{
+           *spawn_error = NULL;
+           return 0;
+       }
+    }
+    assert(0);
+}
+
+SPDConnection*
+spd_open2(const char* client_name, const char* connection_name, const char* 
user_name,
+         SPDConnectionMode mode, SPDConnectionAddress *address, int autospawn,
+         char **error_result)
+{
+    SPDConnection *connection;
+    char *set_client_name;
+    char* conn_name;
+    char* usr_name;
+    int ret;
+    char tcp_no_delay = 1;
+
+    /* Autospawn related */
+    int spawn_err;
+    gchar *spawn_report;
+    char *host_ip;
+    int is_localhost = 1;
+    
+    struct sockaddr_in address_inet;    
+    struct sockaddr_un address_unix;    
+    struct sockaddr *sock_address;
+    size_t sock_address_len;
+    gchar *resolve_error;
+
+    _init_debug();
+
+    if (client_name == NULL){
+      *error_result = strdup("ERROR: Client name not specified");
+      SPD_DBG(*error_result);
+      return NULL;
+    }
+    
+    if (user_name == NULL)
+    {
+        usr_name = strdup((char*) g_get_user_name());
+    }
+    else
+        usr_name = strdup(user_name);
+    
+    if(connection_name == NULL)
+        conn_name = strdup("main");
+    else
+        conn_name = strdup(connection_name);
+
+    if (address == NULL){
+      char *err = NULL;
+      address = spd_get_default_address(&err);
+      if (!address){
+       assert(err);
+       *error_result = err;
+       SPD_DBG(*error_result);
+       return NULL;
+      }
+    }
+    
+    /* Connect to server using the selected method */
+    connection = xmalloc(sizeof(SPDConnection));
+    if (address->method==SPD_METHOD_INET_SOCKET){    
+       host_ip = resolve_host(address->inet_socket_host, &is_localhost, 
&resolve_error);
+       if (host_ip == NULL){
+           *error_result = strdup(resolve_error);
+           g_free(resolve_error);
+           return NULL;
+       }       
+       address_inet.sin_addr.s_addr = inet_addr(host_ip);
+       address_inet.sin_port = htons(address->inet_socket_port);
+       address_inet.sin_family = AF_INET;
+       connection->socket = socket(AF_INET, SOCK_STREAM, 0);
+       sock_address = (struct sockaddr*) &address_inet;
+       sock_address_len = sizeof(address_inet);
+    }else if (address->method==SPD_METHOD_UNIX_SOCKET){
+      /* Create the unix socket */
+      address_unix.sun_family = AF_UNIX;
+      strncpy (address_unix.sun_path, address->unix_socket_name, sizeof 
(address_unix.sun_path));
+      address_unix.sun_path[sizeof (address_unix.sun_path) - 1] = '\0';
+      connection->socket = socket(AF_UNIX, SOCK_STREAM, 0);
+      sock_address = (struct sockaddr*) &address_unix;
+      sock_address_len = SUN_LEN(&address_unix);
+    }else SPD_FATAL("Unsupported connection method for spd_open2()");
+
+    ret = connect(connection->socket, sock_address, sock_address_len);    
+    if (ret == -1){
+       /* Suppose server might not be running, try to autospawn (autostart) it 
*/
+       if (autospawn){ 
+           spawn_err = spawn_server(address, is_localhost, &spawn_report);
+           if (!spawn_err)
+               spawn_report = g_strdup("Server successfully autospawned");
+           ret = connect(connection->socket, sock_address, sock_address_len);  
  
+       }else{
+           spawn_report = g_strdup("Autospawn disabled");
+       }
+       if (ret == -1){
+           if (address->method == SPD_METHOD_INET_SOCKET)
+               *error_result = g_strdup_printf("Error: Can't connect to %s on 
port %d using inet sockets: %s. " \
+                                               "Autospawn: %s", 
address->inet_socket_host,
+                                               address->inet_socket_port, 
strerror(errno), spawn_report);
+           else if (address->method == SPD_METHOD_UNIX_SOCKET)
+               *error_result = g_strdup_printf("Error: Can't connect to unix 
socket %s: %s. Autospawn: %s",
+                                               address->unix_socket_name, 
strerror(errno), spawn_report);
+           else assert (0);
+           SPD_DBG(*error_result);
+           close(connection->socket);  
+           return NULL;
+       }
+    }
+
+    if (address->method == SPD_METHOD_INET_SOCKET)
+       setsockopt(connection->socket, IPPROTO_TCP, TCP_NODELAY, &tcp_no_delay, 
sizeof(int));
+    
+    connection->callback_begin = NULL;
+    connection->callback_end = NULL;
+    connection->callback_im = NULL;
+    connection->callback_pause = NULL;
+    connection->callback_resume = NULL;
+    connection->callback_cancel = NULL;
+
+    connection->mode = mode;
+
+    /* Create a stream from the socket */
+    connection->stream = fdopen(connection->socket, "r");
+    if (!connection->stream) SPD_FATAL("Can't create a stream for socket, 
fdopen() failed.");
+    /* Switch to line buffering mode */
+    ret = setvbuf(connection->stream, NULL, _IONBF, SPD_REPLY_BUF_SIZE);
+    if (ret) SPD_FATAL("Can't set buffering, setvbuf failed.");
+
+    connection->ssip_mutex = xmalloc(sizeof(pthread_mutex_t));
+    pthread_mutex_init(connection->ssip_mutex, NULL);
+
+    if (mode == SPD_MODE_THREADED){
+       SPD_DBG("Initializing threads, condition variables and mutexes...");
+       connection->events_thread = xmalloc(sizeof(pthread_t));
+       connection->cond_reply_ready = xmalloc(sizeof(pthread_cond_t));
+       connection->mutex_reply_ready = xmalloc(sizeof(pthread_mutex_t));
+       connection->cond_reply_ack = xmalloc(sizeof(pthread_cond_t));
+       connection->mutex_reply_ack = xmalloc(sizeof(pthread_mutex_t));
+       pthread_cond_init(connection->cond_reply_ready, NULL);
+       pthread_mutex_init(connection->mutex_reply_ready, NULL);
+       pthread_cond_init(connection->cond_reply_ack, NULL);
+       pthread_mutex_init(connection->mutex_reply_ack, NULL);
+       ret = pthread_create(connection->events_thread, NULL, 
spd_events_handler, connection);
+       if(ret != 0){
+           *error_result = strdup("Thread initialization failed");
+           SPD_DBG(*error_result);
+           return NULL;
+       }
+    }
+
+    /* By now, the connection is created and operational */
+    set_client_name = g_strdup_printf("SET SELF CLIENT_NAME \"%s:%s:%s\"", 
usr_name,
+                                     client_name, conn_name);
+    ret = spd_execute_command_wo_mutex(connection, set_client_name);   
+    xfree(usr_name);  xfree(conn_name);  xfree(set_client_name);
+    return connection;
+}
+
+
+#define RET(r) \
+    { \
+    pthread_mutex_unlock(connection->ssip_mutex); \
+    return r; \
+    }
+
+
+/* Close a Speech Dispatcher connection */
+void
+spd_close(SPDConnection* connection)
+{
+
+    pthread_mutex_lock(connection->ssip_mutex);
+
+    if (connection->mode == SPD_MODE_THREADED){
+       pthread_cancel(*connection->events_thread);
+       pthread_mutex_destroy(connection->mutex_reply_ready);
+       pthread_mutex_destroy(connection->mutex_reply_ack);
+       pthread_cond_destroy(connection->cond_reply_ready);
+       pthread_cond_destroy(connection->cond_reply_ack);
+       pthread_join(*connection->events_thread, NULL);
+       connection->mode = SPD_MODE_SINGLE;
+    }
+
+    /* close the socket */
+    close(connection->socket);
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+
+    pthread_mutex_destroy(connection->ssip_mutex);
+    xfree(connection);
+}
+
+/* Helper functions for spd_say. */
+static inline int
+spd_say_prepare(SPDConnection *connection, SPDPriority priority,
+       const char* text, char **escaped_text)
+{
+    int ret = 0;
+
+    SPD_DBG("Text to say is: %s", text);
+
+    /* Insure that there is no escape sequence in the text */
+    *escaped_text = escape_dot(text);
+    /* Caller is now responsible for escaped_text. */
+    if (*escaped_text == NULL) {       /* Out of memory. */
+       SPD_DBG("spd_say could not allocate memory.");
+       ret = -1;
+    } else {
+       /* Set priority */
+       SPD_DBG("Setting priority");
+       ret = spd_set_priority(connection, priority);
+       if (!ret) {
+           /* Start the data flow */
+           SPD_DBG("Sending SPEAK");
+           ret = spd_execute_command_wo_mutex(connection, "speak");
+           if (ret) {
+               SPD_DBG("Error: Can't start data flow!");
+           }
+       }
+    }
+
+    return ret;
+}
+
+static inline int
+spd_say_sending(SPDConnection *connection, const char* text)
+{
+    int msg_id = -1;
+    int err = 0;
+    char *reply = NULL;
+    char *pret = NULL;
+
+    /* Send data */
+    SPD_DBG("Sending data");
+    pret = spd_send_data_wo_mutex(connection, text, SPD_NO_REPLY);
+    if (pret==NULL) {
+       SPD_DBG("Can't send data wo mutex");
+    } else {
+       /* Terminate data flow */
+       SPD_DBG("Terminating data flow");
+       err = spd_execute_command_with_reply(connection, "\r\n.", &reply);
+       if (err) {
+           SPD_DBG("Can't terminate data flow");
+       } else {
+           msg_id = get_param_int(reply, 1, &err);
+           if (err < 0) {
+               SPD_DBG("Can't determine SSIP message unique ID parameter.");
+               msg_id = -1;
+           }
+       }
+    }
+
+    xfree(reply);
+    xfree(pret);
+    return msg_id;
+}
+
+/* Say TEXT with priority PRIORITY.
+ * Returns msg_uid on success, -1 otherwise. */
+int
+spd_say(SPDConnection *connection, SPDPriority priority, const char* text)
+{
+    char *escaped_text = NULL;
+    int msg_id = -1;
+    int prepare_failed = 0;
+
+    if (text != NULL) {
+    pthread_mutex_lock(connection->ssip_mutex);
+
+       prepare_failed = spd_say_prepare(connection, priority, text, 
&escaped_text);
+       if (!prepare_failed)
+           msg_id = spd_say_sending(connection, escaped_text);
+
+       xfree(escaped_text);
+       pthread_mutex_unlock(connection->ssip_mutex);
+    } else {
+       SPD_DBG("spd_say called with a NULL argument for <text>");
+    }
+
+    SPD_DBG("Returning from spd_say");
+    return msg_id;
+}
+
+/* The same as spd_say, accepts also formated strings */
+int
+spd_sayf(SPDConnection *connection, SPDPriority priority, const char *format, 
...)
+{
+    static int ret;    
+    va_list args;
+    char *buf;
+
+    if (format == NULL) return -1;
+    
+    /* Print the text to buffer */
+    va_start(args, format);
+    buf = g_strdup_vprintf(format, args);
+    va_end(args);
+    
+    /* Send the buffer to Speech Dispatcher */
+    ret = spd_say(connection, priority, buf);  
+    xfree(buf);
+
+    return ret;
+}
+
+int
+spd_stop(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "STOP SELF");
+}
+
+int
+spd_stop_all(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "STOP ALL");
+}
+
+int
+spd_stop_uid(SPDConnection *connection, int target_uid)
+{
+  static char command[16];
+
+  sprintf(command, "STOP %d", target_uid);
+  return spd_execute_command(connection, command);
+}
+
+int
+spd_cancel(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "CANCEL SELF");
+}
+
+int
+spd_cancel_all(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "CANCEL ALL");
+}
+
+int
+spd_cancel_uid(SPDConnection *connection, int target_uid)
+{
+  static char command[16];
+
+  sprintf(command, "CANCEL %d", target_uid);
+  return spd_execute_command(connection, command);
+}
+
+int
+spd_pause(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "PAUSE SELF");
+}
+
+int
+spd_pause_all(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "PAUSE ALL");
+}
+
+int
+spd_pause_uid(SPDConnection *connection, int target_uid)
+{
+  char command[16];
+
+  sprintf(command, "PAUSE %d", target_uid);
+  return spd_execute_command(connection, command);
+}
+
+int
+spd_resume(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "RESUME SELF");
+}
+
+int
+spd_resume_all(SPDConnection *connection)
+{
+  return spd_execute_command(connection, "RESUME ALL");
+}
+
+int
+spd_resume_uid(SPDConnection *connection, int target_uid)
+{
+  static char command[16];
+
+  sprintf(command, "RESUME %d", target_uid);
+  return spd_execute_command(connection, command);
+}
+
+int
+spd_key(SPDConnection *connection, SPDPriority priority, const char *key_name)
+{
+    char *command_key;
+    int ret;
+
+    if (key_name == NULL) return -1;
+
+    pthread_mutex_lock(connection->ssip_mutex);
+
+    ret = spd_set_priority(connection, priority);
+    if (ret) RET(-1);
+
+    command_key = g_strdup_printf("KEY %s", key_name);
+    ret = spd_execute_command_wo_mutex(connection, command_key);
+    xfree(command_key);
+    if (ret) RET(-1);
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+
+    return 0;
+}
+
+int
+spd_char(SPDConnection *connection, SPDPriority priority, const char 
*character)
+{
+    static char command[16];
+    int ret;
+
+    if (character == NULL) return -1;
+    if (strlen(character)>6) return -1;
+
+    pthread_mutex_lock(connection->ssip_mutex);
+
+    ret = spd_set_priority(connection, priority);
+    if (ret) RET(-1);
+
+    sprintf(command, "CHAR %s", character);
+    ret = spd_execute_command_wo_mutex(connection, command);
+    if (ret) RET(-1);
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+
+    return 0;
+}
+
+int
+spd_wchar(SPDConnection *connection, SPDPriority priority, wchar_t wcharacter)
+{
+    static char command[16];
+    char character[8];
+    int ret;
+
+    pthread_mutex_lock(connection->ssip_mutex);
+
+    ret = wcrtomb(character, wcharacter, NULL);
+    if (ret <= 0) RET(-1);
+
+    ret = spd_set_priority(connection, priority);
+    if (ret) RET(-1);
+
+    assert(character != NULL);
+    sprintf(command, "CHAR %s", character);
+    ret = spd_execute_command_wo_mutex(connection, command);
+    if (ret) RET(-1);
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+ 
+    return 0;
+}
+
+int
+spd_sound_icon(SPDConnection *connection, SPDPriority priority, const char 
*icon_name)
+{
+    char *command;
+    int ret;
+
+    if (icon_name == NULL) return -1;
+
+    pthread_mutex_lock(connection->ssip_mutex);
+
+    ret = spd_set_priority(connection, priority);
+    if (ret) RET(-1);
+
+    command = g_strdup_printf("SOUND_ICON %s", icon_name);
+    ret = spd_execute_command_wo_mutex(connection, command);
+    xfree (command);
+    if (ret) RET(-1);
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+    
+    return 0;
+}
+
+int
+spd_w_set_punctuation(SPDConnection *connection, SPDPunctuation type, const 
char* who)
+{
+    char command[32];
+    int ret;
+
+    if (type == SPD_PUNCT_ALL)
+        sprintf(command, "SET %s PUNCTUATION all", who);
+    if (type == SPD_PUNCT_NONE)
+        sprintf(command, "SET %s PUNCTUATION none", who);
+    if (type == SPD_PUNCT_SOME)
+        sprintf(command, "SET %s PUNCTUATION some", who);
+
+    ret = spd_execute_command(connection, command);    
+    
+    return ret;
+}
+
+int
+spd_w_set_capital_letters(SPDConnection *connection, SPDCapitalLetters type, 
const char* who)
+{
+    char command[64];
+    int ret;
+
+    if (type == SPD_CAP_NONE)
+        sprintf(command, "SET %s CAP_LET_RECOGN none", who);
+    if (type == SPD_CAP_SPELL)
+        sprintf(command, "SET %s CAP_LET_RECOGN spell", who);
+    if (type == SPD_CAP_ICON)
+        sprintf(command, "SET %s CAP_LET_RECOGN icon", who);
+
+    ret = spd_execute_command(connection, command);    
+    
+    return ret;
+}
+
+int
+spd_w_set_spelling(SPDConnection *connection, SPDSpelling type, const char* 
who)
+{
+    char command[32];
+    int ret;
+
+    if (type == SPD_SPELL_ON)
+        sprintf(command, "SET %s SPELLING on", who);
+    if (type == SPD_SPELL_OFF)
+        sprintf(command, "SET %s SPELLING off", who);
+
+    ret = spd_execute_command(connection, command);
+
+    return ret;
+}
+
+int
+spd_set_data_mode(SPDConnection *connection, SPDDataMode mode)
+{
+    char command[32];
+    int ret;
+
+    if (mode == SPD_DATA_TEXT)
+        sprintf(command, "SET SELF SSML_MODE off");
+    if (mode == SPD_DATA_SSML)
+        sprintf(command, "SET SELF SSML_MODE on");
+
+    ret = spd_execute_command(connection, command);
+
+    return ret;
+}
+
+int
+spd_w_set_voice_type(SPDConnection *connection, SPDVoiceType type, const char 
*who)
+{
+    static char command[64];
+
+    switch(type){
+    case SPD_MALE1: sprintf(command, "SET %s VOICE MALE1", who); break;
+    case SPD_MALE2: sprintf(command, "SET %s VOICE MALE2", who); break;
+    case SPD_MALE3: sprintf(command, "SET %s VOICE MALE3", who); break;
+    case SPD_FEMALE1: sprintf(command, "SET %s VOICE FEMALE1", who); break;
+    case SPD_FEMALE2: sprintf(command, "SET %s VOICE FEMALE2", who); break;
+    case SPD_FEMALE3: sprintf(command, "SET %s VOICE FEMALE3", who); break;
+    case SPD_CHILD_MALE: sprintf(command, "SET %s VOICE CHILD_MALE", who); 
break;
+    case SPD_CHILD_FEMALE: sprintf(command, "SET %s VOICE CHILD_FEMALE", who); 
break;
+    default: return -1;
+    }
+    
+    return spd_execute_command(connection, command);      
+}
+
+#define SPD_SET_COMMAND_INT(param, ssip_name, condition) \
+    int \
+    spd_w_set_ ## param (SPDConnection *connection, signed int val, const 
char* who) \
+    { \
+        static char command[64]; \
+        if ((!condition)) return -1; \
+        sprintf(command, "SET %s " #ssip_name " %d", who, val); \
+        return spd_execute_command(connection, command); \
+    } \
+    int \
+    spd_set_ ## param (SPDConnection *connection, signed int val) \
+    { \
+        return spd_w_set_ ## param (connection, val, "SELF"); \
+    } \
+    int \
+    spd_set_ ## param ## _all(SPDConnection *connection, signed int val) \
+    { \
+        return spd_w_set_ ## param (connection, val, "ALL"); \
+    } \
+    int \
+    spd_set_ ## param ## _uid(SPDConnection *connection, signed int val, 
unsigned int uid) \
+    { \
+        char who[8]; \
+        sprintf(who, "%d", uid); \
+        return spd_w_set_ ## param (connection, val, who); \
+    }
+
+#define SPD_SET_COMMAND_STR(param, ssip_name) \
+    int \
+    spd_w_set_ ## param (SPDConnection *connection, const char *str, const 
char* who) \
+    { \
+        char *command; \
+        int ret; \
+        if (str == NULL) return -1; \
+        command = g_strdup_printf("SET %s " #param " %s", \
+                              who, str); \
+        ret = spd_execute_command(connection, command); \
+        xfree(command); \
+        return ret; \
+    } \
+    int \
+    spd_set_ ## param (SPDConnection *connection, const char *str) \
+    { \
+        return spd_w_set_ ## param (connection, str, "SELF"); \
+    } \
+    int \
+    spd_set_ ## param ## _all(SPDConnection *connection, const char *str) \
+    { \
+        return spd_w_set_ ## param (connection, str, "ALL"); \
+    } \
+    int \
+    spd_set_ ## param ## _uid(SPDConnection *connection, const char *str, 
unsigned int uid) \
+    { \
+        char who[8]; \
+        sprintf(who, "%d", uid); \
+        return spd_w_set_ ## param (connection, str, who); \
+    }
+
+#define SPD_SET_COMMAND_SPECIAL(param, type) \
+    int \
+    spd_set_ ## param (SPDConnection *connection, type val) \
+    { \
+        return spd_w_set_ ## param (connection, val, "SELF"); \
+    } \
+    int \
+    spd_set_ ## param ## _all(SPDConnection *connection, type val) \
+    { \
+        return spd_w_set_ ## param (connection, val, "ALL"); \
+    } \
+    int \
+    spd_set_ ## param ## _uid(SPDConnection *connection, type val, unsigned 
int uid) \
+    { \
+        char who[8]; \
+        sprintf(who, "%d", uid); \
+        return spd_w_set_ ## param (connection, val, who); \
+    }
+
+SPD_SET_COMMAND_INT(voice_rate, RATE, ((val >= -100) && (val <= +100)) )
+SPD_SET_COMMAND_INT(voice_pitch, PITCH, ((val >= -100) && (val <= +100)) )
+SPD_SET_COMMAND_INT(volume, VOLUME, ((val >= -100) && (val <= +100)) )
+
+SPD_SET_COMMAND_STR(language, LANGUAGE)
+SPD_SET_COMMAND_STR(output_module, OUTPUT_MODULE)
+SPD_SET_COMMAND_STR(synthesis_voice, SYNTHESIS_VOICE)
+
+SPD_SET_COMMAND_SPECIAL(punctuation, SPDPunctuation)
+SPD_SET_COMMAND_SPECIAL(capital_letters, SPDCapitalLetters)
+SPD_SET_COMMAND_SPECIAL(spelling, SPDSpelling)
+SPD_SET_COMMAND_SPECIAL(voice_type, SPDVoiceType)
+
+
+#undef SPD_SET_COMMAND_INT
+#undef SPD_SET_COMMAND_STR
+#undef SPD_SET_COMMAND_SPECIAL
+
+int
+spd_set_notification_on(SPDConnection *connection, SPDNotification 
notification)
+{
+    if (connection->mode == SPD_MODE_THREADED)
+       return spd_set_notification(connection, notification, "on");
+    else
+       return -1;
+}
+
+int
+spd_set_notification_off(SPDConnection *connection, SPDNotification 
notification)
+{
+    if (connection->mode == SPD_MODE_THREADED)
+       return spd_set_notification(connection, notification, "off");
+    else
+       return -1;
+}
+
+
+#define NOTIFICATION_SET(val, ssip_val) \
+    if (notification & val){ \
+       sprintf(command, "SET SELF NOTIFICATION "ssip_val" %s", state);\
+       ret = spd_execute_command_wo_mutex(connection, command);\
+       if (ret < 0) RET(-1);\
+    }
+
+int
+spd_set_notification(SPDConnection *connection, SPDNotification notification, 
const char* state)
+{
+    static char command[64];
+    int ret;
+
+    if (connection->mode != SPD_MODE_THREADED) return -1;
+
+    if (state == NULL){
+      SPD_DBG("Requested state is NULL");
+      return -1;
+    }
+    if (strcmp(state, "on") && strcmp(state, "off")){
+      SPD_DBG("Invalid argument for spd_set_notification: %s", state);
+      return -1;
+    }
+
+    pthread_mutex_lock(connection->ssip_mutex);
+
+    NOTIFICATION_SET(SPD_INDEX_MARKS, "index_marks");
+    NOTIFICATION_SET(SPD_BEGIN, "begin");
+    NOTIFICATION_SET(SPD_END, "end");
+    NOTIFICATION_SET(SPD_CANCEL, "cancel");
+    NOTIFICATION_SET(SPD_PAUSE, "pause");
+    NOTIFICATION_SET(SPD_RESUME, "resume");
+    NOTIFICATION_SET(SPD_RESUME, "pause");
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+
+    return 0;
+}
+#undef NOTIFICATION_SET
+
+
+/* spd_list_modules retrieves information about the available output modules.
+   The return value is a null-terminated array of strings containing output 
module
+   names.
+*/
+
+char**
+spd_list_modules(SPDConnection *connection)
+{
+  char **available_modules;
+  available_modules = spd_execute_command_with_list_reply(connection, "LIST 
OUTPUT_MODULES");
+  return available_modules;
+}
+
+char**
+spd_list_voices(SPDConnection *connection)
+{
+  char **voices;
+  voices = spd_execute_command_with_list_reply(connection, "LIST VOICES");
+  return voices;
+}
+
+SPDVoice**
+spd_list_synthesis_voices(SPDConnection *connection)
+{
+  char **svoices_str;
+  SPDVoice **svoices;
+  int i, num_items;
+  svoices_str = spd_execute_command_with_list_reply(connection, "LIST 
SYNTHESIS_VOICES");
+
+  if (svoices_str == NULL) return NULL;
+
+  for (i=0;;i++)
+    if (svoices_str[i] == NULL) break;
+  num_items = i;
+  svoices = (SPDVoice**) malloc((num_items+1) * sizeof(SPDVoice*));
+
+  for (i=0;i<=num_items;i++){
+    const char delimiters[] = " ";
+    char *running;
+
+    if (svoices_str[i] == NULL) break;
+    running = strdup (svoices_str[i]);
+
+    svoices[i] = (SPDVoice*) malloc(sizeof(SPDVoice));
+    svoices[i]->name = strsep (&running, delimiters);
+    svoices[i]->language = strsep (&running, delimiters);
+    svoices[i]->variant = strsep (&running, delimiters);
+    assert (svoices[i]->name != NULL);
+  }
+
+  svoices[num_items] = NULL;
+
+  return svoices;
+}
+
+char**
+spd_execute_command_with_list_reply(SPDConnection *connection, char *command)
+{
+  char *reply, *line;
+  int err;
+  int max_items = 50;
+  char **result;
+  int i, ret;
+
+  result = malloc((max_items+1)*sizeof(char*));
+
+  ret = spd_execute_command_with_reply(connection, command, &reply);
+  if(!ret_ok(reply)) return NULL;
+  
+  for(i=0;  ;i++){
+    line = get_param_str(reply, i+1, &err);
+    if ((err) || (line == NULL)) break;
+    result[i] = strdup(line);
+    if (i>=max_items-2){
+      max_items *= 2;
+      result = realloc(result, max_items*sizeof(char*));
+    }
+  }
+
+  result[i] = NULL;
+  
+  return result;
+}
+
+//int
+//spd_get_client_list(SPDConnection *connection, char **client_names, int 
*client_ids, int* active){
+//        SPD_DBG("spd_get_client_list: History is not yet implemented.");
+//        return -1;
+//
+//}
+
+int
+spd_get_message_list_fd(SPDConnection *connection, int target, int *msg_ids, 
char **client_names)
+{
+        SPD_DBG("spd_get_client_list: History is not yet implemented.");
+        return -1;
+#if 0
+       sprintf(command, "HISTORY GET MESSAGE_LIST %d 0 20\r\n", target);
+       reply = spd_send_data(fd, command, 1);
+
+/*     header_ok = parse_response_header(reply);
+       if(header_ok != 1){
+               free(reply);
+               return -1;
+       }*/
+
+       for(count=0;  ;count++){
+               record = (char*) parse_response_data(reply, count+1);
+               if (record == NULL) break;
+               record_int = get_rec_int(record, 0);
+               msg_ids[count] = record_int;
+               record_str = (char*) get_rec_str(record, 1);
+               assert(record_str!=NULL);
+               client_names[count] = record_str;
+       }
+       return count;
+#endif
+}
+
+int
+spd_execute_command(SPDConnection *connection, char* command)
+{
+    char *reply;
+    int ret;
+
+    pthread_mutex_lock(connection->ssip_mutex);
+
+    ret = spd_execute_command_with_reply(connection, command, &reply);
+    if (ret){
+      SPD_DBG("Can't execute command in spd_execute_command");
+    }
+    xfree(reply);
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+
+    return ret;
+}
+
+int
+spd_execute_command_wo_mutex(SPDConnection *connection, char* command)
+{
+    char *reply;
+    int ret;
+
+    SPD_DBG("Executing command wo_mutex");
+    ret = spd_execute_command_with_reply(connection, command, &reply);
+    if (ret)
+      SPD_DBG("Can't execute command in spd_execute_command_wo_mutex");
+
+    xfree(reply);
+
+    return ret;
+}
+
+int
+spd_execute_command_with_reply(SPDConnection *connection, char* command, char 
**reply)
+{
+    char *buf;    
+    int r;
+    SPD_DBG("Inside execute_command_with_reply");
+
+    buf = g_strdup_printf("%s\r\n", command);
+    *reply = spd_send_data_wo_mutex(connection, buf, SPD_WAIT_REPLY);
+    xfree(buf);
+    buf = NULL;
+    if(*reply==NULL){
+        SPD_DBG("Can't send data wo mutex in spd_execute_command_with_reply");
+       return -1;
+    }
+
+    r = ret_ok(*reply);
+
+    if (!r) return -1;
+    else return 0;
+}
+
+
+char*
+spd_send_data(SPDConnection *connection, const char *message, int wfr)
+{
+    char *reply;
+    pthread_mutex_lock(connection->ssip_mutex);
+
+
+    if (connection->stream ==NULL) RET( NULL);
+
+    reply = spd_send_data_wo_mutex(connection, message, wfr);
+    if(reply==NULL){
+        SPD_DBG("Can't send data wo mutex in spd_send_data");
+        RET(NULL); 
+    }
+
+    pthread_mutex_unlock(connection->ssip_mutex);
+    return reply;
+}
+
+char*
+spd_send_data_wo_mutex(SPDConnection *connection, const char *message, int wfr)
+{
+
+    char *reply;
+    int bytes;
+
+    SPD_DBG("Inside spd_send_data_wo_mutex");
+
+    if (connection->stream == NULL) return NULL;
+
+    if (connection->mode == SPD_MODE_THREADED){
+       /* Make sure we don't get the cond_reply_ready signal before we are in
+          cond_wait() */
+       pthread_mutex_lock(connection->mutex_reply_ready);
+    }
+    /* write message to the socket */
+    SPD_DBG("Writing to socket");
+    if(!write(connection->socket, message, strlen(message))){
+       SPD_DBG("Can't write to socket: %s", strerror(errno));
+       pthread_mutex_unlock(connection->mutex_reply_ready);
+       return NULL;
+    }
+    SPD_DBG("Written to socket");
+    SPD_DBG(">> : |%s|", message);
+
+    /* read reply to the buffer */
+    if (wfr){
+       if (connection->mode == SPD_MODE_THREADED){
+         /* Wait until the reply is ready */
+         SPD_DBG("Waiting for cond_reply_ready in spd_send_data_wo_mutex");
+         pthread_cond_wait(connection->cond_reply_ready, 
connection->mutex_reply_ready);
+         SPD_DBG("Condition for cond_reply_ready satisfied");
+         pthread_mutex_unlock(connection->mutex_reply_ready);
+         SPD_DBG("Reading the reply in spd_send_data_wo_mutex threaded mode");
+         /* Read the reply */
+         if (connection->reply != NULL){
+               reply = strdup(connection->reply);
+           }else{
+               SPD_DBG("Error: Can't read reply, broken socket in 
spd_send_data.");
+               return NULL;
+           }
+           xfree(connection->reply);
+           bytes = strlen(reply);
+           if (bytes == 0){
+               SPD_DBG("Error: Empty reply, broken socket.");
+               return NULL;
+           }
+           /* Signal the reply has been read */
+           pthread_mutex_lock(connection->mutex_reply_ack);
+           pthread_cond_signal(connection->cond_reply_ack);
+           pthread_mutex_unlock(connection->mutex_reply_ack);
+       }else{
+           reply = get_reply(connection);
+       }
+       if (reply != NULL)
+         SPD_DBG("<< : |%s|\n", reply);        
+    }else{
+       if (connection->mode == SPD_MODE_THREADED)
+           pthread_mutex_unlock(connection->mutex_reply_ready);
+       SPD_DBG("<< : no reply expected");
+        return strdup("NO REPLY");
+    } 
+
+    if (reply==NULL)
+      SPD_DBG("Reply from get_reply is NULL in spd_send_data_wo_mutex");
+
+    SPD_DBG("Returning from spd_send_data_wo_mutex");
+    return reply;
+}
+
+
+/* --------------------- Internal functions ------------------------- */
+
+static int
+spd_set_priority(SPDConnection *connection, SPDPriority priority)
+{
+    static char p_name[16];
+    static char command[64];
+
+    switch(priority){
+    case SPD_IMPORTANT: strcpy(p_name, "IMPORTANT"); break;
+    case SPD_MESSAGE: strcpy(p_name, "MESSAGE"); break;
+    case SPD_TEXT: strcpy(p_name, "TEXT"); break;
+    case SPD_NOTIFICATION: strcpy(p_name, "NOTIFICATION"); break;
+    case SPD_PROGRESS: strcpy(p_name, "PROGRESS"); break;
+    default: 
+      SPD_DBG("Error: Can't set priority! Incorrect value.");
+      return -1;
+    }
+                
+    sprintf(command, "SET SELF PRIORITY %s", p_name);
+    return spd_execute_command_wo_mutex(connection, command);
+}
+
+
+static char*
+get_reply(SPDConnection *connection)
+{
+    GString *str;
+    char *line = NULL;
+    size_t N = 0;
+    int bytes;
+    char *reply;
+    gboolean errors = FALSE;
+
+    str = g_string_new("");
+
+    /* Wait for activity on the socket, when there is some,
+       read all the message line by line */
+    do{
+       bytes = getline(&line, &N, connection->stream); 
+       if (bytes == -1){
+           SPD_DBG("Error: Can't read reply, broken socket in get_reply!");
+           if (connection->stream != NULL)
+             fclose(connection->stream);
+           connection->stream = NULL;
+           errors = TRUE;
+       } else {
+           g_string_append(str, line);
+       }
+       /* terminate if we reached the last line (without '-' after numcode) */
+    }while(!errors &&  !((strlen(line) < 4) || (line[3] == ' ')));
+    
+    xfree(line);       /* getline allocates with malloc. */
+
+    if (errors) {
+       /* Free the GString and its character data, and return NULL. */
+       g_string_free(str, TRUE);
+       reply = NULL;
+    } else {
+           /* The resulting message received from the socket is stored in 
reply */
+           reply = str->str;
+       /* Free the GString, but not its character data. */
+           g_string_free(str, FALSE);
+    }
+
+    return reply;
+}
+
+static void*
+spd_events_handler(void* conn)
+{
+    char *reply;
+    int reply_code;
+    SPDConnection *connection = conn;
+
+    while(1){
+
+       /* Read the reply/event (block if none is available) */
+        SPD_DBG("Getting reply in spd_events_handler");
+       reply = get_reply(connection);
+       if (reply == NULL){
+           SPD_DBG("ERROR: BROKEN SOCKET");
+           reply_code = -1;
+       }else{
+           SPD_DBG("<< : |%s|\n", reply);
+           reply_code = get_err_code(reply);
+       }
+
+       if ((reply_code >= 700) && (reply_code < 800)){
+           int msg_id;
+           int client_id;
+           int err;
+
+           SPD_DBG("Callback detected: %s", reply);
+
+           /* This is an index mark */
+           /* Extract message id */
+           msg_id = get_param_int(reply, 1, &err);
+           if (err < 0){
+             SPD_DBG("Bad reply from Speech Dispatcher: %s (code %d)", reply, 
err);
+             break;
+           }
+           client_id = get_param_int(reply, 2, &err);
+           if (err < 0){
+             SPD_DBG("Bad reply from Speech Dispatcher: %s (code %d)", reply, 
err);
+             break;
+           }
+           /*  Decide if we want to call a callback */
+           if ((reply_code == 701) && (connection->callback_begin))
+               connection->callback_begin(msg_id, client_id, SPD_EVENT_BEGIN);
+           if ((reply_code == 702) && (connection->callback_end))
+               connection->callback_end(msg_id, client_id, SPD_EVENT_END);
+           if ((reply_code == 703) && (connection->callback_cancel))
+               connection->callback_cancel(msg_id, client_id, 
SPD_EVENT_CANCEL);
+           if ((reply_code == 704) && (connection->callback_pause))
+               connection->callback_pause(msg_id, client_id, SPD_EVENT_PAUSE);
+           if ((reply_code == 705) && (connection->callback_resume))
+               connection->callback_resume(msg_id, client_id, 
SPD_EVENT_RESUME);
+           if ((reply_code == 700) && (connection->callback_im)){
+               char* im;
+               int err;
+               im = get_param_str(reply, 3, &err);
+               if ((err < 0) || (im == NULL)){
+                 SPD_DBG("Broken reply from Speech Dispatcher: %s", reply);
+                 break;
+               }
+               /* Call the callback */
+               connection->callback_im(msg_id, client_id, 
SPD_EVENT_INDEX_MARK, im);
+               xfree(im);
+           }
+
+       }else{
+           /* This is a protocol reply */
+           pthread_mutex_lock(connection->mutex_reply_ready);
+           /* Prepare the reply to the reply buffer in connection */
+           if (reply != NULL){
+               connection->reply = strdup(reply);
+           }else{
+             SPD_DBG("Connection reply is NULL");
+             connection->reply = NULL;
+             break;
+           }
+           /* Signal the reply is available on the condition variable */
+           /* this order is correct and necessary */
+           pthread_cond_signal(connection->cond_reply_ready);
+           pthread_mutex_lock(connection->mutex_reply_ack); 
+           pthread_mutex_unlock(connection->mutex_reply_ready);
+           /* Wait until it has bean read */
+           pthread_cond_wait(connection->cond_reply_ack, 
connection->mutex_reply_ack);
+           pthread_mutex_unlock(connection->mutex_reply_ack);
+           xfree(reply);
+           /* Continue */      
+       }
+    }
+    /* In case of broken socket, we must still signal reply ready */
+    if (connection->reply == NULL){
+      SPD_DBG("Signalling reply ready after communication failure");
+      pthread_mutex_unlock(connection->mutex_reply_ready);
+      pthread_mutex_unlock(connection->mutex_reply_ack);
+      if (connection->stream != NULL)
+       fclose(connection->stream);
+      connection->stream = NULL;
+      pthread_cond_signal(connection->cond_reply_ready);
+      pthread_exit(0);
+    }
+    return 0;                  /* to please gcc */
+}
+
+static int
+ret_ok(char *reply)
+{
+       int err;
+
+       if (reply == NULL) return -1;
+
+       err = get_err_code(reply);
+               
+       if ((err>=100) && (err<300)) return 1;
+       if (err>=300) return 0;
+    
+       SPD_FATAL("Internal error during communication.");
+}
+
+static char*
+get_param_str(char* reply, int num, int *err)
+{
+    int i;
+    char *tptr;
+    char *pos;
+    char *pos_begin;
+    char *pos_end;
+    char *rep;
+
+    assert(err != NULL);
+
+    if (num < 1){
+       *err = -1;
+       return NULL;
+    }
+
+    pos = reply;
+    for (i=0; i<=num-2; i++){
+       pos = strstr(pos, "\r\n");      
+       if (pos == NULL){
+           *err = -2;
+           return NULL;
+       }
+       pos += 2;
+    }
+
+    if (strlen(pos) < 4) return NULL;
+    
+    *err = strtol(pos, &tptr, 10);
+    if (*err >= 300 && *err <= 399)
+       return NULL;
+
+    if ((*tptr != '-') || (tptr != pos+3)){
+       *err = -3;
+       return NULL;
+    }
+
+    pos_begin = pos + 4;
+    pos_end = strstr(pos_begin, "\r\n");
+    if (pos_end == NULL){
+       *err = -4;
+       return NULL;
+    }
+
+    rep = (char*) strndup(pos_begin, pos_end - pos_begin);
+    *err = 0;
+    
+    return rep;
+}
+
+static int
+get_param_int(char* reply, int num, int *err)
+{
+    char *rep_str;
+    char *tptr;
+    int ret;
+
+    rep_str = get_param_str(reply, num, err);
+    if (rep_str == NULL){
+       /* err is already set to the error return code, just return */
+       return 0;
+    }
+    
+    ret = strtol(rep_str, &tptr, 10);
+    if (*tptr != '\0'){
+       /* this is not a number */
+       *err = -3;
+       return 0;
+    }    
+    xfree(rep_str);
+
+    return ret;
+}
+
+static int
+get_err_code(char *reply)
+{
+    char err_code[4];
+    int err;
+       
+    if (reply == NULL) return -1;
+    SPD_DBG("spd_send_data:    reply: %s\n", reply);
+
+    err_code[0] = reply[0];    err_code[1] = reply[1];
+    err_code[2] = reply[2];    err_code[3] = '\0';
+
+    SPD_DBG("ret_ok: err_code: |%s|\n", err_code);
+   
+    if(isanum(err_code)){
+        err = atoi(err_code);
+    }else{
+      SPD_DBG("ret_ok: not a number\n");
+      return -1;       
+    }
+
+    return err;
+}
+
+/* isanum() tests if the given string is a number,
+ *  returns 1 if yes, 0 otherwise. */
+static int
+isanum(char *str)
+{
+    int i;
+    if (str == NULL) return 0;
+    for(i=0;i<=strlen(str)-1;i++){
+        if (!isdigit(str[i]))   return 0;
+    }
+    return 1;
+}
+
+static void*
+xmalloc(size_t bytes)
+{
+    void *mem;
+
+    mem = malloc(bytes);
+    if (mem == NULL){
+      SPD_FATAL("Not enough memmory!");
+      exit(1);
+    }
+    
+    return mem;
+}
+
+static void
+xfree(void *ptr)
+{
+    if (ptr != NULL)
+        free(ptr);
+}
+
+/*
+ * escape_dot: Replace . with .. at the start of lines.
+ * @text: text to escape
+ * @Returns: An allocated string, containing the escaped text.
+ */
+static char*
+escape_dot(const char *text)
+{
+    size_t orig_len = 0;
+    const char *orig_end;
+    char *result = NULL;
+    char *result_ptr;
+    static const char *ESCAPED_DOTLINE = "\r\n..";
+    static const size_t ESCAPED_DOTLINELEN = 4;
+    static const size_t DOTLINELEN = 3;
+
+    if (text == NULL)
+        return NULL;
+
+orig_len = strlen(text);
+    orig_end = text + orig_len;
+    result = malloc((orig_len * 2 + 1) * sizeof(char));
+
+    if (result == NULL)
+        return NULL;
+
+    result_ptr = result;
+
+    /* We're over-allocating.  Even if we replaced every character
+     * in text with "..", the length of the escaped string can be no more
+     * than orig_len * 2.  We could tighten that upper bound with
+     * a little more work.
+     */
+
+    if ((orig_len >= 1) && (text[0] == '.')) {
+        *(result_ptr++) = '.';
+        *(result_ptr++) = '.';
+        text += 1;
+    }
+
+    while (text < orig_end) {
+        if ((text[0] == '\r') && (text[1] == '\n') && (text[2] == '.')) {
+            memcpy(result_ptr, ESCAPED_DOTLINE, ESCAPED_DOTLINELEN);
+            result_ptr += ESCAPED_DOTLINELEN;
+            text += DOTLINELEN;
+        } else {
+            *(result_ptr++) = *(text++);
+        }
+    }
+
+    * result_ptr = '\0';
+    return result;
+}
+
+#ifdef LIBSPEECHD_DEBUG
+static void
+SPD_DBG(char *format, ...)
+{
+        va_list args;
+
+       pthread_mutex_lock(&spd_logging_mutex);         
+       va_start(args, format);
+       vfprintf(spd_debug, format, args);
+       va_end(args);
+       fprintf(spd_debug, "\n");
+       fflush(spd_debug);
+       pthread_mutex_unlock(&spd_logging_mutex);       
+}
+#else  /* LIBSPEECHD_DEBUG */
+static void
+SPD_DBG(char *format, ...)
+{
+}
+#endif /* LIBSPEECHD_DEBUG */
diff --git a/src/api/c/libspeechd.h b/src/api/c/libspeechd.h
new file mode 100644
index 0000000..c88f89f
--- /dev/null
+++ b/src/api/c/libspeechd.h
@@ -0,0 +1,278 @@
+
+/*
+ * libspeechd.h - Shared library for easy acces to Speech Dispatcher functions 
(header)
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this package; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $Id: libspeechd.h,v 1.29 2008-07-30 09:47:00 hanke Exp $
+ */
+
+#ifndef _LIBSPEECHD_H
+#define _LIBSPEECHD_H
+
+#include <stdio.h>
+#include <stddef.h>
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+#ifdef LIBSPEECHD_DEBUG
+/* Debugging */
+FILE* spd_debug;
+#endif
+
+/* Unless there is an fatal error, it doesn't print anything */
+#define SPD_FATAL(msg) { printf("Fatal error (libspeechd) [%s:%d]:"msg, 
__FILE__, __LINE__); fflush(stdout); exit(EXIT_FAILURE); }
+/* Speech Dispatcher's default port for inet communication */
+#define SPEECHD_DEFAULT_PORT 6560
+
+/* Arguments for spd_send_data() */
+#define SPD_WAIT_REPLY 1              /* Wait for reply */
+#define SPD_NO_REPLY 0               /* No reply requested */
+
+
+/* --------------------- Public data types ------------------------ */
+
+typedef enum{
+    SPD_PUNCT_ALL = 0,
+    SPD_PUNCT_NONE = 1,
+    SPD_PUNCT_SOME = 2
+}SPDPunctuation;
+
+typedef enum{
+    SPD_CAP_NONE = 0,
+    SPD_CAP_SPELL = 1,
+    SPD_CAP_ICON = 2
+}SPDCapitalLetters;
+
+typedef enum{
+    SPD_SPELL_OFF = 0,
+    SPD_SPELL_ON = 1
+}SPDSpelling;
+
+typedef enum{
+    SPD_DATA_TEXT = 0,
+    SPD_DATA_SSML = 1
+}SPDDataMode;
+    
+typedef enum{
+    SPD_MALE1 = 1,
+    SPD_MALE2 = 2,
+    SPD_MALE3 = 3,
+    SPD_FEMALE1 = 4,
+    SPD_FEMALE2 = 5,
+    SPD_FEMALE3 = 6,
+    SPD_CHILD_MALE = 7,
+    SPD_CHILD_FEMALE = 8
+}SPDVoiceType;
+
+
+typedef struct{
+  char *name;   /* Name of the voice (id) */
+  char *language;  /* 2-letter ISO language code */
+  char *variant;   /* a not-well defined string describing dialect etc. */
+}SPDVoice;
+
+typedef enum{
+    SPD_BEGIN = 1,
+    SPD_END = 2,
+    SPD_INDEX_MARKS = 4,
+    SPD_CANCEL = 8,
+    SPD_PAUSE = 16,
+    SPD_RESUME = 32
+}SPDNotification;
+
+typedef enum{
+    SPD_IMPORTANT = 1,
+    SPD_MESSAGE = 2,
+    SPD_TEXT = 3,
+    SPD_NOTIFICATION = 4,
+    SPD_PROGRESS = 5
+}SPDPriority;
+
+typedef enum{
+    SPD_EVENT_BEGIN,
+    SPD_EVENT_END,
+    SPD_EVENT_CANCEL,
+    SPD_EVENT_PAUSE,
+    SPD_EVENT_RESUME,
+    SPD_EVENT_INDEX_MARK
+}SPDNotificationType;
+
+typedef enum{
+    SPD_MODE_SINGLE = 0,
+    SPD_MODE_THREADED = 1
+}SPDConnectionMode;
+
+typedef enum{
+    SPD_METHOD_UNIX_SOCKET = 0,
+    SPD_METHOD_INET_SOCKET = 1,
+}SPDConnectionMethod;
+
+typedef struct{
+  SPDConnectionMethod method;
+  char *unix_socket_name;
+  char *inet_socket_host;
+  int  inet_socket_port;
+  char *dbus_bus;
+}SPDConnectionAddress;
+
+typedef void (*SPDCallback)(size_t msg_id, size_t client_id, 
SPDNotificationType state);
+typedef void (*SPDCallbackIM)(size_t msg_id, size_t client_id, 
SPDNotificationType state, char *index_mark);
+
+typedef struct{
+
+    /* PUBLIC */
+    SPDCallback callback_begin;
+    SPDCallback callback_end;
+    SPDCallback callback_cancel;
+    SPDCallback callback_pause;
+    SPDCallback callback_resume;
+    SPDCallbackIM callback_im;
+
+    /* PRIVATE */
+    int socket;
+    FILE *stream;
+    SPDConnectionMode mode;
+
+    pthread_mutex_t *ssip_mutex;
+
+    pthread_t *events_thread;
+    pthread_mutex_t *comm_mutex;
+    pthread_cond_t *cond_reply_ready;
+    pthread_mutex_t *mutex_reply_ready;
+    pthread_cond_t *cond_reply_ack;
+    pthread_mutex_t *mutex_reply_ack;
+
+    char *reply;
+
+}SPDConnection;
+
+/* -------------- Public functions --------------------------*/
+
+/* Openning and closing Speech Dispatcher connection */
+SPDConnectionAddress* spd_get_default_address(char** error);
+SPDConnection* spd_open(const char* client_name, const char* connection_name, 
const char* user_name,
+                       SPDConnectionMode mode);
+SPDConnection* spd_open2(const char* client_name, const char* connection_name, 
const char* user_name,
+                        SPDConnectionMode mode, SPDConnectionAddress *address, 
int autospawn,
+                        char **error_result);
+
+void spd_close(SPDConnection* connection);
+
+/* Speaking */
+int spd_say(SPDConnection* connection, SPDPriority priority, const char* text);
+int spd_sayf(SPDConnection* connection, SPDPriority priority, const char 
*format, ...);
+
+/* Speech flow */
+int spd_stop(SPDConnection* connection);
+int spd_stop_all(SPDConnection* connection);
+int spd_stop_uid(SPDConnection* connection, int target_uid);
+
+int spd_cancel(SPDConnection* connection);
+int spd_cancel_all(SPDConnection* connection);
+int spd_cancel_uid(SPDConnection* connection, int target_uid);
+
+int spd_pause(SPDConnection* connection);
+int spd_pause_all(SPDConnection* connection);
+int spd_pause_uid(SPDConnection* connection, int target_uid);
+
+int spd_resume(SPDConnection* connection);
+int spd_resume_all(SPDConnection* connection);
+int spd_resume_uid(SPDConnection* connection, int target_uid);
+
+/* Characters and keys */
+int spd_key(SPDConnection* connection, SPDPriority priority, const char 
*key_name);
+int spd_char(SPDConnection* connection, SPDPriority priority, const char 
*character);
+int spd_wchar(SPDConnection* connection, SPDPriority priority, wchar_t 
wcharacter);
+
+/* Sound icons */
+int spd_sound_icon(SPDConnection* connection, SPDPriority priority, const char 
*icon_name);
+
+/* Setting parameters */
+int spd_set_voice_type(SPDConnection*, SPDVoiceType type);
+int spd_set_voice_type_all(SPDConnection*, SPDVoiceType type);
+int spd_set_voice_type_uid(SPDConnection*, SPDVoiceType type, unsigned int 
uid);
+
+int spd_set_synthesis_voice(SPDConnection*, const char *voice_name);
+int spd_set_synthesis_voice_all(SPDConnection*, const char *voice_name);
+int spd_set_synthesis_voice_uid(SPDConnection*, const char *voice_name, 
unsigned int uid);
+
+int spd_set_data_mode(SPDConnection *connection, SPDDataMode mode);
+
+int spd_set_notification_on(SPDConnection* connection, SPDNotification 
notification);
+int spd_set_notification_off(SPDConnection* connection, SPDNotification 
notification);
+int spd_set_notification(SPDConnection* connection, SPDNotification 
notification, const char* state);
+
+int spd_set_voice_rate(SPDConnection* connection, signed int rate);
+int spd_set_voice_rate_all(SPDConnection* connection, signed int rate);
+int spd_set_voice_rate_uid(SPDConnection* connection, signed int rate, 
unsigned int uid);
+
+int spd_set_voice_pitch(SPDConnection* connection, signed int pitch);
+int spd_set_voice_pitch_all(SPDConnection* connection, signed int pitch);
+int spd_set_voice_pitch_uid(SPDConnection* connection, signed int pitch, 
unsigned int uid);
+
+int spd_set_volume(SPDConnection* connection, signed int volume);
+int spd_set_volume_all(SPDConnection* connection, signed int volume);
+int spd_set_volume_uid(SPDConnection* connection, signed int volume, unsigned 
int uid);
+
+int spd_set_punctuation(SPDConnection* connection, SPDPunctuation type);
+int spd_set_punctuation_all(SPDConnection* connection, SPDPunctuation type);
+int spd_set_punctuation_uid(SPDConnection* connection, SPDPunctuation type, 
unsigned int uid);
+
+int spd_set_capital_letters(SPDConnection* connection, SPDCapitalLetters type);
+int spd_set_capital_letters_all(SPDConnection* connection, SPDCapitalLetters 
type);
+int spd_set_capital_letters_uid(SPDConnection* connection, SPDCapitalLetters 
type, unsigned int uid);
+
+int spd_set_spelling(SPDConnection* connection, SPDSpelling type);
+int spd_set_spelling_all(SPDConnection* connection, SPDSpelling type);
+int spd_set_spelling_uid(SPDConnection* connection, SPDSpelling type, unsigned 
int uid);
+
+int spd_set_language(SPDConnection* connection, const char* language);
+int spd_set_language_all(SPDConnection* connection, const char* language);
+int spd_set_language_uid(SPDConnection* connection, const char* language, 
unsigned int uid);
+
+int spd_set_output_module(SPDConnection* connection, const char* 
output_module);
+int spd_set_output_module_all(SPDConnection* connection, const char* 
output_module);
+int spd_set_output_module_uid(SPDConnection* connection, const char* 
output_module, unsigned int uid);
+
+int spd_get_client_list(SPDConnection *connection, char **client_names, int 
*client_ids, int* active);
+int spd_get_message_list_fd(SPDConnection *connection, int target, int 
*msg_ids, char **client_names);
+
+char** spd_list_modules(SPDConnection *connection);
+char** spd_list_voices(SPDConnection *connection);
+SPDVoice** spd_list_synthesis_voices(SPDConnection *connection);
+char** spd_execute_command_with_list_reply(SPDConnection *connection, char* 
command);
+
+
+/* Direct SSIP communication */
+int spd_execute_command(SPDConnection* connection, char* command);
+int spd_execute_command_with_reply(SPDConnection *connection, char* command, 
char **reply);
+int spd_execute_command_wo_mutex(SPDConnection *connection, char* command);
+char* spd_send_data(SPDConnection* connection, const char *message, int wfr);
+char* spd_send_data_wo_mutex(SPDConnection *connection, const char *message, 
int wfr);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ifndef _LIBSPEECHD_H */
diff --git a/src/c/Makefile.am b/src/c/Makefile.am
deleted file mode 100644
index 7372a27..0000000
--- a/src/c/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-SUBDIRS= api
-
-
diff --git a/src/c/api/Makefile.am b/src/c/api/Makefile.am
deleted file mode 100644
index 1c380a5..0000000
--- a/src/c/api/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-
-localedir = $(datadir)/locale
-inc_local = "-I$(top_srcdir)/include/"
-
-AM_CFLAGS = @ERROR_CFLAGS@ -DLOCALEDIR=\"$(localedir)\" -D_GNU_SOURCE 
-I/usr/include/ $(inc_local) @glib_include@ 
-DSPD_SPAWN_CMD=\""@prefix@/bin/speech-dispatcher"\"
-
-lib_LTLIBRARIES = libspeechd.la
-libspeechd_la_SOURCES = libspeechd.c
-libspeechd_la_HEADERS = libspeechd.h
-libspeechd_ladir = $(includedir)
-libspeechd_la_LDFLAGS = -version-info 
@LIB_SPD_CURRENT@:@LIB_SPD_REVISION@:@LIB_SPD_AGE@ -lpthread
-libspeechd_la_LIBADD = @glib_libs@
-
diff --git a/src/c/api/libspeechd.c b/src/c/api/libspeechd.c
deleted file mode 100644
index 7ef94c2..0000000
--- a/src/c/api/libspeechd.c
+++ /dev/null
@@ -1,1722 +0,0 @@
-/*
-  libspeechd.c - Shared library for easy acces to Speech Dispatcher functions
- *
- * Copyright (C) 2001, 2002, 2003, 2006, 2007, 2008 Brailcom, o.p.s.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this package; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * $Id: libspeechd.c,v 1.37 2008-12-23 09:15:32 pdm Exp $
- */
-
-
-#include <sys/types.h>
-#include <wchar.h>
-#include <sys/socket.h>
-#include <netinet/tcp.h>
-#include <netinet/in.h>
-#include <sys/un.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <glib.h>
-#include <errno.h>
-#include <assert.h>
-#include <netdb.h>
-
-#include "libspeechd.h"
-
-/* Comment/uncomment to switch debugging on/off */
-// #define LIBSPEECHD_DEBUG 1
-
-/* --------------  Private functions headers ------------------------*/
-
-#ifdef LIBSPEECHD_DEBUG
-FILE *spd_debug = NULL;
-#endif
-
-
-static int spd_set_priority(SPDConnection* connection, SPDPriority priority);
-static char* escape_dot(const char *text);
-static int isanum(char* str);          
-static char* get_reply(SPDConnection *connection);
-static int get_err_code(char *reply);
-static char* get_param_str(char* reply, int num, int *err);
-static int get_param_int(char* reply, int num, int *err);
-static void *xmalloc(size_t bytes);
-static void xfree(void *ptr);   
-static int ret_ok(char *reply);
-static void SPD_DBG(char *format, ...);
-static void* spd_events_handler(void*);
-
-pthread_mutex_t spd_logging_mutex;
-
-#if !(defined(__GLIBC__) && defined(_GNU_SOURCE))
-/* Added by Willie Walker - strndup and getline are gcc-isms */
-char *strndup ( const char *s, size_t n)
-{
-        size_t nAvail;
-        char *p;
-
-        if ( !s )
-                return 0;
-
-        if ( strlen(s) > n )
-                nAvail = n + 1;
-        else
-                nAvail = strlen(s) + 1;
-        p = malloc ( nAvail );
-        memcpy ( p, s, nAvail );
-        p[nAvail - 1] = '\0';
-
-        return p;
-}
-
-#define BUFFER_LEN 256
-ssize_t getline (char **lineptr, size_t *n, FILE *f)
-{
-        char ch;
-        size_t m = 0;
-        ssize_t buf_len = 0;
-        char * buf = NULL;
-        char * p = NULL;
-
-       if (errno != 0) {
-                SPD_DBG("getline: errno came in as %d!!!\n", errno);
-               errno = 0;
-       }
-        while ( (ch = getc(f)) !=EOF )
-        {
-                if (errno != 0)
-                        return -1;
-                if ( m++ >= buf_len )
-                {
-                        buf_len += BUFFER_LEN;
-                        buf = (char *) realloc(buf, buf_len + 1);
-                        if ( buf == NULL )
-                        {
-                                SPD_DBG("buf==NULL");
-                                return -1;
-                        }
-                        p = buf + buf_len - BUFFER_LEN;
-                }
-                *p = ch;
-                p++;
-                if ( ch == '\n' )
-                        break;
-        }
-        if ( m == 0 )
-        {
-                SPD_DBG("getline: m=%d!",m);
-                return -1;
-        } else {
-                *p = '\0';
-                *lineptr = buf;
-                *n = m;
-                return m;
-        }
-}
-#endif /* !(defined(__GLIBC__) && defined(_GNU_SOURCE)) */
-
-/* --------------------- Public functions ------------------------- */
-
-#define SPD_REPLY_BUF_SIZE 65536
-
-/* Determine address for the unix socket */
-static char*
-_get_default_unix_socket_name(void)
-{
-  GString* socket_filename;
-  char *h;
-  const char *homedir = g_getenv("HOME");
-  if (!homedir)
-    homedir = g_get_home_dir();
-  socket_filename = g_string_new("");
-  g_string_printf(socket_filename, "%s/.speech-dispatcher/speechd.sock", 
homedir);
-  // Do not regurn glib string, but glibc string...
-  h = strdup(socket_filename->str);
-  g_string_free(socket_filename, 1);
-  return h;
-}
-
-SPDConnectionAddress*
-spd_get_default_address(char **error)
-{
-  const gchar *env_address = g_getenv("SPEECHD_ADDRESS");
-  gchar **pa; /* parsed address */
-  SPDConnectionAddress *address = malloc(sizeof(SPDConnectionAddress));
-
-  if (env_address == NULL){ // Default method = unix sockets
-    address->method = SPD_METHOD_UNIX_SOCKET;
-    address->unix_socket_name = _get_default_unix_socket_name();
-  }else{
-    pa = g_strsplit(env_address, ":", 0);
-    assert (pa);
-    if (!g_strcmp0(pa[0], "unix_socket") || pa[0] == NULL){ // Unix sockets
-      address->method = SPD_METHOD_UNIX_SOCKET;
-      if (pa[1] == NULL){
-       address->unix_socket_name = _get_default_unix_socket_name();
-      }else{
-       address->unix_socket_name = strdup(pa[1]);
-      }
-    }else if (!g_strcmp0(pa[0], "inet_socket")){ // Inet sockets
-      address->method = SPD_METHOD_INET_SOCKET;
-      if (pa[1] == NULL){
-       address->inet_socket_host = strdup("127.0.0.1");
-       address->inet_socket_port = 6560;
-      }else{
-       address->inet_socket_host = strdup(pa[1]);
-       if (pa[2] == NULL){
-         address->inet_socket_port = SPEECHD_DEFAULT_PORT;
-       }else{
-         address->inet_socket_port = atoi(pa[2]);
-        }
-      }
-    }else{ // Unknown or unsupported method requested
-      *error = strdup("Unknown or unsupported communication method");
-      address = NULL;
-    }
-    g_strfreev(pa);
-  }
-  return address;
-}
-
-
-static void _init_debug(void)
-{
-#ifdef LIBSPEECHD_DEBUG
-  if (!spd_debug){
-    spd_debug = fopen("/tmp/libspeechd.log", "w");
-    if (spd_debug == NULL) SPD_FATAL("COULDN'T ACCES FILE INTENDED FOR DEBUG");
-     
-    if(pthread_mutex_init(&spd_logging_mutex, NULL)){
-      fprintf(stderr, "Mutex initialization failed");
-      fflush(stderr);
-      exit(1);
-    }
-    SPD_DBG("Debugging started");
-  }
-#endif /* LIBSPEECHD_DEBUG */
-}
-
-/* Opens a new Speech Dispatcher connection.
- * Returns socket file descriptor of the created connection
- * or -1 if no connection was opened. */
-
-SPDConnection*
-spd_open(const char* client_name, const char* connection_name, const char* 
user_name,
-        SPDConnectionMode mode)
-{
-  char *error;
-  int autospawn = 1;
-  SPDConnection *conn;
-  conn = spd_open2(client_name, connection_name, user_name,
-                  mode, NULL, autospawn, &error);
-  if (!conn){
-    _init_debug();
-    assert(error);
-    SPD_DBG("Could not connect to Speech Dispatcher: %s", error);
-    xfree(error);
-  }
-  return conn;
-}
-
-#define MAX_IP_SIZE 16+1
-/* TODO: This only works in IPV4 */
-static char*
-resolve_host(char* host_name_or_ip, int *is_localhost, gchar **error)
-{
-    struct addrinfo *addr_result;
-    int err;
-    char *resolve_buffer = malloc(MAX_IP_SIZE*sizeof(char));
-    const char *resolved_ip = NULL;
-    char *ip;
-    *error = NULL;
-    struct sockaddr_in *addr_in;
-    
-    if (resolve_buffer == NULL) {
-       *error = g_strdup("Failed to allocate memory.");
-       return NULL;
-    }
-
-    err = getaddrinfo(host_name_or_ip, 0, NULL, &addr_result);
-    if (err){
-       *error = g_strdup_printf("Can't resolve address %d due to error %s:",
-                                err, gai_strerror(err));
-       xfree(resolve_buffer);
-       return NULL;
-    }
-    /* Take the first address returned as we are only interested in host ip */
-    addr_in = (struct sockaddr_in *) addr_result->ai_addr;
-    resolved_ip = inet_ntop(AF_INET, &(addr_in->sin_addr.s_addr), 
resolve_buffer, MAX_IP_SIZE);
-    if (resolved_ip == NULL) {
-       *error = g_strdup_printf("Could not convert address, due to the 
following error: %s",
-                                strerror(errno));
-       freeaddrinfo(addr_result);
-       xfree(resolve_buffer);
-       return NULL;
-    }
-
-    if (!strncmp(resolved_ip, "127.",4)){
-       *is_localhost = 1;
-       /* In case of local addresses, use 127.0.0.1 which is guaranteed
-          to be local and the server listens on it */
-       xfree(resolve_buffer);
-       ip = strdup("127.0.0.1");
-    }else{
-       *is_localhost = 0;
-       ip = resolve_buffer;
-    }
-    freeaddrinfo(addr_result);
-    return ip;
-}
-
-static int
-spawn_server(SPDConnectionAddress *address, int is_localhost, gchar 
**spawn_error)
-{
-    gchar **speechd_cmd = malloc(16*sizeof(char*));
-    gchar *stderr_output;
-    gboolean spawn_ok;
-    GError *gerror = NULL;
-    int exit_status;
-    int i;
-
-    if ((address->method==SPD_METHOD_INET_SOCKET) && (!is_localhost)){
-       *spawn_error = g_strdup("Spawn failed, the given network address 
doesn't seem to be on localhost");
-       return 1;
-    }
-
-    speechd_cmd[0] = g_strdup(SPD_SPAWN_CMD);
-    speechd_cmd[1] = g_strdup("--spawn");
-    speechd_cmd[2] = g_strdup("--communication-method");
-    if (address->method==SPD_METHOD_INET_SOCKET){
-       speechd_cmd[3] = g_strdup("inet_socket");
-       speechd_cmd[4] = g_strdup("--port");
-       speechd_cmd[5] = g_strdup_printf("%d",address->inet_socket_port);
-       speechd_cmd[6] = NULL;
-    }else if (address->method==SPD_METHOD_UNIX_SOCKET){
-       speechd_cmd[3] = g_strdup("unix_socket");
-       speechd_cmd[4] = g_strdup("--socket-path");
-       speechd_cmd[5] = g_strdup_printf("%s", address->unix_socket_name);
-       speechd_cmd[6] = NULL;
-    }else assert (0);
-    
-    spawn_ok = g_spawn_sync(NULL, (gchar**)speechd_cmd, NULL, 
G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL,
-                           NULL, NULL, NULL, &stderr_output, &exit_status, 
&gerror);
-    for (i=0;speechd_cmd[i]!=NULL;i++)
-       g_free(speechd_cmd[i]);
-    if (!spawn_ok){
-       *spawn_error = g_strdup_printf("Autospawn failed. Spawn error %d: %s", 
gerror->code, gerror->message);
-       return 1;
-    }else{
-       if (exit_status){
-           *spawn_error = g_strdup_printf("Autospawn failed. Speech Dispatcher 
refused to start with error code, " \
-                                          "stating this as a reason: %s", 
stderr_output);
-           return 1;
-       }else{
-           *spawn_error = NULL;
-           return 0;
-       }
-    }
-    assert(0);
-}
-
-SPDConnection*
-spd_open2(const char* client_name, const char* connection_name, const char* 
user_name,
-         SPDConnectionMode mode, SPDConnectionAddress *address, int autospawn,
-         char **error_result)
-{
-    SPDConnection *connection;
-    char *set_client_name;
-    char* conn_name;
-    char* usr_name;
-    int ret;
-    char tcp_no_delay = 1;
-
-    /* Autospawn related */
-    int spawn_err;
-    gchar *spawn_report;
-    char *host_ip;
-    int is_localhost = 1;
-    
-    struct sockaddr_in address_inet;    
-    struct sockaddr_un address_unix;    
-    struct sockaddr *sock_address;
-    size_t sock_address_len;
-    gchar *resolve_error;
-
-    _init_debug();
-
-    if (client_name == NULL){
-      *error_result = strdup("ERROR: Client name not specified");
-      SPD_DBG(*error_result);
-      return NULL;
-    }
-    
-    if (user_name == NULL)
-    {
-        usr_name = strdup((char*) g_get_user_name());
-    }
-    else
-        usr_name = strdup(user_name);
-    
-    if(connection_name == NULL)
-        conn_name = strdup("main");
-    else
-        conn_name = strdup(connection_name);
-
-    if (address == NULL){
-      char *err = NULL;
-      address = spd_get_default_address(&err);
-      if (!address){
-       assert(err);
-       *error_result = err;
-       SPD_DBG(*error_result);
-       return NULL;
-      }
-    }
-    
-    /* Connect to server using the selected method */
-    connection = xmalloc(sizeof(SPDConnection));
-    if (address->method==SPD_METHOD_INET_SOCKET){    
-       host_ip = resolve_host(address->inet_socket_host, &is_localhost, 
&resolve_error);
-       if (host_ip == NULL){
-           *error_result = strdup(resolve_error);
-           g_free(resolve_error);
-           return NULL;
-       }       
-       address_inet.sin_addr.s_addr = inet_addr(host_ip);
-       address_inet.sin_port = htons(address->inet_socket_port);
-       address_inet.sin_family = AF_INET;
-       connection->socket = socket(AF_INET, SOCK_STREAM, 0);
-       sock_address = (struct sockaddr*) &address_inet;
-       sock_address_len = sizeof(address_inet);
-    }else if (address->method==SPD_METHOD_UNIX_SOCKET){
-      /* Create the unix socket */
-      address_unix.sun_family = AF_UNIX;
-      strncpy (address_unix.sun_path, address->unix_socket_name, sizeof 
(address_unix.sun_path));
-      address_unix.sun_path[sizeof (address_unix.sun_path) - 1] = '\0';
-      connection->socket = socket(AF_UNIX, SOCK_STREAM, 0);
-      sock_address = (struct sockaddr*) &address_unix;
-      sock_address_len = SUN_LEN(&address_unix);
-    }else SPD_FATAL("Unsupported connection method for spd_open2()");
-
-    ret = connect(connection->socket, sock_address, sock_address_len);    
-    if (ret == -1){
-       /* Suppose server might not be running, try to autospawn (autostart) it 
*/
-       if (autospawn){ 
-           spawn_err = spawn_server(address, is_localhost, &spawn_report);
-           if (!spawn_err)
-               spawn_report = g_strdup("Server successfully autospawned");
-           ret = connect(connection->socket, sock_address, sock_address_len);  
  
-       }else{
-           spawn_report = g_strdup("Autospawn disabled");
-       }
-       if (ret == -1){
-           if (address->method == SPD_METHOD_INET_SOCKET)
-               *error_result = g_strdup_printf("Error: Can't connect to %s on 
port %d using inet sockets: %s. " \
-                                               "Autospawn: %s", 
address->inet_socket_host,
-                                               address->inet_socket_port, 
strerror(errno), spawn_report);
-           else if (address->method == SPD_METHOD_UNIX_SOCKET)
-               *error_result = g_strdup_printf("Error: Can't connect to unix 
socket %s: %s. Autospawn: %s",
-                                               address->unix_socket_name, 
strerror(errno), spawn_report);
-           else assert (0);
-           SPD_DBG(*error_result);
-           close(connection->socket);  
-           return NULL;
-       }
-    }
-
-    if (address->method == SPD_METHOD_INET_SOCKET)
-       setsockopt(connection->socket, IPPROTO_TCP, TCP_NODELAY, &tcp_no_delay, 
sizeof(int));
-    
-    connection->callback_begin = NULL;
-    connection->callback_end = NULL;
-    connection->callback_im = NULL;
-    connection->callback_pause = NULL;
-    connection->callback_resume = NULL;
-    connection->callback_cancel = NULL;
-
-    connection->mode = mode;
-
-    /* Create a stream from the socket */
-    connection->stream = fdopen(connection->socket, "r");
-    if (!connection->stream) SPD_FATAL("Can't create a stream for socket, 
fdopen() failed.");
-    /* Switch to line buffering mode */
-    ret = setvbuf(connection->stream, NULL, _IONBF, SPD_REPLY_BUF_SIZE);
-    if (ret) SPD_FATAL("Can't set buffering, setvbuf failed.");
-
-    connection->ssip_mutex = xmalloc(sizeof(pthread_mutex_t));
-    pthread_mutex_init(connection->ssip_mutex, NULL);
-
-    if (mode == SPD_MODE_THREADED){
-       SPD_DBG("Initializing threads, condition variables and mutexes...");
-       connection->events_thread = xmalloc(sizeof(pthread_t));
-       connection->cond_reply_ready = xmalloc(sizeof(pthread_cond_t));
-       connection->mutex_reply_ready = xmalloc(sizeof(pthread_mutex_t));
-       connection->cond_reply_ack = xmalloc(sizeof(pthread_cond_t));
-       connection->mutex_reply_ack = xmalloc(sizeof(pthread_mutex_t));
-       pthread_cond_init(connection->cond_reply_ready, NULL);
-       pthread_mutex_init(connection->mutex_reply_ready, NULL);
-       pthread_cond_init(connection->cond_reply_ack, NULL);
-       pthread_mutex_init(connection->mutex_reply_ack, NULL);
-       ret = pthread_create(connection->events_thread, NULL, 
spd_events_handler, connection);
-       if(ret != 0){
-           *error_result = strdup("Thread initialization failed");
-           SPD_DBG(*error_result);
-           return NULL;
-       }
-    }
-
-    /* By now, the connection is created and operational */
-    set_client_name = g_strdup_printf("SET SELF CLIENT_NAME \"%s:%s:%s\"", 
usr_name,
-                                     client_name, conn_name);
-    ret = spd_execute_command_wo_mutex(connection, set_client_name);   
-    xfree(usr_name);  xfree(conn_name);  xfree(set_client_name);
-    return connection;
-}
-
-
-#define RET(r) \
-    { \
-    pthread_mutex_unlock(connection->ssip_mutex); \
-    return r; \
-    }
-
-
-/* Close a Speech Dispatcher connection */
-void
-spd_close(SPDConnection* connection)
-{
-
-    pthread_mutex_lock(connection->ssip_mutex);
-
-    if (connection->mode == SPD_MODE_THREADED){
-       pthread_cancel(*connection->events_thread);
-       pthread_mutex_destroy(connection->mutex_reply_ready);
-       pthread_mutex_destroy(connection->mutex_reply_ack);
-       pthread_cond_destroy(connection->cond_reply_ready);
-       pthread_cond_destroy(connection->cond_reply_ack);
-       pthread_join(*connection->events_thread, NULL);
-       connection->mode = SPD_MODE_SINGLE;
-    }
-
-    /* close the socket */
-    close(connection->socket);
-
-    pthread_mutex_unlock(connection->ssip_mutex);
-
-    pthread_mutex_destroy(connection->ssip_mutex);
-    xfree(connection);
-}
-
-/* Helper functions for spd_say. */
-static inline int
-spd_say_prepare(SPDConnection *connection, SPDPriority priority,
-       const char* text, char **escaped_text)
-{
-    int ret = 0;
-
-    SPD_DBG("Text to say is: %s", text);
-
-    /* Insure that there is no escape sequence in the text */
-    *escaped_text = escape_dot(text);
-    /* Caller is now responsible for escaped_text. */
-    if (*escaped_text == NULL) {       /* Out of memory. */
-       SPD_DBG("spd_say could not allocate memory.");
-       ret = -1;
-    } else {
-       /* Set priority */
-       SPD_DBG("Setting priority");
-       ret = spd_set_priority(connection, priority);
-       if (!ret) {
-           /* Start the data flow */
-           SPD_DBG("Sending SPEAK");
-           ret = spd_execute_command_wo_mutex(connection, "speak");
-           if (ret) {
-               SPD_DBG("Error: Can't start data flow!");
-           }
-       }
-    }
-
-    return ret;
-}
-
-static inline int
-spd_say_sending(SPDConnection *connection, const char* text)
-{
-    int msg_id = -1;
-    int err = 0;
-    char *reply = NULL;
-    char *pret = NULL;
-
-    /* Send data */
-    SPD_DBG("Sending data");
-    pret = spd_send_data_wo_mutex(connection, text, SPD_NO_REPLY);
-    if (pret==NULL) {
-       SPD_DBG("Can't send data wo mutex");
-    } else {
-       /* Terminate data flow */
-       SPD_DBG("Terminating data flow");
-       err = spd_execute_command_with_reply(connection, "\r\n.", &reply);
-       if (err) {
-           SPD_DBG("Can't terminate data flow");
-       } else {
-           msg_id = get_param_int(reply, 1, &err);
-           if (err < 0) {
-               SPD_DBG("Can't determine SSIP message unique ID parameter.");
-               msg_id = -1;
-           }
-       }
-    }
-
-    xfree(reply);
-    xfree(pret);
-    return msg_id;
-}
-
-/* Say TEXT with priority PRIORITY.
- * Returns msg_uid on success, -1 otherwise. */
-int
-spd_say(SPDConnection *connection, SPDPriority priority, const char* text)
-{
-    char *escaped_text = NULL;
-    int msg_id = -1;
-    int prepare_failed = 0;
-
-    if (text != NULL) {
-    pthread_mutex_lock(connection->ssip_mutex);
-
-       prepare_failed = spd_say_prepare(connection, priority, text, 
&escaped_text);
-       if (!prepare_failed)
-           msg_id = spd_say_sending(connection, escaped_text);
-
-       xfree(escaped_text);
-       pthread_mutex_unlock(connection->ssip_mutex);
-    } else {
-       SPD_DBG("spd_say called with a NULL argument for <text>");
-    }
-
-    SPD_DBG("Returning from spd_say");
-    return msg_id;
-}
-
-/* The same as spd_say, accepts also formated strings */
-int
-spd_sayf(SPDConnection *connection, SPDPriority priority, const char *format, 
...)
-{
-    static int ret;    
-    va_list args;
-    char *buf;
-
-    if (format == NULL) return -1;
-    
-    /* Print the text to buffer */
-    va_start(args, format);
-    buf = g_strdup_vprintf(format, args);
-    va_end(args);
-    
-    /* Send the buffer to Speech Dispatcher */
-    ret = spd_say(connection, priority, buf);  
-    xfree(buf);
-
-    return ret;
-}
-
-int
-spd_stop(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "STOP SELF");
-}
-
-int
-spd_stop_all(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "STOP ALL");
-}
-
-int
-spd_stop_uid(SPDConnection *connection, int target_uid)
-{
-  static char command[16];
-
-  sprintf(command, "STOP %d", target_uid);
-  return spd_execute_command(connection, command);
-}
-
-int
-spd_cancel(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "CANCEL SELF");
-}
-
-int
-spd_cancel_all(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "CANCEL ALL");
-}
-
-int
-spd_cancel_uid(SPDConnection *connection, int target_uid)
-{
-  static char command[16];
-
-  sprintf(command, "CANCEL %d", target_uid);
-  return spd_execute_command(connection, command);
-}
-
-int
-spd_pause(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "PAUSE SELF");
-}
-
-int
-spd_pause_all(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "PAUSE ALL");
-}
-
-int
-spd_pause_uid(SPDConnection *connection, int target_uid)
-{
-  char command[16];
-
-  sprintf(command, "PAUSE %d", target_uid);
-  return spd_execute_command(connection, command);
-}
-
-int
-spd_resume(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "RESUME SELF");
-}
-
-int
-spd_resume_all(SPDConnection *connection)
-{
-  return spd_execute_command(connection, "RESUME ALL");
-}
-
-int
-spd_resume_uid(SPDConnection *connection, int target_uid)
-{
-  static char command[16];
-
-  sprintf(command, "RESUME %d", target_uid);
-  return spd_execute_command(connection, command);
-}
-
-int
-spd_key(SPDConnection *connection, SPDPriority priority, const char *key_name)
-{
-    char *command_key;
-    int ret;
-
-    if (key_name == NULL) return -1;
-
-    pthread_mutex_lock(connection->ssip_mutex);
-
-    ret = spd_set_priority(connection, priority);
-    if (ret) RET(-1);
-
-    command_key = g_strdup_printf("KEY %s", key_name);
-    ret = spd_execute_command_wo_mutex(connection, command_key);
-    xfree(command_key);
-    if (ret) RET(-1);
-
-    pthread_mutex_unlock(connection->ssip_mutex);
-
-    return 0;
-}
-
-int
-spd_char(SPDConnection *connection, SPDPriority priority, const char 
*character)
-{
-    static char command[16];
-    int ret;
-
-    if (character == NULL) return -1;
-    if (strlen(character)>6) return -1;
-
-    pthread_mutex_lock(connection->ssip_mutex);
-
-    ret = spd_set_priority(connection, priority);
-    if (ret) RET(-1);
-
-    sprintf(command, "CHAR %s", character);
-    ret = spd_execute_command_wo_mutex(connection, command);
-    if (ret) RET(-1);
-
-    pthread_mutex_unlock(connection->ssip_mutex);
-
-    return 0;
-}
-
-int
-spd_wchar(SPDConnection *connection, SPDPriority priority, wchar_t wcharacter)
-{
-    static char command[16];
-    char character[8];
-    int ret;
-
-    pthread_mutex_lock(connection->ssip_mutex);
-
-    ret = wcrtomb(character, wcharacter, NULL);
-    if (ret <= 0) RET(-1);
-
-    ret = spd_set_priority(connection, priority);
-    if (ret) RET(-1);
-
-    assert(character != NULL);
-    sprintf(command, "CHAR %s", character);
-    ret = spd_execute_command_wo_mutex(connection, command);
-    if (ret) RET(-1);
-
-    pthread_mutex_unlock(connection->ssip_mutex);
- 
-    return 0;
-}
-
-int
-spd_sound_icon(SPDConnection *connection, SPDPriority priority, const char 
*icon_name)
-{
-    char *command;
-    int ret;
-
-    if (icon_name == NULL) return -1;
-
-    pthread_mutex_lock(connection->ssip_mutex);
-
-    ret = spd_set_priority(connection, priority);
-    if (ret) RET(-1);
-
-    command = g_strdup_printf("SOUND_ICON %s", icon_name);
-    ret = spd_execute_command_wo_mutex(connection, command);
-    xfree (command);
-    if (ret) RET(-1);
-
-    pthread_mutex_unlock(connection->ssip_mutex);
-    
-    return 0;
-}
-
-int
-spd_w_set_punctuation(SPDConnection *connection, SPDPunctuation type, const 
char* who)
-{
-    char command[32];
-    int ret;
-
-    if (type == SPD_PUNCT_ALL)
-        sprintf(command, "SET %s PUNCTUATION all", who);
-    if (type == SPD_PUNCT_NONE)
-        sprintf(command, "SET %s PUNCTUATION none", who);
-    if (type == SPD_PUNCT_SOME)
-        sprintf(command, "SET %s PUNCTUATION some", who);
-
-    ret = spd_execute_command(connection, command);    
-    
-    return ret;
-}
-
-int
-spd_w_set_capital_letters(SPDConnection *connection, SPDCapitalLetters type, 
const char* who)
-{
-    char command[64];
-    int ret;
-
-    if (type == SPD_CAP_NONE)
-        sprintf(command, "SET %s CAP_LET_RECOGN none", who);
-    if (type == SPD_CAP_SPELL)
-        sprintf(command, "SET %s CAP_LET_RECOGN spell", who);
-    if (type == SPD_CAP_ICON)
-        sprintf(command, "SET %s CAP_LET_RECOGN icon", who);
-
-    ret = spd_execute_command(connection, command);    
-    
-    return ret;
-}
-
-int
-spd_w_set_spelling(SPDConnection *connection, SPDSpelling type, const char* 
who)
-{
-    char command[32];
-    int ret;
-
-    if (type == SPD_SPELL_ON)
-        sprintf(command, "SET %s SPELLING on", who);
-    if (type == SPD_SPELL_OFF)
-        sprintf(command, "SET %s SPELLING off", who);
-
-    ret = spd_execute_command(connection, command);
-
-    return ret;
-}
-
-int
-spd_set_data_mode(SPDConnection *connection, SPDDataMode mode)
-{
-    char command[32];
-    int ret;
-
-    if (mode == SPD_DATA_TEXT)
-        sprintf(command, "SET SELF SSML_MODE off");
-    if (mode == SPD_DATA_SSML)
-        sprintf(command, "SET SELF SSML_MODE on");
-
-    ret = spd_execute_command(connection, command);
-
-    return ret;
-}
-
-int
-spd_w_set_voice_type(SPDConnection *connection, SPDVoiceType type, const char 
*who)
-{
-    static char command[64];
-
-    switch(type){
-    case SPD_MALE1: sprintf(command, "SET %s VOICE MALE1", who); break;
-    case SPD_MALE2: sprintf(command, "SET %s VOICE MALE2", who); break;
-    case SPD_MALE3: sprintf(command, "SET %s VOICE MALE3", who); break;
-    case SPD_FEMALE1: sprintf(command, "SET %s VOICE FEMALE1", who); break;
-    case SPD_FEMALE2: sprintf(command, "SET %s VOICE FEMALE2", who); break;
-    case SPD_FEMALE3: sprintf(command, "SET %s VOICE FEMALE3", who); break;
-    case SPD_CHILD_MALE: sprintf(command, "SET %s VOICE CHILD_MALE", who); 
break;
-    case SPD_CHILD_FEMALE: sprintf(command, "SET %s VOICE CHILD_FEMALE", who); 
break;
-    default: return -1;
-    }
-    
-    return spd_execute_command(connection, command);      
-}
-
-#define SPD_SET_COMMAND_INT(param, ssip_name, condition) \
-    int \
-    spd_w_set_ ## param (SPDConnection *connection, signed int val, const 
char* who) \
-    { \
-        static char command[64]; \
-        if ((!condition)) return -1; \
-        sprintf(command, "SET %s " #ssip_name " %d", who, val); \
-        return spd_execute_command(connection, command); \
-    } \
-    int \
-    spd_set_ ## param (SPDConnection *connection, signed int val) \
-    { \
-        return spd_w_set_ ## param (connection, val, "SELF"); \
-    } \
-    int \
-    spd_set_ ## param ## _all(SPDConnection *connection, signed int val) \
-    { \
-        return spd_w_set_ ## param (connection, val, "ALL"); \
-    } \
-    int \
-    spd_set_ ## param ## _uid(SPDConnection *connection, signed int val, 
unsigned int uid) \
-    { \
-        char who[8]; \
-        sprintf(who, "%d", uid); \
-        return spd_w_set_ ## param (connection, val, who); \
-    }
-
-#define SPD_SET_COMMAND_STR(param, ssip_name) \
-    int \
-    spd_w_set_ ## param (SPDConnection *connection, const char *str, const 
char* who) \
-    { \
-        char *command; \
-        int ret; \
-        if (str == NULL) return -1; \
-        command = g_strdup_printf("SET %s " #param " %s", \
-                              who, str); \
-        ret = spd_execute_command(connection, command); \
-        xfree(command); \
-        return ret; \
-    } \
-    int \
-    spd_set_ ## param (SPDConnection *connection, const char *str) \
-    { \
-        return spd_w_set_ ## param (connection, str, "SELF"); \
-    } \
-    int \
-    spd_set_ ## param ## _all(SPDConnection *connection, const char *str) \
-    { \
-        return spd_w_set_ ## param (connection, str, "ALL"); \
-    } \
-    int \
-    spd_set_ ## param ## _uid(SPDConnection *connection, const char *str, 
unsigned int uid) \
-    { \
-        char who[8]; \
-        sprintf(who, "%d", uid); \
-        return spd_w_set_ ## param (connection, str, who); \
-    }
-
-#define SPD_SET_COMMAND_SPECIAL(param, type) \
-    int \
-    spd_set_ ## param (SPDConnection *connection, type val) \
-    { \
-        return spd_w_set_ ## param (connection, val, "SELF"); \
-    } \
-    int \
-    spd_set_ ## param ## _all(SPDConnection *connection, type val) \
-    { \
-        return spd_w_set_ ## param (connection, val, "ALL"); \
-    } \
-    int \
-    spd_set_ ## param ## _uid(SPDConnection *connection, type val, unsigned 
int uid) \
-    { \
-        char who[8]; \
-        sprintf(who, "%d", uid); \
-        return spd_w_set_ ## param (connection, val, who); \
-    }
-
-SPD_SET_COMMAND_INT(voice_rate, RATE, ((val >= -100) && (val <= +100)) )
-SPD_SET_COMMAND_INT(voice_pitch, PITCH, ((val >= -100) && (val <= +100)) )
-SPD_SET_COMMAND_INT(volume, VOLUME, ((val >= -100) && (val <= +100)) )
-
-SPD_SET_COMMAND_STR(language, LANGUAGE)
-SPD_SET_COMMAND_STR(output_module, OUTPUT_MODULE)
-SPD_SET_COMMAND_STR(synthesis_voice, SYNTHESIS_VOICE)
-
-SPD_SET_COMMAND_SPECIAL(punctuation, SPDPunctuation)
-SPD_SET_COMMAND_SPECIAL(capital_letters, SPDCapitalLetters)
-SPD_SET_COMMAND_SPECIAL(spelling, SPDSpelling)
-SPD_SET_COMMAND_SPECIAL(voice_type, SPDVoiceType)
-
-
-#undef SPD_SET_COMMAND_INT
-#undef SPD_SET_COMMAND_STR
-#undef SPD_SET_COMMAND_SPECIAL
-
-int
-spd_set_notification_on(SPDConnection *connection, SPDNotification 
notification)
-{
-    if (connection->mode == SPD_MODE_THREADED)
-       return spd_set_notification(connection, notification, "on");
-    else
-       return -1;
-}
-
-int
-spd_set_notification_off(SPDConnection *connection, SPDNotification 
notification)
-{
-    if (connection->mode == SPD_MODE_THREADED)
-       return spd_set_notification(connection, notification, "off");
-    else
-       return -1;
-}
-
-
-#define NOTIFICATION_SET(val, ssip_val) \
-    if (notification & val){ \
-       sprintf(command, "SET SELF NOTIFICATION "ssip_val" %s", state);\
-       ret = spd_execute_command_wo_mutex(connection, command);\
-       if (ret < 0) RET(-1);\
-    }
-
-int
-spd_set_notification(SPDConnection *connection, SPDNotification notification, 
const char* state)
-{
-    static char command[64];
-    int ret;
-
-    if (connection->mode != SPD_MODE_THREADED) return -1;
-
-    if (state == NULL){
-      SPD_DBG("Requested state is NULL");
-      return -1;
-    }
-    if (strcmp(state, "on") && strcmp(state, "off")){
-      SPD_DBG("Invalid argument for spd_set_notification: %s", state);
-      return -1;
-    }
-
-    pthread_mutex_lock(connection->ssip_mutex);
-
-    NOTIFICATION_SET(SPD_INDEX_MARKS, "index_marks");
-    NOTIFICATION_SET(SPD_BEGIN, "begin");
-    NOTIFICATION_SET(SPD_END, "end");
-    NOTIFICATION_SET(SPD_CANCEL, "cancel");
-    NOTIFICATION_SET(SPD_PAUSE, "pause");
-    NOTIFICATION_SET(SPD_RESUME, "resume");
-    NOTIFICATION_SET(SPD_RESUME, "pause");
-
-    pthread_mutex_unlock(connection->ssip_mutex);
-
-    return 0;
-}
-#undef NOTIFICATION_SET
-
-
-/* spd_list_modules retrieves information about the available output modules.
-   The return value is a null-terminated array of strings containing output 
module
-   names.
-*/
-
-char**
-spd_list_modules(SPDConnection *connection)
-{
-  char **available_modules;
-  available_modules = spd_execute_command_with_list_reply(connection, "LIST 
OUTPUT_MODULES");
-  return available_modules;
-}
-
-char**
-spd_list_voices(SPDConnection *connection)
-{
-  char **voices;
-  voices = spd_execute_command_with_list_reply(connection, "LIST VOICES");
-  return voices;
-}
-
-SPDVoice**
-spd_list_synthesis_voices(SPDConnection *connection)
-{
-  char **svoices_str;
-  SPDVoice **svoices;
-  int i, num_items;
-  svoices_str = spd_execute_command_with_list_reply(connection, "LIST 
SYNTHESIS_VOICES");
-
-  if (svoices_str == NULL) return NULL;
-
-  for (i=0;;i++)
-    if (svoices_str[i] == NULL) break;
-  num_items = i;
-  svoices = (SPDVoice**) malloc((num_items+1) * sizeof(SPDVoice*));
-
-  for (i=0;i<=num_items;i++){
-    const char delimiters[] = " ";
-    char *running;
-
-    if (svoices_str[i] == NULL) break;
-    running = strdup (svoices_str[i]);
-
-    svoices[i] = (SPDVoice*) malloc(sizeof(SPDVoice));
-    svoices[i]->name = strsep (&running, delimiters);
-    svoices[i]->language = strsep (&running, delimiters);
-    svoices[i]->variant = strsep (&running, delimiters);
-    assert (svoices[i]->name != NULL);
-  }
-
-  svoices[num_items] = NULL;
-
-  return svoices;
-}
-
-char**
-spd_execute_command_with_list_reply(SPDConnection *connection, char *command)
-{
-  char *reply, *line;
-  int err;
-  int max_items = 50;
-  char **result;
-  int i, ret;
-
-  result = malloc((max_items+1)*sizeof(char*));
-
-  ret = spd_execute_command_with_reply(connection, command, &reply);
-  if(!ret_ok(reply)) return NULL;
-  
-  for(i=0;  ;i++){
-    line = get_param_str(reply, i+1, &err);
-    if ((err) || (line == NULL)) break;
-    result[i] = strdup(line);
-    if (i>=max_items-2){
-      max_items *= 2;
-      result = realloc(result, max_items*sizeof(char*));
-    }
-  }
-
-  result[i] = NULL;
-  
-  return result;
-}
-
-//int
-//spd_get_client_list(SPDConnection *connection, char **client_names, int 
*client_ids, int* active){
-//        SPD_DBG("spd_get_client_list: History is not yet implemented.");
-//        return -1;
-//
-//}
-
-int
-spd_get_message_list_fd(SPDConnection *connection, int target, int *msg_ids, 
char **client_names)
-{
-        SPD_DBG("spd_get_client_list: History is not yet implemented.");
-        return -1;
-#if 0
-       sprintf(command, "HISTORY GET MESSAGE_LIST %d 0 20\r\n", target);
-       reply = spd_send_data(fd, command, 1);
-
-/*     header_ok = parse_response_header(reply);
-       if(header_ok != 1){
-               free(reply);
-               return -1;
-       }*/
-
-       for(count=0;  ;count++){
-               record = (char*) parse_response_data(reply, count+1);
-               if (record == NULL) break;
-               record_int = get_rec_int(record, 0);
-               msg_ids[count] = record_int;
-               record_str = (char*) get_rec_str(record, 1);
-               assert(record_str!=NULL);
-               client_names[count] = record_str;
-       }
-       return count;
-#endif
-}
-
-int
-spd_execute_command(SPDConnection *connection, char* command)
-{
-    char *reply;
-    int ret;
-
-    pthread_mutex_lock(connection->ssip_mutex);
-
-    ret = spd_execute_command_with_reply(connection, command, &reply);
-    if (ret){
-      SPD_DBG("Can't execute command in spd_execute_command");
-    }
-    xfree(reply);
-
-    pthread_mutex_unlock(connection->ssip_mutex);
-
-    return ret;
-}
-
-int
-spd_execute_command_wo_mutex(SPDConnection *connection, char* command)
-{
-    char *reply;
-    int ret;
-
-    SPD_DBG("Executing command wo_mutex");
-    ret = spd_execute_command_with_reply(connection, command, &reply);
-    if (ret)
-      SPD_DBG("Can't execute command in spd_execute_command_wo_mutex");
-
-    xfree(reply);
-
-    return ret;
-}
-
-int
-spd_execute_command_with_reply(SPDConnection *connection, char* command, char 
**reply)
-{
-    char *buf;    
-    int r;
-    SPD_DBG("Inside execute_command_with_reply");
-
-    buf = g_strdup_printf("%s\r\n", command);
-    *reply = spd_send_data_wo_mutex(connection, buf, SPD_WAIT_REPLY);
-    xfree(buf);
-    buf = NULL;
-    if(*reply==NULL){
-        SPD_DBG("Can't send data wo mutex in spd_execute_command_with_reply");
-       return -1;
-    }
-
-    r = ret_ok(*reply);
-
-    if (!r) return -1;
-    else return 0;
-}
-
-
-char*
-spd_send_data(SPDConnection *connection, const char *message, int wfr)
-{
-    char *reply;
-    pthread_mutex_lock(connection->ssip_mutex);
-
-
-    if (connection->stream ==NULL) RET( NULL);
-
-    reply = spd_send_data_wo_mutex(connection, message, wfr);
-    if(reply==NULL){
-        SPD_DBG("Can't send data wo mutex in spd_send_data");
-        RET(NULL); 
-    }
-
-    pthread_mutex_unlock(connection->ssip_mutex);
-    return reply;
-}
-
-char*
-spd_send_data_wo_mutex(SPDConnection *connection, const char *message, int wfr)
-{
-
-    char *reply;
-    int bytes;
-
-    SPD_DBG("Inside spd_send_data_wo_mutex");
-
-    if (connection->stream == NULL) return NULL;
-
-    if (connection->mode == SPD_MODE_THREADED){
-       /* Make sure we don't get the cond_reply_ready signal before we are in
-          cond_wait() */
-       pthread_mutex_lock(connection->mutex_reply_ready);
-    }
-    /* write message to the socket */
-    SPD_DBG("Writing to socket");
-    if(!write(connection->socket, message, strlen(message))){
-       SPD_DBG("Can't write to socket: %s", strerror(errno));
-       pthread_mutex_unlock(connection->mutex_reply_ready);
-       return NULL;
-    }
-    SPD_DBG("Written to socket");
-    SPD_DBG(">> : |%s|", message);
-
-    /* read reply to the buffer */
-    if (wfr){
-       if (connection->mode == SPD_MODE_THREADED){
-         /* Wait until the reply is ready */
-         SPD_DBG("Waiting for cond_reply_ready in spd_send_data_wo_mutex");
-         pthread_cond_wait(connection->cond_reply_ready, 
connection->mutex_reply_ready);
-         SPD_DBG("Condition for cond_reply_ready satisfied");
-         pthread_mutex_unlock(connection->mutex_reply_ready);
-         SPD_DBG("Reading the reply in spd_send_data_wo_mutex threaded mode");
-         /* Read the reply */
-         if (connection->reply != NULL){
-               reply = strdup(connection->reply);
-           }else{
-               SPD_DBG("Error: Can't read reply, broken socket in 
spd_send_data.");
-               return NULL;
-           }
-           xfree(connection->reply);
-           bytes = strlen(reply);
-           if (bytes == 0){
-               SPD_DBG("Error: Empty reply, broken socket.");
-               return NULL;
-           }
-           /* Signal the reply has been read */
-           pthread_mutex_lock(connection->mutex_reply_ack);
-           pthread_cond_signal(connection->cond_reply_ack);
-           pthread_mutex_unlock(connection->mutex_reply_ack);
-       }else{
-           reply = get_reply(connection);
-       }
-       if (reply != NULL)
-         SPD_DBG("<< : |%s|\n", reply);        
-    }else{
-       if (connection->mode == SPD_MODE_THREADED)
-           pthread_mutex_unlock(connection->mutex_reply_ready);
-       SPD_DBG("<< : no reply expected");
-        return strdup("NO REPLY");
-    } 
-
-    if (reply==NULL)
-      SPD_DBG("Reply from get_reply is NULL in spd_send_data_wo_mutex");
-
-    SPD_DBG("Returning from spd_send_data_wo_mutex");
-    return reply;
-}
-
-
-/* --------------------- Internal functions ------------------------- */
-
-static int
-spd_set_priority(SPDConnection *connection, SPDPriority priority)
-{
-    static char p_name[16];
-    static char command[64];
-
-    switch(priority){
-    case SPD_IMPORTANT: strcpy(p_name, "IMPORTANT"); break;
-    case SPD_MESSAGE: strcpy(p_name, "MESSAGE"); break;
-    case SPD_TEXT: strcpy(p_name, "TEXT"); break;
-    case SPD_NOTIFICATION: strcpy(p_name, "NOTIFICATION"); break;
-    case SPD_PROGRESS: strcpy(p_name, "PROGRESS"); break;
-    default: 
-      SPD_DBG("Error: Can't set priority! Incorrect value.");
-      return -1;
-    }
-                
-    sprintf(command, "SET SELF PRIORITY %s", p_name);
-    return spd_execute_command_wo_mutex(connection, command);
-}
-
-
-static char*
-get_reply(SPDConnection *connection)
-{
-    GString *str;
-    char *line = NULL;
-    size_t N = 0;
-    int bytes;
-    char *reply;
-    gboolean errors = FALSE;
-
-    str = g_string_new("");
-
-    /* Wait for activity on the socket, when there is some,
-       read all the message line by line */
-    do{
-       bytes = getline(&line, &N, connection->stream); 
-       if (bytes == -1){
-           SPD_DBG("Error: Can't read reply, broken socket in get_reply!");
-           if (connection->stream != NULL)
-             fclose(connection->stream);
-           connection->stream = NULL;
-           errors = TRUE;
-       } else {
-           g_string_append(str, line);
-       }
-       /* terminate if we reached the last line (without '-' after numcode) */
-    }while(!errors &&  !((strlen(line) < 4) || (line[3] == ' ')));
-    
-    xfree(line);       /* getline allocates with malloc. */
-
-    if (errors) {
-       /* Free the GString and its character data, and return NULL. */
-       g_string_free(str, TRUE);
-       reply = NULL;
-    } else {
-           /* The resulting message received from the socket is stored in 
reply */
-           reply = str->str;
-       /* Free the GString, but not its character data. */
-           g_string_free(str, FALSE);
-    }
-
-    return reply;
-}
-
-static void*
-spd_events_handler(void* conn)
-{
-    char *reply;
-    int reply_code;
-    SPDConnection *connection = conn;
-
-    while(1){
-
-       /* Read the reply/event (block if none is available) */
-        SPD_DBG("Getting reply in spd_events_handler");
-       reply = get_reply(connection);
-       if (reply == NULL){
-           SPD_DBG("ERROR: BROKEN SOCKET");
-           reply_code = -1;
-       }else{
-           SPD_DBG("<< : |%s|\n", reply);
-           reply_code = get_err_code(reply);
-       }
-
-       if ((reply_code >= 700) && (reply_code < 800)){
-           int msg_id;
-           int client_id;
-           int err;
-
-           SPD_DBG("Callback detected: %s", reply);
-
-           /* This is an index mark */
-           /* Extract message id */
-           msg_id = get_param_int(reply, 1, &err);
-           if (err < 0){
-             SPD_DBG("Bad reply from Speech Dispatcher: %s (code %d)", reply, 
err);
-             break;
-           }
-           client_id = get_param_int(reply, 2, &err);
-           if (err < 0){
-             SPD_DBG("Bad reply from Speech Dispatcher: %s (code %d)", reply, 
err);
-             break;
-           }
-           /*  Decide if we want to call a callback */
-           if ((reply_code == 701) && (connection->callback_begin))
-               connection->callback_begin(msg_id, client_id, SPD_EVENT_BEGIN);
-           if ((reply_code == 702) && (connection->callback_end))
-               connection->callback_end(msg_id, client_id, SPD_EVENT_END);
-           if ((reply_code == 703) && (connection->callback_cancel))
-               connection->callback_cancel(msg_id, client_id, 
SPD_EVENT_CANCEL);
-           if ((reply_code == 704) && (connection->callback_pause))
-               connection->callback_pause(msg_id, client_id, SPD_EVENT_PAUSE);
-           if ((reply_code == 705) && (connection->callback_resume))
-               connection->callback_resume(msg_id, client_id, 
SPD_EVENT_RESUME);
-           if ((reply_code == 700) && (connection->callback_im)){
-               char* im;
-               int err;
-               im = get_param_str(reply, 3, &err);
-               if ((err < 0) || (im == NULL)){
-                 SPD_DBG("Broken reply from Speech Dispatcher: %s", reply);
-                 break;
-               }
-               /* Call the callback */
-               connection->callback_im(msg_id, client_id, 
SPD_EVENT_INDEX_MARK, im);
-               xfree(im);
-           }
-
-       }else{
-           /* This is a protocol reply */
-           pthread_mutex_lock(connection->mutex_reply_ready);
-           /* Prepare the reply to the reply buffer in connection */
-           if (reply != NULL){
-               connection->reply = strdup(reply);
-           }else{
-             SPD_DBG("Connection reply is NULL");
-             connection->reply = NULL;
-             break;
-           }
-           /* Signal the reply is available on the condition variable */
-           /* this order is correct and necessary */
-           pthread_cond_signal(connection->cond_reply_ready);
-           pthread_mutex_lock(connection->mutex_reply_ack); 
-           pthread_mutex_unlock(connection->mutex_reply_ready);
-           /* Wait until it has bean read */
-           pthread_cond_wait(connection->cond_reply_ack, 
connection->mutex_reply_ack);
-           pthread_mutex_unlock(connection->mutex_reply_ack);
-           xfree(reply);
-           /* Continue */      
-       }
-    }
-    /* In case of broken socket, we must still signal reply ready */
-    if (connection->reply == NULL){
-      SPD_DBG("Signalling reply ready after communication failure");
-      pthread_mutex_unlock(connection->mutex_reply_ready);
-      pthread_mutex_unlock(connection->mutex_reply_ack);
-      if (connection->stream != NULL)
-       fclose(connection->stream);
-      connection->stream = NULL;
-      pthread_cond_signal(connection->cond_reply_ready);
-      pthread_exit(0);
-    }
-    return 0;                  /* to please gcc */
-}
-
-static int
-ret_ok(char *reply)
-{
-       int err;
-
-       if (reply == NULL) return -1;
-
-       err = get_err_code(reply);
-               
-       if ((err>=100) && (err<300)) return 1;
-       if (err>=300) return 0;
-    
-       SPD_FATAL("Internal error during communication.");
-}
-
-static char*
-get_param_str(char* reply, int num, int *err)
-{
-    int i;
-    char *tptr;
-    char *pos;
-    char *pos_begin;
-    char *pos_end;
-    char *rep;
-
-    assert(err != NULL);
-
-    if (num < 1){
-       *err = -1;
-       return NULL;
-    }
-
-    pos = reply;
-    for (i=0; i<=num-2; i++){
-       pos = strstr(pos, "\r\n");      
-       if (pos == NULL){
-           *err = -2;
-           return NULL;
-       }
-       pos += 2;
-    }
-
-    if (strlen(pos) < 4) return NULL;
-    
-    *err = strtol(pos, &tptr, 10);
-    if (*err >= 300 && *err <= 399)
-       return NULL;
-
-    if ((*tptr != '-') || (tptr != pos+3)){
-       *err = -3;
-       return NULL;
-    }
-
-    pos_begin = pos + 4;
-    pos_end = strstr(pos_begin, "\r\n");
-    if (pos_end == NULL){
-       *err = -4;
-       return NULL;
-    }
-
-    rep = (char*) strndup(pos_begin, pos_end - pos_begin);
-    *err = 0;
-    
-    return rep;
-}
-
-static int
-get_param_int(char* reply, int num, int *err)
-{
-    char *rep_str;
-    char *tptr;
-    int ret;
-
-    rep_str = get_param_str(reply, num, err);
-    if (rep_str == NULL){
-       /* err is already set to the error return code, just return */
-       return 0;
-    }
-    
-    ret = strtol(rep_str, &tptr, 10);
-    if (*tptr != '\0'){
-       /* this is not a number */
-       *err = -3;
-       return 0;
-    }    
-    xfree(rep_str);
-
-    return ret;
-}
-
-static int
-get_err_code(char *reply)
-{
-    char err_code[4];
-    int err;
-       
-    if (reply == NULL) return -1;
-    SPD_DBG("spd_send_data:    reply: %s\n", reply);
-
-    err_code[0] = reply[0];    err_code[1] = reply[1];
-    err_code[2] = reply[2];    err_code[3] = '\0';
-
-    SPD_DBG("ret_ok: err_code: |%s|\n", err_code);
-   
-    if(isanum(err_code)){
-        err = atoi(err_code);
-    }else{
-      SPD_DBG("ret_ok: not a number\n");
-      return -1;       
-    }
-
-    return err;
-}
-
-/* isanum() tests if the given string is a number,
- *  returns 1 if yes, 0 otherwise. */
-static int
-isanum(char *str)
-{
-    int i;
-    if (str == NULL) return 0;
-    for(i=0;i<=strlen(str)-1;i++){
-        if (!isdigit(str[i]))   return 0;
-    }
-    return 1;
-}
-
-static void*
-xmalloc(size_t bytes)
-{
-    void *mem;
-
-    mem = malloc(bytes);
-    if (mem == NULL){
-      SPD_FATAL("Not enough memmory!");
-      exit(1);
-    }
-    
-    return mem;
-}
-
-static void
-xfree(void *ptr)
-{
-    if (ptr != NULL)
-        free(ptr);
-}
-
-/*
- * escape_dot: Replace . with .. at the start of lines.
- * @text: text to escape
- * @Returns: An allocated string, containing the escaped text.
- */
-static char*
-escape_dot(const char *text)
-{
-    size_t orig_len = 0;
-    const char *orig_end;
-    char *result = NULL;
-    char *result_ptr;
-    static const char *ESCAPED_DOTLINE = "\r\n..";
-    static const size_t ESCAPED_DOTLINELEN = 4;
-    static const size_t DOTLINELEN = 3;
-
-    if (text == NULL)
-        return NULL;
-
-orig_len = strlen(text);
-    orig_end = text + orig_len;
-    result = malloc((orig_len * 2 + 1) * sizeof(char));
-
-    if (result == NULL)
-        return NULL;
-
-    result_ptr = result;
-
-    /* We're over-allocating.  Even if we replaced every character
-     * in text with "..", the length of the escaped string can be no more
-     * than orig_len * 2.  We could tighten that upper bound with
-     * a little more work.
-     */
-
-    if ((orig_len >= 1) && (text[0] == '.')) {
-        *(result_ptr++) = '.';
-        *(result_ptr++) = '.';
-        text += 1;
-    }
-
-    while (text < orig_end) {
-        if ((text[0] == '\r') && (text[1] == '\n') && (text[2] == '.')) {
-            memcpy(result_ptr, ESCAPED_DOTLINE, ESCAPED_DOTLINELEN);
-            result_ptr += ESCAPED_DOTLINELEN;
-            text += DOTLINELEN;
-        } else {
-            *(result_ptr++) = *(text++);
-        }
-    }
-
-    * result_ptr = '\0';
-    return result;
-}
-
-#ifdef LIBSPEECHD_DEBUG
-static void
-SPD_DBG(char *format, ...)
-{
-        va_list args;
-
-       pthread_mutex_lock(&spd_logging_mutex);         
-       va_start(args, format);
-       vfprintf(spd_debug, format, args);
-       va_end(args);
-       fprintf(spd_debug, "\n");
-       fflush(spd_debug);
-       pthread_mutex_unlock(&spd_logging_mutex);       
-}
-#else  /* LIBSPEECHD_DEBUG */
-static void
-SPD_DBG(char *format, ...)
-{
-}
-#endif /* LIBSPEECHD_DEBUG */
diff --git a/src/c/api/libspeechd.h b/src/c/api/libspeechd.h
deleted file mode 100644
index c88f89f..0000000
--- a/src/c/api/libspeechd.h
+++ /dev/null
@@ -1,278 +0,0 @@
-
-/*
- * libspeechd.h - Shared library for easy acces to Speech Dispatcher functions 
(header)
- *
- * Copyright (C) 2001, 2002, 2003, 2004 Brailcom, o.p.s.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this package; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * $Id: libspeechd.h,v 1.29 2008-07-30 09:47:00 hanke Exp $
- */
-
-#ifndef _LIBSPEECHD_H
-#define _LIBSPEECHD_H
-
-#include <stdio.h>
-#include <stddef.h>
-#include <pthread.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    
-#ifdef LIBSPEECHD_DEBUG
-/* Debugging */
-FILE* spd_debug;
-#endif
-
-/* Unless there is an fatal error, it doesn't print anything */
-#define SPD_FATAL(msg) { printf("Fatal error (libspeechd) [%s:%d]:"msg, 
__FILE__, __LINE__); fflush(stdout); exit(EXIT_FAILURE); }
-/* Speech Dispatcher's default port for inet communication */
-#define SPEECHD_DEFAULT_PORT 6560
-
-/* Arguments for spd_send_data() */
-#define SPD_WAIT_REPLY 1              /* Wait for reply */
-#define SPD_NO_REPLY 0               /* No reply requested */
-
-
-/* --------------------- Public data types ------------------------ */
-
-typedef enum{
-    SPD_PUNCT_ALL = 0,
-    SPD_PUNCT_NONE = 1,
-    SPD_PUNCT_SOME = 2
-}SPDPunctuation;
-
-typedef enum{
-    SPD_CAP_NONE = 0,
-    SPD_CAP_SPELL = 1,
-    SPD_CAP_ICON = 2
-}SPDCapitalLetters;
-
-typedef enum{
-    SPD_SPELL_OFF = 0,
-    SPD_SPELL_ON = 1
-}SPDSpelling;
-
-typedef enum{
-    SPD_DATA_TEXT = 0,
-    SPD_DATA_SSML = 1
-}SPDDataMode;
-    
-typedef enum{
-    SPD_MALE1 = 1,
-    SPD_MALE2 = 2,
-    SPD_MALE3 = 3,
-    SPD_FEMALE1 = 4,
-    SPD_FEMALE2 = 5,
-    SPD_FEMALE3 = 6,
-    SPD_CHILD_MALE = 7,
-    SPD_CHILD_FEMALE = 8
-}SPDVoiceType;
-
-
-typedef struct{
-  char *name;   /* Name of the voice (id) */
-  char *language;  /* 2-letter ISO language code */
-  char *variant;   /* a not-well defined string describing dialect etc. */
-}SPDVoice;
-
-typedef enum{
-    SPD_BEGIN = 1,
-    SPD_END = 2,
-    SPD_INDEX_MARKS = 4,
-    SPD_CANCEL = 8,
-    SPD_PAUSE = 16,
-    SPD_RESUME = 32
-}SPDNotification;
-
-typedef enum{
-    SPD_IMPORTANT = 1,
-    SPD_MESSAGE = 2,
-    SPD_TEXT = 3,
-    SPD_NOTIFICATION = 4,
-    SPD_PROGRESS = 5
-}SPDPriority;
-
-typedef enum{
-    SPD_EVENT_BEGIN,
-    SPD_EVENT_END,
-    SPD_EVENT_CANCEL,
-    SPD_EVENT_PAUSE,
-    SPD_EVENT_RESUME,
-    SPD_EVENT_INDEX_MARK
-}SPDNotificationType;
-
-typedef enum{
-    SPD_MODE_SINGLE = 0,
-    SPD_MODE_THREADED = 1
-}SPDConnectionMode;
-
-typedef enum{
-    SPD_METHOD_UNIX_SOCKET = 0,
-    SPD_METHOD_INET_SOCKET = 1,
-}SPDConnectionMethod;
-
-typedef struct{
-  SPDConnectionMethod method;
-  char *unix_socket_name;
-  char *inet_socket_host;
-  int  inet_socket_port;
-  char *dbus_bus;
-}SPDConnectionAddress;
-
-typedef void (*SPDCallback)(size_t msg_id, size_t client_id, 
SPDNotificationType state);
-typedef void (*SPDCallbackIM)(size_t msg_id, size_t client_id, 
SPDNotificationType state, char *index_mark);
-
-typedef struct{
-
-    /* PUBLIC */
-    SPDCallback callback_begin;
-    SPDCallback callback_end;
-    SPDCallback callback_cancel;
-    SPDCallback callback_pause;
-    SPDCallback callback_resume;
-    SPDCallbackIM callback_im;
-
-    /* PRIVATE */
-    int socket;
-    FILE *stream;
-    SPDConnectionMode mode;
-
-    pthread_mutex_t *ssip_mutex;
-
-    pthread_t *events_thread;
-    pthread_mutex_t *comm_mutex;
-    pthread_cond_t *cond_reply_ready;
-    pthread_mutex_t *mutex_reply_ready;
-    pthread_cond_t *cond_reply_ack;
-    pthread_mutex_t *mutex_reply_ack;
-
-    char *reply;
-
-}SPDConnection;
-
-/* -------------- Public functions --------------------------*/
-
-/* Openning and closing Speech Dispatcher connection */
-SPDConnectionAddress* spd_get_default_address(char** error);
-SPDConnection* spd_open(const char* client_name, const char* connection_name, 
const char* user_name,
-                       SPDConnectionMode mode);
-SPDConnection* spd_open2(const char* client_name, const char* connection_name, 
const char* user_name,
-                        SPDConnectionMode mode, SPDConnectionAddress *address, 
int autospawn,
-                        char **error_result);
-
-void spd_close(SPDConnection* connection);
-
-/* Speaking */
-int spd_say(SPDConnection* connection, SPDPriority priority, const char* text);
-int spd_sayf(SPDConnection* connection, SPDPriority priority, const char 
*format, ...);
-
-/* Speech flow */
-int spd_stop(SPDConnection* connection);
-int spd_stop_all(SPDConnection* connection);
-int spd_stop_uid(SPDConnection* connection, int target_uid);
-
-int spd_cancel(SPDConnection* connection);
-int spd_cancel_all(SPDConnection* connection);
-int spd_cancel_uid(SPDConnection* connection, int target_uid);
-
-int spd_pause(SPDConnection* connection);
-int spd_pause_all(SPDConnection* connection);
-int spd_pause_uid(SPDConnection* connection, int target_uid);
-
-int spd_resume(SPDConnection* connection);
-int spd_resume_all(SPDConnection* connection);
-int spd_resume_uid(SPDConnection* connection, int target_uid);
-
-/* Characters and keys */
-int spd_key(SPDConnection* connection, SPDPriority priority, const char 
*key_name);
-int spd_char(SPDConnection* connection, SPDPriority priority, const char 
*character);
-int spd_wchar(SPDConnection* connection, SPDPriority priority, wchar_t 
wcharacter);
-
-/* Sound icons */
-int spd_sound_icon(SPDConnection* connection, SPDPriority priority, const char 
*icon_name);
-
-/* Setting parameters */
-int spd_set_voice_type(SPDConnection*, SPDVoiceType type);
-int spd_set_voice_type_all(SPDConnection*, SPDVoiceType type);
-int spd_set_voice_type_uid(SPDConnection*, SPDVoiceType type, unsigned int 
uid);
-
-int spd_set_synthesis_voice(SPDConnection*, const char *voice_name);
-int spd_set_synthesis_voice_all(SPDConnection*, const char *voice_name);
-int spd_set_synthesis_voice_uid(SPDConnection*, const char *voice_name, 
unsigned int uid);
-
-int spd_set_data_mode(SPDConnection *connection, SPDDataMode mode);
-
-int spd_set_notification_on(SPDConnection* connection, SPDNotification 
notification);
-int spd_set_notification_off(SPDConnection* connection, SPDNotification 
notification);
-int spd_set_notification(SPDConnection* connection, SPDNotification 
notification, const char* state);
-
-int spd_set_voice_rate(SPDConnection* connection, signed int rate);
-int spd_set_voice_rate_all(SPDConnection* connection, signed int rate);
-int spd_set_voice_rate_uid(SPDConnection* connection, signed int rate, 
unsigned int uid);
-
-int spd_set_voice_pitch(SPDConnection* connection, signed int pitch);
-int spd_set_voice_pitch_all(SPDConnection* connection, signed int pitch);
-int spd_set_voice_pitch_uid(SPDConnection* connection, signed int pitch, 
unsigned int uid);
-
-int spd_set_volume(SPDConnection* connection, signed int volume);
-int spd_set_volume_all(SPDConnection* connection, signed int volume);
-int spd_set_volume_uid(SPDConnection* connection, signed int volume, unsigned 
int uid);
-
-int spd_set_punctuation(SPDConnection* connection, SPDPunctuation type);
-int spd_set_punctuation_all(SPDConnection* connection, SPDPunctuation type);
-int spd_set_punctuation_uid(SPDConnection* connection, SPDPunctuation type, 
unsigned int uid);
-
-int spd_set_capital_letters(SPDConnection* connection, SPDCapitalLetters type);
-int spd_set_capital_letters_all(SPDConnection* connection, SPDCapitalLetters 
type);
-int spd_set_capital_letters_uid(SPDConnection* connection, SPDCapitalLetters 
type, unsigned int uid);
-
-int spd_set_spelling(SPDConnection* connection, SPDSpelling type);
-int spd_set_spelling_all(SPDConnection* connection, SPDSpelling type);
-int spd_set_spelling_uid(SPDConnection* connection, SPDSpelling type, unsigned 
int uid);
-
-int spd_set_language(SPDConnection* connection, const char* language);
-int spd_set_language_all(SPDConnection* connection, const char* language);
-int spd_set_language_uid(SPDConnection* connection, const char* language, 
unsigned int uid);
-
-int spd_set_output_module(SPDConnection* connection, const char* 
output_module);
-int spd_set_output_module_all(SPDConnection* connection, const char* 
output_module);
-int spd_set_output_module_uid(SPDConnection* connection, const char* 
output_module, unsigned int uid);
-
-int spd_get_client_list(SPDConnection *connection, char **client_names, int 
*client_ids, int* active);
-int spd_get_message_list_fd(SPDConnection *connection, int target, int 
*msg_ids, char **client_names);
-
-char** spd_list_modules(SPDConnection *connection);
-char** spd_list_voices(SPDConnection *connection);
-SPDVoice** spd_list_synthesis_voices(SPDConnection *connection);
-char** spd_execute_command_with_list_reply(SPDConnection *connection, char* 
command);
-
-
-/* Direct SSIP communication */
-int spd_execute_command(SPDConnection* connection, char* command);
-int spd_execute_command_with_reply(SPDConnection *connection, char* command, 
char **reply);
-int spd_execute_command_wo_mutex(SPDConnection *connection, char* command);
-char* spd_send_data(SPDConnection* connection, const char *message, int wfr);
-char* spd_send_data_wo_mutex(SPDConnection *connection, const char *message, 
int wfr);
-
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* ifndef _LIBSPEECHD_H */
diff --git a/src/clients/say/Makefile.am b/src/clients/say/Makefile.am
index efb4bca..1308b1e 100644
--- a/src/clients/say/Makefile.am
+++ b/src/clients/say/Makefile.am
@@ -1,9 +1,9 @@
 
 localedir = $(datadir)/locale
 inc_local = "-I$(top_srcdir)/include/"
-c_api = $(top_builddir)/src/c/api
+c_api = $(top_builddir)/src/api/c
 
-AM_CFLAGS = -DLOCALEDIR=\"$(localedir)\" $(inc_local) @glib_include@ 
-I$(top_srcdir)/src/c/api
+AM_CFLAGS = -DLOCALEDIR=\"$(localedir)\" $(inc_local) @glib_include@ 
-I$(top_srcdir)/src/api/c
 
 bin_PROGRAMS = spd-say
 spd_say_SOURCES = say.c options.c options.h
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 314f423..c6d0845 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -1,9 +1,9 @@
 
 localedir = $(datadir)/locale
 inc_local = "-I$(top_srcdir)/include/"
-c_api = $(top_builddir)/src/c/api
+c_api = $(top_builddir)/src/api/c
 
-AM_CFLAGS = -I$(top_srcdir)/src/c/api -DLOCALEDIR=\"$(localedir)\" 
$(inc_local) @glib_include@ -I../audio/
+AM_CFLAGS = -I$(top_srcdir)/src/api/c -DLOCALEDIR=\"$(localedir)\" 
$(inc_local) @glib_include@ -I../audio/
 
 bin_PROGRAMS = long_message clibrary clibrary2 run_test connection_recovery
 
-- 
1.7.2.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]