#include #include #include #include "statemachine.h" #include "sm-marshal.h" #include "statemachine-server.h" enum { PROP_O, PROP_BUS }; enum { MACHINE_CREATED, LAST_SIGNAL }; static guint sm_server_signals[LAST_SIGNAL] = { 0 }; static void sm_server_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void sm_server_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); G_DEFINE_TYPE(SMServer, sm_server, G_TYPE_OBJECT) #include "statemachine-server-glue.h" #include "statemachine-glue.h" static void sm_server_init (SMServer *obj) { obj->machines = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); } static void sm_server_class_init (SMServerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = sm_server_set_property; object_class->get_property = sm_server_get_property; g_object_class_install_property (object_class, PROP_BUS, g_param_spec_boxed ("bus", "bus", "bus", DBUS_TYPE_G_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); sm_server_signals[MACHINE_CREATED] = g_signal_new ("machine-created", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, sm_marshal_VOID__STRING_BOXED, G_TYPE_NONE, 2, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH); } static void sm_server_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { SMServer *server = SM_SERVER (object); switch (prop_id) { case PROP_BUS: server->bus = g_value_get_boxed (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void sm_server_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { SMServer *server = SM_SERVER (object); switch (prop_id) { case PROP_BUS: g_value_set_boxed (value, server->bus); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } gboolean sm_server_create_machine (SMServer *server, const char *name, GError **error) { SMObject *machine; char *path; machine = g_hash_table_lookup (server->machines, name); if (machine != NULL) { g_set_error (error, SM_ERROR, SM_ERROR_NAME_IN_USE, "Statemachine name \"%s\" is already in use", name); return FALSE; } machine = g_object_new (SM_TYPE_OBJECT, "name", name, NULL); path = g_strdup_printf ("/com/example/StateMachines/%s", name); dbus_g_connection_register_g_object (server->bus, path, G_OBJECT (machine)); g_hash_table_insert (server->machines, g_strdup (name), machine); g_print ("Created state machine with name %s at %s\n", name, path); g_signal_emit (server, sm_server_signals[MACHINE_CREATED], 0, name, path); return TRUE; } static void add_machine_to_ptr_array (gpointer key, gpointer val, gpointer data) { const char *name = key; /* SMObject *sm = val; */ GPtrArray *ptrarray = data; g_ptr_array_add (ptrarray, g_strdup_printf ("/com/example/StateMachines/%s", name)); } gboolean sm_server_get_machines (SMServer *server, GPtrArray **machines, GError **error) { *machines = g_ptr_array_new (); g_hash_table_foreach (server->machines, add_machine_to_ptr_array, *machines); return TRUE; } int main (int argc, char **argv) { DBusGConnection *bus; DBusGProxy *bus_proxy; GError *error = NULL; SMServer *server; GMainLoop *mainloop; guint request_name_result; g_type_init (); dbus_g_object_type_install_info (SM_TYPE_SERVER, &dbus_glib_sm_server_object_info); dbus_g_object_type_install_info (SM_TYPE_OBJECT, &dbus_glib_sm_object_object_info); dbus_g_error_domain_register (SM_ERROR, NULL, SM_TYPE_ERROR); mainloop = g_main_loop_new (NULL, FALSE); bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); if (!bus) g_critical ("Couldn't connect to session bus: %s\n", error->message); 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, "com.example.StateServer", G_TYPE_UINT, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, G_TYPE_INVALID, G_TYPE_UINT, &request_name_result, G_TYPE_INVALID)) g_critical ("Couldn't acquire com.example.StateServer: %s\n", error->message); server = g_object_new (SM_TYPE_SERVER, "bus", bus, NULL); dbus_g_connection_register_g_object (bus, "/com/example/StateServer", G_OBJECT (server)); g_print ("StateMachine server initialized\n"); g_main_loop_run (mainloop); exit (0); }