* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "gactiongroupexporter.h"
#include "gdbusmethodinvocation.h"
+#include "gremoteactiongroup.h"
#include "gdbusintrospection.h"
#include "gdbusconnection.h"
-#include "gdbusactiongroup.h"
#include "gactiongroup.h"
-#include "gapplication.h"
#include "gdbuserror.h"
-extern GDBusActionGroupEmitHookFunc g_dbus_action_group_before_emit_hook;
-extern GDBusActionGroupEmitHookFunc g_dbus_action_group_after_emit_hook;
-
/**
* SECTION:gactiongroupexporter
* @title: GActionGroup exporter
+ * @include: gio/gio.h
* @short_description: Export GActionGroups on D-Bus
* @see_also: #GActionGroup, #GDBusActionGroup
*
* detail.
*
* To access an exported #GActionGroup remotely, use
- * g_dbus_action_group_new() to obtain a #GDBusActionGroup.
+ * g_dbus_action_group_get() to obtain a #GDBusActionGroup.
*/
-G_GNUC_INTERNAL GVariant *
+static GVariant *
g_action_group_describe_action (GActionGroup *action_group,
const gchar *name)
{
return g_variant_builder_end (&builder);
}
-/* The org.gtk.Actions interface
- * =============================
- *
- * This interface describes a group of actions.
- *
- * Each action:
- * - has a unique string name
- * - can be activated
- * - optionally has a parameter type that must be given to the activation
- * - has an enabled state that may be true or false
- * - optionally has a state which can change value, but not type
- *
- * Methods
- * -------
- *
- * List :: () → (as)
- *
- * Lists the names of the actions exported at this object path.
- *
- * Describe :: (s) → (bgav)
- *
- * Describes a single action, or a given name.
- *
- * The return value has the following components:
- * b: specifies if the action is currently enabled. This is
- * a hint that attempting to interact with the action will
- * produce no effect.
- * g: specifies the optional parameter type. If not "",
- * the string specifies the type of argument that must
- * be passed to the activation.
- * av: specifies the optional state. If not empty, the array
- * contains the current value of the state as a variant
- *
- * DescribeAll :: () → (a{s(bgav)})
- *
- * Describes all actions in a single round-trip.
- *
- * The dictionary maps action name strings to their descriptions
- * (in the format discussed above).
- *
- * Activate :: (sava{sv}) → ()
- *
- * Requests activation of the named action.
- *
- * The action is named by the first parameter (s).
- *
- * If the action activation requires a parameter then this parameter
- * must be given in the second parameter (av). If there is no parameter
- * to be specified, the array must be empty.
- *
- * The final parameter (a{sv}) is a list of "platform data".
- *
- * This method is not guaranteed to have any particular effect. The
- * implementation may take some action (including changing the state
- * of the action, if it is stateful) or it may take none at all. In
- * particular, callers should expect their request to be completely
- * ignored when the enabled flag is false (but even this is not
- * guaranteed).
- *
- * SetState :: (sva{sv}) → ()
- *
- * Requests the state of an action to be changed to the given value.
- *
- * The action is named by the first parameter (s).
- *
- * The requested new state is given in the second parameter (v).
- * It must be equal in type to the existing state.
- *
- * The final parameter (a{sv}) is a list of "platform data".
- *
- * This method is not guaranteed to have any particular effect.
- * The implementation of an action can choose to ignore the requested
- * state change, or choose to change its state to something else or
- * to trigger other side effects. In particular, callers should expect
- * their request to be completely ignored when the enabled flag is
- * false (but even this is not guaranteed).
- *
- * Signals
- * -------
- *
- * Changed :: (asa{sb}a{sv}a{s(bgav)})
- *
- * Signals that some change has occured to the action group.
- *
- * Four separate types of changes are possible, and the 4 parameters
- * of the change signal reflect these possibilities:
- * as: a list of removed actions
- * a{sb}: a list of actions that had their enabled flag changed
- * a{sv}: a list of actions that had their state changed
- * a{s(bgav)}: a list of new actions added in the same format as
- * the return value of the DescribeAll method
- */
-
/* Using XML saves us dozens of relocations vs. using the introspection
* structure types. We only need to burn cycles and memory if we
* actually use the exporter -- not in every single app using GIO.
*
* It's also a lot easier to read. :)
+ *
+ * For documentation of this interface, see
+ * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI
*/
const char org_gtk_Actions_xml[] =
"<node>"
source = g_idle_source_new ();
exporter->pending_source = source;
g_source_set_callback (source, g_action_group_exporter_dispatch_events, exporter, NULL);
+ g_source_set_name (source, "[gio] g_action_group_exporter_dispatch_events");
g_source_attach (source, exporter->context);
g_source_unref (source);
}
}
static void
-g_action_group_exporter_pre_emit (GActionGroupExporter *exporter,
- GVariant *platform_data)
-{
- if (G_IS_APPLICATION (exporter->action_group))
- G_APPLICATION_GET_CLASS (exporter->action_group)
- ->before_emit (G_APPLICATION (exporter->action_group), platform_data);
-
- else if (g_dbus_action_group_before_emit_hook != NULL)
- (* g_dbus_action_group_before_emit_hook) (exporter->action_group, platform_data);
-}
-
-static void
-g_action_group_exporter_post_emit (GActionGroupExporter *exporter,
- GVariant *platform_data)
-{
- if (G_IS_APPLICATION (exporter->action_group))
- G_APPLICATION_GET_CLASS (exporter->action_group)
- ->after_emit (G_APPLICATION (exporter->action_group), platform_data);
-
- else if (g_dbus_action_group_after_emit_hook != NULL)
- (* g_dbus_action_group_after_emit_hook) (exporter->action_group, platform_data);
-}
-
-static void
org_gtk_Actions_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
GVariant *desc;
g_variant_get (parameters, "(&s)", &name);
+
+ if (!g_action_group_has_action (exporter->action_group, name))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+ "The named action ('%s') does not exist.", name);
+ return;
+ }
+
desc = g_action_group_describe_action (exporter->action_group, name);
result = g_variant_new ("(@(bgav))", desc);
}
g_variant_iter_next (iter, "v", ¶meter);
g_variant_iter_free (iter);
- g_action_group_exporter_pre_emit (exporter, platform_data);
- g_action_group_activate_action (exporter->action_group, name, parameter);
- g_action_group_exporter_post_emit (exporter, platform_data);
+ if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group))
+ g_remote_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (exporter->action_group),
+ name, parameter, platform_data);
+ else
+ g_action_group_activate_action (exporter->action_group, name, parameter);
if (parameter)
g_variant_unref (parameter);
GVariant *state;
g_variant_get (parameters, "(&sv@a{sv})", &name, &state, &platform_data);
- g_action_group_exporter_pre_emit (exporter, platform_data);
- g_action_group_change_action_state (exporter->action_group, name, state);
- g_action_group_exporter_post_emit (exporter, platform_data);
+
+ if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group))
+ g_remote_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (exporter->action_group),
+ name, state, platform_data);
+ else
+ g_action_group_change_action_state (exporter->action_group, name, state);
+
g_variant_unref (platform_data);
g_variant_unref (state);
}