From 21a73df1b5a7e2ace06a1e252ab019392692d21b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 21 Jun 2005 01:18:25 +0000 Subject: 2005-06-20 Colin Walters * configure.in: Add glib/examples. * glib/Makefile.am: Add examples/ * glib/examples/.cvsignore * glib/examples/Makefile.am * glib/examples/example-client.c * glib/examples/example-service.c * glib/examples/example-service.xml * glib/examples/example-signal-emitter.c * glib/examples/example-signal-emitter.xml * glib/examples/example-signal-recipient.c: New files; GLib binding examples, ported from python/examples. --- ChangeLog | 17 ++++ configure.in | 1 + glib/Makefile.am | 2 + glib/examples/.cvsignore | 17 ++++ glib/examples/Makefile.am | 34 ++++++++ glib/examples/example-client.c | 107 ++++++++++++++++++++++++ glib/examples/example-service.c | 138 +++++++++++++++++++++++++++++++ glib/examples/example-service.xml | 19 +++++ glib/examples/example-signal-emitter.c | 132 +++++++++++++++++++++++++++++ glib/examples/example-signal-emitter.xml | 13 +++ glib/examples/example-signal-recipient.c | 103 +++++++++++++++++++++++ 11 files changed, 583 insertions(+) create mode 100644 glib/examples/.cvsignore create mode 100644 glib/examples/Makefile.am create mode 100644 glib/examples/example-client.c create mode 100644 glib/examples/example-service.c create mode 100644 glib/examples/example-service.xml create mode 100644 glib/examples/example-signal-emitter.c create mode 100644 glib/examples/example-signal-emitter.xml create mode 100644 glib/examples/example-signal-recipient.c diff --git a/ChangeLog b/ChangeLog index 6479d73f..ec5b247c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-06-20 Colin Walters + + * configure.in: Add glib/examples. + + * glib/Makefile.am: Add examples/ + + * glib/examples/.cvsignore + * glib/examples/Makefile.am + * glib/examples/example-client.c + * glib/examples/example-service.c + * glib/examples/example-service.xml + * glib/examples/example-signal-emitter.c + * glib/examples/example-signal-emitter.xml + * glib/examples/example-signal-recipient.c: + New files; GLib binding examples, ported from + python/examples. + 2005-06-20 Colin Walters * dbus/dbus-glib.h: diff --git a/configure.in b/configure.in index be728913..228feb0d 100644 --- a/configure.in +++ b/configure.in @@ -1260,6 +1260,7 @@ bus/dbus-daemon.1 Makefile dbus/Makefile glib/Makefile +glib/examples/Makefile python/Makefile python/examples/Makefile qt/Makefile diff --git a/glib/Makefile.am b/glib/Makefile.am index ecd20d56..962cd6f3 100644 --- a/glib/Makefile.am +++ b/glib/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = . examples + INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_GLIB_TOOL_CFLAGS) -DDBUS_COMPILATION=1 -DDBUS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" lib_LTLIBRARIES=libdbus-glib-1.la diff --git a/glib/examples/.cvsignore b/glib/examples/.cvsignore new file mode 100644 index 00000000..fc6a0634 --- /dev/null +++ b/glib/examples/.cvsignore @@ -0,0 +1,17 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la +example-client +example-service +example-service-glue.h +example-signal-recipient +example-signal-emitter +example-signal-emitter-glue.h +run-with-tmp-session-bus.conf +*.bb +*.bbg +*.da +*.gcov diff --git a/glib/examples/Makefile.am b/glib/examples/Makefile.am new file mode 100644 index 00000000..2ba133e6 --- /dev/null +++ b/glib/examples/Makefile.am @@ -0,0 +1,34 @@ +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) -DDBUS_COMPILATION + +## Makefile.am bits for sample client/server pair + +noinst_PROGRAMS= example-client example-service + +example_client_SOURCES= example-client.c +example_client_LDADD= $(top_builddir)/glib/libdbus-glib-1.la + +example_service_SOURCES= example-service.c +example_service_LDADD= $(top_builddir)/glib/libdbus-glib-1.la + +BUILT_SOURCES = example-service-glue.h + +example-service-glue.h: example-service.xml + $(top_builddir)/glib/dbus-binding-tool --prefix=some_object --mode=glib-server --output=example-service-glue.h $(srcdir)/example-service.xml + + +## Makefile.am bits for another client/server pair + +noinst_PROGRAMS += example-signal-recipient example-signal-emitter + +example_signal_recipient_SOURCES=_SOURCES= example-signal-recipient.c +example_signal_recipient_LDADD= $(top_builddir)/glib/libdbus-glib-1.la + +example_signal_emitter_SOURCES= example-signal-emitter.c +example_signal_emitter_LDADD= $(top_builddir)/glib/libdbus-glib-1.la + +BUILT_SOURCES += example-signal-emitter-glue.h + +example-signal-emitter-glue.h: example-signal-emitter.xml + $(top_builddir)/glib/dbus-binding-tool --prefix=test_object --mode=glib-server --output=example-signal-emitter-glue.h $(srcdir)/example-signal-emitter.xml + +CLEANFILES = $(BUILT_SOURCES) diff --git a/glib/examples/example-client.c b/glib/examples/example-client.c new file mode 100644 index 00000000..fb157a75 --- /dev/null +++ b/glib/examples/example-client.c @@ -0,0 +1,107 @@ +#include +#include +#include + +static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); +static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; + +static void +lose (const char *str, ...) +{ + va_list args; + + va_start (args, str); + + vfprintf (stderr, str, args); + fputc ('\n', stderr); + + va_end (args); + + exit (1); +} + +static void +lose_gerror (const char *prefix, GError *error) +{ + lose ("%s: %s", prefix, error->message); +} + +static void +print_hash_value (gpointer key, gpointer val, gpointer data) +{ + printf ("%s -> %s\n", (char *) key, (char *) val); +} + +int +main (int argc, char **argv) +{ + DBusGConnection *bus; + DBusGProxy *remote_object; + DBusGProxy *remote_object_introspectable; + GError *error = NULL; + char **reply_list; + char **reply_ptr; + DBusGValue *hello_reply_struct; + GHashTable *hello_reply_dict; + char *introspect_data; + + g_type_init (); + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) + lose_gerror ("Couldn't connect to session bus", error); + + remote_object = dbus_g_proxy_new_for_name (bus, + "org.designfu.SampleService", + "/SomeObject", + "org.designfu.SampleInterface"); + + if (!dbus_g_proxy_call (remote_object, "HelloWorld", &error, + G_TYPE_STRING, "Hello from example-client.c!", G_TYPE_INVALID, + G_TYPE_STRV, &reply_list, G_TYPE_INVALID)) + lose_gerror ("Failed to complete HelloWorld", error); + + + /* FIXME - we don't support recursive values yet */ +#if 0 + if (!dbus_g_proxy_call (remote_object, "GetTuple", &error, + DBUS_TYPE_G_VALUE, &hello_reply_struct, G_TYPE_INVALID)) + lose_gerror ("Failed to complete GetTuple", error); +#endif + + if (!dbus_g_proxy_call (remote_object, "GetDict", &error, + G_TYPE_INVALID, + DBUS_TYPE_G_STRING_STRING_HASHTABLE, &hello_reply_dict, G_TYPE_INVALID)) + lose_gerror ("Failed to complete GetDict", error); + + printf ("reply_list: "); + for (reply_ptr = reply_list; *reply_ptr; reply_ptr++) + printf ("\"%s\" ", *reply_ptr); + printf ("\n"); + g_strfreev (reply_list); + + /* FIXME; do something with hello_reply_struct */ +#if 0 + dbus_g_value_free (hello_reply_struct); + printf ("\n"); +#endif + + g_hash_table_foreach (hello_reply_dict, print_hash_value, NULL); + g_hash_table_destroy (hello_reply_dict); + + remote_object_introspectable = dbus_g_proxy_new_for_name (bus, + "org.designfu.SampleService", + "/SomeObject", + "org.freedesktop.DBus.Introspectable"); + if (!dbus_g_proxy_call (remote_object_introspectable, "Introspect", &error, + G_TYPE_INVALID, + G_TYPE_STRING, &introspect_data, G_TYPE_INVALID)) + lose_gerror ("Failed to complete Introspect", error); + printf ("%s", introspect_data); + g_free (introspect_data); + + g_object_unref (G_OBJECT (remote_object_introspectable)); + g_object_unref (G_OBJECT (remote_object)); + + exit(0); +} diff --git a/glib/examples/example-service.c b/glib/examples/example-service.c new file mode 100644 index 00000000..0ad700cd --- /dev/null +++ b/glib/examples/example-service.c @@ -0,0 +1,138 @@ +#include +#include +#include + +static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); +static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; + +static void +lose (const char *str, ...) +{ + va_list args; + + va_start (args, str); + + vfprintf (stderr, str, args); + fputc ('\n', stderr); + + va_end (args); + + exit (1); +} + +static void +lose_gerror (const char *prefix, GError *error) +{ + lose ("%s: %s", prefix, error->message); +} + +typedef struct SomeObject SomeObject; +typedef struct SomeObjectClass SomeObjectClass; + +GType some_object_get_type (void); + +struct SomeObject +{ + GObject parent; +}; + +struct SomeObjectClass +{ + GObjectClass parent; +}; + +#define SOME_TYPE_OBJECT (some_object_get_type ()) +#define SOME_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SOME_TYPE_OBJECT, SomeObject)) +#define SOME_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOME_TYPE_OBJECT, SomeObjectClass)) +#define SOME_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOME_TYPE_OBJECT)) +#define SOME_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOME_TYPE_OBJECT)) +#define SOME_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOME_TYPE_OBJECT, SomeObjectClass)) + +G_DEFINE_TYPE(SomeObject, some_object, G_TYPE_OBJECT) + +gboolean some_object_hello_world (SomeObject *obj, const char *hello_message, char ***ret, GError **error); +gboolean some_object_get_tuple (SomeObject *obj, DBusGValue **ret, GError **error); +gboolean some_object_get_dict (SomeObject *obj, GHashTable **ret, GError **error); + +#include "example-service-glue.h" + +static void +some_object_init (SomeObject *obj) +{ +} + +static void +some_object_class_init (SomeObjectClass *klass) +{ +} + +gboolean +some_object_hello_world (SomeObject *obj, const char *hello_message, char ***ret, GError **error) +{ + printf ("%s\n", hello_message); + *ret = g_new (char *, 3); + (*ret)[0] = g_strdup ("Hello"); + (*ret)[1] = g_strdup (" from example-service.c"); + (*ret)[2] = NULL; + + return TRUE; +} + +gboolean +some_object_get_tuple (SomeObject *obj, DBusGValue **ret, GError **error) +{ + /* FIXME */ + return TRUE; +} + +gboolean +some_object_get_dict (SomeObject *obj, GHashTable **ret, GError **error) +{ + *ret = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (*ret, "first", "Hello Dict"); + g_hash_table_insert (*ret, "second", " from example-service.c"); + return TRUE; +} + +int +main (int argc, char **argv) +{ + DBusGConnection *bus; + DBusGProxy *bus_proxy; + GError *error = NULL; + SomeObject *obj; + GMainLoop *mainloop; + guint request_name_result; + + g_type_init (); + + mainloop = g_main_loop_new (NULL, FALSE); + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) + lose_gerror ("Couldn't connect to session bus", error); + + bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); + + if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error, + G_TYPE_STRING, "org.designfu.SampleService", + G_TYPE_UINT, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, + G_TYPE_INVALID, + G_TYPE_UINT, &request_name_result, + G_TYPE_INVALID)) + lose_gerror ("Failed to acquire org.designfu.SampleService", error); + + obj = g_object_new (SOME_TYPE_OBJECT, NULL); + + dbus_g_object_type_install_info (SOME_TYPE_OBJECT, &dbus_glib_some_object_object_info); + + dbus_g_connection_register_g_object (bus, "/SomeObject", G_OBJECT (obj)); + + printf ("service running\n"); + + g_main_loop_run (mainloop); + + exit (0); +} diff --git a/glib/examples/example-service.xml b/glib/examples/example-service.xml new file mode 100644 index 00000000..9c39bb05 --- /dev/null +++ b/glib/examples/example-service.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/glib/examples/example-signal-emitter.c b/glib/examples/example-signal-emitter.c new file mode 100644 index 00000000..13b9c9f7 --- /dev/null +++ b/glib/examples/example-signal-emitter.c @@ -0,0 +1,132 @@ +#include +#include +#include + +static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); +static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; + +static void +lose (const char *str, ...) +{ + va_list args; + + va_start (args, str); + + vfprintf (stderr, str, args); + fputc ('\n', stderr); + + va_end (args); + + exit (1); +} + +static void +lose_gerror (const char *prefix, GError *error) +{ + lose ("%s: %s", prefix, error->message); +} + +typedef struct TestObject TestObject; +typedef struct TestObjectClass TestObjectClass; + +GType test_object_get_type (void); + +struct TestObject +{ + GObject parent; +}; + +struct TestObjectClass +{ + GObjectClass parent; +}; + +enum +{ + HELLO_SIGNAL, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +#define TEST_TYPE_OBJECT (test_object_get_type ()) +#define TEST_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject)) +#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) +#define TEST_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT)) +#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass)) + +G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT) + +gboolean test_object_emit_hello_signal (TestObject *obj, GError **error); + +#include "example-signal-emitter-glue.h" + +static void +test_object_init (TestObject *obj) +{ +} + +static void +test_object_class_init (TestObjectClass *klass) +{ + signals[HELLO_SIGNAL] = + g_signal_new ("hello_signal", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); +} + +gboolean +test_object_emit_hello_signal (TestObject *obj, GError **error) +{ + g_signal_emit (obj, signals[HELLO_SIGNAL], 0, "Hello"); + return TRUE; +} + + +int +main (int argc, char **argv) +{ + DBusGConnection *bus; + DBusGProxy *bus_proxy; + GError *error = NULL; + TestObject *obj; + GMainLoop *mainloop; + guint request_name_result; + + g_type_init (); + + mainloop = g_main_loop_new (NULL, FALSE); + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) + lose_gerror ("Couldn't connect to session bus", error); + + bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); + + if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error, + G_TYPE_STRING, "org.designfu.TestService", + G_TYPE_UINT, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, + G_TYPE_INVALID, + G_TYPE_UINT, &request_name_result, + G_TYPE_INVALID)) + lose_gerror ("Failed to acquire org.designfu.TestService", error); + + obj = g_object_new (TEST_TYPE_OBJECT, NULL); + + dbus_g_object_type_install_info (TEST_TYPE_OBJECT, &dbus_glib_test_object_object_info); + + dbus_g_connection_register_g_object (bus, "/org/designfu/TestService/object", G_OBJECT (obj)); + + printf ("test service running\n"); + + g_main_loop_run (mainloop); + + exit (0); +} diff --git a/glib/examples/example-signal-emitter.xml b/glib/examples/example-signal-emitter.xml new file mode 100644 index 00000000..ae178e3b --- /dev/null +++ b/glib/examples/example-signal-emitter.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/glib/examples/example-signal-recipient.c b/glib/examples/example-signal-recipient.c new file mode 100644 index 00000000..30fa1502 --- /dev/null +++ b/glib/examples/example-signal-recipient.c @@ -0,0 +1,103 @@ +#include +#include +#include + +static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); +static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; + +static void +lose (const char *str, ...) +{ + va_list args; + + va_start (args, str); + + vfprintf (stderr, str, args); + fputc ('\n', stderr); + + va_end (args); + + exit (1); +} + +static void +lose_gerror (const char *prefix, GError *error) +{ + lose ("%s: %s", prefix, error->message); +} + +static gboolean +emit_signal (gpointer arg) +{ + DBusGProxy *proxy = arg; + + dbus_g_proxy_call_no_reply (proxy, "emitHelloSignal", G_TYPE_INVALID); + return TRUE; +} + +static void +hello_signal_handler (DBusGProxy *proxy, const char *hello_string, gpointer user_data) +{ + printf ("Received signal and it says: %s\n", hello_string); +} + +int +main (int argc, char **argv) +{ + DBusGConnection *bus; + DBusGProxy *remote_object; + GError *error = NULL; + GMainLoop *mainloop; + + g_type_init (); + + mainloop = g_main_loop_new (NULL, FALSE); + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) + lose_gerror ("Couldn't connect to session bus", error); + + /* We use _for_name_owner in order to track this particular service + * instance, which lets us receive signals. + */ + remote_object = dbus_g_proxy_new_for_name_owner (bus, + "org.designfu.TestService", + "/org/designfu/TestService/object", + "org.designfu.TestService", + &error); + if (!remote_object) + lose_gerror ("Failed to get name owner", error); + + /* IMPORTANT: + * + * Note because this signal's signature is VOID__STRING, we do not + * need to register a marshaller, since there is a builtin one. + * However for other signatures, you must generate a marshaller, + * then call dbus_g_object_register_marshaller. It would look like + * this: + * + * dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID); + * + */ + + /* Tell DBus what the type signature of the signal callback is; this + * allows us to sanity-check incoming messages before invoking the + * callback. You need to do this once for each proxy you create, + * not every time you want to connect to the signal. + */ + dbus_g_proxy_add_signal (remote_object, "HelloSignal", G_TYPE_STRING, G_TYPE_INVALID); + + /* Actually connect to the signal. Note you can call + * dbus_g_proxy_connect_signal multiple times for one invocation of + * dbus_g_proxy_add_signal. + */ + dbus_g_proxy_connect_signal (remote_object, "HelloSignal", G_CALLBACK (hello_signal_handler), + NULL, NULL); + + + g_timeout_add (2000, emit_signal, remote_object); + + g_main_loop_run (mainloop); + + exit (0); +} -- cgit