statemachine-server.c

00001 #include <dbus/dbus-glib.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 
00005 #include "statemachine.h"
00006 #include "sm-marshal.h"
00007 #include "statemachine-server.h"
00008 
00009 enum
00010 {
00011   PROP_O,
00012   PROP_BUS
00013 };
00014 
00015 enum
00016 {
00017   MACHINE_CREATED,
00018   LAST_SIGNAL
00019 };
00020 
00021 static guint sm_server_signals[LAST_SIGNAL] = { 0 };
00022 
00023 static void     sm_server_set_property       (GObject               *object,
00024                                               guint                  prop_id,
00025                                               const GValue          *value,
00026                                               GParamSpec            *pspec);
00027 static void     sm_server_get_property       (GObject               *object,
00028                                               guint                  prop_id,
00029                                               GValue                *value,
00030                                               GParamSpec            *pspec);
00031 
00032 G_DEFINE_TYPE(SMServer, sm_server, G_TYPE_OBJECT)
00033 
00034 #include "statemachine-server-glue.h"
00035 #include "statemachine-glue.h"
00036 
00037 static void
00038 sm_server_init (SMServer *obj)
00039 {
00040   obj->machines = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
00041 }
00042 
00043 static void
00044 sm_server_class_init (SMServerClass *klass)
00045 {
00046   GObjectClass *object_class = G_OBJECT_CLASS (klass);
00047 
00048   object_class->set_property = sm_server_set_property;
00049   object_class->get_property = sm_server_get_property;
00050 
00051   g_object_class_install_property (object_class,
00052                                    PROP_BUS,
00053                                    g_param_spec_boxed ("bus",
00054                                                        "bus",
00055                                                        "bus",
00056                                                        DBUS_TYPE_G_CONNECTION,
00057                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
00058 
00059   sm_server_signals[MACHINE_CREATED] =
00060     g_signal_new ("machine-created",
00061                   G_OBJECT_CLASS_TYPE (klass),
00062                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00063                   0,
00064                   NULL, NULL,
00065                   sm_marshal_VOID__STRING_BOXED,
00066                   G_TYPE_NONE, 2, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH);
00067 }
00068 
00069 static void
00070 sm_server_set_property (GObject *object,
00071                         guint prop_id,
00072                         const GValue *value,
00073                         GParamSpec *pspec)
00074 {
00075   SMServer *server = SM_SERVER (object);
00076 
00077   switch (prop_id)
00078     {
00079     case PROP_BUS:
00080       server->bus = g_value_get_boxed (value);
00081       break;
00082     default:
00083       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00084       break;
00085     }
00086 }
00087 
00088 static void 
00089 sm_server_get_property (GObject *object,
00090                         guint prop_id,
00091                         GValue *value,
00092                         GParamSpec *pspec)
00093 {
00094   SMServer *server = SM_SERVER (object);
00095 
00096   switch (prop_id)
00097     {
00098     case PROP_BUS:
00099       g_value_set_boxed (value, server->bus);
00100       break;
00101     default:
00102       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00103       break;
00104     }
00105 }
00106 
00107 static void
00108 machine_state_changed_cb (SMObject *obj, const char *state, gpointer data)
00109 {
00110   char *name;
00111 
00112   g_object_get (obj, "name", &name, NULL);
00113   g_print ("Machine %s switching to state %s\n", name, state);
00114   g_free (name);
00115 }
00116 
00117 static void
00118 machine_acquisition_changed_cb (SMObject *obj, gdouble progress, gpointer data)
00119 {
00120   char *name;
00121 
00122   g_object_get (obj, "name", &name, NULL);
00123   g_print ("Machine %s got progress %f\n", name, progress);
00124   g_free (name);
00125 }
00126 
00127 gboolean
00128 sm_server_create_machine (SMServer *server, const char *name, GError **error)
00129 {
00130   SMObject *machine;
00131   char *path;
00132 
00133   machine = g_hash_table_lookup (server->machines, name);
00134   if (machine != NULL)
00135     {
00136       g_set_error (error,
00137                    SM_ERROR,
00138                    SM_ERROR_NAME_IN_USE,
00139                    "Statemachine name \"%s\" is already in use",
00140                    name);
00141       return FALSE;
00142     }
00143 
00144   machine = g_object_new (SM_TYPE_OBJECT, "name", name, NULL);
00145 
00146   path = g_strdup_printf ("/com/example/StateMachines/%s", name);
00147   dbus_g_connection_register_g_object (server->bus, path, G_OBJECT (machine));
00148 
00149   g_hash_table_insert (server->machines, g_strdup (name), machine);
00150 
00151   g_print ("Created state machine with name %s at %s\n", name, path);
00152 
00153   g_signal_connect_object (machine, "state-changed",
00154                            G_CALLBACK (machine_state_changed_cb),
00155                            NULL, 0);
00156   g_signal_connect_object (machine, "acquisition-progress",
00157                            G_CALLBACK (machine_acquisition_changed_cb),
00158                            NULL, 0);
00159 
00160   g_signal_emit (server, sm_server_signals[MACHINE_CREATED], 0, name, path);
00161   
00162   return TRUE;
00163 }
00164 
00165 static void
00166 add_machine_to_ptr_array (gpointer key, gpointer val, gpointer data)
00167 {
00168   const char *name = key;
00169   /* SMObject *sm = val; */
00170   GPtrArray *ptrarray = data;
00171   
00172   g_ptr_array_add (ptrarray, g_strdup_printf ("/com/example/StateMachines/%s",
00173                                               name));
00174 }
00175 
00176 gboolean
00177 sm_server_get_machines (SMServer *server, GPtrArray **machines, GError **error)
00178 {
00179   *machines = g_ptr_array_new ();
00180 
00181   g_hash_table_foreach (server->machines, add_machine_to_ptr_array, *machines);
00182 
00183   return TRUE;
00184 }
00185 
00186 int
00187 main (int argc, char **argv)
00188 {
00189   DBusGConnection *bus;
00190   DBusGProxy *bus_proxy;
00191   GError *error = NULL;
00192   SMServer *server;
00193   GMainLoop *mainloop;
00194   guint request_name_result;
00195 
00196   g_type_init ();
00197   
00198   dbus_g_object_type_install_info (SM_TYPE_SERVER, &dbus_glib_sm_server_object_info);
00199   dbus_g_object_type_install_info (SM_TYPE_OBJECT, &dbus_glib_sm_object_object_info);
00200   dbus_g_error_domain_register (SM_ERROR, NULL, SM_TYPE_ERROR);
00201 
00202   mainloop = g_main_loop_new (NULL, FALSE);
00203 
00204   bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
00205   if (!bus)
00206     g_critical ("Couldn't connect to session bus: %s\n", error->message);
00207 
00208   bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus",
00209                                          "/org/freedesktop/DBus",
00210                                          "org.freedesktop.DBus");
00211 
00212   if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
00213                           G_TYPE_STRING, "com.example.StateServer",
00214                           G_TYPE_UINT, 0,
00215                           G_TYPE_INVALID,
00216                           G_TYPE_UINT, &request_name_result,
00217                           G_TYPE_INVALID))
00218     g_critical ("Couldn't acquire com.example.StateServer: %s\n", error->message);
00219 
00220   server = g_object_new (SM_TYPE_SERVER, "bus", bus, NULL);
00221 
00222   dbus_g_connection_register_g_object (bus, "/com/example/StateServer", G_OBJECT (server));
00223 
00224   g_print ("StateMachine server initialized\n");
00225 
00226   g_main_loop_run (mainloop);
00227 
00228   exit (0);
00229 }

Generated on Sat Dec 6 19:56:17 2008 for D-BUSGLibBindings by  doxygen 1.5.1