diff options
author | Mark Doffman <mdoff@silver-wind.(none)> | 2008-12-17 17:53:30 +0000 |
---|---|---|
committer | Mark Doffman <mdoff@silver-wind.(none)> | 2008-12-18 12:25:38 +0000 |
commit | 95ac4886d1b6649d54daffa7191be1b2bbaf2989 (patch) | |
tree | 7321b1777cd3601007548f99ac75047f21adc910 /droute | |
parent | b37f0b74994912dea13f33d63d3f1395554944b2 (diff) | |
download | at-spi2-atk-95ac4886d1b6649d54daffa7191be1b2bbaf2989.tar.gz |
2008-12-17 Mark Doffman <mark.doffman@codethink.co.uk>
Mega commit that changes droute, adding
an interface for creating a droute context
and registering single, or multiple objects
with the droute context. Modifies atk-adaptor
and registryd to use the new interface.
* droute/
New interface
* atk-adaptor
Use new droute interface
* registryd
Use new droute interface
* pyatspi
Bug fix, methods were using "null" interface.
Diffstat (limited to 'droute')
-rw-r--r-- | droute/Makefile.am | 15 | ||||
-rw-r--r-- | droute/droute-pairhash.c | 6 | ||||
-rw-r--r-- | droute/droute-test.c | 246 | ||||
-rw-r--r-- | droute/droute.c | 122 | ||||
-rw-r--r-- | droute/droute.h | 7 | ||||
-rw-r--r-- | droute/test.interface.One | 15 | ||||
-rw-r--r-- | droute/test.interface.Two | 15 |
7 files changed, 393 insertions, 33 deletions
diff --git a/droute/Makefile.am b/droute/Makefile.am index 46207e4..9ce04f1 100644 --- a/droute/Makefile.am +++ b/droute/Makefile.am @@ -17,3 +17,18 @@ libdroute_la_SOURCES =\ droute-variant.h\ droute-pairhash.c\ droute-pairhash.h + +TESTS = droute-test + +droute_test_CFLAGS = $(DBUS_GLIB_CFLAGS) \ + -I$(top_builddir) + +check_PROGRAMS = droute-test +droute_test_SOURCES = droute-test.c +droute_test_CPPFLAGS = $(DBUS_GLIB_CFLAGS) \ + -I$(top_builddir)\ + -DTEST_INTROSPECTION_DIRECTORY=\"$(top_srcdir)/droute\" + +droute_test_LDFLAGS = $(top_builddir)/dbind/libdbind.la\ + libdroute.la\ + $(DBUS_GLIB_LIBS) diff --git a/droute/droute-pairhash.c b/droute/droute-pairhash.c index 20ff491..0c4ace5 100644 --- a/droute/droute-pairhash.c +++ b/droute/droute-pairhash.c @@ -43,6 +43,7 @@ str_pair_new (const gchar *one, const gchar *two) pair = g_new (StrPair, 1); pair->one = one; pair->two = two; + return pair; } gint @@ -51,6 +52,11 @@ str_pair_hash (gconstpointer key) StrPair *pair = (StrPair *) key; guint hash = 0; + /*g_return_val_if_fail (pair != NULL, 0); + g_return_val_if_fail (pair->one != NULL, 0); + g_return_val_if_fail (pair->two != NULL, 0); + */ + if (*(pair->two) != '\0') { hash = *(pair->two); diff --git a/droute/droute-test.c b/droute/droute-test.c new file mode 100644 index 0000000..1895fb6 --- /dev/null +++ b/droute/droute-test.c @@ -0,0 +1,246 @@ +#include <stdio.h> +#include <glib.h> +#include <string.h> +#include <droute/droute.h> + +#include "dbus/dbus-glib-lowlevel.h" + +#define TEST_OBJECT_PATH "/test/object" +#define TEST_INTERFACE_ONE "test.interface.One" +#define TEST_INTERFACE_TWO "test.interface.Two" + +#define OBJECT_ONE "ObjectOne"; +#define OBJECT_TWO "ObjectTwo"; + +#if !defined TEST_INTROSPECTION_DIRECTORY + #error "No introspection XML directory defined" +#endif + +#define STRING_ONE "StringOne" +#define STRING_TWO "StringTwo" + +#define INT_ONE 0 +#define INT_TWO 456 + +#define NONE_REPLY_STRING "NoneMethod" + +typedef struct _AnObject +{ + gchar *astring; + guint *anint; +} AnObject; + +static DBusConnection *bus; +static GMainLoop *main_loop; +static gboolean success = TRUE; + +static DBusMessage * +impl_null (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + AnObject *object = (AnObject *) user_data; + DBusMessage *reply; + DBusError error; + + reply = dbus_message_new_method_return (message); + return reply; +} + +static DBusMessage * +impl_getInt (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + AnObject *object = (AnObject *) user_data; + DBusMessage *reply; + DBusError error; + + dbus_error_init (&error); + + reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_INT32, &(object->anint), DBUS_TYPE_INVALID); + return reply; +} + +static DBusMessage * +impl_setInt (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + AnObject *object = (AnObject *) user_data; + DBusMessage *reply; + DBusError error; + + dbus_error_init (&error); + + dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &(object->anint), DBUS_TYPE_INVALID); + + reply = dbus_message_new_method_return (message); + return reply; +} + +static DBusMessage * +impl_getString (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + AnObject *object = (AnObject *) user_data; + DBusMessage *reply; + DBusError error; + + dbus_error_init (&error); + + reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_STRING, &(object->astring), DBUS_TYPE_INVALID); + return reply; +} + +static DBusMessage * +impl_setString (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + AnObject *object = (AnObject *) user_data; + DBusMessage *reply; + DBusError error; + + dbus_error_init (&error); + + g_free (object->astring); + dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &(object->astring), DBUS_TYPE_INVALID); + + reply = dbus_message_new_method_return (message); + return reply; +} + +static DBusMessage * +impl_getInterfaceOne (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + AnObject *object = (AnObject *) user_data; + DBusMessage *reply; + DBusError error; + gchar *itf = TEST_INTERFACE_ONE; + + dbus_error_init (&error); + + reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_STRING, &itf, DBUS_TYPE_INVALID); + return reply; +} + +static DBusMessage * +impl_getInterfaceTwo (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + AnObject *object = (AnObject *) user_data; + DBusMessage *reply; + DBusError error; + gchar *itf = TEST_INTERFACE_TWO; + + dbus_error_init (&error); + + reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_STRING, &itf, DBUS_TYPE_INVALID); + return reply; +} + +static DRouteMethod test_methods_one[] = { + {impl_null, "null"}, + {impl_getInt, "getInt"}, + {impl_setInt, "setInt"}, + {impl_getString, "getString"}, + {impl_setString, "setString"}, + {impl_getInterfaceOne, "getInterfaceOne"}, + {NULL, NULL} +}; + +static DRouteMethod test_methods_two[] = { + {impl_null, "null"}, + {impl_getInt, "getInt"}, + {impl_setInt, "setInt"}, + {impl_getString, "getString"}, + {impl_setString, "setString"}, + {impl_getInterfaceTwo, "getInterfaceTwo"}, + {NULL, NULL} +}; + +static DRouteProperty test_properties[] = { + {NULL, NULL, NULL} +}; + +gboolean +do_tests_func (gpointer data) +{ + DBusError error; + gchar *bus_name; + + gchar *expected_string; + gchar *result_string; + + dbus_error_init (&error); + bus_name = dbus_bus_get_unique_name (bus); + + /* --------------------------------------------------------*/ + + dbind_method_call_reentrant (bus, + bus_name, + TEST_OBJECT_PATH, + TEST_INTERFACE_ONE, + "null", + NULL, + ""); + + /* --------------------------------------------------------*/ + + expected_string = TEST_INTERFACE_ONE; + result_string = NULL; + dbind_method_call_reentrant (bus, + bus_name, + TEST_OBJECT_PATH, + TEST_INTERFACE_ONE, + "getInterfaceOne", + NULL, + "=>s", + &result_string); + if (g_strcmp0(expected_string, result_string)) + { + g_print ("Failed: reply to getInterfaceOne not as expected\n"); + goto out; + } + + /* --------------------------------------------------------*/ + +out: + g_main_loop_quit (main_loop); + return FALSE; +} + + +int main (int argc, char **argv) +{ + DRouteContext *cnx; + DRoutePath *path; + AnObject *object; + DBusError error; + + /* Setup some server object */ + + object = g_new0(AnObject, 1); + object->astring = g_strdup (STRING_ONE); + object->anint = INT_ONE; + + dbus_error_init (&error); + main_loop = g_main_loop_new(NULL, FALSE); + bus = dbus_bus_get (DBUS_BUS_SESSION, &error); + dbus_connection_setup_with_g_main(bus, g_main_context_default()); + + cnx = droute_new (bus, TEST_INTROSPECTION_DIRECTORY); + path = droute_add_one (cnx, TEST_OBJECT_PATH, object); + + droute_path_add_interface (path, + TEST_INTERFACE_ONE, + test_methods_one, + test_properties); + + droute_path_add_interface (path, + TEST_INTERFACE_TWO, + test_methods_two, + test_properties); + + g_idle_add (do_tests_func, NULL); + g_main_run(main_loop); + if (success) + return 0; + else + return 1; +} diff --git a/droute/droute.c b/droute/droute.c index 5b1d9de..06ec2bd 100644 --- a/droute/droute.c +++ b/droute/droute.c @@ -31,6 +31,12 @@ #define oom() g_error ("D-Bus out of memory, this message will fail anyway") +#if defined DROUTE_DEBUG + #define _DROUTE_DEBUG(format, args...) g_print (format , ## args) +#else + #define _DROUTE_DEBUG +#endif + struct _DRouteContext { DBusConnection *bus; @@ -73,7 +79,7 @@ path_new (DRouteContext *cnx, { DRoutePath *new_path; - new_path = g_new0 (DRoutePath, 0); + new_path = g_new0 (DRoutePath, 1); new_path->cnx = cnx; new_path->chunks = g_string_chunk_new (CHUNKS_DEFAULT); new_path->interfaces = g_ptr_array_new (); @@ -128,13 +134,21 @@ droute_new (DBusConnection *bus, const char *introspect_dir) void droute_free (DRouteContext *cnx) { - g_pointer_array_foreach ((GFunc) path_free, cnx->registered_paths, NULL); + g_ptr_array_foreach (cnx->registered_paths, (GFunc) path_free, NULL); g_free (cnx->introspect_dir); g_free (cnx); } /*---------------------------------------------------------------------------*/ +DBusConnection * +droute_get_bus (DRouteContext *cnx) +{ + return cnx->bus; +} + +/*---------------------------------------------------------------------------*/ + static DBusObjectPathVTable droute_vtable = { NULL, @@ -185,12 +199,12 @@ droute_path_add_interface(DRoutePath *path, { gchar *itf; - g_return_if_fail (name == NULL); + g_return_if_fail (name != NULL); itf = g_string_chunk_insert (path->chunks, name); g_ptr_array_add (path->interfaces, itf); - for (; methods->name != NULL; methods++) + for (; methods != NULL && methods->name != NULL; methods++) { gchar *meth; @@ -198,7 +212,7 @@ droute_path_add_interface(DRoutePath *path, g_hash_table_insert (path->methods, str_pair_new (itf, meth), methods->func); } - for (; properties->name != NULL; properties++) + for (; properties != NULL && properties->name != NULL; properties++) { gchar *prop; PropertyPair *pair; @@ -233,7 +247,6 @@ impl_prop_GetAll (DBusMessage *message, void *datum = path_get_datum (path, pathstr); dbus_error_init (&error); - if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID)) return dbus_message_new_error (message, DBUS_ERROR_FAILED, error.message); @@ -250,7 +263,7 @@ impl_prop_GetAll (DBusMessage *message, g_hash_table_iter_init (&prop_iter, path->properties); while (g_hash_table_iter_next (&prop_iter, (gpointer*)&key, (gpointer*)&value)) { - if (!g_strcmp (key->one, iface)) + if (!g_strcmp0 (key->one, iface)) { if (!value->get) continue; @@ -280,8 +293,10 @@ impl_prop_GetSet (DBusMessage *message, DBusError error; StrPair pair; - PropertyPair *prop_funcs; + PropertyPair *prop_funcs = NULL; + + dbus_error_init (&error); if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, @@ -300,6 +315,8 @@ impl_prop_GetSet (DBusMessage *message, void *datum = path_get_datum (path, pathstr); DBusMessageIter iter; + _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr); + reply = dbus_message_new_method_return (message); dbus_message_iter_init_append (reply, &iter); (prop_funcs->get) (&iter, datum); @@ -309,12 +326,21 @@ impl_prop_GetSet (DBusMessage *message, void *datum = path_get_datum (path, pathstr); DBusMessageIter iter; + _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr); + dbus_message_iter_init_append (message, &iter); /* Skip the interface and property name */ dbus_message_iter_next(&iter); dbus_message_iter_next(&iter); - (prop_funcs->get) (&iter, datum); + (prop_funcs->set) (&iter, datum); + + reply = dbus_message_new_method_return (message); + } + else + { + reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, "Getter or setter unavailable"); } + return reply; } @@ -338,6 +364,12 @@ handle_properties (DBusConnection *bus, else result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + if (reply) + { + dbus_connection_send (bus, reply, NULL); + dbus_message_unref (reply); + } + return result; } @@ -357,32 +389,32 @@ append_interface (GString *str, const gchar *interface, const gchar *directory) { - gchar *filename; - gchar *contents; - gsize len; - - GError *err = NULL; - - filename = g_build_filename (directory, interface, NULL); - - if (g_file_get_contents (filename, &contents, &len, &err)) - { - g_string_append_len (str, contents, len); - } - else - { - g_warning ("AT-SPI: Cannot find introspection XML file %s - %s", - filename, err->message); - g_error_free (err); - } - - g_string_append (str, "\n"); - g_free (filename); - g_free (contents); + gchar *filename; + gchar *contents; + gsize len; + + GError *err = NULL; + + filename = g_build_filename (directory, interface, NULL); + + if (g_file_get_contents (filename, &contents, &len, &err)) + { + g_string_append_len (str, contents, len); + } + else + { + g_warning ("AT-SPI: Cannot find introspection XML file %s - %s", + filename, err->message); + g_error_free (err); + } + + g_string_append (str, "\n"); + g_free (filename); + g_free (contents); } static DBusHandlerResult -handle_intropsection (DBusConnection *bus, +handle_introspection (DBusConnection *bus, DBusMessage *message, DRoutePath *path, const gchar *iface, @@ -395,7 +427,9 @@ handle_intropsection (DBusConnection *bus, DBusMessage *reply; - if (g_strcmp (member, "Introspect")) + _DROUTE_DEBUG ("DRoute (handle introspection): %s\n", pathstr); + + if (g_strcmp0 (member, "Introspect")) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; output = g_string_new(introspection_header); @@ -442,6 +476,8 @@ handle_other (DBusConnection *bus, pair.one = iface; pair.two = member; + _DROUTE_DEBUG ("DRoute (handle other): %s|%s on %s\n", member, iface, pathstr); + func = (DRouteFunction) g_hash_table_lookup (path->methods, &pair); if (func != NULL) { @@ -485,4 +521,24 @@ handle_message (DBusConnection *bus, DBusMessage *message, void *user_data) return handle_other (bus, message, path, iface, member, pathstr); } +/*---------------------------------------------------------------------------*/ + +DBusMessage * +droute_not_yet_handled_error (DBusMessage *message) +{ + DBusMessage *reply; + gchar *errmsg; + + errmsg= g_strdup_printf ( + "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n", + dbus_message_get_member (message), + dbus_message_get_signature (message), + dbus_message_get_interface (message)); + reply = dbus_message_new_error (message, + DBUS_ERROR_UNKNOWN_METHOD, + errmsg); + g_free (errmsg); + return reply; +} + /*END------------------------------------------------------------------------*/ diff --git a/droute/droute.h b/droute/droute.h index 93de4f7..3943178 100644 --- a/droute/droute.h +++ b/droute/droute.h @@ -28,6 +28,7 @@ #include <droute/droute-variant.h> + typedef DBusMessage *(*DRouteFunction) (DBusConnection *, DBusMessage *, void *); typedef dbus_bool_t (*DRoutePropertyFunction) (DBusMessageIter *, void *); @@ -79,4 +80,10 @@ droute_path_add_interface (DRoutePath *path, const DRouteMethod *methods, const DRouteProperty *properties); +DBusMessage * +droute_not_yet_handled_error (DBusMessage *message); + +DBusConnection * +droute_get_bus (DRouteContext *cnx); + #endif /* _DROUTE_H */ diff --git a/droute/test.interface.One b/droute/test.interface.One new file mode 100644 index 0000000..a8e2206 --- /dev/null +++ b/droute/test.interface.One @@ -0,0 +1,15 @@ +<interface name="test.interface.One"> + <method name="null"/> + <method name="getInt"> + <arg direction="out" type="o"/> + </method> + <method name="setInt"> + <arg direction="in" type="o"/> + </method> + <method name="getString"> + <arg direction="out" type="s"/> + </method> + <method name="setString"> + <arg direction="in" type="s"/> + </method> +</interface> diff --git a/droute/test.interface.Two b/droute/test.interface.Two new file mode 100644 index 0000000..ca661ec --- /dev/null +++ b/droute/test.interface.Two @@ -0,0 +1,15 @@ +<interface name="test.interface.Two"> + <method name="null"/> + <method name="getInt"> + <arg direction="out" type="o"/> + </method> + <method name="setInt"> + <arg direction="in" type="o"/> + </method> + <method name="getString"> + <arg direction="out" type="s"/> + </method> + <method name="setString"> + <arg direction="in" type="s"/> + </method> +</interface> |