Add restart menu item in system menu.
authorHuang Peng <shawn.p.huang@gmail.com>
Fri, 6 Feb 2009 06:54:00 +0000 (14:54 +0800)
committerHuang Peng <shawn.p.huang@gmail.com>
Fri, 6 Feb 2009 06:54:00 +0000 (14:54 +0800)
18 files changed:
bus/dbusimpl.c
bus/dbusimpl.h
bus/ibusimpl.c
bus/main.c
bus/matchrule.c
bus/matchrule.h
bus/registry.c
bus/registry.h
bus/server.c
bus/server.h
client/x11/main.c
ibus/bus.py
ibus/interface/iibus.py
src/ibusbus.c
src/ibusbus.h
src/ibusobject.h
ui/gtk/panel.py
xinput-ibus

index 6a70f89..f8b8566 100644 (file)
@@ -25,9 +25,6 @@
 #include "connection.h"
 #include "matchrule.h"
 
-#define BUS_DBUS_IMPL_GET_PRIVATE(o)  \
-   (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_DBUS_IMPL, BusDBusImplPrivate))
-
 enum {
     NAME_ACQUIRED,
     NAME_LOST,
@@ -39,33 +36,25 @@ enum {
     PROP_0,
 };
 
-
-/* IBusDBusImplPriv */
-struct _BusDBusImplPrivate {
-    GHashTable *unique_names;
-    GHashTable *names;
-    GHashTable *objects;
-    GList *connections;
-    GList *rules;
-    gint id;
-};
-
-typedef struct _BusDBusImplPrivate BusDBusImplPrivate;
-
 static guint dbus_signals[LAST_SIGNAL] = { 0 };
 
 /* functions prototype */
-static void     bus_dbus_impl_class_init      (BusDBusImplClass     *klass);
-static void     bus_dbus_impl_init            (BusDBusImpl          *dbus);
-static void     bus_dbus_impl_dispose         (BusDBusImpl          *dbus);
-static gboolean bus_dbus_impl_ibus_message    (BusDBusImpl          *dbus,
-                                               BusConnection        *connection,
-                                               IBusMessage          *message);
-static void     bus_dbus_impl_name_owner_changed
-                                              (BusDBusImpl          *dbus,
-                                               gchar                *name,
-                                               gchar                *old_name,
-                                               gchar                *new_name);
+static void     bus_dbus_impl_class_init        (BusDBusImplClass   *klass);
+static void     bus_dbus_impl_init              (BusDBusImpl        *dbus);
+static void     bus_dbus_impl_destroy           (BusDBusImpl        *dbus);
+static gboolean bus_dbus_impl_ibus_message      (BusDBusImpl        *dbus,
+                                                 BusConnection      *connection,
+                                                 IBusMessage        *message);
+static void     bus_dbus_impl_name_owner_changed(BusDBusImpl        *dbus,
+                                                 gchar              *name,
+                                                 gchar              *old_name,
+                                                 gchar              *new_name);
+
+
+static void     _connection_destroy_cb          (BusConnection      *connection,
+                                                 BusDBusImpl        *dbus);
+static void     _rule_destroy_cb                (BusMatchRule       *rule,
+                                                 BusDBusImpl        *dbus);
 
 static IBusServiceClass  *parent_class = NULL;
 
@@ -98,7 +87,6 @@ bus_dbus_impl_get_type (void)
 BusDBusImpl *
 bus_dbus_impl_get_default (void)
 {
-    // BusDBusImplPrivate *priv;
     static BusDBusImpl *dbus = NULL;
 
     if (dbus == NULL) {
@@ -118,9 +106,7 @@ bus_dbus_impl_class_init (BusDBusImplClass *klass)
 
     parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass);
 
-    g_type_class_add_private (klass, sizeof (BusDBusImplPrivate));
-
-    gobject_class->dispose = (GObjectFinalizeFunc) bus_dbus_impl_dispose;
+    IBUS_OBJECT_CLASS (gobject_class)->destroy = (IBusObjectDestroyFunc) bus_dbus_impl_destroy;
 
     service_class->ibus_message = (ServiceIBusMessageFunc) bus_dbus_impl_ibus_message;
 
@@ -145,25 +131,48 @@ bus_dbus_impl_class_init (BusDBusImplClass *klass)
 static void
 bus_dbus_impl_init (BusDBusImpl *dbus)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
-    priv->unique_names = g_hash_table_new (g_str_hash, g_str_equal);
-    priv->names = g_hash_table_new (g_str_hash, g_str_equal);
-    priv->objects = g_hash_table_new (g_str_hash, g_str_equal);
-    priv->connections = NULL;
-    priv->rules = NULL;
-    priv->id = 1;
+    dbus->unique_names = g_hash_table_new (g_str_hash, g_str_equal);
+    dbus->names = g_hash_table_new (g_str_hash, g_str_equal);
+    dbus->objects = g_hash_table_new (g_str_hash, g_str_equal);
+    dbus->connections = NULL;
+    dbus->rules = NULL;
+    dbus->id = 1;
 
     g_object_ref (dbus);
-    g_hash_table_insert (priv->objects, DBUS_PATH_DBUS, dbus);
+    g_hash_table_insert (dbus->objects, DBUS_PATH_DBUS, dbus);
 }
 
 static void
-bus_dbus_impl_dispose (BusDBusImpl *dbus)
+bus_dbus_impl_destroy (BusDBusImpl *dbus)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+    GList *p;
+
+    for (p = dbus->rules; p != NULL; p = p->next) {
+        BusMatchRule *rule = BUS_MATCH_RULE (p->data);
+        g_signal_handlers_disconnect_by_func (rule, _rule_destroy_cb, dbus);
+        ibus_object_destroy ((IBusObject *) rule);
+        g_object_unref (rule);
+    }
+    g_list_free (dbus->rules);
+    dbus->rules = NULL;
+    
+    for (p = dbus->connections; p != NULL; p = p->next) {
+        BusConnection *connection = BUS_CONNECTION (p->data);
+        g_signal_handlers_disconnect_by_func (connection, _connection_destroy_cb, dbus);
+        ibus_connection_close ((IBusConnection *) connection);
+        ibus_object_destroy ((IBusObject *) connection);
+        g_object_unref (connection);
+    }
+    g_list_free (dbus->connections);
+    dbus->connections = NULL;
+
+    g_hash_table_remove_all (dbus->unique_names);
+    g_hash_table_remove_all (dbus->names);
+    g_hash_table_remove_all (dbus->objects);
+
+    dbus->unique_names = NULL;
+    dbus->names = NULL;
+    dbus->objects = NULL;
 
     G_OBJECT_CLASS(parent_class)->dispose (G_OBJECT (dbus));
 }
@@ -293,9 +302,6 @@ _dbus_hello (BusDBusImpl    *dbus,
              IBusMessage    *message,
              BusConnection  *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     IBusMessage *reply_message;
 
     if (bus_connection_get_unique_name (connection) != NULL) {
@@ -306,12 +312,12 @@ _dbus_hello (BusDBusImpl    *dbus,
     else {
         gchar *name;
 
-        name = g_strdup_printf (":1.%d", priv->id ++);
+        name = g_strdup_printf (":1.%d", dbus->id ++);
         bus_connection_set_unique_name (connection, name);
         g_free (name);
 
         name = (gchar *) bus_connection_get_unique_name (connection);
-        g_hash_table_insert (priv->unique_names, name, connection);
+        g_hash_table_insert (dbus->unique_names, name, connection);
 
         reply_message = ibus_message_new_method_return (message);
         ibus_message_append_args (reply_message,
@@ -340,9 +346,6 @@ _dbus_list_names (BusDBusImpl       *dbus,
                   IBusMessage       *message,
                   BusConnection     *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     IBusMessage *reply_message;
     IBusMessageIter iter, sub_iter;
     GList *name, *names;
@@ -353,7 +356,7 @@ _dbus_list_names (BusDBusImpl       *dbus,
     ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "s", &sub_iter);
 
     // append unique names
-    names = g_hash_table_get_keys (priv->unique_names);
+    names = g_hash_table_get_keys (dbus->unique_names);
 
     names = g_list_sort (names, (GCompareFunc) g_strcmp0);
     for (name = names; name != NULL; name = name->next) {
@@ -362,7 +365,7 @@ _dbus_list_names (BusDBusImpl       *dbus,
     g_list_free (names);
 
     // append well-known names
-    names = g_hash_table_get_keys (priv->names);
+    names = g_hash_table_get_keys (dbus->names);
     names = g_list_sort (names, (GCompareFunc) g_strcmp0);
     for (name = names; name != NULL; name = name->next) {
         ibus_message_iter_append (&sub_iter, G_TYPE_STRING, &(name->data));
@@ -379,9 +382,6 @@ _dbus_name_has_owner (BusDBusImpl   *dbus,
                       IBusMessage   *message,
                       BusConnection *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     gchar *name;
     gboolean retval;
     gboolean has_owner;
@@ -402,10 +402,10 @@ _dbus_name_has_owner (BusDBusImpl   *dbus,
     }
 
     if (name[0] == ':') {
-        has_owner = g_hash_table_lookup (priv->unique_names, name) != NULL;
+        has_owner = g_hash_table_lookup (dbus->unique_names, name) != NULL;
     }
     else {
-        has_owner = g_hash_table_lookup (priv->names, name) != NULL;
+        has_owner = g_hash_table_lookup (dbus->names, name) != NULL;
     }
 
     reply_message = ibus_message_new_method_return (message);
@@ -422,9 +422,6 @@ _dbus_get_name_owner (BusDBusImpl   *dbus,
                       IBusMessage   *message,
                       BusConnection *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     gchar *name;
     BusConnection *owner;
     gboolean retval;
@@ -477,9 +474,6 @@ _dbus_get_id (BusDBusImpl   *dbus,
               IBusMessage   *message,
               BusConnection *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     IBusMessage *reply_message;
     const gchar *name;
 
@@ -506,10 +500,7 @@ _rule_destroy_cb (BusMatchRule *rule,
     g_assert (BUS_IS_MATCH_RULE (rule));
     g_assert (BUS_IS_DBUS_IMPL (dbus));
 
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
-    priv->rules = g_list_remove (priv->rules, rule);
+    dbus->rules = g_list_remove (dbus->rules, rule);
     g_object_unref (rule);
 }
 
@@ -518,9 +509,6 @@ _dbus_add_match (BusDBusImpl    *dbus,
                  IBusMessage    *message,
                  BusConnection  *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     IBusMessage *reply_message;
     IBusError *error;
     gboolean retval;
@@ -551,7 +539,7 @@ _dbus_add_match (BusDBusImpl    *dbus,
         return reply_message;
     }
 
-    for (link = priv->rules; link != NULL; link = link->next) {
+    for (link = dbus->rules; link != NULL; link = link->next) {
         if (bus_match_rule_is_equal (rule, BUS_MATCH_RULE (link->data))) {
             bus_match_rule_add_recipient (BUS_MATCH_RULE (link->data), connection);
             g_object_unref (rule);
@@ -562,7 +550,7 @@ _dbus_add_match (BusDBusImpl    *dbus,
 
     if (rule) {
         bus_match_rule_add_recipient (rule, connection);
-        priv->rules = g_list_append (priv->rules, rule);
+        dbus->rules = g_list_append (dbus->rules, rule);
         g_signal_connect (rule, "destroy", G_CALLBACK (_rule_destroy_cb), dbus);
     }
 
@@ -575,9 +563,6 @@ _dbus_remove_match (BusDBusImpl     *dbus,
                     IBusMessage     *message,
                     BusConnection   *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     IBusMessage *reply_message;
     IBusError *error;
     gchar *rule_text;
@@ -605,7 +590,7 @@ _dbus_remove_match (BusDBusImpl     *dbus,
         return reply_message;
     }
 
-    for (link = priv->rules; link != NULL; link = link->next) {
+    for (link = dbus->rules; link != NULL; link = link->next) {
         if (bus_match_rule_is_equal (rule, BUS_MATCH_RULE (link->data))) {
             bus_match_rule_remove_recipient (BUS_MATCH_RULE (link->data), connection);
             break;
@@ -623,9 +608,6 @@ _dbus_request_name (BusDBusImpl     *dbus,
                     IBusMessage     *message,
                     BusConnection   *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     IBusMessage *reply_message;
     IBusError *error;
     gchar *name;
@@ -644,7 +626,7 @@ _dbus_request_name (BusDBusImpl     *dbus,
         return reply_message;
     }
 
-    if (g_hash_table_lookup (priv->names, name) != NULL) {
+    if (g_hash_table_lookup (dbus->names, name) != NULL) {
         reply_message = ibus_message_new_error_printf (message,
                                                        DBUS_ERROR_FAILED,
                                                        "Name %s has owner",
@@ -653,7 +635,7 @@ _dbus_request_name (BusDBusImpl     *dbus,
     }
 
     retval = 1;
-    g_hash_table_insert (priv->names,
+    g_hash_table_insert (dbus->names,
                          (gpointer )bus_connection_add_name (connection, name),
                          connection);
     reply_message = ibus_message_new_method_return (message);
@@ -680,9 +662,6 @@ _dbus_release_name (BusDBusImpl     *dbus,
                     IBusMessage     *message,
                     BusConnection   *connection)
 {
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     IBusMessage *reply_message;
     IBusError *error;
     gchar *name;
@@ -826,6 +805,10 @@ _connection_ibus_message_cb (BusConnection  *connection,
 
     const gchar *dest;
 
+    if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) {
+        return;
+    }
+    
     if (ibus_message_is_signal (message,
                                 DBUS_INTERFACE_LOCAL,
                                 "Disconnected")) {
@@ -872,12 +855,9 @@ _connection_ibus_message_cb (BusConnection  *connection,
                 const gchar *path;
                 IBusService *object;
 
-                BusDBusImplPrivate *priv;
-                priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
                 path = ibus_message_get_path (message);
 
-                object = g_hash_table_lookup (priv->objects, path);
+                object = g_hash_table_lookup (dbus->objects, path);
 
                 if (object == NULL ||
                     ibus_service_handle_message (object,
@@ -915,10 +895,6 @@ _connection_ibus_message_sent_cb (BusConnection  *connection,
                                   IBusMessage    *message,
                                   BusDBusImpl    *dbus)
 {
-    g_assert (BUS_IS_CONNECTION (connection));
-    g_assert (message != NULL);
-    g_assert (BUS_IS_DBUS_IMPL (dbus));
-
     bus_dbus_impl_dispatch_message_by_rule (dbus, message, connection);
 }
 
@@ -929,9 +905,6 @@ _connection_destroy_cb (BusConnection   *connection,
     g_assert (BUS_IS_CONNECTION (connection));
     g_assert (BUS_IS_DBUS_IMPL (dbus));
 
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     /*
     ibus_service_remove_from_connection (
                     IBUS_SERVICE (dbus),
@@ -940,7 +913,7 @@ _connection_destroy_cb (BusConnection   *connection,
 
     const gchar *unique_name = bus_connection_get_unique_name (connection);
     if (unique_name != NULL) {
-        g_hash_table_remove (priv->unique_names, unique_name);
+        g_hash_table_remove (dbus->unique_names, unique_name);
         g_signal_emit (dbus,
                        dbus_signals[NAME_OWNER_CHANGED],
                        0,
@@ -952,7 +925,7 @@ _connection_destroy_cb (BusConnection   *connection,
     const GList *name = bus_connection_get_names (connection);
 
     while (name != NULL) {
-        g_hash_table_remove (priv->names, name->data);
+        g_hash_table_remove (dbus->names, name->data);
         g_signal_emit (dbus,
                        dbus_signals[NAME_OWNER_CHANGED],
                        0,
@@ -962,7 +935,7 @@ _connection_destroy_cb (BusConnection   *connection,
         name = name->next;
     }
 
-    priv->connections = g_list_remove (priv->connections, connection);
+    dbus->connections = g_list_remove (dbus->connections, connection);
     g_object_unref (connection);
 }
 
@@ -974,13 +947,10 @@ bus_dbus_impl_new_connection (BusDBusImpl    *dbus,
     g_assert (BUS_IS_DBUS_IMPL (dbus));
     g_assert (BUS_IS_CONNECTION (connection));
 
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
-    g_assert (g_list_find (priv->connections, connection) == NULL);
+    g_assert (g_list_find (dbus->connections, connection) == NULL);
 
     g_object_ref (connection);
-    priv->connections = g_list_append (priv->connections, connection);
+    dbus->connections = g_list_append (dbus->connections, connection);
 
     g_signal_connect (connection,
                       "ibus-message",
@@ -1010,17 +980,14 @@ bus_dbus_impl_get_connection_by_name (BusDBusImpl    *dbus,
 
     BusConnection *connection = NULL;
 
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
-
     if (name[0] == ':') {
         connection = BUS_CONNECTION (g_hash_table_lookup (
-                                        priv->unique_names,
+                                        dbus->unique_names,
                                         name));
     }
     else {
         connection = BUS_CONNECTION (g_hash_table_lookup (
-                                        priv->names,
+                                        dbus->names,
                                         name));
     }
 
@@ -1038,6 +1005,10 @@ bus_dbus_impl_dispatch_message (BusDBusImpl  *dbus,
     const gchar *destination;
     BusConnection *dest_connection = NULL;
 
+    if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) {
+        return;
+    }
+
     destination = ibus_message_get_destination (message);
 
     if (destination != NULL) {
@@ -1074,8 +1045,9 @@ bus_dbus_impl_dispatch_message_by_rule (BusDBusImpl     *dbus,
 
     static gint32 data_slot = -1;
 
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+    if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) {
+        return;
+    }
 
     if (data_slot == -1) {
         dbus_message_allocate_data_slot (&data_slot);
@@ -1093,7 +1065,7 @@ bus_dbus_impl_dispatch_message_by_rule (BusDBusImpl     *dbus,
     }
 #endif
 
-    for (link = priv->rules; link != NULL; link = link->next) {
+    for (link = dbus->rules; link != NULL; link = link->next) {
         if (bus_match_rule_get_recipients (BUS_MATCH_RULE (link->data),
                                            message,
                                            &recipients)) {
@@ -1116,11 +1088,7 @@ static void
 _object_destroy_cb (IBusService *object,
                     BusDBusImpl *dbus)
 {
-    gboolean retval;
-
-    retval = bus_dbus_impl_unregister_object (dbus, object);
-
-    g_assert (retval);
+    bus_dbus_impl_unregister_object (dbus, object);
 }
 
 gboolean
@@ -1131,17 +1099,19 @@ bus_dbus_impl_register_object (BusDBusImpl *dbus,
     g_assert (IBUS_IS_SERVICE (object));
 
     const gchar *path;
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+    
+    if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) {
+        return FALSE;
+    }
 
     path = ibus_service_get_path (object);
 
     g_return_val_if_fail (path, FALSE);
 
-    g_return_val_if_fail  (g_hash_table_lookup (priv->objects, path) == NULL, FALSE);
+    g_return_val_if_fail  (g_hash_table_lookup (dbus->objects, path) == NULL, FALSE);
 
     g_object_ref (object);
-    g_hash_table_insert (priv->objects, (gpointer)path, object);
+    g_hash_table_insert (dbus->objects, (gpointer)path, object);
 
     g_signal_connect (object, "destroy", G_CALLBACK (_object_destroy_cb), dbus);
 
@@ -1156,17 +1126,19 @@ bus_dbus_impl_unregister_object (BusDBusImpl *dbus,
     g_assert (IBUS_IS_SERVICE (object));
 
     const gchar *path;
-    BusDBusImplPrivate *priv;
-    priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus);
+    
+    if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) {
+        return FALSE;
+    }
 
     path = ibus_service_get_path (object);
     g_return_val_if_fail (path, FALSE);
 
-    g_return_val_if_fail  (g_hash_table_lookup (priv->objects, path) == object, FALSE);
+    g_return_val_if_fail  (g_hash_table_lookup (dbus->objects, path) == object, FALSE);
 
     g_signal_handlers_disconnect_by_func (object, G_CALLBACK (_object_destroy_cb), dbus);
 
-    g_hash_table_remove (priv->objects, path);
+    g_hash_table_remove (dbus->objects, path);
     g_object_unref (object);
 
     return TRUE;
index d04326e..7ef856b 100644 (file)
@@ -52,6 +52,12 @@ typedef struct _BusDBusImplClass BusDBusImplClass;
 struct _BusDBusImpl {
     IBusService parent;
     /* instance members */
+    GHashTable *unique_names;
+    GHashTable *names;
+    GHashTable *objects;
+    GList *connections;
+    GList *rules;
+    gint id;
 };
 
 struct _BusDBusImplClass {
index 31799d6..e92b373 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
 #include "ibusimpl.h"
 #include "dbusimpl.h"
 #include "server.h"
@@ -828,19 +832,59 @@ _ibus_list_active_engines (BusIBusImpl   *ibus,
     return reply;
 }
 
+extern gchar **g_argv;
+
 static IBusMessage *
-_ibus_kill (BusIBusImpl     *ibus,
+_ibus_exit (BusIBusImpl     *ibus,
             IBusMessage     *message,
             BusConnection   *connection)
 {
     IBusMessage *reply;
+    IBusError *error;
+    gboolean restart;
+    
+    if (!ibus_message_get_args (message,
+                                &error,
+                                G_TYPE_BOOLEAN, &restart,
+                                G_TYPE_INVALID)) {
+        reply = ibus_message_new_error (message,
+                                        DBUS_ERROR_INVALID_ARGS,
+                                        "Argument 1 of Exit should be an boolean");
+        ibus_error_free (error);
+        return reply;
+    }
 
     reply = ibus_message_new_method_return (message);
     ibus_connection_send ((IBusConnection *) connection, reply);
     ibus_connection_flush ((IBusConnection *) connection);
     ibus_message_unref (reply);
 
-    ibus_object_destroy (IBUS_OBJECT (ibus));
+    
+    if (!restart) {
+        exit (0);
+    }
+    else {
+        glong timeout;
+        gint fd;
+        gint status;
+        
+        bus_registry_stop_all_components (ibus->registry);
+        ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
+        for (fd = 3; fd <= sysconf (_SC_OPEN_MAX); fd++) {
+            close (fd);
+        }
+        for (timeout = 0; waitpid (0, &status, WNOHANG) != -1;) {
+            usleep (1000);
+            timeout += 1000;
+            if (timeout >= G_USEC_PER_SEC * 2) {
+                g_warning ("Not every child processes exited!");
+            }
+        };
+        execv (g_argv[0], g_argv);
+        g_warning ("execv %s failed!", g_argv[0]);
+        exit (-1);
+    }
+    
     return NULL;
 }
 
@@ -870,7 +914,7 @@ bus_ibus_impl_ibus_message (BusIBusImpl     *ibus,
         { IBUS_INTERFACE_IBUS, "RegisterComponent",     _ibus_register_component },
         { IBUS_INTERFACE_IBUS, "ListEngines",           _ibus_list_engines },
         { IBUS_INTERFACE_IBUS, "ListActiveEngines",     _ibus_list_active_engines },
-        { IBUS_INTERFACE_IBUS, "Kill",                  _ibus_kill },
+        { IBUS_INTERFACE_IBUS, "Exit",                  _ibus_exit },
         { NULL, NULL, NULL }
     };
 
index 74e05d8..4650bfc 100644 (file)
 #include "server.h"
 #include "ibusimpl.h"
 
+gchar **g_argv = NULL;
+
 static gboolean daemonize = FALSE;
 static gboolean single = FALSE;
 static gboolean xim = FALSE;
 static gchar *panel = "default";
 static gchar *config = "default";
 static gchar *desktop = "gnome";
+static gchar *address = "";
+static gboolean rescan = FALSE;
 static gboolean verbose = FALSE;
 
 static const GOptionEntry entries[] =
@@ -40,6 +44,8 @@ static const GOptionEntry entries[] =
     { "desktop", 'n', 0, G_OPTION_ARG_STRING, &desktop, "specify the name of desktop session. [default=gnome]", "name" },
     { "panel", 'p', 0, G_OPTION_ARG_STRING, &panel, "specify the cmdline of panel program.", "cmdline" },
     { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "specify the cmdline of config program.", "cmdline" },
+    { "address", 'a', 0, G_OPTION_ARG_STRING, &address, "specify the address of ibus daemon.", "address" },
+    { "rescan", 'r', 0, G_OPTION_ARG_NONE, &rescan, "force to rescan components, and recreate registry cache.", NULL },
     { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "verbose.", NULL },
     { NULL },
 };
@@ -91,11 +97,15 @@ main (gint argc, gchar **argv)
 
     g_option_context_add_main_entries (context, entries, "ibus-daemon");
 
+    g_argv = g_strdupv (argv);
     if (!g_option_context_parse (context, &argc, &argv, &error)) {
         g_printerr ("Option parsing failed: %s\n", error->message);
         exit (-1);
     }
 
+    /* create a new process group */
+    setpgrp ();
+
     if (daemonize) {
         if (daemon (1, 0) != 0) {
             g_printerr ("Can not daemonize ibus.\n");
index 6884fd6..6bf75c5 100644 (file)
    (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_CONFIG_PROXY, BusMatchRulePrivate))
 
 
-static void      bus_match_rule_class_init      (BusMatchRuleClass    *klass);
-static void      bus_match_rule_init            (BusMatchRule         *rule);
-static void      bus_match_rule_destroy         (BusMatchRule         *rule);
-
+static void      bus_match_rule_class_init      (BusMatchRuleClass  *klass);
+static void      bus_match_rule_init            (BusMatchRule       *rule);
+static void      bus_match_rule_destroy         (BusMatchRule       *rule);
+static void      _connection_destroy_cb         (BusConnection      *connection,
+                                                 BusMatchRule       *rule);
 static IBusObjectClass  *parent_class = NULL;
 
 GType
@@ -98,6 +99,8 @@ bus_match_rule_destroy (BusMatchRule *rule)
 
     for (link = rule->recipients; link != NULL; link = link->next) {
         BusRecipient *recipient = (BusRecipient *) link->data;
+        g_signal_handlers_disconnect_by_func (recipient->connection,
+                                              G_CALLBACK (_connection_destroy_cb), rule);
         g_object_unref (recipient->connection);
         g_slice_free (BusRecipient, recipient);
     }
index e8aaf39..b69825d 100644 (file)
@@ -63,7 +63,7 @@ struct _BusRecipient {
 };
 
 struct _BusMatchRule {
-    IBusProxy parent;
+    IBusObject parent;
     /* instance members */
     gint   flags;
     gint   message_type;
@@ -77,7 +77,7 @@ struct _BusMatchRule {
 };
 
 struct _BusMatchRuleClass {
-    IBusProxyClass parent;
+    IBusObjectClass parent;
     /* class members */
 };
 
index cdc1aa7..516554e 100644 (file)
@@ -409,6 +409,14 @@ bus_registry_find_engine_by_name (BusRegistry *registry,
     return (IBusEngineDesc *) g_hash_table_lookup (registry->engine_table, name);
 }
 
+void
+bus_registry_stop_all_components (BusRegistry *registry)
+{
+    g_assert (BUS_IS_REGISTRY (registry));
+
+    g_list_foreach (registry->components, (GFunc) ibus_component_stop, NULL);
+    
+}
 
 BusFactoryProxy *
 bus_registry_name_owner_changed (BusRegistry *registry,
index 9dadda6..377ac45 100644 (file)
@@ -67,10 +67,8 @@ GType            bus_registry_get_type          (void);
 BusRegistry     *bus_registry_new               (void);
 GList           *bus_registry_get_components    (BusRegistry    *registry);
 GList           *bus_registry_get_engines       (BusRegistry    *registry);
-gboolean         bus_registry_exec_component    (BusRegistry    *registry,
-                                                 const gchar    *name);
-gboolean         bus_registry_kill_component    (BusRegistry    *registry,
-                                                 const gchar    *name);
+void             bus_registry_stop_all_components    
+                                                (BusRegistry    *registry);
 
 IBusComponent   *bus_registry_lookup_component_by_name
                                                 (BusRegistry    *registry,
index 2ae36bf..3a957db 100644 (file)
@@ -128,6 +128,8 @@ static void
 bus_server_init (BusServer *server)
 {
     server->loop = g_main_loop_new (NULL, FALSE);
+    server->dbus = bus_dbus_impl_get_default (); 
+    server->ibus = bus_ibus_impl_get_default (); 
 }
 
 static void
@@ -135,7 +137,7 @@ bus_server_new_connection (BusServer     *server,
                            BusConnection *connection)
 {
     g_assert (BUS_IS_SERVER (server));
-    bus_dbus_impl_new_connection (BUS_DEFAULT_DBUS, connection);
+    bus_dbus_impl_new_connection (server->dbus, connection);
 }
 
 static void
@@ -143,6 +145,11 @@ bus_server_destroy (BusServer *server)
 {
     g_assert (BUS_IS_SERVER (server));
 
+    ibus_object_destroy ((IBusObject *) server->dbus);
+    g_object_unref (server->dbus);
+    ibus_object_destroy ((IBusObject *) server->ibus);
+    g_object_unref (server->ibus);
+
     while (g_main_loop_is_running (server->loop)) {
         g_main_loop_quit (server->loop);
     }
index 9ea5794..fd9bf11 100644 (file)
@@ -21,6 +21,8 @@
 #define __SERVER_H_
 
 #include <ibus.h>
+#include "dbusimpl.h"
+#include "ibusimpl.h"
 
 /*
  * Type macros.
@@ -53,6 +55,9 @@ struct _BusServer {
     /* instance members */
     GMainLoop *loop;
 
+    BusDBusImpl *dbus;
+    BusIBusImpl *ibus;
+
 };
 
 struct _BusServerClass {
index 734c898..db29eab 100644 (file)
@@ -982,7 +982,7 @@ static void
 _atexit_cb ()
 {
     if (_bus) {
-        ibus_bus_kill(_bus);
+        ibus_bus_exit(_bus, False);
     }
 }
 
index 6ca5f7d..3925385 100644 (file)
@@ -125,8 +125,8 @@ class Bus(object.Object):
     def create_input_context(self, client_name):
         return self.__ibus.CreateInputContext(client_name)
 
-    def kill(self):
-        return self.__ibus.Kill()
+    def exit(self, restart):
+        return self.__ibus.Exit(restart)
 
     def get_config(self):
         try:
index 848f798..fa71a71 100644 (file)
@@ -66,6 +66,6 @@ class IIBus(dbus.service.Object):
     @method(out_signature="av")
     def ListActiveEngines(self, dbusconn): pass
 
-    @async_method()
-    def Kill(self, dbusconn, reply_cb, error_cb): pass
+    @method(in_signature="b")
+    def Exit(self, restart, dbusconn): pass
 
index be72770..481d303 100644 (file)
@@ -684,7 +684,8 @@ ibus_bus_get_connection (IBusBus *bus)
 }
 
 gboolean
-ibus_bus_kill (IBusBus *bus)
+ibus_bus_exit (IBusBus *bus,
+               gboolean restart)
 {
     g_assert (IBUS_IS_BUS (bus));
 
@@ -694,6 +695,7 @@ ibus_bus_kill (IBusBus *bus)
                             IBUS_PATH_IBUS,
                             IBUS_INTERFACE_IBUS,
                             "Kill",
+                            G_TYPE_BOOLEAN, &restart,
                             G_TYPE_INVALID,
                             G_TYPE_INVALID);
     return result;
index e548c82..be1fba8 100644 (file)
@@ -81,7 +81,8 @@ void         ibus_bus_remove_match      (IBusBus        *bus,
 const gchar *ibus_bus_get_name_owner    (IBusBus        *bus,
                                          const gchar    *name);
 /* declare ibus methods */
-gboolean     ibus_bus_kill              (IBusBus        *bus);
+gboolean     ibus_bus_exit              (IBusBus        *bus,
+                                         gboolean        restart);
 IBusInputContext
             *ibus_bus_create_input_context
                                         (IBusBus        *bus,
index 2c09882..67fb95b 100644 (file)
@@ -50,9 +50,10 @@ typedef enum {
     IBUS_RESERVED_2     = (1 << 3),
 } IBusObjectFlags;
 
-#define IBUS_OBJECT_FLAGS(obj)         (IBUS_OBJECT (obj)->flags)
+#define IBUS_OBJECT_FLAGS(obj)             (IBUS_OBJECT (obj)->flags)
 #define IBUS_OBJECT_SET_FLAGS(obj,flag)    G_STMT_START{ (IBUS_OBJECT_FLAGS (obj) |= (flag)); }G_STMT_END
 #define IBUS_OBJECT_UNSET_FLAGS(obj,flag)  G_STMT_START{ (IBUS_OBJECT_FLAGS (obj) &= ~(flag)); }G_STMT_END
+#define IBUS_OBJECT_DESTROYED(obj)         (IBUS_OBJECT_FLAGS (obj) & IBUS_DESTROYED)
 
 G_BEGIN_DECLS
 
index 284dbb6..759fb56 100644 (file)
@@ -278,6 +278,10 @@ class Panel(ibus.PanelBase):
             self.__sys_menu_item_activate_cb, gtk.STOCK_ABOUT)
         menu.add(item)
         menu.add(gtk.SeparatorMenuItem())
+        item = gtk.MenuItem(_("Restart"))
+        item.connect("activate",
+            self.__sys_menu_item_activate_cb, "Restart")
+        menu.add(item)
         item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
         item.connect("activate",
             self.__sys_menu_item_activate_cb, gtk.STOCK_QUIT)
@@ -375,8 +379,10 @@ class Panel(ibus.PanelBase):
             about_dialog.set_logo_icon_name("ibus")
             about_dialog.run()
             about_dialog.destroy()
-        elif command == gtk.STOCK_QUIT:
-            self.__bus.kill()
+        elif command == gtk.STOCK_QUIT: 
+            self.__bus.exit(False)
+        elif command == "Restart":
+            self.__bus.exit(True)
         else:
             print >> sys.stderr, "Unknown command %s" % command
     
index be3dc26..b0bab2e 100644 (file)
@@ -1,7 +1,7 @@
 XIM=ibus
 XIM_PROGRAM="/usr/bin/ibus-daemon"
 ICON="/usr/share/ibus/icons/ibus.svg"
-# XIM_ARGS="0xffffffff"
+XIM_ARGS="-x"
 PREFERENCE_PROGRAM=/usr/bin/ibus-setup
 SHORT_DESC="IBus"
 GTK_IM_MODULE=ibus