/** * Get information on one method (annotations, parameters, return * values, etc). * * TODO: * 1. Add missing documentation (see ????) * 2. Check to make sure that the second parameter is a string. (Also * do other error checking. See below.) * 3. Make sure that you get annotations for parameters and return * values (if they exist). * 4. Add tags for the other parts of the record (if they aren't * there already). For example, something like * '((name gimp_image_new) * (annotations "...") * (inputs (width integer "width of image")) * (outputs (image integer "id of created image"))) * If you'd prefer, input and output could also have their own * tags. * (inputs ((name width) (type integer) (annotations "width of image"))) * 5. Add a function to louDBus/unsafe that pretty prints this. * (If you'd prefer, you can add it to this file. But you can't * use printf to pretty print.) * 6. Add information for the garbage collector. (Yup, you'll need to * read really bad documentation on this. But try.) */ static Scheme_Object * loudbus_method_info (int argc, Scheme_Object **argv) { Scheme_Object *val, *val2; // ???? Scheme_Object *result = NULL; // The result we're building Scheme_Object *arglist = NULL; // The list of arguments Scheme_Object *outarglist = NULL; // The list of return values Scheme_Object *annolist = NULL; // The list of annotations Scheme_Object *name = NULL; // The method's name Scheme_Object *parampair = NULL; // ???? Scheme_Object *outparampair = NULL; // ???? GDBusMethodInfo *method; // Information on one method GDBusAnnotationInfo *anno; // Information on the annotations GDBusArgInfo *args, *outargs; // Information on the arguments LouDBusProxy *proxy; // The proxy gchar *methodName; // The method name int m; // Counter variable for methods // Get the proxy proxy = scheme_object_to_proxy (argv[0]); if (proxy == NULL) { scheme_wrong_type ("loudbus-methods", "LouDBusProxy *", 0, argc, argv); } // if proxy == NULL //Get the method name. WHAT IF WE CAN'T CONVERT TO A STRING???? methodName = scheme_object_to_string (argv[1]); // Permit the use of dashes in method names by converting them back // to underscores (which is what we use over DBus). score_it_all (methodName); //Get the method struct. WHAT IF THE METHOD DOESN'T EXIST???? method = g_dbus_interface_info_lookup_method (proxy->iinfo, methodName); // Build the list for arguments. arglist = scheme_null; for (m = parray_len ((gpointer *) method->in_args) - 1; m >= 0; m--) { args = method->in_args[m]; //Go through the arguments. val = scheme_make_symbol (args->name); val2 = scheme_make_symbol (args->signature); parampair = scheme_make_pair (val, val2); arglist = scheme_make_pair (parampair, arglist); } // for each argument //Build list for output. outarglist = scheme_null; for (m = parray_len ((gpointer *) method->out_args) - 1; m >= 0; m--) { outargs = method->out_args[m]; val = scheme_make_symbol (outargs->name); val2 = scheme_make_symbol (outargs->signature); outparampair = scheme_make_pair (val, val2); outarglist = scheme_make_pair (outparampair, outarglist); } // for each output formals // Build list of annotations annolist = scheme_null; for (m = parray_len ((gpointer *) method->annotations) - 1; m >= 0; m--) { anno = method->annotations[m]; //Go through the annotations. val = scheme_make_locale_string (anno->value); annolist = scheme_make_pair (val, annolist); } // for each annotation // Create the name entry name = scheme_null; name = scheme_make_pair (scheme_make_symbol(methodName), name); name = scheme_make_pair (scheme_make_symbol("name"), name); result = scheme_null; result = scheme_make_pair (annolist, result); result = scheme_make_pair (outarglist, result); result = scheme_make_pair (arglist, result); result = scheme_make_pair (name, result); // And we're done. return result; } // loudbus_method_info
/** * The kernel of the various mechanisms for calling D-Bus functions. */ static Scheme_Object * dbus_call_kernel (LouDBusProxy *proxy, gchar *dbus_name, gchar *external_name, int argc, Scheme_Object **argv) { GDBusMethodInfo *method; // Information on the actual method int arity; // The arity of that method GVariant *actuals; // The actual parameters GVariant *gresult; // The result from the function call as a GVariant Scheme_Object *sresult; // That Scheme result as a Scheme object GError *error; // Possible error from call // Grab the method information. method = g_dbus_interface_info_lookup_method (proxy->iinfo, dbus_name); if (method == NULL) { scheme_signal_error ("no such method: %s", dbus_name); } // if the method is invalid // Get the arity arity = g_dbus_method_info_num_formals (method); if (arity != argc) { scheme_signal_error ("%s expected %d params, received %d", external_name, arity, argc); } // if the arity is incorrect // Build the actuals actuals = scheme_objects_to_parameter_tuple (external_name, argc, argv, method->in_args); if (actuals == NULL) { scheme_signal_error ("%s: could not convert parameters", external_name); } // if (actuals == NULL) // Call the function. error = NULL; gresult = g_dbus_proxy_call_sync (proxy->proxy, dbus_name, actuals, 0, -1, NULL, &error); if (gresult == NULL) { if (error != NULL) { scheme_signal_error ("%s: call failed because %s", external_name, error->message); } // if (error != NULL) else { scheme_signal_error ("%s: call failed for unknown reason", external_name); } // if something went wrong, but there's no error } // if (gresult == NULL) // Convert to Scheme form sresult = g_variant_to_scheme_object (gresult); if (sresult == NULL) { scheme_signal_error ("%s: could not convert return values", external_name); } // if (sresult == NULL) // And we're done. return sresult; } // dbus_call_kernel
gboolean gnome_media_keys_will_be_useful() { GDBusConnection *bus = NULL; GVariant *response = NULL; GDBusNodeInfo *node_info = NULL; GDBusInterfaceInfo *interface_info; GDBusMethodInfo *method_info; const gchar *xml_data; gboolean result = TRUE; bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); if (!bus) { result = FALSE; goto out; } response = g_dbus_connection_call_sync(bus, "org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys", "org.freedesktop.DBus.Introspectable", "Introspect", NULL, G_VARIANT_TYPE ("(s)"), G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, NULL); if (!response) { result = FALSE; goto out; } g_variant_get(response, "(&s)", &xml_data); node_info = g_dbus_node_info_new_for_xml(xml_data, NULL); if (!node_info) { result = FALSE; goto out; } interface_info = g_dbus_node_info_lookup_interface(node_info, "org.gnome.SettingsDaemon.MediaKeys"); if (!interface_info) { result = FALSE; goto out; } method_info = g_dbus_interface_info_lookup_method(interface_info, "GrabMediaPlayerKeys"); if (!method_info) { result = FALSE; goto out; } out: if (bus) g_object_unref(bus); if (response) g_variant_unref(response); if (node_info) g_dbus_node_info_unref(node_info); return result; }