X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=blobdiff_plain;f=droute%2Fdroute.c;h=82eea8f95740d4e0db17bbab7193a767f8d15c7b;hp=24ccea490aa73a77203a15e2ca55f74a7597cca7;hb=87be4982ef114dd00cc8d8ee5687e890d06b3420;hpb=cd30c52d1ca09b4f637b5838cc68fac478270892 diff --git a/droute/droute.c b/droute/droute.c index 24ccea4..82eea8f 100644 --- a/droute/droute.c +++ b/droute/droute.c @@ -23,6 +23,7 @@ #include #include +#include #include "droute.h" #include "droute-pairhash.h" @@ -39,7 +40,6 @@ struct _DRouteContext { - DBusConnection *bus; GPtrArray *registered_paths; gchar *introspect_string; @@ -48,12 +48,16 @@ struct _DRouteContext struct _DRoutePath { DRouteContext *cnx; + gchar *path; + gboolean prefix; GStringChunk *chunks; GPtrArray *interfaces; GPtrArray *introspection; GHashTable *methods; GHashTable *properties; + DRouteIntrospectChildrenFunction introspect_children_cb; + void *introspect_children_data; void *user_data; DRouteGetDatumFunction get_datum; }; @@ -78,13 +82,19 @@ droute_object_does_not_exist_error (DBusMessage *message); static DRoutePath * path_new (DRouteContext *cnx, + const char *path, + gboolean prefix, void *user_data, + DRouteIntrospectChildrenFunction introspect_children_cb, + void *introspect_children_data, DRouteGetDatumFunction get_datum) { DRoutePath *new_path; new_path = g_new0 (DRoutePath, 1); new_path->cnx = cnx; + new_path->path = g_strdup (path); + new_path->prefix = prefix; new_path->chunks = g_string_chunk_new (CHUNKS_DEFAULT); new_path->interfaces = g_ptr_array_new (); new_path->introspection = g_ptr_array_new (); @@ -97,8 +107,10 @@ path_new (DRouteContext *cnx, new_path->properties = g_hash_table_new_full ((GHashFunc)str_pair_hash, str_pair_equal, g_free, - NULL); + g_free); + new_path->introspect_children_cb = introspect_children_cb; + new_path->introspect_children_data = introspect_children_data; new_path->user_data = user_data; new_path->get_datum = get_datum; @@ -108,11 +120,13 @@ path_new (DRouteContext *cnx, static void path_free (DRoutePath *path, gpointer user_data) { + g_free (path->path); g_string_chunk_free (path->chunks); g_ptr_array_free (path->interfaces, TRUE); - g_ptr_array_free (path->introspection, FALSE); + g_free(g_ptr_array_free (path->introspection, FALSE)); g_hash_table_destroy (path->methods); g_hash_table_destroy (path->properties); + g_free (path); } static void * @@ -127,12 +141,11 @@ path_get_datum (DRoutePath *path, const gchar *pathstr) /*---------------------------------------------------------------------------*/ DRouteContext * -droute_new (DBusConnection *bus) +droute_new () { DRouteContext *cnx; cnx = g_new0 (DRouteContext, 1); - cnx->bus = bus; cnx->registered_paths = g_ptr_array_new (); return cnx; @@ -142,17 +155,12 @@ void droute_free (DRouteContext *cnx) { g_ptr_array_foreach (cnx->registered_paths, (GFunc) path_free, NULL); + g_ptr_array_free (cnx->registered_paths, TRUE); g_free (cnx); } /*---------------------------------------------------------------------------*/ -DBusConnection * -droute_get_bus (DRouteContext *cnx) -{ - return cnx->bus; -} - /*---------------------------------------------------------------------------*/ static DBusObjectPathVTable droute_vtable = @@ -168,16 +176,8 @@ droute_add_one (DRouteContext *cnx, const void *data) { DRoutePath *new_path; - gboolean registered; - new_path = path_new (cnx, (void *) data, NULL); - - registered = dbus_connection_register_object_path (cnx->bus, path, &droute_vtable, new_path); - if (!registered) - { - path_free (new_path, NULL); - return NULL; - } + new_path = path_new (cnx, path, FALSE, (void *)data, NULL, NULL, NULL); g_ptr_array_add (cnx->registered_paths, new_path); return new_path; @@ -187,14 +187,15 @@ DRoutePath * droute_add_many (DRouteContext *cnx, const char *path, const void *data, + DRouteIntrospectChildrenFunction introspect_children_cb, + void *introspect_children_data, const DRouteGetDatumFunction get_datum) { DRoutePath *new_path; - new_path = path_new (cnx, (void *) data, get_datum); - - if (!dbus_connection_register_fallback (cnx->bus, path, &droute_vtable, new_path)) - oom(); + new_path = path_new (cnx, path, TRUE, (void *) data, + introspect_children_cb, introspect_children_data, + get_datum); g_ptr_array_add (cnx->registered_paths, new_path); return new_path; @@ -215,7 +216,7 @@ droute_path_add_interface(DRoutePath *path, itf = g_string_chunk_insert (path->chunks, name); g_ptr_array_add (path->interfaces, itf); - g_ptr_array_add (path->introspection, introspect); + g_ptr_array_add (path->introspection, (gpointer) introspect); for (; methods != NULL && methods->name != NULL; methods++) { @@ -326,7 +327,11 @@ impl_prop_GetSet (DBusMessage *message, prop_funcs = (PropertyPair *) g_hash_table_lookup (path->properties, &pair); if (!prop_funcs) +#ifdef DBUS_ERROR_UNKNOWN_PROPERTY + return dbus_message_new_error (message, DBUS_ERROR_UNKNOWN_PROPERTY, "Property unavailable"); +#else return dbus_message_new_error (message, DBUS_ERROR_FAILED, "Property unavailable"); +#endif datum = path_get_datum (path, pathstr); if (!datum) @@ -361,6 +366,12 @@ impl_prop_GetSet (DBusMessage *message, reply = dbus_message_new_method_return (message); } +#ifdef DBUS_ERROR_PROPERTY_READ_ONLY + else if (!get) + { + reply = dbus_message_new_error (message, DBUS_ERROR_PROPERTY_READ_ONLY, "Property is read-only"); + } +#endif else { reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, "Getter or setter unavailable"); @@ -370,6 +381,35 @@ impl_prop_GetSet (DBusMessage *message, } static DBusHandlerResult +handle_dbus (DBusConnection *bus, + DBusMessage *message, + const gchar *iface, + const gchar *member, + const gchar *pathstr) +{ + static int id = 1; + char *id_str = (char *) g_malloc(40); + DBusMessage *reply; + + if (strcmp (iface, DBUS_INTERFACE_DBUS) != 0 || + strcmp (member, "Hello") != 0) + { + g_free (id_str); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + /* TODO: Fix this hack (we don't handle wrap-around, for instance) */ + sprintf (id_str, ":1.%d", id++); + reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_STRING, &id_str, DBUS_TYPE_INVALID); + dbus_connection_send (bus, reply, NULL); + dbus_connection_flush (bus); + dbus_message_unref (reply); + g_free (id_str); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult handle_properties (DBusConnection *bus, DBusMessage *message, DRoutePath *path, @@ -377,7 +417,7 @@ handle_properties (DBusConnection *bus, const gchar *member, const gchar *pathstr) { - DBusMessage *reply; + DBusMessage *reply = NULL; DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; if (!g_strcmp0(member, "GetAll")) @@ -432,10 +472,23 @@ handle_introspection (DBusConnection *bus, g_string_append_printf(output, introspection_node_element, pathstr); - for (i=0; i < path->introspection->len; i++) + if (!path->get_datum || path_get_datum (path, pathstr)) { - gchar *introspect = (gchar *) g_ptr_array_index (path->introspection, i); - g_string_append (output, introspect); + for (i=0; i < path->introspection->len; i++) + { + gchar *introspect = (gchar *) g_ptr_array_index (path->introspection, i); + g_string_append (output, introspect); + } + } + + if (path->introspect_children_cb) + { + gchar *children = (*path->introspect_children_cb) (pathstr, path->introspect_children_data); + if (children) + { + g_string_append (output, children); + g_free (children); + } } g_string_append(output, introspection_footer); @@ -485,16 +538,15 @@ handle_other (DBusConnection *bus, else reply = (func) (bus, message, datum); - if (!reply) + /* All D-Bus method calls must have a reply. + * If one is not provided presume that the caller has already + * sent one. + */ + if (reply) { - /* All D-Bus method calls must have a reply. - * If one is not provided presume that the call has a void - * return and no error has occured. - */ - reply = dbus_message_new_method_return (message); + dbus_connection_send (bus, reply, NULL); + dbus_message_unref (reply); } - dbus_connection_send (bus, reply, NULL); - dbus_message_unref (reply); result = DBUS_HANDLER_RESULT_HANDLED; } @@ -524,7 +576,9 @@ handle_message (DBusConnection *bus, DBusMessage *message, void *user_data) iface == NULL) return result; - if (!strcmp (iface, "org.freedesktop.DBus.Properties")) + if (!strcmp (pathstr, DBUS_PATH_DBUS)) + result = handle_dbus (bus, message, iface, member, pathstr); + else if (!strcmp (iface, "org.freedesktop.DBus.Properties")) result = handle_properties (bus, message, path, iface, member, pathstr); else if (!strcmp (iface, "org.freedesktop.DBus.Introspectable")) result = handle_introspection (bus, message, path, iface, member, pathstr); @@ -552,9 +606,15 @@ droute_object_does_not_exist_error (DBusMessage *message) dbus_message_get_signature (message), dbus_message_get_interface (message), dbus_message_get_path (message)); +#ifdef DBUS_ERROR_UNKNOWN_OBJECT + reply = dbus_message_new_error (message, + DBUS_ERROR_UNKNOWN_OBJECT, + errmsg); +#else reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, errmsg); +#endif g_free (errmsg); return reply; } @@ -615,4 +675,54 @@ droute_invalid_arguments_error (DBusMessage *message) return reply; } +void +droute_path_register (DRoutePath *path, DBusConnection *bus) +{ + if (path->prefix) + dbus_connection_register_fallback (bus, path->path, &droute_vtable, path); + else + dbus_connection_register_object_path (bus, path->path, + &droute_vtable, path); +} + +void +droute_path_unregister (DRoutePath *path, DBusConnection *bus) +{ + dbus_connection_unregister_object_path (bus, path->path); +} + +void +droute_context_register (DRouteContext *cnx, DBusConnection *bus) +{ + g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_register, + bus); +} + +void +droute_context_unregister (DRouteContext *cnx, DBusConnection *bus) +{ + g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_unregister, + bus); +} + +void +droute_context_deregister (DRouteContext *cnx, DBusConnection *bus) +{ + g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_unregister, + bus); +} + +void +droute_intercept_dbus (DBusConnection *bus) +{ + dbus_connection_register_object_path (bus, DBUS_PATH_DBUS, + &droute_vtable, NULL); +} + +void +droute_unintercept_dbus (DBusConnection *bus) +{ + dbus_connection_unregister_object_path (bus, DBUS_PATH_DBUS); +} + /*END------------------------------------------------------------------------*/