[dasher: 10/11] Gtk2: reimplement speech using new DasherCore SupportsSpeech/Speak API.



commit 8390588b5e9b1b9d78fd2bdc720716a4c28fcc4c
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Mon Jun 14 16:16:04 2010 +0100

    Gtk2: reimplement speech using new DasherCore SupportsSpeech/Speak API.
    
    Rewrote initialization code to keep trying servers until finding a voice.
    
    Remove old speech code - action, control event handling, command "forwarding".
    Also remove associated calls/wrappers to/round {Register,{Disc,C}onnect}Node

 Src/Gtk2/DasherControl.cpp          |   18 +++-
 Src/Gtk2/DasherControl.h            |   18 +++-
 Src/Gtk2/GtkDasherControl.cpp       |   18 ---
 Src/Gtk2/GtkDasherControl.h         |    3 -
 Src/Gtk2/Makefile.am                |    4 +-
 Src/Gtk2/Speech.cpp                 |   79 ++++++++++++
 Src/Gtk2/Speech.h                   |   24 ++++
 Src/Gtk2/dasher_action_speech.cpp   |  235 -----------------------------------
 Src/Gtk2/dasher_action_speech.h     |   31 -----
 Src/Gtk2/dasher_editor.cpp          |    3 -
 Src/Gtk2/dasher_editor_internal.cpp |   45 +------
 Src/Gtk2/dasher_main.cpp            |   85 +------------
 Src/Gtk2/dasher_main.h              |    2 +-
 13 files changed, 147 insertions(+), 418 deletions(-)
---
diff --git a/Src/Gtk2/DasherControl.cpp b/Src/Gtk2/DasherControl.cpp
index 260fcf5..d7a5cc2 100644
--- a/Src/Gtk2/DasherControl.cpp
+++ b/Src/Gtk2/DasherControl.cpp
@@ -9,7 +9,7 @@
 #include "Timer.h"
 #include "../DasherCore/Event.h"
 #include "../DasherCore/ModuleManager.h"
-
+#include "dasher_main.h"
 #include <fcntl.h>
 
 #include <gtk/gtk.h>
@@ -191,6 +191,22 @@ void CDasherControl::ScanColourFiles(std::vector<std::string> &vFileList) {
   g_pattern_spec_free(colourglob);
 }
 
+extern DasherMain *g_pDasherMain;
+std::string CDasherControl::GetAllContext() {
+  const gchar *text = dasher_main_get_all_text(g_pDasherMain);
+  return text;
+}
+
+#ifdef GNOME_SPEECH
+bool CDasherControl::SupportsSpeech() {
+  return m_Speech.Init();
+}
+
+void CDasherControl::Speak(const std::string &strText, bool bInterrupt) {
+  m_Speech.Speak(strText, bInterrupt);
+}
+#endif
+
 CDasherControl::~CDasherControl() {
   if(m_pMouseInput) {
     m_pMouseInput = NULL;
diff --git a/Src/Gtk2/DasherControl.h b/Src/Gtk2/DasherControl.h
index 669ceae..1f1305a 100644
--- a/Src/Gtk2/DasherControl.h
+++ b/Src/Gtk2/DasherControl.h
@@ -17,6 +17,10 @@
 #include "tilt_input.h"
 #endif
 
+#ifdef GNOME_SPEECH
+#include "Speech.h"
+#endif
+
 #include "mouse_input.h"
 
 #include "GtkDasherControl.h"
@@ -131,9 +135,13 @@ public:
   ///Override to broadcast signal...
   virtual void Stop();
   
-  virtual std::string GetAllContext() {
-    throw "Hack to make Gtk2 compile, should not be called as supportsSpeech()/supportsClipboard()==false";
-  }
+  virtual std::string GetAllContext();
+
+#ifdef GNOME_SPEECH
+  ///override default non-implementation if compiling with speech...
+  virtual bool SupportsSpeech();
+  virtual void Speak(const std::string &strText, bool bInterrupt);
+#endif
 
 private:
   //  virtual void CreateSettingsStore();
@@ -196,6 +204,10 @@ private:
   ///
 
   //  CKeyboardHelper *m_pKeyboardHelper;
+
+#ifdef GNOME_SPEECH
+  CSpeech m_Speech;
+#endif
 };
 
 #endif
diff --git a/Src/Gtk2/GtkDasherControl.cpp b/Src/Gtk2/GtkDasherControl.cpp
index 7e2c70c..cc7ed22 100644
--- a/Src/Gtk2/GtkDasherControl.cpp
+++ b/Src/Gtk2/GtkDasherControl.cpp
@@ -222,24 +222,6 @@ gtk_dasher_control_set_offset(GtkDasherControl *pControl, int iOffset) {
 }
 
 void 
-gtk_dasher_control_register_node(GtkDasherControl *pControl, int iID, const gchar *szLabel, int iColour) {
-  GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
-  pPrivate->pControl->RegisterNode(iID, szLabel, iColour);
-}
-
-void 
-gtk_dasher_control_connect_node(GtkDasherControl *pControl, int iChild, int iParent, int iAfter) {
-  GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
-  pPrivate->pControl->ConnectNode(iChild, iParent, iAfter);
-}
-
-void 
-gtk_dasher_control_disconnect_node(GtkDasherControl *pControl, int iChild, int iParent) {
-  GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
-  pPrivate->pControl->DisconnectNode(iChild, iParent);
-}
-
-void 
 gtk_dasher_control_external_key_down(GtkDasherControl *pControl, int iKeyVal) {
   GtkDasherControlPrivate *pPrivate = GTK_DASHER_CONTROL_GET_PRIVATE(pControl);
   pPrivate->pControl->ExternalKeyDown(iKeyVal);
diff --git a/Src/Gtk2/GtkDasherControl.h b/Src/Gtk2/GtkDasherControl.h
index 9cfcff0..63a7910 100644
--- a/Src/Gtk2/GtkDasherControl.h
+++ b/Src/Gtk2/GtkDasherControl.h
@@ -79,9 +79,6 @@ void gtk_dasher_control_set_context(GtkDasherControl *pControl, const gchar *szC
 void gtk_dasher_control_set_buffer(GtkDasherControl *pControl, int iOffset);
 void gtk_dasher_control_set_offset(GtkDasherControl *pControl, int iOffset);
 void gtk_dasher_control_unset_buffer(GtkDasherControl *pControl);
-void gtk_dasher_control_register_node(GtkDasherControl *pControl, int iID, const gchar *szLabel, int iColour);
-void gtk_dasher_control_connect_node(GtkDasherControl *pControl, int iChild, int iParent, int iAfter);
-void gtk_dasher_control_disconnect_node(GtkDasherControl *pControl, int iChild, int iParent);
 void gtk_dasher_control_external_key_down(GtkDasherControl *pControl, int iKeyVal);
 void gtk_dasher_control_external_key_up(GtkDasherControl *pControl, int iKeyVal);
 gboolean gtk_dasher_control_get_module_settings(GtkDasherControl * pControl, const gchar *szModule, SModuleSettings **pSettings, gint *iCount);
diff --git a/Src/Gtk2/Makefile.am b/Src/Gtk2/Makefile.am
index bdeecd6..08ebbab 100644
--- a/Src/Gtk2/Makefile.am
+++ b/Src/Gtk2/Makefile.am
@@ -39,6 +39,8 @@ libdashercontrol_la_SOURCES = \
 		PangoCache.h \
 		Timer.cpp \
 		Timer.h \
+		Speech.cpp \
+		Speech.h \
 		custom_marshal.cpp \
 		custom_marshal.h \
 		game_mode_helper.cpp \
@@ -62,8 +64,6 @@ libdashergtk_la_SOURCES = \
 		dasher_action_keyboard_maemo.h \
 		dasher_action_script.cpp \
 		dasher_action_script.h \
-		dasher_action_speech.cpp \
-		dasher_action_speech.h \
 		dasher_buffer_set.cpp \
 		dasher_buffer_set.h \
 		dasher_editor.cpp \
diff --git a/Src/Gtk2/Speech.cpp b/Src/Gtk2/Speech.cpp
new file mode 100644
index 0000000..86590bd
--- /dev/null
+++ b/Src/Gtk2/Speech.cpp
@@ -0,0 +1,79 @@
+// TODO: Make inclusion in build system conditional
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef GNOME_SPEECH
+#include "Speech.h"
+
+CSpeech::CSpeech() : m_speaker(NULL) {
+  CORBA_exception_init(&m_ev);
+}
+
+CSpeech::~CSpeech() {
+  if (m_speaker) {
+    bonobo_object_release_unref(m_speaker, &m_ev);
+    GNOME_Speech_SynthesisDriver_unref(m_driver, &m_ev);
+  }
+  CORBA_exception_free(&m_ev);
+}
+
+
+bool CSpeech::Init() {
+  if (m_speaker) return true;
+
+  Bonobo_ServerInfoList *servers = bonobo_activation_query("repo_ids.has_one(['IDL:GNOME/Speech/SynthesisDriver:0.2','IDL:GNOME/Speech/SynthesisDriver:0.3'])", NULL, &m_ev);
+
+  if(servers->_length == 0) {
+    g_warning(_("Unable to initialize speech support\n"));
+    return false;
+  }
+
+  for(unsigned int i = 0; i < servers->_length; i++) {
+    
+    Bonobo_ServerInfo *info = &servers->_buffer[i];
+
+    m_driver = bonobo_activation_activate_from_id((const Bonobo_ActivationID)info->iid, 0, NULL, &m_ev);
+    if(BONOBO_EX(&m_ev)) continue;
+
+    GNOME_Speech_SynthesisDriver_driverInit(m_driver, &m_ev);
+
+    GNOME_Speech_VoiceInfoList *voices = GNOME_Speech_SynthesisDriver_getAllVoices(m_driver, &m_ev);
+
+    if(voices == NULL || BONOBO_EX(&m_ev) || voices->_length == 0) {
+      CORBA_free(voices);
+      GNOME_Speech_SynthesisDriver_unref(m_driver, &m_ev);
+      continue;
+    }
+
+    m_speaker = GNOME_Speech_SynthesisDriver_createSpeaker(m_driver, &voices->_buffer[0], &m_ev);
+    CORBA_free(voices);
+    break;
+  }
+
+  CORBA_free(servers);
+
+  if (m_speaker) {
+    GNOME_Speech_ParameterList *list = GNOME_Speech_Speaker_getSupportedParameters(m_speaker, &m_ev);
+    if(BONOBO_EX(&m_ev) || list->_length == 0) {
+      g_warning(_("Warning: unable to set speech parameters\n"));
+    } else {
+      for(unsigned i = 0; i < list->_length; i++) {
+        GNOME_Speech_Parameter *p = &(list->_buffer[i]);
+        if(!strcmp(p->name, "rate")) {
+          GNOME_Speech_Speaker_setParameterValue(m_speaker, p->name, 200.0, &m_ev);
+        }
+      }
+    }
+    CORBA_free(list);
+  } else
+    g_warning(_("Unable to initialize voices\n"));
+
+  return m_speaker != NULL;
+}
+
+void CSpeech::Speak(const std::string &strText, bool bInterrupt) {
+    if (Init())
+      GNOME_Speech_Speaker_say(m_speaker, strText.c_str(), &m_ev);
+}
+
+#endif
diff --git a/Src/Gtk2/Speech.h b/Src/Gtk2/Speech.h
new file mode 100644
index 0000000..7283352
--- /dev/null
+++ b/Src/Gtk2/Speech.h
@@ -0,0 +1,24 @@
+// TODO: Make inclusion in build system conditional
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef GNOME_SPEECH
+
+#include <string>
+#include <glib/gi18n.h>
+#include <gnome-speech/gnome-speech.h>
+#include <libbonobo.h>
+
+class CSpeech {
+public:
+  CSpeech();
+  ~CSpeech();
+  bool Init();
+  void Speak(const std::string &strText, bool bInterrupt);
+private:
+  GNOME_Speech_SynthesisDriver m_driver;
+  GNOME_Speech_Speaker m_speaker;
+  CORBA_Environment m_ev;
+};
+
+#endif
diff --git a/Src/Gtk2/dasher_editor.cpp b/Src/Gtk2/dasher_editor.cpp
index 2b250f3..4a1422d 100644
--- a/Src/Gtk2/dasher_editor.cpp
+++ b/Src/Gtk2/dasher_editor.cpp
@@ -31,9 +31,6 @@
 #else
 #include "dasher_action_script.h"
 #endif
-#ifdef GNOME_SPEECH
-#include "dasher_action_speech.h"
-#endif 
 #include "dasher_editor.h"
 #include "dasher_external_buffer.h"
 #include "dasher_internal_buffer.h"
diff --git a/Src/Gtk2/dasher_editor_internal.cpp b/Src/Gtk2/dasher_editor_internal.cpp
index f419e94..87082a7 100644
--- a/Src/Gtk2/dasher_editor_internal.cpp
+++ b/Src/Gtk2/dasher_editor_internal.cpp
@@ -20,10 +20,6 @@
 #include "dasher_action_script.h"
 #endif
 
-#ifdef GNOME_SPEECH
-#include "dasher_action_speech.h"
-#endif 
-
 #include "dasher_editor_internal.h"
 #include "dasher_external_buffer.h"
 #include "dasher_internal_buffer.h"
@@ -925,40 +921,6 @@ dasher_editor_internal_command(DasherEditor *pSelf, const gchar *szCommand) {
     return TRUE;
   }
  
-  /* TODO: We need a rethink here */
-  const gchar *szForwardCommand = NULL;
-  gint iSubCommand = 0;
-
-  if(!strcmp(szCommand, "speakall")) {
-    szForwardCommand = "Speak";
-    iSubCommand = 0;
-  }
-  else if(!strcmp(szCommand, "speaklast")) {
-    szForwardCommand = "Speak";
-    iSubCommand = 1;
-  }
-  else if(!strcmp(szCommand, "speakrepeat")) {
-    szForwardCommand = "Speak";
-    iSubCommand = 2;
-  }
-
-  if(szForwardCommand) {
-    gboolean bActionIterStarted = false;
-    EditorAction *pActionIter = pPrivate->pActionRing;
-    
-    while((pActionIter != pPrivate->pActionRing) || !bActionIterStarted) {
-      bActionIterStarted = true;
-      
-      if(!strcmp(dasher_action_get_name(pActionIter->pAction), szForwardCommand)) {
-	dasher_action_execute(pActionIter->pAction, DASHER_EDITOR(pSelf), iSubCommand);
-	return TRUE;
-      }
-      
-      pActionIter = pActionIter->pNext;
-    }
-    return TRUE;
-  }
-
   return FALSE;
 }
 
@@ -1051,9 +1013,10 @@ dasher_editor_internal_setup_actions(DasherEditor *pSelf) {
   // TODO: Activate and deactivate methods for actions
   // TODO: Clear shouldn't be a special case (include support for false in clear method)
 
-#ifdef GNOME_SPEECH
-  dasher_editor_internal_add_action(pSelf, DASHER_ACTION(dasher_action_speech_new()));
-#endif
+  //ACL 14/6/09 Removing old speech code: the Control Mode bits of this
+  // are now in DasherCore, & the old DasherAction would no-op if used in
+  // any otherway! (Also the whole actions code stuff seems so unfinished etc.
+  // anyway...that perhaps it's best removed?)
 
   dasher_editor_internal_add_action(pSelf, DASHER_ACTION(dasher_action_keyboard_new(pPrivate->pExternalBuffer)));
 
diff --git a/Src/Gtk2/dasher_main.cpp b/Src/Gtk2/dasher_main.cpp
index 46afe64..f3376a2 100644
--- a/Src/Gtk2/dasher_main.cpp
+++ b/Src/Gtk2/dasher_main.cpp
@@ -126,7 +126,6 @@ static void dasher_main_load_state(DasherMain *pSelf);
 static void dasher_main_save_state(DasherMain *pSelf);
 static void dasher_main_setup_window(DasherMain *pSelf);
 static void dasher_main_populate_controls(DasherMain *pSelf);
-static void dasher_main_connect_control(DasherMain *pSelf);
 static gboolean dasher_main_command(DasherMain *pSelf, const gchar *szCommand);
 static gint dasher_main_lookup_key(DasherMain *pSelf, guint iKeyVal);
 
@@ -345,7 +344,6 @@ dasher_main_new(int *argc, char ***argv, SCommandLine *pCommandLine) {
     /* Set up various bits and pieces */
     dasher_main_set_window_title(pDasherMain);
     dasher_main_populate_controls(pDasherMain);
-    dasher_main_connect_control(pDasherMain);
 
     gtk_key_snooper_install(dasher_main_key_snooper, pDasherMain);
 
@@ -600,11 +598,11 @@ dasher_main_create_preferences(DasherMain *pSelf) {
   pPrivate->pPreferencesDialogue = dasher_preferences_dialogue_new(pPrivate->pPrefXML, pPrivate->pEditor, pPrivate->pAppSettings, pPrivate->pMainWindow);
 }
 
-// DasherEditor *
-// dasher_main_get_editor(DasherMain *pSelf) {
-//   DasherMainPrivate *pPrivate = DASHER_MAIN_GET_PRIVATE(pSelf);
-//   return pPrivate->pEditor;
-// }
+const gchar *
+dasher_main_get_all_text(DasherMain *pSelf) {
+   DasherMainPrivate *pPrivate = DASHER_MAIN_GET_PRIVATE(pSelf);
+   return dasher_editor_get_all_text(pPrivate->pEditor);
+}
 
 static void 
 dasher_main_handle_parameter_change(DasherMain *pSelf, int iParameter) {
@@ -778,62 +776,6 @@ dasher_main_populate_controls(DasherMain *pSelf) {
                             dasher_app_settings_get_long(pPrivate->pAppSettings, LP_MAX_BITRATE) / 100.0);
 }
 
-static void 
-dasher_main_connect_control(DasherMain *pSelf) {
-  /* TODO: This is very much temporary - we need to think of a better
-     way of presenting application commands in a unified way */
-#ifdef GNOME_SPEECH
-  DasherMainPrivate *pPrivate = DASHER_MAIN_GET_PRIVATE(pSelf);
-
-  gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                    Dasher::CControlManager::CTL_USER,
-                                    "Speak", -1 );
-
-  gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                   Dasher::CControlManager::CTL_USER, 
-                                   Dasher::CControlManager::CTL_ROOT, -2);
-
-
-  gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                    Dasher::CControlManager::CTL_USER + 1, 
-                                    "All", -1 );
-
-  gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                    Dasher::CControlManager::CTL_USER + 2, 
-                                    "Last", -1 );
-
-  gtk_dasher_control_register_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                    Dasher::CControlManager::CTL_USER + 3, 
-                                    "Repeat", -1 );
-
-  gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                   Dasher::CControlManager::CTL_USER + 1, 
-                                   Dasher::CControlManager::CTL_USER, -2);
-
-  gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                   -1, 
-                                   Dasher::CControlManager::CTL_USER + 1, -2);
-
-  gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                   Dasher::CControlManager::CTL_USER + 2, 
-                                   Dasher::CControlManager::CTL_USER, -2);
-
-  gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                   -1,
-                                   Dasher::CControlManager::CTL_USER + 2, -2);
-
-  gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                   Dasher::CControlManager::CTL_USER + 3, 
-                                   Dasher::CControlManager::CTL_USER, -2);
-
-  gtk_dasher_control_connect_node( GTK_DASHER_CONTROL(pPrivate->pDasherWidget), 
-                                   -1,
-                                   Dasher::CControlManager::CTL_USER + 3, -2);
-
-#endif
-
-}
-
 static gboolean 
 dasher_main_command(DasherMain *pSelf, const gchar *szCommand) {
   DasherMainPrivate *pPrivate = DASHER_MAIN_GET_PRIVATE(pSelf);
@@ -1392,23 +1334,6 @@ handle_control_event(GtkDasherControl *pDasherControl, gint iEvent, gpointer dat
   if(!g_pDasherMain)
     return;
   
-  /* TODO: replace this with something a little more sensible */
-
-  switch(iEvent) {
-  case Dasher::CControlManager::CTL_USER + 1:
-    dasher_main_command(g_pDasherMain, "speakall");
-    return;
-  case Dasher::CControlManager::CTL_USER + 2:
-    dasher_main_command(g_pDasherMain, "speaklast");
-    return;
-  case Dasher::CControlManager::CTL_USER + 3:
-    dasher_main_command(g_pDasherMain, "speakrepeat");
-    return;
-  default:
-    break;
-  }
-
-
   // TODO: This is a horrible hack here to make the release work!  
 
   g_bSend = false;
diff --git a/Src/Gtk2/dasher_main.h b/Src/Gtk2/dasher_main.h
index 29927f8..02a345b 100644
--- a/Src/Gtk2/dasher_main.h
+++ b/Src/Gtk2/dasher_main.h
@@ -36,7 +36,7 @@ struct _SCommandLine {
 
 DasherMain *dasher_main_new(int *argc, char ***argv, SCommandLine *pCommandLine);
 GType dasher_main_get_type();
-//DasherEditorInternal *dasher_main_get_editor(DasherMain *pSelf);
+const gchar *dasher_main_get_all_text(DasherMain *pSelf);
 void dasher_main_show(DasherMain *pSelf);
 G_END_DECLS
 



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