Add signal handlers to ibus-chewing to listen for config changes.

BUG=chromium-os:4604
TEST=Enable ibus chewing.  Change the number of candidates in the chewing options dialog.  Check that the change has worked.

Review URL: http://codereview.chromium.org/2899003
diff --git a/src/IBusChewingEngine-keys.c b/src/IBusChewingEngine-keys.c
index c7ee417..1092cf2 100644
--- a/src/IBusChewingEngine-keys.c
+++ b/src/IBusChewingEngine-keys.c
@@ -216,3 +216,10 @@
     IBusChewingEngine *self=IBUS_CHEWING_ENGINE(engine);
     self_handle_candidate_clicked(self, index, button, state);
 }
+
+void ibus_config_value_changed(IBusConfig *config, const gchar *section,
+	const gchar *name, GValue *value, gpointer userData) {
+    G_DEBUG_MSG(3,"[I3] ibus_config_value_changed(-, %s, %s, -, -)", section, name);
+    IBusChewingEngine *self=IBUS_CHEWING_ENGINE(userData);
+    self_handle_config_value_changed(self, section, name, value);
+}
diff --git a/src/IBusChewingEngine.gob b/src/IBusChewingEngine.gob
index 0fe13ac..e65e77e 100644
--- a/src/IBusChewingEngine.gob
+++ b/src/IBusChewingEngine.gob
@@ -142,6 +142,8 @@
 	guint keyval, guint  modifiers);
 void ibus_chewing_engine_candidate_clicked(IBusEngine *engine, guint index,
 	guint button, guint state);
+void ibus_config_value_changed(IBusConfig *config, const gchar *section,
+	const gchar *name, GValue *value, gpointer userData);
 
 #ifndef IBUS_1_1
 gboolean ibus_chewing_engine_process_key_event_1_2(IBusEngine *engine,
@@ -152,7 +154,7 @@
 
 %{
 extern gboolean ibus_chewing_verbose;
-//extern IBusConfig *iConfig;
+extern IBusConfig *iConfig;
 
 #define IBUS_CHEWING_MAIN
 #include "IBusChewingEngine-def.c"
@@ -194,6 +196,7 @@
 	destroywith ibus_lookup_table_clear;
     protected guint tableCursor=0;
     protected gboolean tableVisible=FALSE;
+    protected gulong handler_id = 0;
 
     public IBusProperty    *chieng_prop={
         g_object_ref_sink (
@@ -275,6 +278,15 @@
 	ibus_engine_class->candidate_clicked = ibus_chewing_engine_candidate_clicked;
     }
 
+    override (G:Object) void
+    finalize (G:Object *gobject){
+	Self *self=SELF(gobject);
+	G_DEBUG_MSG(1,"[I1] finalize()");
+	if (self->config && self->handler_id) {
+	    g_signal_handler_disconnect(self->config, self->handler_id);
+	}
+    }
+
     private  void load_setting(self){
 #define BUFFER_SIZE_LOCAL 200
 	G_DEBUG_MSG(3,"[I3] load_setting()");
@@ -770,6 +782,25 @@
 	}
     }
 
+    protected void handle_config_value_changed(self, const gchar *section, const gchar *name, GValue *value){
+	int i;
+	PropertyContext context = {NULL, self};
+	G_DEBUG_MSG(4,"[I4]  handle_config_value_changed(), section=%s, name=%s",section,name);
+	// Filter out config values that don't apply to chewing.
+	if (strcmp(section, "engine/Chewing")) {
+	    return;
+	}
+
+	// Search through the property definitions to see if we use this value.
+	for (i=0; propSpecs[i].valueType!=G_TYPE_INVALID;i++){
+	    if (0 == strcmp(propSpecs[i].key, name)){
+		// Call the assignment function associated with the config value.
+		propSpecs[i].setFunc(&context, value);
+		return;
+	    }
+	}
+    }
+
     protected int current_num_candidate(self){
 	if (chewing_cand_TotalChoice(self->context) >=
 	    (chewing_cand_CurrentPage(self->context)+1) * chewing_cand_ChoicePerPage(self->context)) {
@@ -972,15 +1003,16 @@
         Self *self=SELF(engine);
 
         if (!self->config){
-
-            /* connections_list is not avail in init, so we put it here */
-	    GList  *connections_list=ibus_service_get_connections(IBUS_SERVICE(engine));
-	    g_assert(connections_list);
-	    g_assert(connections_list->data);
-	    IBusConnection *iConnection=(IBusConnection *) connections_list->data;
-	    self->config=ibus_config_new(iConnection);
+	    self->config=iConfig;
 	    self_load_setting(self);
         }
+	if (!self->handler_id) {
+	    // Watch the ibus config service for config changes.  If one of chewing's values
+	    // changes, the local state needs to be updated to match.
+	    self->handler_id = g_signal_connect(self->config, "value-changed",
+		G_CALLBACK(ibus_config_value_changed), self);
+	}
+	G_DEBUG_MSG(2,"[I2] enable() config = %x handler_id = %d", self->config, self->handler_id);
 	self_refresh_property_list(self);
 	self->inputMode=CHEWING_INPUT_MODE_SELECTING_DONE;
 	ibus_chewing_engine_set_status_flag(self, ENGINE_STATUS_ENABLED);
diff --git a/src/main.c b/src/main.c
index 027d05f..5e3349a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,6 +35,7 @@
 /* options */
 static gboolean ibus = FALSE;
 int ibus_chewing_verbose= 0;
+IBusConfig *iConfig = NULL;
 
 static const GOptionEntry entries[] =
 {
@@ -60,6 +61,9 @@
 {
     bus = ibus_bus_new ();
     g_signal_connect (bus, "disconnected", G_CALLBACK (ibus_disconnected_cb), NULL);
+    iConfig = ibus_bus_get_config (bus);
+    if (iConfig)
+        g_object_ref_sink (iConfig);
 
     IBusConnection *iConnection=ibus_bus_get_connection (bus);
     factory = ibus_factory_new (iConnection);