Back to index

unity  6.0.0
test_service_hud.c
Go to the documentation of this file.
00001 #include "test_service_hud.h"
00002 #include <unity.h>
00003 #include <gio/gio.h>
00004 
00005 const char * hud_interface = 
00006 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00007 "<node name=\"/\">\n"
00008 "        <interface name=\"com.canonical.hud\">\n"
00009 "<!-- Properties -->\n"
00010 "                <!-- None -->\n"
00011 "\n"
00012 "<!-- Functions -->\n"
00013 "                <method name=\"StartQuery\">\n"
00014 "                        <!-- in -->\n"
00015 "                        <arg type=\"s\" name=\"query\" direction=\"in\" />\n"
00016 "                        <arg type=\"i\" name=\"entries\" direction=\"in\" />\n"
00017 "                        <!-- out -->\n"
00018 "                        <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
00019 "                        <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n"
00020 "                        <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n"
00021 "                </method>\n"
00022 "\n"
00023 "                <method name=\"ExecuteQuery\">\n"
00024 "                        <arg type=\"v\" name=\"key\" direction=\"in\" />\n"
00025 "                        <arg type=\"u\" name=\"timestamp\" direction=\"in\" />\n"
00026 "                </method>\n"
00027 "\n"
00028 "                <method name=\"CloseQuery\">\n"
00029 "                        <arg type=\"v\" name=\"querykey\" direction=\"in\" />\n"
00030 "                </method>\n"
00031 "\n"
00032 "<!-- Signals -->\n"
00033 "                <signal name=\"UpdatedQuery\">\n"
00034 "                        <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
00035 "                        <arg type=\"a(sssssv)\" name=\"suggestions\" direction=\"out\" />\n"
00036 "                        <arg type=\"v\" name=\"querykey\" direction=\"out\" />\n"
00037 "                </signal>\n"
00038 "\n"
00039 "<!-- End of interesting stuff -->\n"
00040 "\n"
00041 "        </interface>\n"
00042 "</node>\n"
00043 ;
00044 static void bus_got_cb          (GObject *object, GAsyncResult * res, gpointer user_data);
00045 static void bus_method          (GDBusConnection *connection,
00046                                 const gchar *sender,
00047                                 const gchar *object_path,
00048                                 const gchar *interface_name,
00049                                 const gchar *method_name,
00050                                 GVariant *parameters,
00051                                 GDBusMethodInvocation *invocation,
00052                                 gpointer user_data);
00053 
00054 static gboolean                 do_emit_signal(gpointer data);
00055 static void                     emit_signal(GDBusConnection *connection);
00056 
00057 
00058 G_DEFINE_TYPE(ServiceHud, service_hud, G_TYPE_OBJECT);
00059 static GDBusNodeInfo * node_info = NULL;
00060 static GDBusInterfaceInfo * iface_info = NULL;
00061 static GDBusInterfaceVTable bus_vtable = {
00062   method_call: bus_method,
00063   get_property: NULL,
00064   set_property: NULL,
00065 };
00066 
00067 struct _ServiceHudPrivate
00068 {
00069   GDBusConnection * bus;
00070   GCancellable * bus_lookup;
00071   guint bus_registration;
00072   guint sig_emission_handle;
00073 };
00074 
00075 static void
00076 service_hud_dispose(GObject* object)
00077 {
00078   ServiceHud* self = SERVICE_HUD(object);
00079   if (self->priv->bus_lookup != NULL) {
00080     g_cancellable_cancel(self->priv->bus_lookup);
00081     g_object_unref(self->priv->bus_lookup);
00082     self->priv->bus_lookup = NULL;
00083   }
00084 
00085   if (self->priv->bus_registration != 0) {
00086     g_dbus_connection_unregister_object(self->priv->bus, self->priv->bus_registration);
00087     self->priv->bus_registration = 0;
00088   }
00089 
00090   if (self->priv->bus != NULL) {
00091     g_object_unref(self->priv->bus);
00092     self->priv->bus = NULL;
00093   }
00094 
00095   if (self->priv->sig_emission_handle) {
00096     g_source_remove(self->priv->sig_emission_handle);
00097     self->priv->sig_emission_handle = 0;
00098   }
00099 
00100 }
00101 
00102 static void
00103 service_hud_class_init(ServiceHudClass* klass)
00104 {
00105   G_OBJECT_CLASS(klass)->dispose = service_hud_dispose;
00106   g_type_class_add_private (klass, sizeof (ServiceHudPrivate));
00107 
00108   if (node_info == NULL) 
00109   {
00110     GError * error = NULL;
00111 
00112     node_info = g_dbus_node_info_new_for_xml(hud_interface, &error);
00113     if (error != NULL) 
00114     {
00115         g_error("Unable to parse HUD interface: %s", error->message);
00116         g_error_free(error);
00117     }
00118   }
00119 
00120   if (node_info != NULL && iface_info == NULL) 
00121   {
00122     iface_info = g_dbus_node_info_lookup_interface(node_info,"com.canonical.hud");
00123     if (iface_info == NULL) 
00124     {
00125       g_error("Unable to find interface 'com.canonical.hud'");
00126     }
00127   }
00128 
00129 }
00130 
00131 static void
00132 service_hud_init(ServiceHud* self)
00133 {
00134   self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SERVICE_TYPE_HUD, ServiceHudPrivate);
00135   self->priv->bus = NULL;
00136   self->priv->bus_lookup = NULL;
00137   self->priv->bus_registration = 0;
00138   
00139   self->priv->bus_lookup = g_cancellable_new();
00140   g_bus_get(G_BUS_TYPE_SESSION, self->priv->bus_lookup, bus_got_cb, self);
00141 }
00142 
00143 ServiceHud*
00144 service_hud_new()
00145 {
00146   return g_object_new(SERVICE_TYPE_HUD, NULL);
00147 }
00148 
00149 static void
00150 bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data)
00151 {
00152   GError * error = NULL;
00153   ServiceHud * self = SERVICE_HUD(user_data);
00154   GDBusConnection * bus;
00155 
00156   bus = g_bus_get_finish(res, &error);
00157   if (error != NULL) {
00158     g_critical("Unable to get bus: %s", error->message);
00159     g_error_free(error);
00160     return;
00161   }
00162 
00163   self->priv->bus = bus;
00164 
00165   /* Register object */
00166   self->priv->bus_registration = g_dbus_connection_register_object(bus,
00167                                                   /* path */       "/com/canonical/hud",
00168                                                   /* interface */  iface_info,
00169                                                   /* vtable */     &bus_vtable,
00170                                                   /* userdata */   self,
00171                                                   /* destroy */    NULL,
00172                                                   /* error */      &error);
00173 
00174   if (error != NULL) {
00175     g_critical ("Unable to create bus connection object, %s", error->message);
00176     g_error_free(error);
00177     return;
00178   }
00179   else
00180   {
00181     self->priv->sig_emission_handle = g_timeout_add(1000, do_emit_signal, bus);
00182   }
00183   
00184   return;
00185 }
00186 
00187 static gboolean
00188 do_emit_signal(gpointer data)
00189 {
00190   emit_signal(G_DBUS_CONNECTION(data));
00191   return TRUE;
00192 }
00193 
00194 static void
00195 emit_signal(GDBusConnection *connection)
00196 {
00197   GVariant *query;
00198   int num_entries = 5;
00199 
00200   /* Build into into a variant */
00201   GVariantBuilder ret_builder;
00202   g_variant_builder_init(&ret_builder, G_VARIANT_TYPE_TUPLE);
00203   g_variant_builder_add_value(&ret_builder, g_variant_new_string("target"));
00204   GVariantBuilder builder;
00205   
00206   g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
00207    
00208   int i = 0;
00209   for (i = 0; i < num_entries; i++) 
00210   {
00211     gchar* target = g_strdup_printf("test-%i", i);
00212     gchar* icon = g_strdup_printf("icon-%i", i);
00213     gchar* future_icon = g_strdup(icon);
00214     gchar* completion_text = g_strdup_printf("completion-%i", i);
00215     gchar* accelerator = g_strdup_printf("<alt>+whatever");
00216 
00217     GVariantBuilder tuple;
00218     g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);
00219     g_variant_builder_add_value(&tuple, g_variant_new_string(target));
00220     g_variant_builder_add_value(&tuple, g_variant_new_string(icon));
00221     g_variant_builder_add_value(&tuple, g_variant_new_string(future_icon));
00222     g_variant_builder_add_value(&tuple, g_variant_new_string(completion_text));
00223     g_variant_builder_add_value(&tuple, g_variant_new_string(accelerator));
00224     // build a fake key
00225     GVariant* key;
00226     {
00227       GVariantBuilder keybuilder;
00228       g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
00229       g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00230       g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00231       g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00232       g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
00233 
00234       key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
00235     }
00236     g_variant_ref_sink(key);
00237     g_variant_builder_add_value(&tuple, key);
00238     g_variant_builder_add_value(&builder, g_variant_builder_end(&tuple));
00239     g_free(target);
00240     g_free(icon);
00241     g_free(future_icon);
00242     g_free(completion_text);
00243   }
00244   g_variant_builder_add_value(&ret_builder, g_variant_builder_end(&builder));
00245  
00246   GVariant* query_key;
00247   {
00248     GVariantBuilder keybuilder;
00249     g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
00250     g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00251     g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00252     g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00253     g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
00254 
00255     query_key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
00256   }
00257   g_variant_ref_sink(query_key);
00258   g_variant_builder_add_value(&ret_builder, query_key);
00259   
00260   query = g_variant_builder_end(&ret_builder);
00261   
00262   g_dbus_connection_emit_signal (connection, NULL, "/com/canonical/hud",
00263                                  "com.canonical.hud", "UpdatedQuery",
00264                                  query, NULL);
00265 }
00266 
00267 static void
00268 bus_method (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data)
00269 {
00270   if (g_strcmp0(method_name, "StartQuery") == 0) 
00271   {
00272     GVariant * ret = NULL;
00273     gchar * query = NULL;
00274     int num_entries = 0;
00275 
00276     g_variant_get(parameters, "(si)", &query, &num_entries);
00277 
00278     /* Build into into a variant */
00279     GVariantBuilder ret_builder;
00280     g_variant_builder_init(&ret_builder, G_VARIANT_TYPE_TUPLE);
00281     g_variant_builder_add_value(&ret_builder, g_variant_new_string("target"));
00282     GVariantBuilder builder;
00283     
00284     g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
00285      
00286     int i = 0;
00287     for (i = 0; i < num_entries; i++) 
00288     {
00289       gchar* target = g_strdup_printf("test-%i", i);
00290       gchar* icon = g_strdup_printf("icon-%i", i);
00291       gchar* future_icon = g_strdup(icon);
00292       gchar* completion_text = g_strdup_printf("completion-%i", i);
00293       gchar* accelerator = g_strdup_printf("<alt>+whatever");
00294 
00295       GVariantBuilder tuple;
00296       g_variant_builder_init(&tuple, G_VARIANT_TYPE_TUPLE);
00297       g_variant_builder_add_value(&tuple, g_variant_new_string(target));
00298       g_variant_builder_add_value(&tuple, g_variant_new_string(icon));
00299       g_variant_builder_add_value(&tuple, g_variant_new_string(future_icon));
00300       g_variant_builder_add_value(&tuple, g_variant_new_string(completion_text));
00301       g_variant_builder_add_value(&tuple, g_variant_new_string(accelerator));
00302       // build a fake key
00303       GVariant* key;
00304       {
00305         GVariantBuilder keybuilder;
00306         g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
00307         g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00308         g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00309         g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00310         g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
00311 
00312         key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
00313       }
00314       g_variant_ref_sink(key);
00315       g_variant_builder_add_value(&tuple, key);
00316       g_variant_builder_add_value(&builder, g_variant_builder_end(&tuple));
00317       g_free(target);
00318       g_free(icon);
00319       g_free(future_icon);
00320       g_free(completion_text);
00321     }
00322     g_variant_builder_add_value(&ret_builder, g_variant_builder_end(&builder));
00323    
00324     GVariant* query_key;
00325     {
00326       GVariantBuilder keybuilder;
00327       g_variant_builder_init(&keybuilder, G_VARIANT_TYPE_TUPLE);
00328       g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00329       g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00330       g_variant_builder_add_value(&keybuilder, g_variant_new_string("dummy string"));
00331       g_variant_builder_add_value(&keybuilder, g_variant_new_int32(1986));
00332 
00333       query_key = g_variant_new_variant(g_variant_builder_end(&keybuilder));
00334     }
00335     g_variant_ref_sink(query_key);
00336     g_variant_builder_add_value(&ret_builder, query_key);
00337     
00338     ret = g_variant_builder_end(&ret_builder);
00339 
00340     g_dbus_method_invocation_return_value(invocation, ret);
00341     g_free(query);
00342   } 
00343   else if (g_strcmp0(method_name, "ExecuteQuery") == 0) 
00344   {
00345     GVariant * key = NULL;
00346     key = g_variant_get_child_value(parameters, 0);
00347     g_dbus_method_invocation_return_value(invocation, NULL);
00348     g_variant_unref(key);
00349   }
00350   else if (g_strcmp0(method_name, "CloseQuery") == 0)
00351   {
00352     GVariant * key = NULL;
00353     key = g_variant_get_child_value(parameters, 0);
00354     g_dbus_method_invocation_return_value(invocation, NULL);
00355     g_variant_unref(key);
00356   }
00357 
00358   return;
00359 }
00360